You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by an...@apache.org on 2009/10/23 12:18:43 UTC

svn commit: r828988 - in /tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl: AsyncJDKInvocationHandler.java AsyncResponse.java JDKProxyFactory.java

Author: antelder
Date: Fri Oct 23 10:18:42 2009
New Revision: 828988

URL: http://svn.apache.org/viewvc?rev=828988&view=rev
Log:
Add example of runtime support for handling JAXWS async client APIs

Added:
    tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncJDKInvocationHandler.java
    tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncResponse.java
Modified:
    tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java

Added: tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncJDKInvocationHandler.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncJDKInvocationHandler.java?rev=828988&view=auto
==============================================================================
--- tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncJDKInvocationHandler.java (added)
+++ tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncJDKInvocationHandler.java Fri Oct 23 10:18:42 2009
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.tuscany.sca.core.invocation.impl;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.concurrent.Future;
+
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Response;
+
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.oasisopen.sca.ServiceReference;
+
+public class AsyncJDKInvocationHandler extends JDKInvocationHandler {
+    private static final long serialVersionUID = 1L;
+
+    public AsyncJDKInvocationHandler(MessageFactory messageFactory, ServiceReference<?> callableReference) {
+        super(messageFactory, callableReference);
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        if (isAsyncCallback(method)) {
+            return doInvokeAsyncCallback(proxy, method, args);            
+        } else if (isAsyncPoll(method)) {
+            return doInvokeAsyncPoll(proxy, method, args);            
+        } else {
+            return super.invoke(proxy, method, args);
+        }
+    }
+
+    protected boolean isAsyncCallback(Method method) {
+        if (method.getName().endsWith("Async") && (method.getReturnType().isAssignableFrom(Future.class))) {
+            if (method.getParameterTypes().length > 0) {
+                return method.getParameterTypes()[method.getParameterTypes().length-1].isAssignableFrom(AsyncHandler.class);
+            }
+        }
+        return false;
+    }
+
+    protected boolean isAsyncPoll(Method method) {
+        return method.getName().endsWith("Async") && (method.getReturnType().isAssignableFrom(Response.class));
+    }
+
+    protected AsyncResponse doInvokeAsyncPoll(Object proxy, Method asyncMethod, Object[] args) {
+        Object response;
+        boolean isException;
+        try {
+            response = super.invoke(proxy, getNonAsyncMethod(asyncMethod), args);
+            isException = false;
+        } catch (Throwable e) {
+            response = e;
+            isException = true;
+        }
+        return new AsyncResponse(response, isException);
+    }
+
+    private Object doInvokeAsyncCallback(Object proxy, Method asyncMethod, Object[] args) {
+        AsyncHandler handler = (AsyncHandler)args[args.length-1];
+        Response response = doInvokeAsyncPoll(proxy,asyncMethod,Arrays.copyOf(args, args.length-1));
+        handler.handleResponse(response);
+        
+        return null;
+    }
+
+    protected Method getNonAsyncMethod(Method asyncMethod) {
+        String methodName = asyncMethod.getName().substring(0, asyncMethod.getName().length()-5);
+        for (Method m : businessInterface.getMethods()) {
+            if (methodName.equals(m.getName())) {
+                return m;
+            }
+        }
+        throw new IllegalStateException("No non-async method matching async method " + asyncMethod.getName());
+    }
+}

Added: tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncResponse.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncResponse.java?rev=828988&view=auto
==============================================================================
--- tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncResponse.java (added)
+++ tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncResponse.java Fri Oct 23 10:18:42 2009
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.tuscany.sca.core.invocation.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.xml.ws.Response;
+
+public class AsyncResponse implements Response {
+
+    private Object response;
+    private boolean isException;
+
+    public AsyncResponse(Object response, boolean isException) {
+        this.response = response;
+        this.isException = isException;
+    }
+    
+    public Map getContext() {
+        return new HashMap();
+    }
+
+    public boolean cancel(boolean mayInterruptIfRunning) {
+        return false;
+    }
+
+    public Object get() throws InterruptedException, ExecutionException {
+        if (isException) {
+            throw new ExecutionException((Throwable)response);
+        } else {
+            return response;
+        }
+    }
+
+    public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+        return get();
+    }
+
+    public boolean isCancelled() {
+        return false;
+    }
+
+    public boolean isDone() {
+        return true;
+    }
+
+}

Modified: tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java?rev=828988&r1=828987&r2=828988&view=diff
==============================================================================
--- tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java (original)
+++ tuscany/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java Fri Oct 23 10:18:42 2009
@@ -20,10 +20,15 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.List;
+import java.util.concurrent.Future;
+
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Response;
 
 import org.apache.tuscany.sca.common.java.collection.LRUCache;
 import org.apache.tuscany.sca.core.LifeCycleListener;
@@ -63,7 +68,12 @@
     public <T> T createProxy(ServiceReference<T> callableReference) throws ProxyCreationException {
         assert callableReference != null;
         final Class<T> interfaze = callableReference.getBusinessInterface();
-        InvocationHandler handler = new JDKInvocationHandler(messageFactory, callableReference);
+        InvocationHandler handler;
+        if (isAsync(interfaze)) {
+            handler = new AsyncJDKInvocationHandler(messageFactory, callableReference);
+        } else {
+            handler = new JDKInvocationHandler(messageFactory, callableReference);
+        }
         // Allow privileged access to class loader. Requires RuntimePermission in security policy.
         ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
             public ClassLoader run() {
@@ -74,6 +84,24 @@
         ((ServiceReferenceImpl)callableReference).setProxy(proxy);
         return interfaze.cast(proxy);
     }
+    
+    private boolean isAsync(Class<?> interfaze) {
+        for (Method method : interfaze.getMethods()) {
+            if (method.getName().endsWith("Async")) {
+                if (method.getReturnType().isAssignableFrom(Future.class)) {
+                    if (method.getParameterTypes().length > 0) {
+                        if (method.getParameterTypes()[method.getParameterTypes().length-1].isAssignableFrom(AsyncHandler.class)) {
+                            return true;
+                        }
+                    }
+                }
+                if (method.getReturnType().isAssignableFrom(Response.class)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 
     public <T> T createCallbackProxy(Class<T> interfaze, List<RuntimeWire> wires) throws ProxyCreationException {
         ServiceReferenceImpl<T> callbackReference = new CallbackServiceReferenceImpl(interfaze, wires, this);