You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by rf...@apache.org on 2010/05/27 08:00:05 UTC

svn commit: r948681 - in /tuscany/sca-java-2.x/trunk/modules: assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/ assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/ binding-rest-runtime/src/main/java/org/apache/tuscany/sca/bi...

Author: rfeng
Date: Thu May 27 06:00:05 2010
New Revision: 948681

URL: http://svn.apache.org/viewvc?rev=948681&view=rev
Log:
Adding rest binding reference support

Modified:
    tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java
    tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/WrapperInfo.java
    tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java
    tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTReferenceBindingProvider.java

Modified: tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java?rev=948681&r1=948680&r2=948681&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/OperationImpl.java Thu May 27 06:00:05 2010
@@ -238,6 +238,11 @@ public class OperationImpl implements Op
 
         copy.attributes = new ConcurrentHashMap<Object, Object>();
         copy.attributes.putAll(attributes);
+        
+        // [rfeng] We need to clone the wrapper as it holds the databinding information
+        if (wrapper != null) {
+            copy.wrapper = (WrapperInfo)wrapper.clone();
+        }
 
         return copy;
     }

Modified: tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/WrapperInfo.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/WrapperInfo.java?rev=948681&r1=948680&r2=948681&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/WrapperInfo.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/util/WrapperInfo.java Thu May 27 06:00:05 2010
@@ -48,7 +48,7 @@ import org.apache.tuscany.sca.interfaced
  * @version $Rev$ $Date$
  * @tuscany.spi.extension.asclient
  */
-public class WrapperInfo {
+public class WrapperInfo implements Cloneable {
     private ElementInfo inputWrapperElement;
 
     private ElementInfo outputWrapperElement;
@@ -188,4 +188,17 @@ public class WrapperInfo {
     public void setOutputWrapperType(DataType<XMLType> outputWrapperType) {
         this.outputWrapperType = outputWrapperType;
     }
+
+    @Override
+    public Object clone() throws CloneNotSupportedException {
+        WrapperInfo copy = (WrapperInfo) super.clone();
+        if (inputWrapperType != null) {
+            copy.inputWrapperType = (DataType<XMLType>)inputWrapperType.clone();
+        }
+        if (outputWrapperType != null) {
+            copy.outputWrapperType = (DataType<XMLType>)outputWrapperType.clone();
+        }
+        return copy;
+
+    }
 }

Modified: tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java?rev=948681&r1=948680&r2=948681&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java Thu May 27 06:00:05 2010
@@ -19,24 +19,45 @@
 
 package org.apache.tuscany.sca.binding.rest.provider;
 
-import java.lang.reflect.Type;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
+import javax.ws.rs.Consumes;
+import javax.ws.rs.CookieParam;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
 import javax.ws.rs.HEAD;
+import javax.ws.rs.HeaderParam;
 import javax.ws.rs.HttpMethod;
+import javax.ws.rs.MatrixParam;
 import javax.ws.rs.OPTIONS;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriBuilder;
 
+import org.apache.tuscany.sca.assembly.WireFormat;
 import org.apache.tuscany.sca.binding.rest.RESTBinding;
+import org.apache.tuscany.sca.binding.rest.wireformat.json.JSONWireFormat;
+import org.apache.tuscany.sca.binding.rest.wireformat.xml.XMLWireFormat;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
 import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
 import org.apache.tuscany.sca.invocation.Invoker;
 import org.apache.tuscany.sca.invocation.Message;
 import org.apache.wink.client.ClientConfig;
-import org.apache.wink.client.EntityType;
 import org.apache.wink.client.Resource;
 import org.apache.wink.client.RestClient;
 
@@ -44,13 +65,19 @@ import org.apache.wink.client.RestClient
  * 
  */
 public class RESTBindingInvoker implements Invoker {
+    private ExtensionPointRegistry registry;
     private RESTBinding binding;
     private Operation operation;
+    private RestClient restClient;
+    private String httpMethod;
+    private Class<?> responseType;
 
-    public RESTBindingInvoker(RESTBinding binding, Operation operation) {
+    public RESTBindingInvoker(ExtensionPointRegistry registry, RESTBinding binding, Operation operation) {
         super();
+        this.registry = registry;
         this.binding = binding;
         this.operation = operation;
+        this.restClient = createRestClient();
     }
 
     private static Map<Class<?>, String> mapping = new HashMap<Class<?>, String>();
@@ -63,41 +90,164 @@ public class RESTBindingInvoker implemen
         mapping.put(OPTIONS.class, HttpMethod.OPTIONS);
     }
 
-    public Message invoke(Message msg) {
+    private static <T extends Annotation> T getAnnotation(Annotation[] annotations, Class<T> type) {
+        for (Annotation a : annotations) {
+            if (a.annotationType() == type) {
+                return type.cast(a);
+            }
+        }
+        return null;
+    }
+
+    private RestClient createRestClient() {
         ClientConfig config = new ClientConfig();
-        RestClient client = new RestClient();
-        Resource resource = client.resource(binding.getURI());
-        String method = null;
+        config.applications(new Application() {
+
+            @Override
+            public Set<Class<?>> getClasses() {
+                return Collections.emptySet();
+            }
+
+            @Override
+            public Set<Object> getSingletons() {
+                Set<Object> providers = new HashSet<Object>();
+                providers.add(new DataBindingJAXRSReader(registry));
+                providers.add(new DataBindingJAXRSWriter(registry));
+                return providers;
+            }
+
+        });
+        RestClient client = new RestClient(config);
+
         for (Map.Entry<Class<?>, String> e : mapping.entrySet()) {
             if (operation.getAttributes().get(e.getKey()) != null) {
-                method = e.getValue();
+                httpMethod = e.getValue();
                 break;
             }
         }
-        EntityType<?> entityType = new EntityType() {
 
-            @Override
-            public Class getRawClass() {
-                if (operation.getOutputType() != null) {
-                    return operation.getOutputType().getPhysical();
-                } else {
-                    return null;
-                }
-            }
+        if (operation.getOutputType() != null) {
+            responseType = operation.getOutputType().getPhysical();
+        } else {
+            responseType = null;
+        }
+        return client;
+    }
 
-            @Override
-            public Type getType() {
-                if (operation.getOutputType() != null) {
-                    return operation.getOutputType().getGenericType();
-                } else {
-                    return null;
-                }
+    public Message invoke(Message msg) {
+
+        Object entity = null;
+        Object[] args = msg.getBody();
+        
+        URI uri = URI.create(binding.getURI());
+        UriBuilder uriBuilder = UriBuilder.fromUri(uri);
+
+        Method method = ((JavaOperation)operation).getJavaMethod();
+        uriBuilder.path(method);
+
+        Map<String, Object> pathParams = new HashMap<String, Object>();
+        Map<String, Object> matrixParams = new HashMap<String, Object>();
+        Map<String, Object> queryParams = new HashMap<String, Object>();
+        Map<String, Object> headerParams = new HashMap<String, Object>();
+        Map<String, Object> formParams = new HashMap<String, Object>();
+        Map<String, Object> cookieParams = new HashMap<String, Object>();
+
+        boolean isEntity = true;
+        for (int i = 0; i < method.getParameterTypes().length; i++) {
+            Annotation[] annotations = method.getParameterAnnotations()[i];
+            PathParam pathParam = getAnnotation(annotations, PathParam.class);
+            if (pathParam != null) {
+                isEntity = false;
+                pathParams.put(pathParam.value(), args[i]);
+            }
+            MatrixParam matrixParam = getAnnotation(annotations, MatrixParam.class);
+            if (matrixParam != null) {
+                isEntity = false;
+                matrixParams.put(matrixParam.value(), args[i]);
+            }
+            QueryParam queryParam = getAnnotation(annotations, QueryParam.class);
+            if (queryParam != null) {
+                isEntity = false;
+                queryParams.put(queryParam.value(), args[i]);
             }
+            HeaderParam headerParam = getAnnotation(annotations, HeaderParam.class);
+            if (headerParam != null) {
+                isEntity = false;
+                headerParams.put(headerParam.value(), args[i]);
+            }
+            FormParam formParam = getAnnotation(annotations, FormParam.class);
+            if (formParam != null) {
+                isEntity = false;
+                formParams.put(formParam.value(), args[i]);
+            }
+            CookieParam cookieParam = getAnnotation(annotations, CookieParam.class);
+            if (cookieParam != null) {
+                isEntity = false;
+                cookieParams.put(cookieParam.value(), args[i]);
+            }
+            if(isEntity) {
+                entity = args[i];
+            }
+        }
+
+        for (Map.Entry<String, Object> p : queryParams.entrySet()) {
+            uriBuilder.replaceQueryParam(p.getKey(), p.getValue());
+        }
+        for (Map.Entry<String, Object> p : matrixParams.entrySet()) {
+            uriBuilder.replaceMatrixParam(p.getKey(), p.getValue());
+        }
+        
+        uri = uriBuilder.buildFromMap(pathParams);
+        Resource resource = restClient.resource(uri);
+        
+        for (Map.Entry<String, Object> p : headerParams.entrySet()) {
+            resource.header(p.getKey(), String.valueOf(p.getValue()));
+        }
+
+        for (Map.Entry<String, Object> p : cookieParams.entrySet()) {
+            Cookie cookie = new Cookie(p.getKey(), String.valueOf(p.getValue()));
+            resource.cookie(cookie);
+        }
 
-        };
-        Object result = resource.invoke(method, entityType, msg.getBody());
+        resource.contentType(getContentType());
+        resource.accept(getAccepts());        
+
+        Object result = resource.invoke(httpMethod, responseType, entity);
         msg.setBody(result);
         return msg;
     }
 
+    private String getContentType() {
+        String contentType = MediaType.APPLICATION_OCTET_STREAM;
+        Consumes consumes = ((JavaOperation)operation).getJavaMethod().getAnnotation(Consumes.class);
+        if (consumes != null && consumes.value().length > 0) {
+            contentType = consumes.value()[0];
+        }
+        WireFormat wf = binding.getRequestWireFormat();
+        if (wf != null) {
+            if (XMLWireFormat.REST_WIREFORMAT_XML_QNAME.equals(wf.getSchemaName())) {
+                contentType = MediaType.APPLICATION_XML;
+            } else if (JSONWireFormat.REST_WIREFORMAT_JSON_QNAME.equals(wf.getSchemaName())) {
+                contentType = MediaType.APPLICATION_JSON;
+            }
+        }
+        return contentType;
+    }
+
+    private String[] getAccepts() {
+        String accepts[] = {MediaType.APPLICATION_OCTET_STREAM};
+        Produces produces = ((JavaOperation)operation).getJavaMethod().getAnnotation(Produces.class);
+        if (produces != null) {
+            accepts = produces.value();
+        }
+        WireFormat wf = binding.getResponseWireFormat();
+        if (wf != null) {
+            if (XMLWireFormat.REST_WIREFORMAT_XML_QNAME.equals(wf.getSchemaName())) {
+                accepts = new String[] {MediaType.APPLICATION_XML};
+            } else if (JSONWireFormat.REST_WIREFORMAT_JSON_QNAME.equals(wf.getSchemaName())) {
+                accepts = new String[] {MediaType.APPLICATION_JSON};
+            }
+        }
+        return accepts;
+    }
 }

Modified: tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTReferenceBindingProvider.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTReferenceBindingProvider.java?rev=948681&r1=948680&r2=948681&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTReferenceBindingProvider.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTReferenceBindingProvider.java Thu May 27 06:00:05 2010
@@ -44,7 +44,7 @@ public class RESTReferenceBindingProvide
     }
 
     public Invoker createInvoker(Operation operation) {
-        return new RESTBindingInvoker((RESTBinding)endpointReference.getBinding(), operation);
+        return new RESTBindingInvoker(registry, (RESTBinding)endpointReference.getBinding(), operation);
     }
 
     public InterfaceContract getBindingInterfaceContract() {