Author: dkulp
Date: Tue Jul 3 10:02:03 2007
New Revision: 552913
URL: http://svn.apache.org/viewvc?view=rev&rev=552913
Log:
WrapperType optimizations - phase 2
* If asm is available, generate a class that will do all the wrapper type
handling without any reflection. If no asm, fallback to reflection (with
cached Method/Field objects).
Added:
incubator/cxf/trunk/distribution/src/main/release/licenses/asm.txt (with
props)
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java
- copied, changed from r552502,
incubator/cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/WrapperHelper.java
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
(with props)
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperHelperTest.java
- copied, changed from r552502,
incubator/cxf/trunk/common/common/src/test/java/org/apache/cxf/jaxb/WrapperHelperTest.java
Removed:
incubator/cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/WrapperHelper.java
incubator/cxf/trunk/common/common/src/test/java/org/apache/cxf/jaxb/WrapperHelperTest.java
Modified:
incubator/cxf/trunk/distribution/src/main/release/lib/WHICH_JARS
incubator/cxf/trunk/parent/pom.xml
incubator/cxf/trunk/rt/frontend/jaxws/pom.xml
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassInInterceptor.java
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassOutInterceptor.java
Modified: incubator/cxf/trunk/distribution/src/main/release/lib/WHICH_JARS
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/distribution/src/main/release/lib/WHICH_JARS?view=diff&rev=552913&r1=552912&r2=552913
==============================================================================
--- incubator/cxf/trunk/distribution/src/main/release/lib/WHICH_JARS (original)
+++ incubator/cxf/trunk/distribution/src/main/release/lib/WHICH_JARS Tue Jul 3
10:02:03 2007
@@ -26,6 +26,7 @@
- jaxws-api.jar
- saaj-api.jar
- saaj-impl.jar
+- asm.jar (optional, but helps with performance of wrapper types)
For XML Configuration support:
- aopalliance.jar
Added: incubator/cxf/trunk/distribution/src/main/release/licenses/asm.txt
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/distribution/src/main/release/licenses/asm.txt?view=auto&rev=552913
==============================================================================
--- incubator/cxf/trunk/distribution/src/main/release/licenses/asm.txt (added)
+++ incubator/cxf/trunk/distribution/src/main/release/licenses/asm.txt Tue Jul
3 10:02:03 2007
@@ -0,0 +1,30 @@
+Copyright (c) 2000-2005 INRIA, France Telecom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
Propchange: incubator/cxf/trunk/distribution/src/main/release/licenses/asm.txt
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/cxf/trunk/distribution/src/main/release/licenses/asm.txt
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: incubator/cxf/trunk/parent/pom.xml
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/parent/pom.xml?view=diff&rev=552913&r1=552912&r2=552913
==============================================================================
--- incubator/cxf/trunk/parent/pom.xml (original)
+++ incubator/cxf/trunk/parent/pom.xml Tue Jul 3 10:02:03 2007
@@ -609,7 +609,7 @@
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
- <version>2.2.3</version>
+ <version>3.0</version>
</dependency>
<dependency>
<groupId>velocity</groupId>
Modified: incubator/cxf/trunk/rt/frontend/jaxws/pom.xml
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/pom.xml?view=diff&rev=552913&r1=552912&r2=552913
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/pom.xml (original)
+++ incubator/cxf/trunk/rt/frontend/jaxws/pom.xml Tue Jul 3 10:02:03 2007
@@ -60,6 +60,10 @@
<artifactId>jaxws-api</artifactId>
</dependency>
<dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-api</artifactId>
<version>${project.version}</version>
@@ -140,7 +144,7 @@
<scm>
<connection>scm:svn:http://svn.apache.org/repos/asf/incubator/cxf/trunk/rt/frontend/jaxws</connection>
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/cxf/trunk/rt/frontend/jaxws</developerConnection>
-
<url>http://svn.apache.org/viewvc/incubator/cxf/trunk/cxf-parent/cxf-rt-frontend-jaxws</url>
- </scm>
+
<url>http://svn.apache.org/viewvc/incubator/cxf/trunk/cxf-parent/cxf-rt-frontend-jaxws</url>
+ </scm>
</project>
Modified:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassInInterceptor.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassInInterceptor.java?view=diff&rev=552913&r1=552912&r2=552913
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassInInterceptor.java
(original)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassInInterceptor.java
Tue Jul 3 10:02:03 2007
@@ -25,7 +25,6 @@
import java.util.logging.Logger;
import org.apache.cxf.interceptor.Fault;
-import org.apache.cxf.jaxb.WrapperHelper;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
Modified:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassOutInterceptor.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassOutInterceptor.java?view=diff&rev=552913&r1=552912&r2=552913
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassOutInterceptor.java
(original)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperClassOutInterceptor.java
Tue Jul 3 10:02:03 2007
@@ -24,7 +24,6 @@
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.interceptor.Fault;
-import org.apache.cxf.jaxb.WrapperHelper;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
Copied:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java
(from r552502,
incubator/cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/WrapperHelper.java)
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java?view=diff&rev=552913&p1=incubator/cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/WrapperHelper.java&r1=552502&p2=incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java&r2=552913
==============================================================================
---
incubator/cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/WrapperHelper.java
(original)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java
Tue Jul 3 10:02:03 2007
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.cxf.jaxb;
+package org.apache.cxf.jaxws.interceptors;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -30,73 +30,18 @@
import javax.xml.bind.annotation.XmlElement;
import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.jaxb.JAXBUtils;
+
+public abstract class WrapperHelper {
+ private static final Class NO_PARAMS[] = new Class[0];
-public class WrapperHelper {
- private static final Class NO_PARAMS[] = new Class[0];
- final Class<?> wrapperType;
- final Method setMethods[];
- final Method getMethods[];
- final Method jaxbObjectMethods[];
- final Field fields[];
- final Object objectFactory;
-
- WrapperHelper(Class<?> wt,
- Method sets[],
- Method gets[],
- Method jaxbs[],
- Field f[],
- Object of) {
- setMethods = sets;
- getMethods = gets;
- fields = f;
- jaxbObjectMethods = jaxbs;
- wrapperType = wt;
- objectFactory = of;
- }
+ public abstract Object createWrapperObject(List<?> lst)
+ throws Fault;
- public Object createWrapperObject(List<?> lst)
- throws InstantiationException, IllegalAccessException,
- IllegalArgumentException, InvocationTargetException {
-
- Object ret = wrapperType.newInstance();
-
- for (int x = 0; x < setMethods.length; x++) {
- Object o = lst.get(x);
- if (jaxbObjectMethods[x] != null) {
- o = jaxbObjectMethods[x].invoke(objectFactory, o);
- }
- if (o instanceof List) {
- List<Object> col =
CastUtils.cast((List)getMethods[x].invoke(ret));
- List<Object> olst = CastUtils.cast((List)o);
- col.addAll(olst);
- } else if (setMethods[x] != null) {
- setMethods[x].invoke(ret, o);
- } else {
- fields[x].set(ret, lst.get(x));
- }
- }
-
- return ret;
- }
-
- public List<Object> getWrapperParts(Object o)
- throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
-
- List<Object> ret = new ArrayList<Object>(getMethods.length);
- for (int x = 0; x < getMethods.length; x++) {
- if (getMethods[x] != null) {
- ret.add(getValue(getMethods[x], o));
- } else if (fields[x] != null) {
- ret.add(fields[x].get(o));
- } else {
- //placeholder
- ret.add(null);
- }
- }
-
- return ret;
- }
+ public abstract List<Object> getWrapperParts(Object o) throws Fault;
+
public static WrapperHelper createWrapperHelper(Class<?> wrapperType,
List<String> partNames,
@@ -223,7 +168,8 @@
}
}
- return new WrapperHelper(wrapperType,
+
+ return createWrapperHelper(wrapperType,
setMethods.toArray(new
Method[setMethods.size()]),
getMethods.toArray(new
Method[getMethods.size()]),
jaxbMethods.toArray(new
Method[jaxbMethods.size()]),
@@ -250,4 +196,112 @@
return method.invoke(in);
}
}
+ private static WrapperHelper createWrapperHelper(Class<?> wrapperType,
+ Method setMethods[],
+ Method getMethods[],
+ Method jaxbMethods[],
+ Field fields[],
+ Object objectFactory) {
+ WrapperHelper wh = compileWrapperHelper(wrapperType,
+ setMethods,
+ getMethods,
+ jaxbMethods,
+ fields,
+ objectFactory);
+ if (wh == null) {
+ wh = new ReflectWrapperHelper(wrapperType,
+ setMethods,
+ getMethods,
+ jaxbMethods,
+ fields,
+ objectFactory);
+ }
+ return wh;
+ }
+ private static WrapperHelper compileWrapperHelper(Class<?> wrapperType,
+ Method setMethods[],
+ Method getMethods[],
+ Method jaxbMethods[],
+ Field fields[],
+ Object objectFactory) {
+ try {
+ Class.forName("org.objectweb.asm.ClassWriter");
+ return WrapperHelperCompiler.compileWrapperHelper(wrapperType,
setMethods, getMethods,
+ jaxbMethods,
fields, objectFactory);
+ } catch (ClassNotFoundException e) {
+ //ASM not found, just use reflection based stuff
+ }
+ return null;
+ }
+
+ static class ReflectWrapperHelper extends WrapperHelper {
+ final Class<?> wrapperType;
+ final Method setMethods[];
+ final Method getMethods[];
+ final Method jaxbObjectMethods[];
+ final Field fields[];
+ final Object objectFactory;
+
+ ReflectWrapperHelper(Class<?> wt,
+ Method sets[],
+ Method gets[],
+ Method jaxbs[],
+ Field f[],
+ Object of) {
+ setMethods = sets;
+ getMethods = gets;
+ fields = f;
+ jaxbObjectMethods = jaxbs;
+ wrapperType = wt;
+ objectFactory = of;
+ }
+
+ public Object createWrapperObject(List<?> lst)
+ throws Fault {
+
+ try {
+ Object ret = wrapperType.newInstance();
+
+ for (int x = 0; x < setMethods.length; x++) {
+ Object o = lst.get(x);
+ if (jaxbObjectMethods[x] != null) {
+ o = jaxbObjectMethods[x].invoke(objectFactory, o);
+ }
+ if (o instanceof List) {
+ List<Object> col =
CastUtils.cast((List)getMethods[x].invoke(ret));
+ List<Object> olst = CastUtils.cast((List)o);
+ col.addAll(olst);
+ } else if (setMethods[x] != null) {
+ setMethods[x].invoke(ret, o);
+ } else {
+ fields[x].set(ret, lst.get(x));
+ }
+ }
+ return ret;
+ } catch (Exception ex) {
+ throw new Fault(ex);
+ }
+ }
+
+ public List<Object> getWrapperParts(Object o) throws Fault {
+ try {
+ List<Object> ret = new ArrayList<Object>(getMethods.length);
+ for (int x = 0; x < getMethods.length; x++) {
+ if (getMethods[x] != null) {
+ ret.add(getValue(getMethods[x], o));
+ } else if (fields[x] != null) {
+ ret.add(fields[x].get(o));
+ } else {
+ //placeholder
+ ret.add(null);
+ }
+ }
+
+ return ret;
+ } catch (Exception ex) {
+ throw new Fault(ex);
+ }
+ }
+ }
+
}
Added:
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?view=auto&rev=552913
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
(added)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
Tue Jul 3 10:02:03 2007
@@ -0,0 +1,372 @@
+/**
+ * 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.interceptors;
+
+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.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>();
+ 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("\\.", "/"));
+ }
+
+ private WrapperHelperCompiler() {
+ //utility class
+ }
+
+ static WrapperHelper compileWrapperHelper(Class<?> wrapperType,
+ Method setMethods[],
+ Method getMethods[],
+ Method jaxbMethods[],
+ Field fields[],
+ Object objectFactory) {
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
+ | ClassWriter.COMPUTE_FRAMES);
+
+ String newClassName = wrapperType.getName() + "_WrapperTypeHelper";
+ newClassName = newClassName.replaceAll("\\$", ".");
+ newClassName = periodToSlashes(newClassName);
+ cw.visit(Opcodes.V1_5,
+ Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER,
+ newClassName,
+ null,
+ periodToSlashes(WrapperHelper.class.getName()),
+ null);
+
+ addConstructor(newClassName, cw, objectFactory == null ? null :
objectFactory.getClass());
+ boolean b = addCreateWrapperObject(newClassName, wrapperType,
+ setMethods,
+ getMethods,
+ jaxbMethods,
+ objectFactory == null ? null :
objectFactory.getClass(),
+ cw);
+ if (b) {
+ b = addGetWrapperParts(newClassName, wrapperType,
+ getMethods, fields, cw);
+ }
+
+
+ try {
+ if (b) {
+ cw.visitEnd();
+ byte bt[] = cw.toByteArray();
+ Class<?> cl = new
TypeHelperClassLoader(wrapperType.getClassLoader())
+ .defineClass(newClassName.replaceAll("/", "."), bt);
+
+ Object o = cl.newInstance();
+ return WrapperHelper.class.cast(o);
+ }
+ } catch (Exception e) {
+ //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) {
+ String ofName = "L" + periodToSlashes(objectFactory.getName()) +
";";
+ FieldVisitor fv = cw.visitField(0, "factory",
+ ofName,
+ null, null);
+ fv.visitEnd();
+ }
+
+ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V",
null, null);
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel(l0);
+
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
+ periodToSlashes(WrapperHelper.class.getName()),
+ "<init>",
+ "()V");
+ if (objectFactory != null) {
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitTypeInsn(Opcodes.NEW,
periodToSlashes(objectFactory.getName()));
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
+ periodToSlashes(objectFactory.getName()),
+ "<init>", "()V");
+ mv.visitFieldInsn(Opcodes.PUTFIELD, periodToSlashes(newClassName),
+ "factory", "L" +
periodToSlashes(objectFactory.getName()) + ";");
+ }
+
+ mv.visitInsn(Opcodes.RETURN);
+
+ Label l1 = new Label();
+ mv.visitLabel(l1);
+ mv.visitLocalVariable("this", "L" + newClassName + ";", null, l0, l1,
0);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+ private static boolean addCreateWrapperObject(String newClassName,
+ Class<?> wrapperClass,
+ Method[] setMethods,
+ Method[] getMethods,
+ Method[] jaxbObjectMethods,
+ Class<?> objectFactory,
+ ClassWriter cw) {
+ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
+ "createWrapperObject",
+
"(Ljava/util/List;)Ljava/lang/Object;",
+
"(Ljava/util/List<*>;)Ljava/lang/Object;",
+ new String[] {
+
"org/apache/cxf/interceptor/Fault"
+ });
+ mv.visitCode();
+ Label lBegin = new Label();
+ mv.visitLabel(lBegin);
+
+ mv.visitTypeInsn(Opcodes.NEW, periodToSlashes(wrapperClass.getName()));
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
periodToSlashes(wrapperClass.getName()),
+ "<init>", "()V");
+ mv.visitVarInsn(Opcodes.ASTORE, 2);
+
+ for (int x = 0; x < setMethods.length; x++) {
+ if (getMethods[x] == null) {
+ return false;
+ }
+ Class<?> tp = getMethods[x].getReturnType();
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+
+
+ if (Collection.class.isAssignableFrom(tp)) {
+ // call getFoo().addAll(lst)
+
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
+ periodToSlashes(wrapperClass.getName()),
+ getMethods[x].getName(),
+ getMethodSignature(getMethods[x]));
+
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitIntInsn(Opcodes.BIPUSH, x);
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
"get", "(I)Ljava/lang/Object;");
+ mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/List");
+ mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/List");
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
+ "addAll", "(Ljava/util/Collection;)Z");
+ mv.visitInsn(Opcodes.POP);
+
+ } else {
+ if (JAXBElement.class.isAssignableFrom(tp)) {
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD,
periodToSlashes(newClassName),
+ "factory",
+ "L" +
periodToSlashes(objectFactory.getName()) + ";");
+ }
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitIntInsn(Opcodes.BIPUSH, x);
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
"get", "(I)Ljava/lang/Object;");
+
+ if (tp.isPrimitive()) {
+ mv.visitTypeInsn(Opcodes.CHECKCAST,
NONPRIMITIVE_MAP.get(tp));
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
NONPRIMITIVE_MAP.get(tp),
+ tp.getName() + "Value", "()" +
PRIMITIVE_MAP.get(tp));
+ } else if (JAXBElement.class.isAssignableFrom(tp)) {
+ mv.visitTypeInsn(Opcodes.CHECKCAST,
+
periodToSlashes(jaxbObjectMethods[x].getParameterTypes()[0].getName()));
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
periodToSlashes(objectFactory.getName()),
+ jaxbObjectMethods[x].getName(),
+
getMethodSignature(jaxbObjectMethods[x]));
+ } else if (tp.isArray()) {
+ mv.visitTypeInsn(Opcodes.CHECKCAST, getClassCode(tp));
+ } else {
+ mv.visitTypeInsn(Opcodes.CHECKCAST,
periodToSlashes(tp.getName()));
+ }
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
+ periodToSlashes(wrapperClass.getName()),
+ setMethods[x].getName(), "(" +
getClassCode(tp) + ")V");
+ }
+ }
+
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+ mv.visitInsn(Opcodes.ARETURN);
+
+ Label lEnd = new Label();
+ mv.visitLabel(lEnd);
+ mv.visitLocalVariable("this", "L" + newClassName + ";", null, lBegin,
lEnd, 0);
+ mv.visitLocalVariable("lst", "Ljava/util/List;",
"Ljava/util/List<*>;", lBegin, lEnd, 1);
+ mv.visitLocalVariable("ok", "L" +
periodToSlashes(wrapperClass.getName()) + ";",
+ null, lBegin, lEnd, 2);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ return true;
+ }
+ private static boolean addGetWrapperParts(String newClassName,
+ Class<?> wrapperClass,
+ Method getMethods[],
+ Field fields[],
+ ClassWriter cw) {
+ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
+ "getWrapperParts",
+
"(Ljava/lang/Object;)Ljava/util/List;",
+
"(Ljava/lang/Object;)Ljava/util/List<Ljava/lang/Object;>;",
+ new String[] {
+
"org/apache/cxf/interceptor/Fault"
+ });
+ mv.visitCode();
+ Label lBegin = new Label();
+ mv.visitLabel(lBegin);
+
+ //the ret List
+ mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList",
"<init>", "()V");
+ mv.visitVarInsn(Opcodes.ASTORE, 2);
+
+ // cast the Object to the wrapperType type
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitTypeInsn(Opcodes.CHECKCAST,
periodToSlashes(wrapperClass.getName()));
+ mv.visitVarInsn(Opcodes.ASTORE, 3);
+
+ for (int x = 0; x < getMethods.length; x++) {
+ Method method = getMethods[x];
+ if (method == null && fields[x] != null) {
+ //fallback to reflection mode
+ return false;
+ }
+
+ if (method == null) {
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
+ "add", "(Ljava/lang/Object;)Z");
+ mv.visitInsn(Opcodes.POP);
+ } else {
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+ mv.visitVarInsn(Opcodes.ALOAD, 3);
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
+ periodToSlashes(wrapperClass.getName()),
+ method.getName(),
+ getMethodSignature(method));
+ if (method.getReturnType().isPrimitive()) {
+ //wrap into Object type
+ createObjectWrapper(mv, method.getReturnType());
+ }
+ if
(JAXBElement.class.isAssignableFrom(method.getReturnType())) {
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
+ "javax/xml/bind/JAXBElement",
+ "getValue", "()Ljava/lang/Object;");
+ }
+
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
"add", "(Ljava/lang/Object;)Z");
+ mv.visitInsn(Opcodes.POP);
+ }
+ }
+
+ //return the list
+ Label l2 = new Label();
+ mv.visitLabel(l2);
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+ mv.visitInsn(Opcodes.ARETURN);
+
+
+ Label lEnd = new Label();
+ mv.visitLabel(lEnd);
+ mv.visitLocalVariable("this", "L" + newClassName + ";", null, lBegin,
lEnd, 0);
+ mv.visitLocalVariable("o", "Ljava/lang/Object;", null, lBegin, lEnd,
1);
+ mv.visitLocalVariable("ret", "Ljava/util/List;",
"Ljava/util/List<Ljava/lang/Object;>;",
+ lBegin, lEnd, 2);
+ mv.visitLocalVariable("ok", "L" +
periodToSlashes(wrapperClass.getName()) + ";",
+ null, lBegin, lEnd, 3);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ return true;
+ }
+
+
+ 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);
+ }
+
+}
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Copied:
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperHelperTest.java
(from r552502,
incubator/cxf/trunk/common/common/src/test/java/org/apache/cxf/jaxb/WrapperHelperTest.java)
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperHelperTest.java?view=diff&rev=552913&p1=incubator/cxf/trunk/common/common/src/test/java/org/apache/cxf/jaxb/WrapperHelperTest.java&r1=552502&p2=incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperHelperTest.java&r2=552913
==============================================================================
---
incubator/cxf/trunk/common/common/src/test/java/org/apache/cxf/jaxb/WrapperHelperTest.java
(original)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperHelperTest.java
Tue Jul 3 10:02:03 2007
@@ -16,8 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.cxf.jaxb;
+package org.apache.cxf.jaxws;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -27,6 +28,7 @@
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
+import org.apache.cxf.jaxws.interceptors.WrapperHelper;
import org.junit.Assert;
import org.junit.Test;
@@ -37,21 +39,28 @@
public void getBooleanTypeWrappedPart() throws Exception {
SetIsOK ok = new SetIsOK();
ok.setParameter3(new boolean[] {true, false});
+ ok.setParameter4("hello");
List<String> partNames = Arrays.asList(new String[] {
"Parameter1",
"Parameter2",
- "Parameter3"
+ "Parameter3",
+ "Parameter4",
+ "Parameter5",
});
List<String> elTypeNames = Arrays.asList(new String[] {
"boolean",
"int",
- "boolean"
+ "boolean",
+ "string",
+ "string",
});
List<Class<?>> partClasses = Arrays.asList(new Class<?>[] {
Boolean.TYPE,
Integer.TYPE,
- boolean[].class
+ boolean[].class,
+ String.class,
+ List.class,
});
WrapperHelper wh = WrapperHelper.createWrapperHelper(SetIsOK.class,
@@ -60,14 +69,13 @@
partClasses);
List<Object> lst = wh.getWrapperParts(ok);
- assertEquals(3, lst.size());
+ assertEquals(5, lst.size());
assertTrue(lst.get(0) instanceof Boolean);
assertTrue(lst.get(1) instanceof Integer);
-
-
assertTrue(lst.get(2) instanceof boolean[]);
assertTrue(((boolean[])lst.get(2))[0]);
assertFalse(((boolean[])lst.get(2))[1]);
+ assertEquals("hello", (String)lst.get(3));
lst.set(0, Boolean.TRUE);
Object o = wh.createWrapperObject(lst);
@@ -76,11 +84,12 @@
assertTrue(ok.isParameter1());
assertTrue(ok.getParameter3()[0]);
assertFalse(ok.getParameter3()[1]);
+ assertEquals("hello", ok.getParameter4());
}
@XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = { "parameter1", "parameter2", "parameter3"
})
+ @XmlType(name = "", propOrder = { "parameter1", "parameter2",
"parameter3", "parameter4" })
@XmlRootElement(name = "setIsOK")
public static class SetIsOK {
@@ -90,7 +99,12 @@
protected int parameter2;
@XmlElement(name = "Parameter3")
protected boolean parameter3[];
-
+ @XmlElement(name = "Parameter4")
+ protected String parameter4;
+ @XmlElement(name = "Parameter5")
+ protected List<String> parameter5 = new ArrayList<String>();
+
+
/**
* Gets the value of the parameter1 property.
*
@@ -138,6 +152,17 @@
*/
public void setParameter3(boolean value[]) {
this.parameter3 = value;
+ }
+
+ public String getParameter4() {
+ return parameter4;
+ }
+ public void setParameter4(String value) {
+ this.parameter4 = value;
+ }
+
+ public List<String> getParameter5() {
+ return parameter5;
}
}
}