Author: awiner
Date: Thu Feb 19 18:46:40 2009
New Revision: 745964
URL: http://svn.apache.org/viewvc?rev=745964&view=rev
Log:
Support per-request item handlers:
This adds support for per-request handlers: handlers registered by
Class will be created once per-request, handlers registered by instance
will (of course) just use that instance.
(I've also fixed unchecked coercion warnings)
Modified:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java
Modified:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java?rev=745964&r1=745963&r2=745964&view=diff
==============================================================================
---
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java
(original)
+++
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DefaultHandlerRegistry.java
Thu Feb 19 18:46:40 2009
@@ -30,6 +30,7 @@
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.Injector;
+import com.google.inject.Provider;
import com.google.inject.name.Named;
import org.json.JSONException;
@@ -142,48 +143,54 @@
* Adds a custom handler.
*/
public void addHandlers(Object... handlers) {
- for (Object handler : handlers) {
- Class handlerType;
+ for (final Object handler : handlers) {
+ Class<?> handlerType;
+ Provider<?> handlerProvider;
if (handler instanceof Class) {
- handlerType = (Class) handler;
- handler = injector.getInstance(handlerType);
+ handlerType = (Class<?>) handler;
+ handlerProvider = injector.getProvider(handlerType);
} else {
handlerType = handler.getClass();
+ handlerProvider = new Provider<Object>() {
+ public Object get() {
+ return handler;
+ }
+ };
}
if (!handlerType.isAnnotationPresent(Service.class)) {
throw new IllegalStateException("Attempt to bind unannotated service
implementation " +
handlerType.getName());
}
Service service = (Service) handlerType.getAnnotation(Service.class);
- String serviceName = service.name();
for (Method m : handlerType.getMethods()) {
if (m.isAnnotationPresent(Operation.class)) {
Operation op = m.getAnnotation(Operation.class);
- createRpcHandler(handler, service, op, m);
- createRestHandler(handler, service, op, m);
+ createRpcHandler(handlerProvider, service, op, m);
+ createRestHandler(handlerProvider, service, op, m);
}
}
}
}
- private void createRestHandler(Object handler, Service service, Operation
op, Method m) {
+ private void createRestHandler(Provider<?> handlerProvider,
+ Service service, Operation op, Method m) {
// Check for request item subclass constructor
- Class requestItemType = m.getParameterTypes()[0];
+ Class<?> requestItemType = m.getParameterTypes()[0];
try {
if (RequestItem.class.isAssignableFrom(requestItemType)) {
if (requestItemType == RequestItem.class) {
requestItemType = BaseRequestItem.class;
}
- Constructor reqItemConstructor =
+ Constructor<?> reqItemConstructor =
requestItemType.getConstructor(Map.class, SecurityToken.class,
BeanConverter.class,
BeanJsonConverter.class);
String opName = m.getName();
if (!StringUtils.isEmpty(op.name())) {
opName = op.name();
}
- RestInvocationHandler restHandler = new RestInvocationHandler(service,
op, m, handler,
- beanJsonConverter, reqItemConstructor,
+ RestInvocationHandler restHandler = new RestInvocationHandler(service,
op, m,
+ handlerProvider, beanJsonConverter, reqItemConstructor,
new ExecutionListenerWrapper(service.name(), opName,
executionListener));
String serviceName = service.name();
@@ -217,15 +224,16 @@
}
- private void createRpcHandler(Object handler, Service service, Operation op,
Method m) {
+ private void createRpcHandler(Provider<?> handlerProvider,
+ Service service, Operation op, Method m) {
// Check for request item subclass constructor
- Class requestItemType = m.getParameterTypes()[0];
+ Class<?> requestItemType = m.getParameterTypes()[0];
try {
if (RequestItem.class.isAssignableFrom(requestItemType)) {
if (requestItemType == RequestItem.class) {
requestItemType = BaseRequestItem.class;
}
- Constructor reqItemConstructor =
+ Constructor<?> reqItemConstructor =
requestItemType.getConstructor(JSONObject.class,
SecurityToken.class,
BeanConverter.class,
BeanJsonConverter.class);
@@ -235,7 +243,7 @@
opName = op.name();
}
RpcInvocationHandler rpcHandler =
- new RpcInvocationHandler(m, handler, beanJsonConverter,
reqItemConstructor,
+ new RpcInvocationHandler(m, handlerProvider, beanJsonConverter,
reqItemConstructor,
new ExecutionListenerWrapper(service.name(), opName,
executionListener));
rpcOperations.put(service.name() + "." + opName, rpcHandler);
}
@@ -270,23 +278,24 @@
*/
static final class RpcInvocationHandler {
private Method receiver;
- Object handlerInstance;
+ Provider<?> handlerProvider;
BeanJsonConverter beanJsonConverter;
- Constructor requestItemConstructor;
+ Constructor<?> requestItemConstructor;
ExecutionListenerWrapper listener;
- private RpcInvocationHandler(Method receiver, Object handlerInstance,
+ private RpcInvocationHandler(Method receiver,
+ Provider<?> handlerProvider,
BeanJsonConverter beanJsonConverter,
- Constructor reqItemConstructor,
+ Constructor<?> reqItemConstructor,
ExecutionListenerWrapper listener) {
this.receiver = receiver;
- this.handlerInstance = handlerInstance;
+ this.handlerProvider = handlerProvider;
this.beanJsonConverter = beanJsonConverter;
this.requestItemConstructor = reqItemConstructor;
this.listener = listener;
}
- public Future execute(JSONObject rpc, SecurityToken token, BeanConverter
converter) {
+ public Future<?> execute(JSONObject rpc, SecurityToken token,
BeanConverter converter) {
try {
RequestItem item;
if (rpc.has("params")) {
@@ -297,9 +306,9 @@
converter, beanJsonConverter);
}
listener.executing(item);
- Object result = receiver.invoke(handlerInstance, item);
+ Object result = receiver.invoke(handlerProvider.get(), item);
if (result instanceof Future) {
- return (Future) result;
+ return (Future<?>) result;
}
return ImmediateFuture.newInstance(result);
} catch (InvocationTargetException ite) {
@@ -334,24 +343,26 @@
* return non-Future types by wrapping them in ImmediateFuture.
*/
static final class RestInvocationHandler {
- Method receiver;
- Object handlerInstance;
- Service service;
- Operation operation;
+ final Method receiver;
+ final Provider<?> handlerProvider;
+ final Service service;
+ final Operation operation;
final String[] expectedUrl;
- BeanJsonConverter beanJsonConverter;
- Constructor requestItemConstructor;
- ExecutionListenerWrapper listener;
-
- private RestInvocationHandler(Service service, Operation operation,
- Method receiver, Object handlerInstance,
- BeanJsonConverter beanJsonConverter,
- Constructor requestItemConstructor,
- ExecutionListenerWrapper listener) {
+ final BeanJsonConverter beanJsonConverter;
+ final Constructor<?> requestItemConstructor;
+ final ExecutionListenerWrapper listener;
+
+ private RestInvocationHandler(Service service,
+ Operation operation,
+ Method receiver,
+ Provider<?> handlerProvider,
+ BeanJsonConverter beanJsonConverter,
+ Constructor<?> requestItemConstructor,
+ ExecutionListenerWrapper listener) {
this.service = service;
this.operation = operation;
this.receiver = receiver;
- this.handlerInstance = handlerInstance;
+ this.handlerProvider = handlerProvider;
expectedUrl = service.path().split("/");
this.beanJsonConverter = beanJsonConverter;
this.requestItemConstructor = requestItemConstructor;
@@ -368,9 +379,9 @@
RequestItem item = (RequestItem)
requestItemConstructor.newInstance(parameters, token,
converter, beanJsonConverter);
listener.executing(item);
- Object result = receiver.invoke(handlerInstance, item);
+ Object result = receiver.invoke(handlerProvider.get(), item);
if (result instanceof Future) {
- return (Future) result;
+ return (Future<?>) result;
}
return ImmediateFuture.newInstance(result);
} catch (InvocationTargetException ite) {
@@ -414,7 +425,7 @@
this.error = error;
}
- public Future execute(Map parameters, Reader body,
+ public Future<?> execute(Map<String, String[]> parameters, Reader body,
SecurityToken token, BeanConverter converter) {
return ImmediateFuture.errorInstance(error);
}
@@ -431,7 +442,7 @@
this.error = error;
}
- public Future execute(SecurityToken token, BeanConverter converter) {
+ public Future<?> execute(SecurityToken token, BeanConverter converter) {
return ImmediateFuture.errorInstance(error);
}
}
@@ -439,7 +450,7 @@
/**
* Path matching and parameter extraction for REST.
*/
- static class RestPath implements Comparable {
+ static class RestPath implements Comparable<RestPath> {
enum PartType {
CONST, SINGULAR_PARAM, PLURAL_PARAM
@@ -468,7 +479,6 @@
parts = Lists.newArrayList();
for (int i = 0; i < partArr.length; i++) {
String part = partArr[i];
- PartType type = PartType.CONST;
if (part.startsWith("{")) {
if (part.endsWith("}+")) {
parts.add(new Part(part.substring(1, part.length() - 2),
PartType.PLURAL_PARAM));
@@ -526,13 +536,11 @@
return new RestInvocationWrapper(parsedParams, handler);
}
-
/**
* Rank based on the number of consant parts they accept, where the
constant parts occur
* and lexical ordering.
*/
- public int compareTo(Object o) {
- RestPath other = (RestPath) o;
+ public int compareTo(RestPath other) {
// Rank first by number of constant elements in the path
int result = other.constCount - this.constCount;
if (result == 0) {
Modified:
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java?rev=745964&r1=745963&r2=745964&view=diff
==============================================================================
---
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java
(original)
+++
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DefaultHandlerRegistryTest.java
Thu Feb 19 18:46:40 2009
@@ -77,7 +77,7 @@
JSONObject rpc = new JSONObject("{method : makebelieve.get}");
RpcHandler rpcHandler = registry.getRpcHandler(rpc);
try {
- Future future = rpcHandler.execute(null, null);
+ Future<?> future = rpcHandler.execute(null, null);
future.get();
fail("Expect exception for missing method");
} catch (ExecutionException t) {
@@ -91,7 +91,7 @@
public void testRestHandler_serviceDoesntExist() {
RestHandler restHandler = registry.getRestHandler("/makebelieve", "GET");
try {
- Future future = restHandler.execute(Maps.<String, String[]>newHashMap(),
null, null, null);
+ Future<?> future = restHandler.execute(Maps.<String,
String[]>newHashMap(), null, null, null);
future.get();
fail("Expect exception for missing method");
} catch (ExecutionException t) {
@@ -105,14 +105,14 @@
public void testNonFutureDispatch() throws Exception {
// Test calling a handler method which does not return a future
RestHandler handler = registry.getRestHandler("/test", "GET");
- Future future = handler.execute(Maps.<String, String[]>newHashMap(), null,
null, null);
+ Future<?> future = handler.execute(Maps.<String, String[]>newHashMap(),
null, null, null);
assertEquals(future.get(), TestHandler.GET_RESPONSE);
}
public void testFutureDispatch() throws Exception {
// Test calling a handler method which does not return a future
RestHandler handler = registry.getRestHandler("/test", "POST");
- Future future = handler.execute(Maps.<String, String[]>newHashMap(), null,
null, null);
+ Future<?> future = handler.execute(Maps.<String, String[]>newHashMap(),
null, null, null);
assertEquals(future.get(), TestHandler.CREATE_RESPONSE);
}
@@ -120,7 +120,7 @@
// Test calling a handler method which does not return a future
JSONObject rpc = new JSONObject("{ method : test.exception }");
RpcHandler handler = registry.getRpcHandler(rpc);
- Future future = handler.execute(null, null);
+ Future<?> future = handler.execute(null, null);
try {
future.get();
fail("Service method did not produce NullPointerException from Future");
@@ -133,7 +133,7 @@
// Test calling a handler method which does not return a future
JSONObject rpc = new JSONObject("{ method : test.futureException }");
RpcHandler handler = registry.getRpcHandler(rpc);
- Future future = handler.execute(null, null);
+ Future<?> future = handler.execute(null, null);
try {
future.get();
fail("Service method did not produce ExecutionException from Future");