From da0aff02c15c1e29b844717f4e8911e0d1e80f5b Mon Sep 17 00:00:00 2001 From: lresende Date: Fri, 30 Apr 2010 17:15:53 +0000 Subject: Enhanced support for JAX-RS annotations allowing @Path({id}) to be mapped to an operation expecting a id paramenter. This gives basic support for get and delete operations on a given resource git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@939744 13f79535-47bb-0310-9956-ffa450edef68 --- .../JAXRSOperationSelectorInterceptor.java | 76 ++++++++++++++++++---- .../rest/provider/RESTBindingListenerServlet.java | 11 ++++ .../rest/provider/RESTServiceBindingProvider.java | 36 +++++----- .../json/provider/JSONWireFormatInterceptor.java | 5 +- 4 files changed, 93 insertions(+), 35 deletions(-) (limited to 'sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache') diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java index 199ba0a696..d71762f11e 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/operationselector/jaxrs/provider/JAXRSOperationSelectorInterceptor.java @@ -19,17 +19,22 @@ package org.apache.tuscany.sca.binding.rest.operationselector.jaxrs.provider; +import java.lang.reflect.Method; +import java.net.URLDecoder; import java.util.List; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; +import javax.ws.rs.Path; import org.apache.tuscany.sca.common.http.HTTPContext; +import org.apache.tuscany.sca.common.http.HTTPUtil; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.JavaOperation; import org.apache.tuscany.sca.invocation.Interceptor; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.Message; @@ -69,13 +74,34 @@ public class JAXRSOperationSelectorInterceptor implements Interceptor { } public Message invoke(Message msg) { - HTTPContext bindingContext = (HTTPContext) msg.getBindingContext(); - - Operation operation = findOperation(bindingContext.getHttpRequest().getMethod()); - - msg.setOperation(operation); - - return getNext().invoke(msg); + try { + HTTPContext bindingContext = (HTTPContext) msg.getBindingContext(); + + String path = URLDecoder.decode(HTTPUtil.getRequestPath(bindingContext.getHttpRequest()), "UTF-8"); + + if(path.startsWith("/")) { + path = path.substring(1); + } + + List operations = filterOperationsByHttpMethod(interfaceContract, bindingContext.getHttpRequest().getMethod()); + + Operation operation = findOperation(path, operations); + + final JavaOperation javaOperation = (JavaOperation) operation; + final Method method = javaOperation.getJavaMethod(); + + if(path != null && path.length() > 0) { + if(method.getAnnotation(Path.class) != null) { + msg.setBody(new Object[]{path}); + } + } + + msg.setOperation(operation); + + return getNext().invoke(msg); + } catch(Exception e) { + throw new RuntimeException(e); + } } /** @@ -84,7 +110,7 @@ public class JAXRSOperationSelectorInterceptor implements Interceptor { * @param http_method * @return */ - private Operation findOperation(String http_method) { + private static List filterOperationsByHttpMethod(InterfaceContract interfaceContract, String http_method) { List operations = null; if(http_method.equalsIgnoreCase("get")) { @@ -97,13 +123,35 @@ public class JAXRSOperationSelectorInterceptor implements Interceptor { operations = (List) interfaceContract.getInterface().getAttributes().get(DELETE.class); } - Operation result = null; - if(operations != null) { - if(! operations.isEmpty()) { - result = operations.get(0); + return operations; + } + + /** + * Find the operation from the component service contract + * @param componentService + * @param http_method + * @return + */ + private Operation findOperation(String path, List operations) { + Operation operation = null; + + for(Operation op : operations) { + final JavaOperation javaOperation = (JavaOperation) op; + final Method method = javaOperation.getJavaMethod(); + + if(path != null && path.length() > 0) { + if(method.getAnnotation(Path.class) != null) { + operation = op; + break; + } + } else { + if(method.getAnnotation(Path.class) == null) { + operation = op; + break; + } } } - - return result; + + return operation; } } diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingListenerServlet.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingListenerServlet.java index b96a45338a..cb65d74293 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingListenerServlet.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingListenerServlet.java @@ -55,6 +55,7 @@ public class RESTBindingListenerServlet extends HttpServlet { transient private Binding binding; transient private Invoker bindingInvoker; + private Invoker invoker; private Invoker getInvoker; private Invoker conditionalGetInvoker; private Invoker putInvoker; @@ -421,6 +422,16 @@ public class RESTBindingListenerServlet extends HttpServlet { } } + + public void setInvoker(Invoker invoker) { + this.invoker = invoker; + } + + public Invoker getInvoker() { + return invoker; + } + + /** * @return the getInvoker */ diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTServiceBindingProvider.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTServiceBindingProvider.java index a037e6e45c..514cb4cc96 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTServiceBindingProvider.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTServiceBindingProvider.java @@ -98,7 +98,6 @@ public class RESTServiceBindingProvider implements EndpointProvider { } - //clone the service contract to avoid databinding issues try { this.serviceContract = (InterfaceContract) service.getInterfaceContract().clone(); @@ -119,45 +118,42 @@ public class RESTServiceBindingProvider implements EndpointProvider { Invoker bindingInvoker = endpoint.getBindingInvocationChain().getHeadInvoker(); bindingListenerServlet = new RESTBindingListenerServlet(binding, bindingInvoker, messageFactory ); for (InvocationChain invocationChain : endpoint.getInvocationChains()) { + Operation operation = invocationChain.getTargetOperation(); + Invoker serviceInvoker = invocationChain.getHeadInvoker(); String operationName = operation.getName(); - if (operationName.equals("get")) { - Invoker getInvoker = invocationChain.getHeadInvoker(); - bindingListenerServlet.setGetInvoker(getInvoker); + + if (binding.getOperationSelector() != null || binding.getRequestWireFormat() != null) { + bindingListenerServlet.setInvoker(serviceInvoker); + servlet = bindingListenerServlet; + } else if (operationName.equals("get")) { + bindingListenerServlet.setGetInvoker(serviceInvoker); servlet = bindingListenerServlet; } else if (operationName.equals("conditionalGet")) { - Invoker conditionalGetInvoker = invocationChain.getHeadInvoker(); - bindingListenerServlet.setConditionalGetInvoker(conditionalGetInvoker); + bindingListenerServlet.setConditionalGetInvoker(serviceInvoker); servlet = bindingListenerServlet; } else if (operationName.equals("delete")) { - Invoker deleteInvoker = invocationChain.getHeadInvoker(); - bindingListenerServlet.setDeleteInvoker(deleteInvoker); + bindingListenerServlet.setDeleteInvoker(serviceInvoker); servlet = bindingListenerServlet; } else if (operationName.equals("conditionalDelete")) { - Invoker conditionalDeleteInvoker = invocationChain.getHeadInvoker(); - bindingListenerServlet.setConditionalDeleteInvoker(conditionalDeleteInvoker); + bindingListenerServlet.setConditionalDeleteInvoker(serviceInvoker); servlet = bindingListenerServlet; } else if (operationName.equals("put")) { - Invoker putInvoker = invocationChain.getHeadInvoker(); - bindingListenerServlet.setPutInvoker(putInvoker); + bindingListenerServlet.setPutInvoker(serviceInvoker); servlet = bindingListenerServlet; } else if (operationName.equals("conditionalPut")) { - Invoker conditionalPutInvoker = invocationChain.getHeadInvoker(); - bindingListenerServlet.setConditionalPutInvoker(conditionalPutInvoker); + bindingListenerServlet.setConditionalPutInvoker(serviceInvoker); servlet = bindingListenerServlet; } else if (operationName.equals("post")) { - Invoker postInvoker = invocationChain.getHeadInvoker(); - bindingListenerServlet.setPostInvoker(postInvoker); + bindingListenerServlet.setPostInvoker(serviceInvoker); servlet = bindingListenerServlet; } else if (operationName.equals("conditionalPost")) { - Invoker conditionalPostInvoker = invocationChain.getHeadInvoker(); - bindingListenerServlet.setConditionalPostInvoker(conditionalPostInvoker); + bindingListenerServlet.setConditionalPostInvoker(serviceInvoker); servlet = bindingListenerServlet; } else if (operationName.equals("service")) { - Invoker serviceInvoker = invocationChain.getHeadInvoker(); servlet = new RESTServiceListenerServlet(binding, serviceInvoker, messageFactory); break; - } + } } if (servlet == null) { throw new IllegalStateException("No get or service method found on the service"); diff --git a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java index 353cf811a5..a8d9c08d08 100644 --- a/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java +++ b/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/wireformat/json/provider/JSONWireFormatInterceptor.java @@ -21,6 +21,7 @@ package org.apache.tuscany.sca.binding.rest.wireformat.json.provider; import java.io.CharArrayWriter; +import org.apache.tuscany.sca.common.http.HTTPContext; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.invocation.Interceptor; import org.apache.tuscany.sca.invocation.Invoker; @@ -49,8 +50,10 @@ public class JSONWireFormatInterceptor implements Interceptor { } public Message invoke(Message msg) { + HTTPContext bindingContext = (HTTPContext) msg.getBindingContext(); + try { - if(msg.getBody() != null) { + if(bindingContext.getHttpRequest().getMethod().equalsIgnoreCase("get") == false && bindingContext.getHttpRequest().getMethod().equalsIgnoreCase("delete") == false && msg.getBody() != null) { Object[] args = msg.getBody(); CharArrayWriter data = (CharArrayWriter) args[0]; -- cgit v1.2.3