Author: dkulp
Date: Tue Dec 15 02:54:08 2009
New Revision: 890613
URL: http://svn.apache.org/viewvc?rev=890613&view=rev
Log:
Merged revisions 890605 via svnmerge from
https://svn.apache.org/repos/asf/cxf/trunk
........
r890605 | dkulp | 2009-12-14 21:37:40 -0500 (Mon, 14 Dec 2009) | 1 line
[CXF-1758] Allow some more advanced usages of Generics with JAX-WS
........
Added:
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/GenericsService2.java
- copied unchanged from r890605,
cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/GenericsService2.java
Modified:
cxf/branches/2.2.x-fixes/ (props changed)
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodDispatcher.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsImplementorInfo.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java
cxf/branches/2.2.x-fixes/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified:
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodDispatcher.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodDispatcher.java?rev=890613&r1=890612&r2=890613&view=diff
==============================================================================
---
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodDispatcher.java
(original)
+++
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/JAXWSMethodDispatcher.java
Tue Dec 15 02:54:08 2009
@@ -20,6 +20,9 @@
package org.apache.cxf.jaxws;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
import java.util.logging.Logger;
import org.apache.cxf.common.i18n.Message;
@@ -71,8 +74,32 @@
if (!endpointClass.isAssignableFrom(method.getDeclaringClass())) {
try {
- method = endpointClass.getMethod(method.getName(),
+ Method m2 = endpointClass.getMethod(method.getName(),
(Class[])method.getParameterTypes());
+ if (Modifier.isVolatile(m2.getModifiers())) {
+ //bridge method, need to map the generics
+ Class params[] = method.getParameterTypes();
+ for (Type t : method.getGenericParameterTypes()) {
+ if (t instanceof TypeVariable) {
+ TypeVariable tv = (TypeVariable)t;
+ for (int x = 0; x <
implInfo.getSEIClass().getTypeParameters().length; x++) {
+ TypeVariable t2 =
implInfo.getSEIClass().getTypeParameters()[x];
+ if (t2.getName().equals(tv.getName())) {
+ params[x] =
(Class)implInfo.getSEIType().getActualTypeArguments()[x];
+ }
+ }
+ }
+ }
+ method = endpointClass.getMethod(method.getName(),
+ params);
+ } else {
+ method = m2;
+ }
+ try {
+ method.setAccessible(true);
+ } catch (Throwable t) {
+ //ignore
+ }
} catch (SecurityException e) {
throw new ServiceConstructionException(e);
}
Modified:
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java?rev=890613&r1=890612&r2=890613&view=diff
==============================================================================
---
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
(original)
+++
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
Tue Dec 15 02:54:08 2009
@@ -181,10 +181,18 @@
}
def = findClass(className, method.getDeclaringClass());
- if (def != null) {
- wrapperPart.setTypeClass(def);
- wrapperBeans.add(def);
- return;
+ String origClassName = className;
+ int count = 0;
+ while (def != null) {
+ Boolean b = messageInfo.getProperty("parameterized",
Boolean.class);
+ if (b != null && b) {
+ className = origClassName + (++count);
+ def = findClass(className, method.getDeclaringClass());
+ } else {
+ wrapperPart.setTypeClass(def);
+ wrapperBeans.add(def);
+ return;
+ }
}
String classFileName = periodToSlashes(className);
cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
classFileName, null,
Modified:
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsImplementorInfo.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsImplementorInfo.java?rev=890613&r1=890612&r2=890613&view=diff
==============================================================================
---
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsImplementorInfo.java
(original)
+++
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsImplementorInfo.java
Tue Dec 15 02:54:08 2009
@@ -49,6 +49,7 @@
private Class<?> implementorClass;
private Class<?> seiClass;
+ private ParameterizedType seiType;
private List<WebService> wsAnnotations = new ArrayList<WebService>(2);
private WebServiceProvider wsProviderAnnotation;
@@ -60,6 +61,9 @@
public Class<?> getSEIClass() {
return seiClass;
}
+ public ParameterizedType getSEIType() {
+ return seiType;
+ }
public Class<?> getImplementorClass() {
return implementorClass;
@@ -287,6 +291,15 @@
throw new WebServiceException(expString);
}
wsAnnotations.add(seiAnnotation);
+
+ for (int x = implementorClass.getInterfaces().length - 1; x >= 0;
x--) {
+ if (seiClass.equals(implementorClass.getInterfaces()[x])) {
+ Type type = implementorClass.getGenericInterfaces()[x];
+ if (type instanceof ParameterizedType) {
+ seiType = (ParameterizedType)type;
+ }
+ }
+ }
}
wsProviderAnnotation =
implementorClass.getAnnotation(WebServiceProvider.class);
}
Modified:
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java?rev=890613&r1=890612&r2=890613&view=diff
==============================================================================
---
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
(original)
+++
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
Tue Dec 15 02:54:08 2009
@@ -115,6 +115,7 @@
this.implInfo = implInfo;
initConfiguration(implInfo);
this.serviceClass = implInfo.getEndpointClass();
+ this.serviceType = implInfo.getSEIType();
loadWSFeatureAnnotation(implInfo.getSEIClass(),
implInfo.getImplementorClass());
}
@@ -190,6 +191,7 @@
}
setJaxWsImplementorInfo(new JaxWsImplementorInfo(serviceClass));
super.setServiceClass(getJaxWsImplementorInfo().getEndpointClass());
+ super.setServiceType(getJaxWsImplementorInfo().getSEIType());
}
@Override
protected void checkServiceClassAnnotations(Class<?> sc) {
Modified:
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java?rev=890613&r1=890612&r2=890613&view=diff
==============================================================================
---
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java
(original)
+++
cxf/branches/2.2.x-fixes/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/CodeFirstTest.java
Tue Dec 15 02:54:08 2009
@@ -47,6 +47,7 @@
import org.apache.cxf.jaxws.service.Entity;
import org.apache.cxf.jaxws.service.FooServiceImpl;
import org.apache.cxf.jaxws.service.GenericsService;
+import org.apache.cxf.jaxws.service.GenericsService2;
import org.apache.cxf.jaxws.service.Hello;
import org.apache.cxf.jaxws.service.HelloInterface;
import org.apache.cxf.jaxws.service.QueryResult;
@@ -339,6 +340,63 @@
}
@Test
+ public void testCXF1758() throws Exception {
+ JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
+ factory.setServiceBean(new GenericsService2Impl());
+ factory.setAddress("local://localhost/test");
+ Server server = null;
+ server = factory.create();
+ Document doc = getWSDLDocument(server);
+ org.apache.cxf.helpers.XMLUtils.printDOM(doc);
+
assertValid("//xsd:schema/xsd:complexty...@name='convert']/xsd:sequence/xsd:eleme...@type='xs:int']",
+ doc);
+
+ factory = new JaxWsServerFactoryBean();
+ factory.setServiceBean(new GenericsService2<Float, Double>() {
+ public Double convert(Float t) {
+ return t.doubleValue();
+ }
+
+ public GenericsService2.Value<Double>
convert2(GenericsService2.Value<Float> in) {
+ return new
GenericsService2.Value<Double>(in.getValue().doubleValue());
+ }
+ });
+ factory.setAddress("local://localhost/test2");
+ server = factory.create();
+ Document doc2 = getWSDLDocument(server);
+ //org.apache.cxf.helpers.XMLUtils.printDOM(doc2);
+
assertValid("//xsd:schema/xsd:complexty...@name='convert']/xsd:sequence/"
+ + "xsd:eleme...@type='xs:float']",
+ doc2);
+
+ QName serviceName = new QName("http://service.jaxws.cxf.apache.org/",
"Generics2");
+ QName portName = new QName("http://service.jaxws.cxf.apache.org/",
"Generics2Port");
+
+ ServiceImpl service = new ServiceImpl(getBus(), (URL)null,
serviceName, null);
+ service.addPort(portName, "http://schemas.xmlsoap.org/soap/",
+ "local://localhost/test2");
+
+ GenericsService2Typed proxy = service.getPort(portName,
+
GenericsService2Typed.class);
+ assertEquals("", 3.14d, proxy.convert(3.14f), 0.00001);
+ assertEquals("", 3.14d, proxy.convert2(new
GenericsService2.Value<Float>(3.14f)).getValue(), 0.00001);
+
+ }
+
+ public static interface GenericsService2Typed extends
GenericsService2<Float, Double> {
+
+ }
+ public static class GenericsService2Impl implements
GenericsService2<Integer, String> {
+ public String convert(Integer t) {
+ return t.toString();
+ }
+
+ public GenericsService2.Value<String>
convert2(GenericsService2.Value<Integer> in) {
+ return new
GenericsService2.Value<String>(in.getValue().toString());
+ }
+ }
+
+ @Test
public void testCXF1510() throws Exception {
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setServiceClass(NoRootBare.class);
Modified:
cxf/branches/2.2.x-fixes/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java?rev=890613&r1=890612&r2=890613&view=diff
==============================================================================
---
cxf/branches/2.2.x-fixes/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
(original)
+++
cxf/branches/2.2.x-fixes/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
Tue Dec 15 02:54:08 2009
@@ -28,6 +28,7 @@
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@@ -152,7 +153,9 @@
protected String wsdlURL;
protected Class<?> serviceClass;
-
+ protected ParameterizedType serviceType;
+ protected Map<Type, Map<String, Class<?>>> parameterizedTypes;
+
protected final Map<String, String> schemaLocationMapping = new
HashMap<String, String>();
private List<AbstractServiceConfiguration> serviceConfigurations =
@@ -1442,6 +1445,9 @@
if (isInParam(method, j)) {
final QName q = getInParameterName(op, method, j);
MessagePartInfo part = inMsg.addMessagePart(getInPartName(op,
method, j));
+
+
+
initializeParameter(part, paramClasses[j],
method.getGenericParameterTypes()[j]);
//TODO:remove method param annotations
part.setProperty(METHOD_PARAM_ANNOTATIONS,
method.getParameterAnnotations());
@@ -1711,6 +1717,21 @@
rawClass = getClass(type);
}
}
+ if (type instanceof TypeVariable) {
+ if (parameterizedTypes == null) {
+ processParameterizedTypes();
+ }
+ TypeVariable var = (TypeVariable)type;
+ Map<String, Class<?>> mp =
parameterizedTypes.get(var.getGenericDeclaration());
+ if (mp != null) {
+ Class<?> c =
parameterizedTypes.get(var.getGenericDeclaration()).get(var.getName());
+ if (c != null) {
+ rawClass = c;
+ type = c;
+ part.getMessageInfo().setProperty("parameterized",
Boolean.TRUE);
+ }
+ }
+ }
part.setProperty(GENERIC_TYPE, type);
// if rawClass is List<String>, it will be converted to array
// and set it to type class
@@ -2239,7 +2260,35 @@
public Class<?> getServiceClass() {
return serviceClass;
}
-
+ private void processParameterizedTypes() {
+ parameterizedTypes = new HashMap<Type, Map<String, Class<?>>>();
+ if (serviceClass.isInterface()) {
+ processTypes(serviceClass, serviceType);
+ } else {
+ for (int x = 0; x < serviceClass.getInterfaces().length; x++) {
+ processTypes(serviceClass.getInterfaces()[x],
serviceClass.getGenericInterfaces()[x]);
+ }
+ processTypes(serviceClass.getSuperclass(),
serviceClass.getGenericSuperclass());
+ }
+ }
+ protected void processTypes(Class sc, Type tp) {
+ if (tp != null && tp instanceof ParameterizedType) {
+ ParameterizedType ptp = (ParameterizedType)tp;
+ Type c = (Class)ptp.getRawType();
+ Map<String, Class<?>> m = new HashMap<String, Class<?>>();
+ parameterizedTypes.put(c, m);
+ for (int x = 0; x < ptp.getActualTypeArguments().length; x++) {
+ Type t = ptp.getActualTypeArguments()[x];
+ TypeVariable<?> tv = sc.getTypeParameters()[x];
+ if (t instanceof Class) {
+ m.put(tv.getName(), (Class)t);
+ }
+ }
+ }
+ }
+ public void setServiceType(ParameterizedType servicetype) {
+ serviceType = servicetype;
+ }
public void setServiceClass(Class<?> serviceClass) {
this.serviceClass = serviceClass;
checkServiceClassAnnotations(serviceClass);