summaryrefslogtreecommitdiffstats
path: root/java/sca
diff options
context:
space:
mode:
authorantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2009-10-23 10:18:42 +0000
committerantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2009-10-23 10:18:42 +0000
commit4e8a796b4dfba27549f5d91a3e269c84e99a9d14 (patch)
tree241ff9fc830e93a450b895b2c3c8004707f95065 /java/sca
parentb1f09c1c389f634fe5cf7836898aa9d01aa82e42 (diff)
Add example of runtime support for handling JAXWS async client APIs
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@828988 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca')
-rw-r--r--java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncJDKInvocationHandler.java93
-rw-r--r--java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncResponse.java68
-rw-r--r--java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java30
3 files changed, 190 insertions, 1 deletions
diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncJDKInvocationHandler.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncJDKInvocationHandler.java
new file mode 100644
index 0000000000..aeccfa8b05
--- /dev/null
+++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncJDKInvocationHandler.java
@@ -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());
+ }
+}
diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncResponse.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncResponse.java
new file mode 100644
index 0000000000..07086dfae3
--- /dev/null
+++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/AsyncResponse.java
@@ -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;
+ }
+
+}
diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java
index e0d0a40985..853e28fafa 100644
--- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java
+++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKProxyFactory.java
@@ -20,10 +20,15 @@ package org.apache.tuscany.sca.core.invocation.impl;
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 class JDKProxyFactory implements ProxyFactory, LifeCycleListener {
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 @@ public class JDKProxyFactory implements ProxyFactory, LifeCycleListener {
((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);