You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2008/03/18 23:38:22 UTC
svn commit: r638615 - in /incubator/cxf/branches/2.0.x-fixes: ./
rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java
rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
Author: dkulp
Date: Tue Mar 18 15:38:17 2008
New Revision: 638615
URL: http://svn.apache.org/viewvc?rev=638615&view=rev
Log:
Merged revisions 638186 via svnmerge from
https://svn.apache.org/repos/asf/incubator/cxf/trunk
........
r638186 | dkulp | 2008-03-17 22:56:36 -0400 (Mon, 17 Mar 2008) | 2 lines
Fixes to allow the use of the ASM generated wrapper helper (instead of reflection) in more cases
........
Modified:
incubator/cxf/branches/2.0.x-fixes/ (props changed)
incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java
incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
Propchange: incubator/cxf/branches/2.0.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified: incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java
URL: http://svn.apache.org/viewvc/incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java?rev=638615&r1=638614&r2=638615&view=diff
==============================================================================
--- incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java (original)
+++ incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelper.java Tue Mar 18 15:38:17 2008
@@ -42,6 +42,7 @@
public abstract List<Object> getWrapperParts(Object o) throws Fault;
+ public abstract String getSignature();
public static WrapperHelper createWrapperHelper(Class<?> wrapperType,
List<String> partNames,
@@ -260,7 +261,9 @@
wrapperType = wt;
objectFactory = of;
}
-
+ public String getSignature() {
+ return "" + System.identityHashCode(this);
+ }
public Object createWrapperObject(List<?> lst)
throws Fault {
Modified: incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java
URL: http://svn.apache.org/viewvc/incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java?rev=638615&r1=638614&r2=638615&view=diff
==============================================================================
--- incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java (original)
+++ incubator/cxf/branches/2.0.x-fixes/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/WrapperHelperCompiler.java Tue Mar 18 15:38:17 2008
@@ -24,9 +24,12 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import javax.xml.bind.JAXBElement;
+import org.apache.cxf.common.util.WeakIdentityHashMap;
+
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
@@ -34,6 +37,8 @@
import org.objectweb.asm.Opcodes;
final class WrapperHelperCompiler {
+ private static final Map<Class<?>, TypeHelperClassLoader> LOADER_MAP
+ = new WeakIdentityHashMap<Class<?>, TypeHelperClassLoader>();
private static final Map<Class<?>, String> PRIMITIVE_MAP = new HashMap<Class<?>, String>();
private static final Map<Class<?>, String> NONPRIMITIVE_MAP = new HashMap<Class<?>, String>();
@@ -138,9 +143,31 @@
if (cw == null) {
return null;
}
- String newClassName = wrapperType.getName() + "_WrapperTypeHelper";
+ int count = 1;
+ String newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
newClassName = newClassName.replaceAll("\\$", ".");
newClassName = periodToSlashes(newClassName);
+
+ Class<?> cls = findClass(newClassName.replace('/', '.'), wrapperType);
+ while (cls != null) {
+ try {
+ WrapperHelper helper = WrapperHelper.class.cast(cls.newInstance());
+ if (!helper.getSignature().equals(computeSignature())) {
+ count++;
+ newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
+ newClassName = newClassName.replaceAll("\\$", ".");
+ newClassName = periodToSlashes(newClassName);
+ cls = findClass(newClassName.replace('/', '.'), wrapperType);
+ } else {
+ return helper;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+
+
cw.visit(Opcodes.V1_5,
Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER,
newClassName,
@@ -149,13 +176,15 @@
null);
addConstructor(newClassName, cw, objectFactory == null ? null : objectFactory.getClass());
- boolean b = addCreateWrapperObject(newClassName,
- objectFactory == null ? null : objectFactory.getClass());
+ boolean b = addSignature();
+ if (b) {
+ addCreateWrapperObject(newClassName,
+ objectFactory == null ? null : objectFactory.getClass());
+ }
if (b) {
b = addGetWrapperParts(newClassName, wrapperType,
getMethods, fields, cw);
}
-
try {
if (b) {
@@ -167,21 +196,46 @@
Object o = cl.newInstance();
return WrapperHelper.class.cast(o);
}
- } catch (Exception e) {
+ } catch (Throwable e) {
//ignore, we'll just fall down to reflection based
}
return null;
}
-
- private static class TypeHelperClassLoader extends ClassLoader {
- TypeHelperClassLoader(ClassLoader parent) {
- super(parent);
+
+ private String computeSignature() {
+ StringBuilder b = new StringBuilder();
+ b.append(setMethods.length).append(':');
+ for (int x = 0; x < setMethods.length; x++) {
+ if (getMethods[x] == null) {
+ b.append("null,");
+ } else {
+ b.append(getMethods[x].getName()).append('/');
+ b.append(getMethods[x].getReturnType().getName()).append(',');
+ }
}
- public Class<?> defineClass(String name, byte bytes[]) {
- return super.defineClass(name, bytes, 0, bytes.length);
+ return b.toString();
+ }
+
+ private boolean addSignature() {
+ String sig = computeSignature();
+ if (sig == null) {
+ return false;
}
+ MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
+ "getSignature", "()Ljava/lang/String;", null, null);
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel(l0);
+ mv.visitLdcInsn(sig);
+ mv.visitInsn(Opcodes.ARETURN);
+ Label l1 = new Label();
+ mv.visitLabel(l1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ return true;
}
+
private static void addConstructor(String newClassName, ClassWriter cw, Class<?> objectFactory) {
if (objectFactory != null) {
@@ -322,7 +376,6 @@
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.visitVarInsn(Opcodes.ASTORE, 4);
mv.visitVarInsn(Opcodes.ALOAD, 3);
Label nonNullLabel = new Label();
@@ -339,6 +392,8 @@
} else {
mv.visitVarInsn(Opcodes.ALOAD, 2);
mv.visitVarInsn(Opcodes.ALOAD, 4);
+ mv.visitTypeInsn(Opcodes.CHECKCAST,
+ getMethods[x].getReturnType().getName().replace('.', '/'));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
periodToSlashes(wrapperType.getName()),
setMethods[x].getName(),
@@ -475,6 +530,56 @@
}
}
return new String(ch);
+ }
+
+
+ public Class<?> loadClass(String className, Class clz , byte[] bytes) {
+ TypeHelperClassLoader loader = getTypeHelperClassLoader(clz);
+ return loader.defineClass(className, bytes);
+ }
+ public Class<?> findClass(String className, Class clz) {
+ TypeHelperClassLoader loader = getTypeHelperClassLoader(clz);
+ return loader.lookupDefinedClass(className);
+ }
+
+ private static synchronized TypeHelperClassLoader getTypeHelperClassLoader(Class<?> l) {
+ TypeHelperClassLoader ret = LOADER_MAP.get(l);
+ if (ret == null) {
+ ret = new TypeHelperClassLoader(l.getClassLoader());
+ LOADER_MAP.put(l, ret);
+ }
+ return ret;
+ }
+
+ public static class TypeHelperClassLoader extends ClassLoader {
+ Map<String, Class<?>> defined = new ConcurrentHashMap<String, Class<?>>();
+
+ TypeHelperClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+ public Class<?> lookupDefinedClass(String name) {
+ return defined.get(name);
+ }
+
+ public Class<?> defineClass(String name, byte bytes[]) {
+ if (name.endsWith("package-info")) {
+ Package p = super.getPackage(name.substring(0, name.length() - 13));
+ if (p == null) {
+ definePackage(name.substring(0, name.length() - 13).replace('/', '.'),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null);
+ }
+ }
+
+ Class<?> ret = super.defineClass(name.replace('/', '.'), bytes, 0, bytes.length);
+ defined.put(name, ret);
+ return ret;
+ }
}
}