xapi.io.impl.IORequestBuilderDefault Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xapi-dev Show documentation
Show all versions of xapi-dev Show documentation
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.copyDictionary;
import static xapi.collect.X_Collect.newDictionary;
import static xapi.io.IOConstants.METHOD_DELETE;
import static xapi.io.IOConstants.METHOD_GET;
import static xapi.io.IOConstants.METHOD_HEAD;
import static xapi.io.IOConstants.METHOD_PATCH;
import static xapi.io.IOConstants.METHOD_POST;
import static xapi.io.IOConstants.METHOD_PUT;
import xapi.collect.api.StringDictionary;
import xapi.collect.api.StringTo.Many;
import xapi.except.NotYetImplemented;
import xapi.io.X_IO;
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.X_Log;
import xapi.util.X_Runtime;
import xapi.util.X_String;
import xapi.util.api.ConvertsValue;
import xapi.util.api.ErrorHandler;
import xapi.util.api.Pointer;
import xapi.util.api.SuccessHandler;
public class IORequestBuilderDefault implements IORequestBuilder{
private int modifier;
private String url;
private ConvertsValue deserializer;
private ConvertsValue serializer;
private final StringDictionary headers = initHeaders();
private Out value;
protected static class IO implements IORequest {
boolean pending = true, cancel = false;
private IORequest request;
private final Pointer response;
private final Pointer error;
private String statusText;
private int statusCode;
public IO(final Pointer response, final Pointer error) {
this.response = response;
this.error = error;
}
@Override
public boolean isPending() {
return pending;
}
@Override
public boolean isSuccess() {
if (request == null) {
return false;
}
return !(pending || cancel) && error.get() == null && request.isSuccess();
}
@Override
public void cancel() {
cancel = true;
pending = false;
request.cancel();
}
@Override
public Out response() {
try {
return response.get();
} finally {
pending = false;
}
}
@Override
public Many headers() {
return request.headers();
}
/**
* @param request -> set request
*/
public void setRequest(final IORequest request) {
this.request = request;
if (cancel) {
request.cancel();
}
}
/**
* @see xapi.io.api.IORequest#getStatusCode()
*/
@Override
public int getStatusCode() {
return statusCode;
}
/**
* @see xapi.io.api.IORequest#getStatusText()
*/
@Override
public String getStatusText() {
return statusText;
}
};
@Override
public IORequest send(final SuccessHandler handler) {
// Take a snapshot of the builder values, in case user reuses it.
final int modifer = this.modifier;
final String url = this.url;
final ConvertsValue serializer = this.serializer;
final StringDictionary headerCopy = initHeaders();
copyDictionary(this.headers, headerCopy);
final Pointer result = new Pointer(value);
final Pointer failure = new Pointer(null);
final IOService service = service();
final IO request = createIO(result, failure);
final IOCallback> callback = createCallback(request, result, failure, deserializer, handler);
final IORequest io;
// perform the actual send.
switch (modifer) {
case METHOD_DELETE:
throw new NotYetImplemented("Method DELETE not yet implemented");
// service.delete(url, headerCopy, callback);
// break;
case METHOD_GET:
io = service.get(url, headerCopy, callback);
break;
case METHOD_POST:
throw new NotYetImplemented("Method POST not yet implemented");
// service.post(url, serializer.convert(value), headerCopy, callback);
// break;
case METHOD_PUT:
throw new NotYetImplemented("Method PUT not yet implemented");
// service.put(url, toBinary(serializer.convert(value)), headerCopy, callback);
// break;
case METHOD_HEAD:
throw new NotYetImplemented("Method HEAD not yet implemented");
case METHOD_PATCH:
throw new NotYetImplemented("Method PATCH not yet implemented");
default:
throw new UnsupportedOperationException("Unknown request type "+modifer);
}
request.setRequest(io);
return request;
}
private IOCallback> createCallback(final IO request, final Pointer result,
final Pointer failure, final ConvertsValue deserializer, final SuccessHandler handler) {
return new IOCallback>() {
private boolean cancel = false;
@Override
public void onSuccess(final IOMessage t) {
if (cancel) {
if (X_Runtime.isDebug()) {
X_Log.trace("Ignoring cancelled message", t.url(), t.body());
}
return;
}
request.pending = false;
request.statusCode = t.statusCode();
request.statusText = t.statusMessage();
if (deserializer == null) {
assert X_String.isEmpty(t.body()) : "Non-null response without a " +
"deserializer instance for "+url+"\n Response: "+t.body();
} else {
result.set(deserializer.convert(t.body()));
}
if (handler != null) {
handler.onSuccess(result.get());
}
}
@Override
@SuppressWarnings("unchecked")
public void onError(final Throwable e) {
failure.set(e);
request.pending = false;
if (handler instanceof ErrorHandler) {
((ErrorHandler)handler).onError(e);
}
}
@Override
public void onCancel() {
cancel = true;
request.cancel();
}
@Override
public boolean isCancelled() {
return cancel;
}
};
}
protected IO createIO(final Pointer result, final Pointer failure) {
return new IO(result, failure);
}
protected byte[] toBinary(final String convert) {
return X_String.getBytes(convert);
}
protected StringDictionary initHeaders() {
return newDictionary();
}
@Override
public IOService service() {
return X_IO.getIOService();
}
@Override
public IORequestBuilder setDeserializer(final ConvertsValue deserializer) {
this.deserializer = deserializer;
return this;
}
@Override
public IORequestBuilder setSerializer(final ConvertsValue serializer) {
this.serializer = serializer;
return this;
}
@Override
public IORequestBuilder setUrl(final String url) {
this.url = url;
return this;
}
@Override
public IORequestBuilder setHeader(final String header, final String value) {
headers.setValue(header, value);
return this;
}
@Override
public IORequestBuilder setModifier(final int modifier) {
this.modifier = modifier;
return this;
}
@Override
public IORequestBuilder setValue(final Out value) {
this.value = value;
return this;
}
}