blob: d62207edb218468e029f4729dd328f03647e1eb0 [file] [log] [blame]
/*********************************************************************
* Copyright (c) 2011, 2013 Tasktop Technologies and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*********************************************************************/
package org.eclipse.mylyn.internal.gerrit.core.client;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.mylyn.internal.gerrit.core.GerritConnector;
import org.eclipse.mylyn.internal.gerrit.core.client.GerritHttpClient.JsonEntity;
import org.osgi.framework.Version;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwtjsonrpc.client.RemoteJsonService;
/**
* @author Steffen Pingel
*/
public class GerritService implements InvocationHandler {
public static class GerritRequest {
private static ThreadLocal<GerritRequest> currentRequest = new ThreadLocal<GerritRequest>();
public static GerritRequest getCurrentRequest() {
return currentRequest.get();
}
public static void setCurrentRequest(GerritRequest request) {
currentRequest.set(request);
}
private final IProgressMonitor monitor;
public GerritRequest(IProgressMonitor monitor) {
this.monitor = monitor;
}
public IProgressMonitor getMonitor() {
return monitor;
}
}
public static <T extends RemoteJsonService> T create(Class<T> serviceClass, GerritHttpClient gerritHttpClient,
Version version) {
InvocationHandler handler = new GerritService(gerritHttpClient, GerritConnector.GERRIT_260_RPC_URI
+ serviceClass.getSimpleName());
return serviceClass.cast(Proxy.newProxyInstance(GerritService.class.getClassLoader(),
new Class<?>[] { serviceClass }, handler));
}
private final String uri;
protected GerritHttpClient client;
public GerritService(GerritHttpClient client, String uri) {
this.client = client;
this.uri = uri;
}
public String getServiceUri() {
return uri;
}
public Object invoke(Object proxy, final Method method, Object[] args) {
final JSonSupport json = new JSonSupport();
// construct request
final List<Object> parameters = new ArrayList<Object>(args.length - 1);
for (int i = 0; i < args.length - 1; i++) {
parameters.add(args[i]);
}
@SuppressWarnings("unchecked")
AsyncCallback<Object> callback = (AsyncCallback<Object>) args[args.length - 1];
try {
GerritRequest request = GerritRequest.getCurrentRequest();
IProgressMonitor monitor = (request != null) ? request.getMonitor() : null;
// execute request
String responseMessage = client.postJsonRequest(getServiceUri(), new JsonEntity() {
@Override
public String getContent() {
String methodName = method.getName();
if (methodName.endsWith("X")) { //$NON-NLS-1$
methodName = methodName.substring(0, methodName.length() - 1);
}
return json.createRequest(client.getId(), client.getXsrfKey(), methodName, parameters);
}
}, monitor);
// the last parameter is a parameterized callback that defines the return type
Type[] types = method.getGenericParameterTypes();
final Type resultType = ((ParameterizedType) types[types.length - 1]).getActualTypeArguments()[0];
Object result = json.parseJsonResponse(responseMessage, resultType);
callback.onSuccess(result);
} catch (Throwable e) {
callback.onFailure(e);
}
// all methods are designed to be asynchronous and expected to return void
return null;
};
}