cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ashaki...@apache.org
Subject svn commit: r1560688 - in /cxf/trunk: core/src/main/java/org/apache/cxf/service/invoker/ rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/ systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/
Date Thu, 23 Jan 2014 14:09:19 GMT
Author: ashakirin
Date: Thu Jan 23 14:09:19 2014
New Revision: 1560688

URL: http://svn.apache.org/r1560688
Log:
Fixed [CXF-5512]: @UseAsyncMethod annotation doesn't work for classes implementing Provider<T>

Modified:
    cxf/trunk/core/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
    cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
    cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
    cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java

Modified: cxf/trunk/core/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
URL: http://svn.apache.org/viewvc/cxf/trunk/core/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java?rev=1560688&r1=1560687&r2=1560688&view=diff
==============================================================================
--- cxf/trunk/core/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java (original)
+++ cxf/trunk/core/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java Thu Jan
23 14:09:19 2014
@@ -66,7 +66,7 @@ public abstract class AbstractInvoker im
                 params = new MessageContentsList(o);
             }
             
-            m = adjustMethodAndParams(m, exchange, params);
+            m = adjustMethodAndParams(m, exchange, params, serviceObject.getClass());
             
             //Method m = (Method)bop.getOperationInfo().getProperty(Method.class.getName());
             m = matchMethod(m, serviceObject);
@@ -80,7 +80,8 @@ public abstract class AbstractInvoker im
 
     protected Method adjustMethodAndParams(Method m,
                                            Exchange ex,
-                                           List<Object> params) {
+                                           List<Object> params,
+                                           Class<?> serviceObjectClass) {
         //nothing to do
         return m;
     }

Modified: cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java?rev=1560688&r1=1560687&r2=1560688&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
(original)
+++ cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
Thu Jan 23 14:09:19 2014
@@ -20,6 +20,8 @@
 package org.apache.cxf.jaxws;
 
 import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -30,6 +32,7 @@ import java.util.concurrent.ExecutionExc
 
 import javax.activation.DataHandler;
 import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Provider;
 import javax.xml.ws.Response;
 import javax.xml.ws.handler.MessageContext;
 import javax.xml.ws.handler.MessageContext.Scope;
@@ -52,6 +55,7 @@ import org.apache.cxf.message.FaultMode;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageContentsList;
 import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.service.factory.ServiceConstructionException;
 import org.apache.cxf.service.invoker.Factory;
 import org.apache.cxf.service.invoker.FactoryInvoker;
 import org.apache.cxf.service.invoker.SingletonFactory;
@@ -77,18 +81,24 @@ public abstract class AbstractJAXWSMetho
         }
         return null;
     }
-    protected Method adjustMethodAndParams(Method m, Exchange ex, List<Object> params)
{
+
+    @Override
+    protected Method adjustMethodAndParams(Method mOriginal, Exchange ex, List<Object>
params,
+                                           Class<?> serviceObjectClass) {
+        // If class implements Provider<T> interface, use overriden method from service
object class
+        // to check UseAsyncMethod annotation
+        Method mso = getProviderServiceObjectMethod(mOriginal, serviceObjectClass);
         
-        UseAsyncMethod uam = m.getAnnotation(UseAsyncMethod.class);
+        UseAsyncMethod uam = mso.getAnnotation(UseAsyncMethod.class);
         if (uam != null) {
             BindingOperationInfo bop = ex.getBindingOperationInfo();
             Method ret = bop.getProperty(ASYNC_METHOD, Method.class);
             if (ret == null) {
-                Class<?> ptypes[] = new Class<?>[m.getParameterTypes().length
+ 1];
-                System.arraycopy(m.getParameterTypes(), 0, ptypes, 0, m.getParameterTypes().length);
-                ptypes[m.getParameterTypes().length] = AsyncHandler.class;
+                Class<?> ptypes[] = new Class<?>[mso.getParameterTypes().length
+ 1];
+                System.arraycopy(mso.getParameterTypes(), 0, ptypes, 0, mso.getParameterTypes().length);
+                ptypes[mso.getParameterTypes().length] = AsyncHandler.class;
                 try {
-                    ret = m.getDeclaringClass().getMethod(m.getName() + "Async", ptypes);
+                    ret = mso.getDeclaringClass().getMethod(mso.getName() + "Async", ptypes);
                     bop.setProperty(ASYNC_METHOD, ret);
                 } catch (Throwable t) {
                     //ignore
@@ -115,9 +125,52 @@ public abstract class AbstractJAXWSMetho
                 }
             }
         }
-        return m;
+        return mOriginal;
     }
     
+    private Method getProviderServiceObjectMethod(Method m, Class<?> serviceObjectClass)
{
+        if (!Provider.class.isAssignableFrom(serviceObjectClass)) {
+            return m;
+        }
+        Class<?> currentSvcClass = serviceObjectClass;
+        Class<?> genericType = null;
+
+        while (currentSvcClass != null) {
+            genericType = getProviderGenericType(currentSvcClass);
+            if (genericType != null) {
+                break;
+            }
+            // Check superclass until top
+            currentSvcClass = currentSvcClass.getSuperclass();
+        }
+        // Should never happens
+        if (genericType == null) {
+            return m;
+        }
+        try {
+            return serviceObjectClass.getMethod("invoke", genericType);
+        } catch (Exception e) {
+            throw new ServiceConstructionException(e);
+        }
+    }
+
+    private Class<?> getProviderGenericType(Class<?> svcClass) {
+        Type[] interfaces = svcClass.getGenericInterfaces();
+        for (Type interfaceType : interfaces) {
+            if (interfaceType instanceof ParameterizedType) {
+                ParameterizedType paramInterface = (ParameterizedType)interfaceType;
+                if (!paramInterface.getRawType().equals(Provider.class)) {
+                    continue;
+                }
+                Type[] typeArgs = paramInterface.getActualTypeArguments();
+                if (typeArgs.length > 0) {
+                    return (Class<?>)typeArgs[0];
+                }
+            }
+        }
+        return null;
+    }
+
     class JaxwsServerHandler implements AsyncHandler<Object> {
         Response<Object> r;
         Continuation continuation;

Modified: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java?rev=1560688&r1=1560687&r2=1560688&view=diff
==============================================================================
--- cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
(original)
+++ cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
Thu Jan 23 14:09:19 2014
@@ -19,6 +19,7 @@
 
 package org.apache.cxf.systest.jaxws;
 
+import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
@@ -40,8 +41,10 @@ import java.util.logging.Logger;
 import java.util.zip.GZIPInputStream;
 
 import javax.xml.namespace.QName;
+import javax.xml.transform.stream.StreamSource;
 import javax.xml.ws.AsyncHandler;
 import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Dispatch;
 import javax.xml.ws.Endpoint;
 import javax.xml.ws.Response;
 import javax.xml.ws.Service;
@@ -71,7 +74,6 @@ import org.apache.hello_world_soap_http.
 import org.apache.hello_world_soap_http.types.BareDocumentResponse;
 import org.apache.hello_world_soap_http.types.GreetMeLaterResponse;
 import org.apache.hello_world_soap_http.types.GreetMeResponse;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -960,4 +962,19 @@ public class ClientServerTest extends Ab
         assertEquals("Hello World", resp);
     }
 
+    @Test
+    public void testEchoProviderAsync() throws Exception {
+        String requestString = "<echo/>";
+        Service service = Service.create(serviceName);
+        service.addPort(fakePortName, javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING,
+                        "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider");
+        Dispatch<StreamSource> dispatcher = service.createDispatch(fakePortName,
+                                                                   StreamSource.class,
+                                                                   Service.Mode.PAYLOAD);
+
+        StreamSource request = new StreamSource(new ByteArrayInputStream(requestString.getBytes()));
+        StreamSource response = dispatcher.invoke(request);
+
+        assertEquals(requestString, StaxUtils.toString(response));
+    }
 }

Modified: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java?rev=1560688&r1=1560687&r2=1560688&view=diff
==============================================================================
--- cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java (original)
+++ cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java Thu Jan
23 14:09:19 2014
@@ -25,8 +25,14 @@ import java.util.List;
 import java.util.concurrent.Future;
 
 import javax.jws.WebService;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
 import javax.xml.ws.AsyncHandler;
 import javax.xml.ws.Endpoint;
+import javax.xml.ws.Provider;
+import javax.xml.ws.Service;
+import javax.xml.ws.ServiceMode;
+import javax.xml.ws.WebServiceProvider;
 
 import org.apache.cxf.annotations.UseAsyncMethod;
 import org.apache.cxf.jaxws.EndpointImpl;
@@ -58,6 +64,10 @@ public class Server extends AbstractBusT
         address = "http://localhost:" + PORT + "/SoapContext/AsyncSoapPort";
         eps.add(Endpoint.publish(address, implementor));
         
+        implementor = new AsyncEchoProvider();
+        address = "http://localhost:" + PORT + "/SoapContext/AsyncEchoProvider";
+        eps.add(Endpoint.publish(address, implementor));
+
         implementor = new GreeterImplMultiPort();
         address = "http://localhost:" + PORT + "/MultiPort/GreeterPort";
         eps.add(Endpoint.publish(address, implementor));
@@ -143,6 +153,33 @@ public class Server extends AbstractBusT
         }
     }
 
+    @WebServiceProvider
+    @ServiceMode(value = Service.Mode.PAYLOAD)
+    public class AsyncEchoProvider implements Provider<StreamSource> {
+
+        @Override
+        @UseAsyncMethod
+        public StreamSource invoke(StreamSource request) {
+            throw new RuntimeException("Should be async");
+        }
+
+        public Future<?> invokeAsync(final StreamSource s, final AsyncHandler<Source>
asyncHandler) {
+            final ServerAsyncResponse<Source> r = new ServerAsyncResponse<Source>();
+            new Thread() {
+                public void run() {
+                    try {
+                        Thread.sleep(500);
+                    } catch (InterruptedException e) {
+                        // ignore
+                    }
+                    r.set(s);
+                    asyncHandler.handleResponse(r);
+                }
+            } .start();
+            return r;
+        }
+    }
+
     public static void main(String[] args) {
         try {
             Server s = new Server();



Mime
View raw message