Author: ashakirin
Date: Thu Jan 23 14:53:47 2014
New Revision: 1560703
URL: http://svn.apache.org/r1560703
Log:
Backported [CXF-5512]: @UseAsyncMethod annotation doesn't work for classes
implementing Provider<T>
Modified:
cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
Modified:
cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java?rev=1560703&r1=1560702&r2=1560703&view=diff
==============================================================================
---
cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
(original)
+++
cxf/branches/2.7.x-fixes/api/src/main/java/org/apache/cxf/service/invoker/AbstractInvoker.java
Thu Jan 23 14:53:47 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/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java?rev=1560703&r1=1560702&r2=1560703&view=diff
==============================================================================
---
cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
(original)
+++
cxf/branches/2.7.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/AbstractJAXWSMethodInvoker.java
Thu Jan 23 14:53:47 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/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java?rev=1560703&r1=1560702&r2=1560703&view=diff
==============================================================================
---
cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
(original)
+++
cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerTest.java
Thu Jan 23 14:53:47 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;
@@ -41,8 +42,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;
@@ -63,6 +66,7 @@ import org.apache.cxf.frontend.ClientPro
import org.apache.cxf.helpers.XMLUtils;
import org.apache.cxf.helpers.XPathUtils;
import org.apache.cxf.message.Message;
+import org.apache.cxf.staxutils.StaxUtils;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.hello_world_soap_http.BadRecordLitFault;
@@ -76,7 +80,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;
@@ -1057,4 +1060,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/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java?rev=1560703&r1=1560702&r2=1560703&view=diff
==============================================================================
---
cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
(original)
+++
cxf/branches/2.7.x-fixes/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/Server.java
Thu Jan 23 14:53:47 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.interceptor.URIMappingInterceptor;
@@ -60,6 +66,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));
@@ -146,6 +156,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();