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/06 09:43:55 UTC

svn commit: r601658 - in /incubator/cxf/trunk: rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/ rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/ rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/util/ rt/frontend/jaxws/src/tes...

Author: ema
Date: Thu Dec  6 00:43:54 2007
New Revision: 601658

URL: http://svn.apache.org/viewvc?rev=601658&view=rev
Log:
[CXF-1267]Directly generate wrapper bean class .
Fixe minor issue in WrapperBeanFiledAnnotator 

Added:
    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/util/
    incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/util/ASMHelper.java
    incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java
    incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers.java
    incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbersImpl.java
Modified:
    incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
    incubator/cxf/trunk/tools/javato/ws/src/main/java/org/apache/cxf/tools/java2wsdl/generator/wsdl11/annotator/WrapperBeanFieldAnnotator.java

Added: 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=601658&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java Thu Dec  6 00:43:54 2007
@@ -0,0 +1,229 @@
+/**
+ * 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.cxf.jaxws;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttachmentRef;
+import javax.xml.bind.annotation.XmlList;
+import javax.xml.bind.annotation.XmlMimeType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.jaxws.util.ASMHelper;
+import org.apache.cxf.service.factory.ReflectionServiceFactoryBean;
+import org.apache.cxf.service.model.InterfaceInfo;
+import org.apache.cxf.service.model.MessageInfo;
+import org.apache.cxf.service.model.MessagePartInfo;
+import org.apache.cxf.service.model.OperationInfo;
+import org.apache.cxf.tools.common.ToolConstants;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+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) {
+            return ToolConstants.DEFAULT_PACKAGE_NAME;
+        }
+        return pkg.getName();
+
+    }
+
+    private Annotation[] getMethodParameterAnnotations(final MessagePartInfo mpi) {
+        Annotation[][] paramAnno = 
+            (Annotation[][])mpi.getProperty(ReflectionServiceFactoryBean.METHOD_PARAM_ANNOTATIONS);
+        int index = mpi.getIndex();
+        if (paramAnno != null && index < paramAnno.length && index >= 0) {
+            return paramAnno[index];
+        }
+        return null;
+    }
+
+    private List<Annotation> getJaxbAnnos(MessagePartInfo mpi) {
+        List<Annotation> list = new java.util.concurrent.CopyOnWriteArrayList<Annotation>();
+        Annotation[] anns = getMethodParameterAnnotations(mpi);
+        if (anns != null) {
+            for (Annotation anno : anns) {
+                if (anno.annotationType() == XmlList.class || anno.annotationType() == XmlAttachmentRef.class
+                    || anno.annotationType() == XmlJavaTypeAdapter.class) {
+                    list.add(anno);
+                }
+            }
+        }
+        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;
+    }
+
+    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);
+
+        AnnotationVisitor av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlRootElement;", true);
+        av0.visit("name", wrapperElement.getLocalPart());
+        av0.visit("namespace", wrapperElement.getNamespaceURI());
+        av0.visitEnd();
+
+        av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlAccessorType;", true);
+        av0.visitEnum("value", "Ljavax/xml/bind/annotation/XmlAccessType;", "FIELD");
+        av0.visitEnd();
+
+        av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlType;", true);
+        av0.visit("name", wrapperElement.getLocalPart());
+        av0.visit("namespace", wrapperElement.getNamespaceURI());
+        av0.visitEnd();
+
+        
+        
+        for (MessagePartInfo mpi : messageInfo.getMessageParts()) {
+            generateMessagePart(cw, mpi, method, classFileName);
+        }
+
+        cw.visitEnd();
+        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];
+        String classCode = getClassCode(clz);
+        FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, name, classCode, null, null);
+        AnnotationVisitor av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlElement;", true);
+        av0.visit("name", name);
+        av0.visit("namespace", "");
+        av0.visitEnd();
+
+        List<Annotation> jaxbAnnos = getJaxbAnnos(mpi);
+        for (Annotation ann : jaxbAnnos) {
+            if (ann instanceof XmlMimeType) {
+                av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlMimeType;", true);
+                av0.visit("value", ((XmlMimeType)ann).value());
+                av0.visitEnd();
+            } else if (ann instanceof XmlJavaTypeAdapter) {
+                av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/adapters/XmlJavaTypeAdapter;", true);
+                av0.visit("value", ((XmlJavaTypeAdapter)ann).value());
+                av0.visit("type", ((XmlJavaTypeAdapter)ann).type());
+                av0.visitEnd();
+            } else if (ann instanceof XmlAttachmentRef) {
+                av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/adapters/XmlAttachmentRef;", true);
+                av0.visitEnd();
+            } else if (ann instanceof XmlList) {
+                av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/adapters/XmlList;", true);
+                av0.visitEnd();
+            }
+        }
+
+        fv.visitEnd();
+
+        String methodName = StringUtils.capitalize(name);
+        
+        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, 
+                                          "get" + methodName, "(" + classCode + ")V", null, null);
+        mv.visitCode();
+        Label l2 = new Label();
+        mv.visitLabel(l2);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, classFileName, name, classCode);
+        mv.visitInsn(Opcodes.ARETURN);
+        Label l3 = new Label();
+        mv.visitLabel(l3);
+        mv.visitLocalVariable("this", classCode, null, l2, l3, 0);
+        mv.visitMaxs(1, 1);
+        mv.visitEnd();
+
+        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "set" + methodName, "(" + classCode + ")V", null, null);
+        mv.visitCode();
+        Label l4 = new Label();
+        mv.visitLabel(l4);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitVarInsn(Opcodes.ALOAD, 1);
+        mv.visitFieldInsn(Opcodes.PUTFIELD, className, name, 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.visitMaxs(2, 2);
+
+        mv.visitEnd();
+    
+    }
+    
+    
+    private static class TypeHelperClassLoader extends ClassLoader {
+        TypeHelperClassLoader(ClassLoader parent) {
+            super(parent);
+        }
+        public Class<?> defineClass(String name, byte bytes[]) {
+            return super.defineClass(name, bytes, 0, bytes.length);
+        }
+    }
+    
+}

Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java?rev=601658&r1=601657&r2=601658&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java (original)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java Thu Dec  6 00:43:54 2007
@@ -18,46 +18,21 @@
  */
 package org.apache.cxf.jaxws.interceptors;
 
-import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
 
 import javax.xml.bind.JAXBElement;
 
+import org.apache.cxf.jaxws.util.ASMHelper;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.FieldVisitor;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 
-final class WrapperHelperCompiler {
-    private static final Map<Class<?>, String> PRIMITIVE_MAP = new HashMap<Class<?>, String>();
-    private static final Map<Class<?>, String> NONPRIMITIVE_MAP = new HashMap<Class<?>, String>();
-    
-    private static boolean oldASM;
-    
-    static {
-        PRIMITIVE_MAP.put(Byte.TYPE, "B");
-        PRIMITIVE_MAP.put(Boolean.TYPE, "Z");
-        PRIMITIVE_MAP.put(Long.TYPE, "J");
-        PRIMITIVE_MAP.put(Integer.TYPE, "I");
-        PRIMITIVE_MAP.put(Short.TYPE, "S");
-        PRIMITIVE_MAP.put(Character.TYPE, "C");
-        PRIMITIVE_MAP.put(Float.TYPE, "F");
-        PRIMITIVE_MAP.put(Double.TYPE, "D");
-
-        NONPRIMITIVE_MAP.put(Byte.TYPE, Byte.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Boolean.TYPE, Boolean.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Long.TYPE, Long.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Integer.TYPE, Integer.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Short.TYPE, Short.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Character.TYPE, Character.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Float.TYPE, Float.class.getName().replaceAll("\\.", "/"));
-        NONPRIMITIVE_MAP.put(Double.TYPE, Double.class.getName().replaceAll("\\.", "/"));
-    }    
+final class WrapperHelperCompiler extends ASMHelper {
+  
     
     final Class<?> wrapperType;
     final Method setMethods[];
@@ -66,6 +41,7 @@
     final Field fields[];
     final Object objectFactory;
     final ClassWriter cw;
+
     
     private WrapperHelperCompiler(Class<?> wrapperType,
                                   Method setMethods[],
@@ -79,40 +55,7 @@
         this.jaxbMethods = jaxbMethods;
         this.fields = fields;
         this.objectFactory = objectFactory;
-        
-
-        ClassWriter newCw = null;
-        if (!oldASM) {
-            Class<ClassWriter> cls = ClassWriter.class;
-            try {
-                //ASM 1.5.x/2.x
-                Constructor<ClassWriter> cons = cls.getConstructor(new Class<?>[] {Boolean.TYPE});
-                
-                try {
-                    //got constructor, now check if it's 1.x which is very different from 2.x and 3.x 
-                    cls.getMethod("newConstInt", new Class<?>[] {Integer.TYPE});               
-                    //newConstInt was removed in 2.x, if we get this far, we're using 1.5.x,
-                    //set to null so we don't attempt to use it.
-                    newCw = null;    
-                    oldASM = true;
-                } catch (Throwable t) {
-                    newCw = cons.newInstance(new Object[] {Boolean.TRUE});
-                }
-                
-            } catch (Throwable e) {
-                //ASM 3.x
-                try {
-                    Constructor<ClassWriter> cons = cls.getConstructor(new Class<?>[] {Integer.TYPE});
-                    int i = cls.getField("COMPUTE_MAXS").getInt(null);
-                    i |= cls.getField("COMPUTE_FRAMES").getInt(null);
-                    newCw = cons.newInstance(new Object[] {Integer.valueOf(i)});
-                } catch (Throwable e1) {
-                    //ignore
-                }
-                
-            }
-        }
-        cw = newCw;
+        cw = createClassWriter();
     }
 
     static WrapperHelper compileWrapperHelper(Class<?> wrapperType,
@@ -129,11 +72,15 @@
                                         fields,
                                         objectFactory).compile();
         } catch (Throwable t) {
-            //Some error - probably a bad version of ASM or similar
+            // Some error - probably a bad version of ASM or similar
             return null;
         }
     }
+    
 
+    
+    
+    
     public WrapperHelper compile() {
         if (cw == null) {
             return null;
@@ -160,28 +107,17 @@
         try {
             if (b) {
                 cw.visitEnd();
-                byte bt[] = cw.toByteArray();
-                Class<?> cl = new TypeHelperClassLoader(wrapperType.getClassLoader())
-                    .defineClass(newClassName.replaceAll("/", "."), bt);
-                                 
+                byte bt[] = cw.toByteArray();                
+                Class<?> cl = loadClass(newClassName, wrapperType, bt);
                 Object o = cl.newInstance();
                 return WrapperHelper.class.cast(o);
             }
         } catch (Exception e) {
-            //ignore, we'll just fall down to reflection based
+            // ignore, we'll just fall down to reflection based
         }
         return null;
     }
     
-    
-    private static class TypeHelperClassLoader extends ClassLoader {
-        TypeHelperClassLoader(ClassLoader parent) {
-            super(parent);
-        }
-        public Class<?> defineClass(String name, byte bytes[]) {
-            return super.defineClass(name, bytes, 0, bytes.length);
-        }
-    }
     private static void addConstructor(String newClassName, ClassWriter cw,  Class<?> objectFactory) {
         
         if (objectFactory != null) {
@@ -246,7 +182,7 @@
             if (getMethods[x] == null) { 
                 if (setMethods[x] == null
                     && fields[x] == null) {
-                    //null placeholder, just skip it
+                    // null placeholder, just skip it
                     continue;
                 } else {
                     return false;
@@ -304,13 +240,13 @@
     }
     
     private void doCollection(MethodVisitor mv, int x) {
-        //List aVal = obj.getA();
-        //List newA = (List)lst.get(99);
-        //if (aVal == null) {
-        //    obj.setA(newA);
-        //} else {
-        //    aVal.addAll(newA);
-        //}
+        // List aVal = obj.getA();
+        // List newA = (List)lst.get(99);
+        // if (aVal == null) {
+        // obj.setA(newA);
+        // } else {
+        // aVal.addAll(newA);
+        // }
         
         mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                            periodToSlashes(wrapperType.getName()),
@@ -372,7 +308,7 @@
         Label lBegin = new Label();
         mv.visitLabel(lBegin);
                
-        //the ret List
+        // the ret List
         mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
         mv.visitInsn(Opcodes.DUP);
         mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V");
@@ -386,7 +322,7 @@
         for (int x = 0; x < getMethods.length; x++) {
             Method method = getMethods[x];
             if (method == null && fields[x] != null) {
-                //fallback to reflection mode
+                // fallback to reflection mode
                 return false;
             }
             
@@ -404,7 +340,7 @@
                                    method.getName(), 
                                    getMethodSignature(method));
                 if (method.getReturnType().isPrimitive()) {
-                    //wrap into Object type
+                    // wrap into Object type
                     createObjectWrapper(mv, method.getReturnType());
                 }
                 if (JAXBElement.class.isAssignableFrom(method.getReturnType())) {
@@ -418,7 +354,7 @@
             }
         }
         
-        //return the list
+        // return the list
         Label l2 = new Label();
         mv.visitLabel(l2);
         mv.visitVarInsn(Opcodes.ALOAD, 2);
@@ -439,42 +375,18 @@
     }
     
     
-    private static String getMethodSignature(Method m) {
-        StringBuffer buf = new StringBuffer("(");
-        for (Class<?> cl : m.getParameterTypes()) {
-            buf.append(getClassCode(cl));
-        }
-        buf.append(")");
-        buf.append(getClassCode(m.getReturnType()));
-        
-        return buf.toString();
-    }
-    private static String getClassCode(Class<?> cl) {
-        if (cl == Void.TYPE) {
-            return "V";
-        }
-        if (cl.isPrimitive()) {
-            return PRIMITIVE_MAP.get(cl);
-        }
-        if (cl.isArray()) {
-            return "[" + getClassCode(cl.getComponentType());
-        }
-        return "L" + periodToSlashes(cl.getName()) + ";";
-    }
+
+
     private static void createObjectWrapper(MethodVisitor mv, Class<?> cl) {
         mv.visitMethodInsn(Opcodes.INVOKESTATIC, NONPRIMITIVE_MAP.get(cl),
                            "valueOf", "(" + PRIMITIVE_MAP.get(cl) + ")L" 
                            + NONPRIMITIVE_MAP.get(cl) + ";");
     }
     
-    private static String periodToSlashes(String s) {
-        char ch[] = s.toCharArray();
-        for (int x = 0; x < ch.length; x++) {
-            if (ch[x] == '.') {
-                ch[x] = '/';
-            }
-        }
-        return new String(ch);
-    }
+
+    
+    
+        
+
 
 }

Added: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/util/ASMHelper.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/util/ASMHelper.java?rev=601658&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/util/ASMHelper.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/util/ASMHelper.java Thu Dec  6 00:43:54 2007
@@ -0,0 +1,143 @@
+/**
+ * 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.cxf.jaxws.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.objectweb.asm.ClassWriter;
+
+public class ASMHelper {
+    protected static final Map<Class<?>, String> PRIMITIVE_MAP = new HashMap<Class<?>, String>();
+    protected static final Map<Class<?>, String> NONPRIMITIVE_MAP = new HashMap<Class<?>, String>();
+    
+    protected static boolean oldASM;
+    
+    static {
+        PRIMITIVE_MAP.put(Byte.TYPE, "B");
+        PRIMITIVE_MAP.put(Boolean.TYPE, "Z");
+        PRIMITIVE_MAP.put(Long.TYPE, "J");
+        PRIMITIVE_MAP.put(Integer.TYPE, "I");
+        PRIMITIVE_MAP.put(Short.TYPE, "S");
+        PRIMITIVE_MAP.put(Character.TYPE, "C");
+        PRIMITIVE_MAP.put(Float.TYPE, "F");
+        PRIMITIVE_MAP.put(Double.TYPE, "D");
+
+        NONPRIMITIVE_MAP.put(Byte.TYPE, Byte.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Boolean.TYPE, Boolean.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Long.TYPE, Long.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Integer.TYPE, Integer.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Short.TYPE, Short.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Character.TYPE, Character.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Float.TYPE, Float.class.getName().replaceAll("\\.", "/"));
+        NONPRIMITIVE_MAP.put(Double.TYPE, Double.class.getName().replaceAll("\\.", "/"));
+    }
+    
+    protected static String getMethodSignature(Method m) {
+        StringBuffer buf = new StringBuffer("(");
+        for (Class<?> cl : m.getParameterTypes()) {
+            buf.append(getClassCode(cl));
+        }
+        buf.append(")");
+        buf.append(getClassCode(m.getReturnType()));
+        
+        return buf.toString();
+    }
+    
+    protected static String periodToSlashes(String s) {
+        char ch[] = s.toCharArray();
+        for (int x = 0; x < ch.length; x++) {
+            if (ch[x] == '.') {
+                ch[x] = '/';
+            }
+        }
+        return new String(ch);
+    }
+    
+    
+    public static String getClassCode(Class<?> cl) {
+        if (cl == Void.TYPE) {
+            return "V";
+        }
+        if (cl.isPrimitive()) {
+            return PRIMITIVE_MAP.get(cl);
+        }
+        if (cl.isArray()) {
+            return "[" + getClassCode(cl.getComponentType());
+        }
+        return "L" + periodToSlashes(cl.getName()) + ";";
+    }
+    
+    
+    public ClassWriter createClassWriter() {
+        ClassWriter newCw = null;
+        if (!oldASM) {
+            Class<ClassWriter> cls = ClassWriter.class;
+            try {
+                // ASM 1.5.x/2.x
+                Constructor<ClassWriter> cons = cls.getConstructor(new Class<?>[] {Boolean.TYPE});
+                
+                try {
+                    // got constructor, now check if it's 1.x which is very
+                    // different from 2.x and 3.x
+                    cls.getMethod("newConstInt", new Class<?>[] {Integer.TYPE});               
+                    // newConstInt was removed in 2.x, if we get this far, we're
+                    // using 1.5.x,
+                    // set to null so we don't attempt to use it.
+                    newCw = null;    
+                    oldASM = true;
+                } catch (Throwable t) {
+                    newCw = cons.newInstance(new Object[] {Boolean.TRUE});
+                }
+                
+            } catch (Throwable e) {
+                // ASM 3.x
+                try {
+                    Constructor<ClassWriter> cons = cls.getConstructor(new Class<?>[] {Integer.TYPE});
+                    int i = cls.getField("COMPUTE_MAXS").getInt(null);
+                    i |= cls.getField("COMPUTE_FRAMES").getInt(null);
+                    newCw = cons.newInstance(new Object[] {Integer.valueOf(i)});
+                } catch (Throwable e1) {
+                    // ignore
+                }
+                
+            }
+        }
+        return newCw;
+    }
+    
+    
+    public Class<?> loadClass(String className, Class clz , byte[] bytes) { 
+        TypeHelperClassLoader loader = new TypeHelperClassLoader(clz.getClassLoader());
+        return loader.defineClass(className, bytes);
+    }
+    
+    public static class TypeHelperClassLoader extends ClassLoader {
+        TypeHelperClassLoader(ClassLoader parent) {
+            super(parent);
+        }
+        public Class<?> defineClass(String name, byte bytes[]) {
+            return super.defineClass(name, bytes, 0, bytes.length);
+        }
+    }
+    
+}

Added: 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=601658&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java Thu Dec  6 00:43:54 2007
@@ -0,0 +1,54 @@
+/**
+ * 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.cxf.jaxws;
+
+import java.util.List;
+
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.jaxws.service.AddNumbersImpl;
+import org.apache.cxf.jaxws.support.JaxWsImplementorInfo;
+import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.InterfaceInfo;
+import org.apache.cxf.service.model.ServiceInfo;
+import org.junit.After;
+import org.junit.Assert;
+
+public class WrapperClassGeneratorTest extends Assert {
+    
+    @After
+    public void tearDown() {
+        BusFactory.setDefaultBus(null);
+    }
+    
+    @org.junit.Test
+    public void testForAttachementRef() {
+        JaxWsImplementorInfo implInfo = 
+            new JaxWsImplementorInfo(AddNumbersImpl.class);
+        JaxWsServiceFactoryBean jaxwsFac = new JaxWsServiceFactoryBean(implInfo);
+        jaxwsFac.setBus(BusFactory.getDefaultBus());
+        Service service = jaxwsFac.create();
+        ServiceInfo serviceInfo =  service.getServiceInfos().get(0);
+        InterfaceInfo interfaceInfo = serviceInfo.getInterface();
+        WrapperClassGenerator wrapperClassGenerator = new WrapperClassGenerator(interfaceInfo);
+        List<Class> list = wrapperClassGenerator.genearte();
+        assertEquals(2, list.size());       
+    }
+}

Added: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers.java?rev=601658&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers.java Thu Dec  6 00:43:54 2007
@@ -0,0 +1,35 @@
+/**
+ * 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.cxf.jaxws.service;
+import java.util.List;
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.xml.bind.annotation.XmlList;
+
+@WebService
+public interface AddNumbers {
+    @WebMethod
+    List<Integer> addNumbers(
+                             @WebParam
+                             @XmlList
+                             List<String> arg);
+}

Added: incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbersImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbersImpl.java?rev=601658&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbersImpl.java (added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbersImpl.java Thu Dec  6 00:43:54 2007
@@ -0,0 +1,31 @@
+/**
+ * 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.cxf.jaxws.service;
+
+import java.util.List;
+
+@javax.jws.WebService(endpointInterface = "org.apache.cxf.jaxws.service.AddNumbers")
+public class AddNumbersImpl implements AddNumbers {
+
+    public List<Integer> addNumbers(List<String> arg) {
+        return null;
+    }
+
+}

Modified: incubator/cxf/trunk/tools/javato/ws/src/main/java/org/apache/cxf/tools/java2wsdl/generator/wsdl11/annotator/WrapperBeanFieldAnnotator.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/tools/javato/ws/src/main/java/org/apache/cxf/tools/java2wsdl/generator/wsdl11/annotator/WrapperBeanFieldAnnotator.java?rev=601658&r1=601657&r2=601658&view=diff
==============================================================================
--- incubator/cxf/trunk/tools/javato/ws/src/main/java/org/apache/cxf/tools/java2wsdl/generator/wsdl11/annotator/WrapperBeanFieldAnnotator.java (original)
+++ incubator/cxf/trunk/tools/javato/ws/src/main/java/org/apache/cxf/tools/java2wsdl/generator/wsdl11/annotator/WrapperBeanFieldAnnotator.java Thu Dec  6 00:43:54 2007
@@ -64,7 +64,7 @@
                 jaxbAnn.addElement(new JAnnotationElement("type", ((XmlJavaTypeAdapter)ann).type()));
                 jField.addAnnotation(jaxbAnn);
             } else if (ann instanceof XmlAttachmentRef) {
-                JAnnotation jaxbAnn = new JAnnotation(XmlJavaTypeAdapter.class);
+                JAnnotation jaxbAnn = new JAnnotation(XmlAttachmentRef.class);
                 jField.addAnnotation(jaxbAnn);
             } else if (ann instanceof XmlList) {
                 JAnnotation jaxbAnn = new JAnnotation(XmlList.class);