I am developing a GWT app for the Google Apps marketplace. I am using AppEngine with Restlet on the server side. Client side I use the GWT edition of Restlet. This is a great combination. I have my domain objects shared between client and server and as such no need for DTO's or proxies and so on. On the client side I can simply call Restlet resources :
CustomerResourceProxy customerResource = GWT.create(CustomerResourceProxy.class);
customerResource.getClientResource().setReference("/customer");
customerResource.retrieve(new Result<Customer>() { .... }
No need to parse the underlying XML or use JSNI to interpret incoming JSON.
BUT... part of the app is a GMAIL contextual gadget, and I cannot simply use the above code because all communication between a Gadget and the server must pass through GadgetsIO makeRequest.
So... just for the gadget, I will have to make the effort of parsing the XML or using JSNI to interpret the incoming JSON.
Is it überhaupt possible to hack the Restlet GWT client to pass all communication via GadgetsIO and what would it take ? Any pointers very welcome !
K.
I managed to get Restlet resources to work within a Gadget using GWT by making some changes to the Restlet GWT edition :
In GwtClientCall I replaced the standard GWT requestbuilder by the GadgetRequestBuilder (which will IoProvider.makeRequest), like this :
public GwtClientCall(GwtHttpClientHelper helper, String method, String requestUri, boolean hasEntity) {
super(helper, method, requestUri);
Reference requestRef = new Reference(requestUri);
if (requestRef.isRelative() || requestRef.getScheme().startsWith("http")) {
this.requestBuilder = new GadgetsRequestBuilder(method, requestUri);
this.requestBuilder.setTimeoutMillis(getHelper().getSocketConnectTimeoutMs());
this.responseHeadersAdded = false;
} else {
throw new IllegalArgumentException("Only HTTP or HTTPS resource URIs are allowed here");
}
}
In the gadgetsrequestbuilder, I had to make some changes so it would pass the headers in the request :
private GadgetsRequest doSend(String requestData, final RequestCallback callback) throws RequestException {
final RequestOptions options = RequestOptions.newInstance();
options.setMethodType(methodType);
if (requestData != null && requestData.length() > 0) {
options.setPostData(requestData);
}
options.setAuthorizationType(AuthorizationType.SIGNED);
options.setContentType(ContentType.DOM);
setHeaders(options);
final GadgetsRequest gadgetsRequest = new GadgetsRequest(getTimeoutMillis(), callback);
gadgetsRequest.setPending(true);
IoProvider.get().makeRequest(getUrl(), new ResponseReceivedHandler<Object>() {
public void onResponseReceived(ResponseReceivedEvent<Object> event) {
gadgetsRequest.fireOnResponseReceived(event, callback);
}
}, options);
return gadgetsRequest;
}
the gadget container by default strips the response headers, so i manually add the MediaType.APPLICATION_JAVA_OBJECT_GWT
@Override
public Series<org.restlet.client.engine.header.Header> getResponseHeaders() {
final Series<org.restlet.client.engine.header.Header> result = super.getResponseHeaders();
if (!this.responseHeadersAdded && (getResponse() != null)) {
Header[] headers = getResponse().getHeaders();
for (int i = 0; i < headers.length; i++) {
if (headers[i] != null) {
result.add(headers[i].getName(), headers[i].getValue());
}
}
result.add(HeaderConstants.HEADER_CONTENT_TYPE, MediaType.APPLICATION_JAVA_OBJECT_GWT.toString());
this.responseHeadersAdded = true;
}
return result;
}
A lot of dialogboxes for debugging later, it works :-)