You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by em...@apache.org on 2007/12/07 07:19:51 UTC
svn commit: r602001 - in /incubator/cxf/trunk/rt/frontend:
jaxws/src/main/java/org/apache/cxf/jaxws/
jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/
jaxws/src/test/java/org/apache/cxf/jaxws/
simple/src/main/java/org/apache/cxf/service/factory/
Author: ema
Date: Thu Dec 6 22:19:49 2007
New Revision: 602001
URL: http://svn.apache.org/viewvc?rev=602001&view=rev
Log:
Polish WrapperClassGenerator and test it against JAXB
Modified:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java
incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java?rev=602001&r1=602000&r2=602001&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java Thu Dec 6 22:19:49 2007
@@ -21,6 +21,8 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.util.List;
import javax.xml.bind.annotation.XmlAttachmentRef;
@@ -30,6 +32,7 @@
import javax.xml.namespace.QName;
import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.JavaUtils;
import org.apache.cxf.jaxws.util.ASMHelper;
import org.apache.cxf.service.factory.ReflectionServiceFactoryBean;
import org.apache.cxf.service.model.InterfaceInfo;
@@ -47,11 +50,12 @@
public final class WrapperClassGenerator extends ASMHelper {
private List<Class> wrapperBeanList = new java.util.concurrent.CopyOnWriteArrayList<Class>();
private InterfaceInfo interfaceInfo;
-
+
public WrapperClassGenerator(InterfaceInfo inf) {
interfaceInfo = inf;
-
+
}
+
private String getPackageName(Method method) {
Package pkg = method.getDeclaringClass().getPackage();
if (pkg == null) {
@@ -62,8 +66,8 @@
}
private Annotation[] getMethodParameterAnnotations(final MessagePartInfo mpi) {
- Annotation[][] paramAnno =
- (Annotation[][])mpi.getProperty(ReflectionServiceFactoryBean.METHOD_PARAM_ANNOTATIONS);
+ Annotation[][] paramAnno = (Annotation[][])mpi
+ .getProperty(ReflectionServiceFactoryBean.METHOD_PARAM_ANNOTATIONS);
int index = mpi.getIndex();
if (paramAnno != null && index < paramAnno.length && index >= 0) {
return paramAnno[index];
@@ -84,18 +88,20 @@
}
return list;
}
-
+
public List<Class> genearte() {
for (OperationInfo opInfo : interfaceInfo.getOperations()) {
if (opInfo.isUnwrappedCapable()) {
Method method = (Method)opInfo.getProperty(ReflectionServiceFactoryBean.METHOD);
MessageInfo messageInfo = opInfo.getUnwrappedOperation().getInput();
createWrapperClass(messageInfo, method, true);
+
messageInfo = opInfo.getUnwrappedOperation().getOutput();
if (messageInfo != null) {
createWrapperClass(messageInfo, method, false);
}
-
+
+
}
}
return wrapperBeanList;
@@ -104,18 +110,15 @@
private void createWrapperClass(MessageInfo messageInfo, Method method, boolean isRequest) {
QName wrapperElement = messageInfo.getName();
-
+
ClassWriter cw = createClassWriter();
String className = getPackageName(method) + ".jaxws." + StringUtils.capitalize(method.getName());
if (!isRequest) {
className = className + "Response";
}
String classFileName = periodToSlashes(className);
- cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
- classFileName, null, "java/lang/Object",
- null);
-
- // cw.visitSource("AddNumbers.java", null);
+ cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, classFileName, null,
+ "java/lang/Object", null);
AnnotationVisitor av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlRootElement;", true);
av0.visit("name", wrapperElement.getLocalPart());
@@ -131,27 +134,69 @@
av0.visit("namespace", wrapperElement.getNamespaceURI());
av0.visitEnd();
-
-
+ // add constructor
+ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ Label lbegin = new Label();
+ mv.visitLabel(lbegin);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+ mv.visitInsn(Opcodes.RETURN);
+ Label lend = new Label();
+ mv.visitLabel(lend);
+ mv.visitLocalVariable("this", "L" + classFileName + ";", null, lbegin, lend, 0);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+
for (MessagePartInfo mpi : messageInfo.getMessageParts()) {
generateMessagePart(cw, mpi, method, classFileName);
}
cw.visitEnd();
+ java.io.FileOutputStream fout;
+ try {
+ fout = new java.io.FileOutputStream(new java.io.File("d:/AddNumbers.class"));
+ fout.write(cw.toByteArray());
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
Class<?> clz = loadClass(className, method.getDeclaringClass(), cw.toByteArray());
messageInfo.getMessagePart(0).setTypeClass(clz);
wrapperBeanList.add(clz);
}
-
+
private void generateMessagePart(ClassWriter cw, MessagePartInfo mpi, Method method, String className) {
String classFileName = periodToSlashes(className);
- final Class[] paramClasses = method.getParameterTypes();
- int idx = mpi.getIndex();
String name = mpi.getName().getLocalPart();
- Class clz = paramClasses[idx];
+ Class clz = mpi.getTypeClass();
+ Object obj = mpi.getProperty(ReflectionServiceFactoryBean.RAW_CLASS);
+ if (obj != null) {
+ clz = (Class)obj;
+ }
+ Class genericTypeClass = null;
+ Type genericType = (Type)mpi.getProperty(ReflectionServiceFactoryBean.GENERIC_TYPE);
+ if (genericType instanceof ParameterizedType) {
+ ParameterizedType ptype = (ParameterizedType)genericType;
+
+ Type[] types = ptype.getActualTypeArguments();
+ // TODO: more complex Parameterized type
+ if (types.length > 0 && types[0] instanceof Class) {
+ genericTypeClass = (Class)types[0];
+ }
+ }
String classCode = getClassCode(clz);
- FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, name, classCode, null, null);
+
+ String filedDescriptor = null;
+ if (genericTypeClass != null) {
+ filedDescriptor = classCode.substring(0, classCode.lastIndexOf(";")) + "<"
+ + getClassCode(genericTypeClass) + ">;";
+ }
+ String fieldName = JavaUtils.makeNonJavaKeyword(name);
+
+ FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldName, classCode, filedDescriptor, null);
AnnotationVisitor av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlElement;", true);
av0.visit("name", name);
av0.visit("namespace", "");
@@ -169,25 +214,26 @@
av0.visit("type", ((XmlJavaTypeAdapter)ann).type());
av0.visitEnd();
} else if (ann instanceof XmlAttachmentRef) {
- av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/adapters/XmlAttachmentRef;", true);
+ av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlAttachmentRef;", true);
av0.visitEnd();
} else if (ann instanceof XmlList) {
- av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/adapters/XmlList;", true);
+ av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlList;", true);
av0.visitEnd();
}
+
}
fv.visitEnd();
String methodName = StringUtils.capitalize(name);
-
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
- "get" + methodName, "()" + classCode , null, null);
+
+ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "get" + methodName, "()" + classCode, null,
+ null);
mv.visitCode();
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, classFileName, name, classCode);
+ mv.visitFieldInsn(Opcodes.GETFIELD, classFileName, fieldName, classCode);
mv.visitInsn(Opcodes.ARETURN);
Label l3 = new Label();
mv.visitLabel(l3);
@@ -201,19 +247,18 @@
mv.visitLabel(l4);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitFieldInsn(Opcodes.PUTFIELD, className, name, classCode);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, className, fieldName, classCode);
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitInsn(Opcodes.RETURN);
Label l6 = new Label();
mv.visitLabel(l6);
-
+
mv.visitLocalVariable("this", "L" + classFileName + ";", null, l4, l6, 0);
- mv.visitLocalVariable(name, classCode, null, l4, l6, 1);
+ mv.visitLocalVariable(fieldName, classCode, null, l4, l6, 1);
mv.visitMaxs(2, 2);
mv.visitEnd();
-
+
}
-
}
Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java?rev=602001&r1=602000&r2=602001&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java Thu Dec 6 22:19:49 2007
@@ -53,9 +53,14 @@
List<Field> fields = new ArrayList<Field>(partNames.size());
Method allMethods[] = wrapperType.getMethods();
+ String packageName = wrapperType.getName().substring(0, wrapperType.getName().lastIndexOf("."));
- String objectFactoryClassName = wrapperType.getPackage().getName()
- + ".ObjectFactory";
+ //if wrappertype class is generated by ASM,getPackage() always return null
+ if (wrapperType.getPackage() != null) {
+ packageName = wrapperType.getPackage().getName();
+ }
+
+ String objectFactoryClassName = packageName + ".ObjectFactory";
Object objectFactory = null;
try {
@@ -325,4 +330,5 @@
}
}
+
}
Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java?rev=602001&r1=602000&r2=602001&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java Thu Dec 6 22:19:49 2007
@@ -19,9 +19,15 @@
package org.apache.cxf.jaxws;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
import org.apache.cxf.BusFactory;
+import org.apache.cxf.jaxws.interceptors.WrapperHelper;
import org.apache.cxf.jaxws.service.AddNumbersImpl;
import org.apache.cxf.jaxws.support.JaxWsImplementorInfo;
import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
@@ -39,7 +45,7 @@
}
@org.junit.Test
- public void testForAttachementRef() {
+ public void testForXmlList() throws Exception {
JaxWsImplementorInfo implInfo =
new JaxWsImplementorInfo(AddNumbersImpl.class);
JaxWsServiceFactoryBean jaxwsFac = new JaxWsServiceFactoryBean(implInfo);
@@ -48,7 +54,75 @@
ServiceInfo serviceInfo = service.getServiceInfos().get(0);
InterfaceInfo interfaceInfo = serviceInfo.getInterface();
WrapperClassGenerator wrapperClassGenerator = new WrapperClassGenerator(interfaceInfo);
- List<Class> list = wrapperClassGenerator.genearte();
- assertEquals(2, list.size());
+ List<Class> wrapperClassList = wrapperClassGenerator.genearte();
+ assertEquals(2, wrapperClassList.size());
+
+ Class requestClass = wrapperClassList.get(0);
+ Class responseClass = wrapperClassList.get(1);
+ if (!requestClass.getSimpleName().equals("AddNumbers")) {
+ Class tmp = requestClass;
+ requestClass = responseClass;
+ responseClass = tmp;
+ }
+
+ // Create request wrapper Object
+ List<String> partNames = Arrays.asList(new String[] {"arg0"});
+ List<String> elTypeNames = Arrays.asList(new String[] {"list"});
+ List<Class<?>> partClasses = Arrays.asList(new Class<?>[] {List.class});
+
+ String className = requestClass.getName();
+ className = className.substring(0, className.lastIndexOf(".") + 1);
+
+ WrapperHelper wh = WrapperHelper.createWrapperHelper(requestClass,
+ partNames, elTypeNames, partClasses);
+
+ List<Object> paraList = new ArrayList<Object>();
+ List<String> valueList = new ArrayList<String>();
+ valueList.add("str1");
+ valueList.add("str2");
+ valueList.add("str3");
+ paraList.add(valueList);
+ Object requestObj = wh.createWrapperObject(paraList);
+ // Create response wrapper Object
+
+ partNames = Arrays.asList(new String[] {"return"});
+ elTypeNames = Arrays.asList(new String[] {"list"});
+ partClasses = Arrays.asList(new Class<?>[] {List.class});
+
+ className = responseClass.getName();
+ className = className.substring(0, className.lastIndexOf(".") + 1);
+
+ wh = WrapperHelper.createWrapperHelper(responseClass,
+ partNames, elTypeNames, partClasses);
+ List<Object> resPara = new ArrayList<Object>();
+ List<Integer> intValueList = new ArrayList<Integer>();
+ intValueList.add(1);
+ intValueList.add(2);
+ intValueList.add(3);
+ resPara.add(intValueList);
+ Object responseObj = wh.createWrapperObject(resPara);
+
+ JAXBContext jaxbContext = JAXBContext.newInstance(wrapperClassList.toArray(new Class[]{}));
+ java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();
+ Marshaller marshaller = jaxbContext.createMarshaller();
+
+ //check marshall wrapper
+ marshaller.marshal(requestObj, bout);
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ + "<ns2:addNumbers xmlns:ns2=\"http://service.jaxws.cxf.apache.org/\">"
+ + "<arg0>str1 str2 str3</arg0></ns2:addNumbers>";
+
+ assertEquals("The generated request wrapper class does not contain the correct annotations",
+ expected, bout.toString());
+
+
+ bout.reset();
+ marshaller.marshal(responseObj, bout);
+ expected = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+ + "<ns2:addNumbersResponse xmlns:ns2=\"http://service.jaxws.cxf.apache.org/\">"
+ + "<return>1</return><return>2</return><return>3</return></ns2:addNumbersResponse>";
+ assertEquals("The generated response wrapper class is not correct", expected, bout.toString());
+
}
+
}
Modified: incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java?rev=602001&r1=602000&r2=602001&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java (original)
+++ incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java Thu Dec 6 22:19:49 2007
@@ -117,6 +117,7 @@
public static final String ENDPOINT_CLASS = "endpoint.class";
public static final String GENERIC_TYPE = "generic.type";
+ public static final String RAW_CLASS = "rawclass";
public static final String MODE_OUT = "messagepart.mode.out";
public static final String MODE_INOUT = "messagepart.mode.inout";
public static final String HOLDER = "messagepart.isholder";
@@ -1264,6 +1265,11 @@
rawClass = getHolderClass(paramType);
}
part.setProperty(GENERIC_TYPE, type);
+ //if rawClass is List<String>, it will be converted to array
+ //and set it to type class
+ if (Collection.class.isAssignableFrom(rawClass)) {
+ part.setProperty(RAW_CLASS, rawClass);
+ }
part.setTypeClass(rawClass);
}
@@ -1647,6 +1653,7 @@
}
return null;
}
+
protected String getResponseWrapperClassName(Method selected) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
String cls = c.getResponseWrapperClassName(selected);