All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xapi.io.impl.AbstractIOService Maven / Gradle / Ivy

Go to download

Everything needed to run a comprehensive dev environment. Just type X_ and pick a service from autocomplete; new dev modules will be added as they are built. The only dev service not included in the uber jar is xapi-dev-maven, as it includes all runtime dependencies of maven, adding ~4 seconds to build time, and 6 megabytes to the final output jar size (without xapi-dev-maven, it's ~1MB).

The newest version!
package xapi.io.impl;

import static xapi.collect.X_Collect.newClassMap;

import javax.inject.Provider;

import xapi.collect.X_Collect;
import xapi.collect.api.ClassTo;
import xapi.collect.api.StringDictionary;
import xapi.collect.api.StringTo.Many;
import xapi.io.IOConstants;
import xapi.io.api.IOCallback;
import xapi.io.api.IOMessage;
import xapi.io.api.IORequest;
import xapi.io.api.IORequestBuilder;
import xapi.io.service.IOService;
import xapi.log.api.LogLevel;
import xapi.util.X_Namespace;
import xapi.util.X_Properties;
import xapi.util.api.ConvertsValue;
import xapi.util.api.ReceivesValue;
import xapi.util.api.RemovalHandler;

public abstract class AbstractIOService  implements IOService{

  public AbstractIOService() {
  }

  protected static final IORequest cancelled = new IORequest() {

    @Override
    public boolean isPending() {
      return false;
    }

    @Override
    public boolean isSuccess() {
      return false;
    }

    @Override
    public void cancel() {
    }

    @Override
    public String response() {
      return null;
    }

    @Override
    public Many headers() {
      return X_Collect.newStringMultiMap(String.class);
    }

    @Override
    public int getStatusCode() {
      return STATUS_CANCELLED;
    }

    @Override
    public String getStatusText() {
      return "Request Cancelled";
    }
  };

  public abstract class AbstractIORequest implements IORequest {

    private boolean pending = true;
    private String value;
    private volatile boolean cancel;
    private boolean started;
    protected Provider> resultHeaders;
    private int statusCode = STATUS_INCOMPLETE;
    private String statusText = "Request Incomplete";

    @Override
    public boolean isPending() {
      return pending;
    }

    public void start() {
      this.started = true;
    }

    @Override
    public boolean isSuccess() {
      return pending == false && cancel == false && value != null;
    }

    @Override
    public void cancel() {
      this.pending = false;
      this.cancel = false;
    }

    @Override
    public Many headers() {
      return resultHeaders == null ? X_Collect.newStringMultiMap(String.class) : resultHeaders.get();
    }

    public boolean isStarted() {
      return started;
    }

    public boolean isCancelled() {
      return cancel;
    }

    /**
     * @return -> value
     */
    public String getValue() {
      return value;
    }

    /**
     * @param value -> set value
     */
    public void setValue(final String value) {
      pending = false;
      this.value = value;
    }

    public void setResultHeaders(final Provider> resultHeaders) {
      this.resultHeaders = resultHeaders;
    }

    public void setStatus(final int statusCode, final String statusText) {
      this.statusCode = statusCode;
      this.statusText = statusText;
    }

    @Override
    public int getStatusCode() {
      return statusCode;
    }

    @Override
    public String getStatusText() {
      return statusText;
    }

  }

  @SuppressWarnings("unchecked")
  private static final Class> SERIAL_CLASS
    = Class.class.cast(ConvertsValue.class);

  @SuppressWarnings("unchecked")
  private static final Class> DESERIAL_CLASS
    = Class.class.cast(ConvertsValue.class);

  protected final ClassTo> serializers = newClassMap(SERIAL_CLASS);

  protected final ClassTo> deserializers = newClassMap(DESERIAL_CLASS);

  @Override
  @SuppressWarnings("unchecked") // The class key is always checked for us...
  public  IORequestBuilder request(final Class classLit, final String id) {
    return this.createRequestBuilder()
      .setUrl(toUrl(classLit, id))
      .setDeserializer(ConvertsValue.class.cast(deserializers.get(classLit)))
      .setSerializer(ConvertsValue.class.cast(serializers.get(classLit)))
    ;
  }

  protected  IORequestBuilderDefault createRequestBuilder() {
    return new IORequestBuilderDefault();
  }

  protected LogLevel logLevel() {
    return LogLevel.DEBUG;
  }

  @Override
  @SuppressWarnings({
      "unchecked", "rawtypes"
  })
  public  RemovalHandler registerParser(final Class classLit,
    final ConvertsValue serializer,
    final ConvertsValue deserializer
    ) {
    final ConvertsValue currentSerializer = serializers.put(classLit, serializer);
    final ConvertsValue currentDeserialize = deserializers.put(classLit, deserializer);
    // In case a user wants to wrap the existing serializers, we will send them the previous instances.
    if (serializer instanceof ReceivesValue) {
      ((ReceivesValue)serializer).set(currentSerializer);
    }
    if (deserializer instanceof ReceivesValue) {
      ((ReceivesValue)deserializer).set(currentDeserialize);
    }
    return new RemovalHandler() {
      @Override
      public void remove() {
        // check before set.
        if (serializers.get(classLit) == serializer) {
          serializers.put(classLit, currentSerializer);
        }
        if (deserializers.get(classLit) == deserializer) {
          deserializers.put(classLit, currentDeserialize);
        }
      }
    };
  }

  @Override
  public void put(final String url, final byte[] body, final StringDictionary headers,
    final IOCallback> callback) {

  }

  protected String uriBase() {
    final String port = X_Properties.getProperty(X_Namespace.PROPERTY_SERVER_PORT, "");
    return System.getProperty(X_Namespace.PROPERTY_SERVER_HOST, "0.0.0.0")
      + (port.length()==0?"":":"+port);
  }

  /**
   * Allow subclasses to apply any settings to the connection before we open it
   * @param connect - An instance of whatever transport mechanism this IO service uses, just before it is opened.
   * @param modifiers - The type of connection,
   * see {@link IOConstants#METHOD_GET}, {@link IOConstants#METHOD_PUT} and friends
   */
  protected void applySettings(final Transport connect, final int modifiers) {

  }

  protected String normalize(String uri) {
    if (uri.charAt(0) == '/') {
      uri = uriBase() + uri;
    }
    if (!uri.contains("://")) {
      uri = "http://"+uri;
    }
    return uri;
  }

  protected String toUrl(final Class classLit, final String id) {
    return id;
  }

  @Override
  public void delete(final String url, final StringDictionary headers, final IOCallback> callback) {

  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy