You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2020/12/17 01:24:44 UTC
[cxf] 01/03: [cxf-8340] add precompiled class for Graalvm native
support (#721)
This is an automated email from the ASF dual-hosted git repository.
reta pushed a commit to branch 3.4.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 5ec867cd053cb9121f0b5260eff8020bb1aed0b2
Author: olivier dufour <ol...@gmail.com>
AuthorDate: Thu Dec 17 00:36:41 2020 +0100
[cxf-8340] add precompiled class for Graalvm native support (#721)
CXF-8340: Add precompiled (generated) class loading for Graalvm native support
---
.../java/org/apache/cxf/common/jaxb/JAXBUtils.java | 432 +------------------
.../cxf/common/spi/ClassGeneratorClassLoader.java | 150 +++++++
.../cxf/common/spi/ClassLoaderProxyService.java | 58 +++
.../apache/cxf/common/spi/ClassLoaderService.java | 26 ++
.../cxf/common/spi/GeneratedClassClassLoader.java | 115 +++++
.../spi/GeneratedClassClassLoaderCapture.java | 36 ++
.../common/spi/GeneratedNamespaceClassLoader.java | 51 +++
.../cxf/common/spi/NamespaceClassCreator.java | 32 ++
.../cxf/common/spi/NamespaceClassGenerator.java | 451 +++++++++++++++++++
.../java/org/apache/cxf/common/util/ASMHelper.java | 441 +------------------
.../org/apache/cxf/common/util/ASMHelperImpl.java | 274 ++++++++++++
.../org/apache/cxf/common/util/OpcodesProxy.java | 94 ++++
.../org/apache/cxf/common/util/StringUtils.java | 14 +
.../main/resources/META-INF/cxf/bus-extensions.txt | 2 +
.../org/apache/cxf/common/util/ASMHelperTest.java | 35 +-
parent/pom.xml | 4 +-
.../org/apache/cxf/binding/corba/CorbaConduit.java | 4 +-
.../cxf/binding/corba/CorbaServerConduit.java | 4 +-
.../interceptors/CorbaStreamInInterceptor.java | 3 +-
.../cxf/binding/corba/utils/CorbaAnyHelper.java | 270 +-----------
.../corba/utils/CorbaFixedAnyImplClassCreator.java | 23 +
.../CorbaFixedAnyImplClassCreatorProxyService.java | 48 +++
.../corba/utils/CorbaFixedAnyImplClassLoader.java | 35 ++
.../corba/utils/CorbaFixedAnyImplGenerator.java | 276 ++++++++++++
.../binding/corba/wsdl/WSDLExtensionRegister.java | 6 +-
.../main/resources/META-INF/cxf/bus-extensions.txt | 1 +
.../apache/cxf/binding/corba/CorbaConduitTest.java | 7 +
.../cxf/binding/corba/CorbaServerConduitTest.java | 4 +
.../binding/xml/wsdl11/XMLWSDLExtensionLoader.java | 9 +-
.../cxf/binding/xml/interceptor/TestBase.java | 3 +-
.../org/apache/cxf/jaxb/FactoryClassCreator.java | 24 ++
.../org/apache/cxf/jaxb/FactoryClassGenerator.java | 86 ++++
.../org/apache/cxf/jaxb/FactoryClassLoader.java | 40 ++
.../apache/cxf/jaxb/FactoryClassProxyService.java | 48 +++
.../apache/cxf/jaxb/JAXBContextInitializer.java | 62 +--
.../java/org/apache/cxf/jaxb/JAXBDataBinding.java | 31 +-
.../cxf/jaxb/WrapperHelperClassGenerator.java | 451 +++++++++++++++++++
.../apache/cxf/jaxb/WrapperHelperClassLoader.java | 64 +++
.../org/apache/cxf/jaxb/WrapperHelperCompiler.java | 475 ---------------------
.../org/apache/cxf/jaxb/WrapperHelperCreator.java | 31 ++
.../apache/cxf/jaxb/WrapperHelperProxyService.java | 53 +++
.../org/apache/cxf/jaxb/io/DataWriterImpl.java | 11 +-
.../main/resources/META-INF/cxf/bus-extensions.txt | 2 +
.../org/apache/cxf/jaxb/JAXBDataBindingTest.java | 27 +-
.../apache/cxf/jaxb/JAXBEncoderDecoderTest.java | 5 +-
.../java/org/apache/cxf/jaxb/JAXBUtilsTest.java | 5 +-
.../cxf/jaxrs/provider/AbstractJAXBProvider.java | 2 +-
.../apache/cxf/jaxws/WrapperClassGenerator.java | 154 ++++---
.../apache/cxf/jaxws/spi/WrapperClassCreator.java | 28 ++
.../jaxws/spi/WrapperClassCreatorProxyService.java | 53 +++
.../apache/cxf/jaxws/spi/WrapperClassLoader.java | 119 ++++++
.../cxf/jaxws/support/JaxWsServiceFactoryBean.java | 10 +-
.../main/resources/META-INF/cxf/bus-extensions.txt | 1 +
...ava => WrapperNamespaceClassGeneratorTest.java} | 67 ++-
.../org/apache/cxf/jaxws/service/AddNumbers2.java | 35 ++
.../apache/cxf/jaxws/service/AddNumbers2Impl.java | 36 ++
.../cxf/endpoint/dynamic/DynamicClientFactory.java | 2 +-
.../endpoint/dynamic/ExceptionClassCreator.java | 23 +
.../dynamic/ExceptionClassCreatorProxyService.java | 48 +++
.../endpoint/dynamic/ExceptionClassGenerator.java | 95 +++++
.../cxf/endpoint/dynamic/ExceptionClassLoader.java | 42 ++
.../cxf/endpoint/dynamic/TypeClassInitializer.java | 70 +--
.../main/resources/META-INF/cxf/bus-extensions.txt | 1 +
.../transport/http/HTTPWSDLExtensionLoader.java | 10 +-
.../jms/wsdl11/JMSWSDLExtensionLoader.java | 4 +-
.../impl/AddressingWSDLExtensionLoader.java | 5 +-
.../org/apache/cxf/wsdl/ExtensionClassCreator.java | 25 ++
.../wsdl/ExtensionClassCreatorProxyService.java | 50 +++
.../apache/cxf/wsdl/ExtensionClassGenerator.java | 294 +++++++++++++
.../org/apache/cxf/wsdl/ExtensionClassLoader.java | 43 ++
.../org/apache/cxf/wsdl/JAXBExtensionHelper.java | 295 +------------
.../main/resources/META-INF/cxf/bus-extensions.txt | 2 +-
.../apache/cxf/wsdl/JAXBExtensionHelperTest.java | 67 +--
.../cxf/systest/jaxws/ClientServerMiscTest.java | 13 +-
74 files changed, 3782 insertions(+), 2135 deletions(-)
diff --git a/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java b/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java
index ebaefee..920b096 100644
--- a/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java
+++ b/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java
@@ -76,14 +76,10 @@ import org.w3c.dom.Node;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
+import org.apache.cxf.Bus;
import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.FieldVisitor;
-import org.apache.cxf.common.util.ASMHelper.Label;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelper.Opcodes;
+import org.apache.cxf.common.spi.ClassLoaderService;
import org.apache.cxf.common.util.CachedClass;
import org.apache.cxf.common.util.PackageUtils;
import org.apache.cxf.common.util.ProxyHelper;
@@ -619,9 +615,10 @@ public final class JAXBUtils {
return jaxbXjcLoader;
}
- public static Object setNamespaceMapper(final Map<String, String> nspref,
- Marshaller marshaller) throws PropertyException {
- Object mapper = createNamespaceWrapper(marshaller.getClass(), nspref);
+ public static Object setNamespaceMapper(Bus bus, final Map<String, String> nspref,
+ Marshaller marshaller) throws PropertyException {
+ ClassLoaderService classLoaderService = bus.getExtension(ClassLoaderService.class);
+ Object mapper = classLoaderService.createNamespaceWrapperInstance(marshaller.getClass(), nspref);
if (mapper != null) {
if (marshaller.getClass().getName().contains(".internal.")) {
marshaller.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper",
@@ -1081,423 +1078,6 @@ public final class JAXBUtils {
return false;
}
- private static synchronized Object createNamespaceWrapper(Class<?> mcls, Map<String, String> map) {
- String postFix = "";
- if (mcls.getName().contains("eclipse")) {
- return createEclipseNamespaceMapper(mcls, map);
- } else if (mcls.getName().contains(".internal")) {
- postFix = "Internal";
- } else if (mcls.getName().contains("com.sun")) {
- postFix = "RI";
- }
- ASMHelper helper = new ASMHelper();
- String className = "org.apache.cxf.jaxb.NamespaceMapper";
- className += postFix;
- Class<?> cls = helper.findClass(className, JAXBUtils.class);
- Throwable t = null;
- if (cls == null) {
- try {
- ClassWriter cw = helper.createClassWriter();
- if (cw != null) {
- cls = createNamespaceWrapperInternal(helper, cw, postFix, mcls);
- }
- } catch (RuntimeException ex) {
- // continue
- t = ex;
- }
- }
- if (cls == null
- && (!mcls.getName().contains(".internal.") && mcls.getName().contains("com.sun"))) {
- try {
- cls = ClassLoaderUtils.loadClass("org.apache.cxf.common.jaxb.NamespaceMapper",
- JAXBUtils.class);
- } catch (Throwable ex2) {
- // ignore
- t = ex2;
- }
- }
- if (cls != null) {
- try {
- return cls.getConstructor(Map.class).newInstance(map);
- } catch (Exception e) {
- // ignore
- t = e;
- }
- }
- LOG.log(Level.INFO, "Could not create a NamespaceMapper compatible with Marshaller class " + mcls.getName(), t);
- return null;
- }
- /*
- // This is the "prototype" for the ASM generated class below
- public static class MapNamespacePrefixMapper2
- extends org.eclipse.persistence.internal.oxm.record.namespaces.MapNamespacePrefixMapper {
-
- String[] nsctxt;
-
- public MapNamespacePrefixMapper2(Map<String, String> foo) {
- super(foo);
- }
- public String[] getPreDeclaredNamespaceUris() {
- String[] sup = super.getPreDeclaredNamespaceUris();
- if (nsctxt == null) {
- return sup;
- }
- List<String> s = new ArrayList<>(Arrays.asList(sup));
- for (int x = 1; x < nsctxt.length; x = x + 2) {
- s.remove(nsctxt[x]);
- }
- return s.toArray(new String[s.size()]);
- }
- public void setContextualNamespaceDecls(String[] f) {
- nsctxt = f;
- }
- public String[] getContextualNamespaceDecls() {
- return nsctxt;
- }
- }
- */
- //CHECKSTYLE:OFF
- //bunch of really long ASM based methods that cannot be shortened easily
- private static Object createEclipseNamespaceMapper(Class<?> mcls, Map<String, String> map) {
- ASMHelper helper = new ASMHelper();
- String className = "org.apache.cxf.jaxb.EclipseNamespaceMapper";
- String slashedName = "org/apache/cxf/jaxb/EclipseNamespaceMapper";
- Class<?> cls = helper.findClass(className, JAXBUtils.class);
-
- if (cls == null) {
- ClassWriter cw = helper.createClassWriter();
- if (cw == null) {
- return null;
- }
- String superName = "org/eclipse/persistence/internal/oxm/record/namespaces/MapNamespacePrefixMapper";
- FieldVisitor fv;
- MethodVisitor mv;
- cw.visit(Opcodes.V1_6,
- Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
- slashedName, null,
- superName, null);
-
- cw.visitSource("EclipseNamespaceMapper.java", null);
-
- fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
- fv.visitEnd();
-
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/util/Map;)V",
- "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
- mv.visitCode();
- Label l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
- superName, "<init>", "(Ljava/util/Map;)V", false);
- Label l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitInsn(Opcodes.RETURN);
- Label l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
-
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V",
- null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(47, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitFieldInsn(Opcodes.PUTFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(48, l1);
- mv.visitInsn(Opcodes.RETURN);
- l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l2, 0);
- mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(51, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
- mv.visitInsn(Opcodes.ARETURN);
- l1 = helper.createLabel();
-
- mv.visitLabel(l1);
- mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l1, 0);
-
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(1036, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
- superName,
- "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", false);
- mv.visitVarInsn(Opcodes.ASTORE, 1);
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(1037, l1);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
- l2 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
- Label l3 = helper.createLabel();
- mv.visitLabel(l3);
- mv.visitLineNumber(1038, l3);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitInsn(Opcodes.ARETURN);
- mv.visitLabel(l2);
- mv.visitLineNumber(1040, l2);
- mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"[Ljava/lang/String;"}, 0, null);
- mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
- mv.visitInsn(Opcodes.DUP);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Arrays", "asList",
- "([Ljava/lang/Object;)Ljava/util/List;", false);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>",
- "(Ljava/util/Collection;)V", false);
- mv.visitVarInsn(Opcodes.ASTORE, 2);
- Label l4 = helper.createLabel();
- mv.visitLabel(l4);
- mv.visitLineNumber(1041, l4);
- mv.visitInsn(Opcodes.ICONST_1);
- mv.visitVarInsn(Opcodes.ISTORE, 3);
- Label l5 = helper.createLabel();
- mv.visitLabel(l5);
- Label l6 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.GOTO, l6);
- Label l7 = helper.createLabel();
- mv.visitLabel(l7);
- mv.visitLineNumber(1042, l7);
- mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] {"java/util/List", Opcodes.INTEGER}, 0, null);
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
- mv.visitVarInsn(Opcodes.ILOAD, 3);
- mv.visitInsn(Opcodes.AALOAD);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "remove", "(Ljava/lang/Object;)Z", true);
- mv.visitInsn(Opcodes.POP);
- Label l8 = helper.createLabel();
- mv.visitLabel(l8);
- mv.visitLineNumber(1041, l8);
- mv.visitIincInsn(3, 2);
- mv.visitLabel(l6);
- mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
- mv.visitVarInsn(Opcodes.ILOAD, 3);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD,
- slashedName,
- "nsctxt", "[Ljava/lang/String;");
- mv.visitInsn(Opcodes.ARRAYLENGTH);
- mv.visitJumpInsn(Opcodes.IF_ICMPLT, l7);
- Label l9 = helper.createLabel();
- mv.visitLabel(l9);
- mv.visitLineNumber(1044, l9);
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "size", "()I", true);
- mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
- "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", true);
- mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/String;");
- mv.visitInsn(Opcodes.ARETURN);
- Label l10 = helper.createLabel();
- mv.visitLabel(l10);
- mv.visitLocalVariable("this", "L" + slashedName + ";",
- null, l0, l10, 0);
- mv.visitLocalVariable("sup", "[Ljava/lang/String;", null, l1, l10, 1);
- mv.visitLocalVariable("s", "Ljava/util/List;", "Ljava/util/List<Ljava/lang/String;>;", l4, l10, 2);
- mv.visitLocalVariable("x", "I", null, l5, l9, 3);
- mv.visitMaxs(3, 4);
- mv.visitEnd();
-
- cw.visitEnd();
-
- byte[] bts = cw.toByteArray();
- cls = helper.loadClass(className,
- mcls, bts);
- }
- try {
- return cls.getConstructor(Map.class).newInstance(map);
- } catch (Throwable e) {
- e.printStackTrace();
- return null;
- }
- }
-
- private static Class<?> createNamespaceWrapperInternal(ASMHelper helper, ClassWriter cw,
- String postFix, Class<?> ref) {
- String className = "org.apache.cxf.jaxb.NamespaceMapper" + postFix;
- String superName = "com/sun/xml/"
- + ("RI".equals(postFix) ? "" : "internal/")
- + "bind/marshaller/NamespacePrefixMapper";
- String postFixedName = "org/apache/cxf/jaxb/NamespaceMapper" + postFix;
-
- FieldVisitor fv;
- MethodVisitor mv;
-
- cw.visit(Opcodes.V1_6,
- Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
- postFixedName, null,
- superName, null);
-
- cw.visitSource("NamespaceMapper.java", null);
-
- fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL,
- "nspref", "Ljava/util/Map;",
- "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;", null);
- fv.visitEnd();
-
- fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
- fv.visitEnd();
-
- fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
- "EMPTY_STRING", "[Ljava/lang/String;", null, null);
- fv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
- mv.visitCode();
- Label l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(30, l0);
- mv.visitInsn(Opcodes.ICONST_0);
- mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
- mv.visitFieldInsn(Opcodes.PUTSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
- mv.visitInsn(Opcodes.RETURN);
- mv.visitMaxs(1, 0);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
- "(Ljava/util/Map;)V",
- "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(32, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", "()V", false);
- Label l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(29, l1);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
- mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
- Label l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLineNumber(33, l2);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nspref", "Ljava/util/Map;");
- Label l3 = helper.createLabel();
- mv.visitLabel(l3);
- mv.visitLineNumber(34, l3);
- mv.visitInsn(Opcodes.RETURN);
- Label l4 = helper.createLabel();
- mv.visitLabel(l4);
- mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
- mv.visitLocalVariable("nspref",
- "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;",
- l0, l4, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPreferredPrefix",
- "(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;",
- null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(39, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nspref", "Ljava/util/Map;");
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map",
- "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
- mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
- mv.visitVarInsn(Opcodes.ASTORE, 4);
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(40, l1);
- mv.visitVarInsn(Opcodes.ALOAD, 4);
- l2 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.IFNULL, l2);
- l3 = helper.createLabel();
- mv.visitLabel(l3);
- mv.visitLineNumber(41, l3);
- mv.visitVarInsn(Opcodes.ALOAD, 4);
- mv.visitInsn(Opcodes.ARETURN);
- mv.visitLabel(l2);
- mv.visitLineNumber(43, l2);
- mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitInsn(Opcodes.ARETURN);
- l4 = helper.createLabel();
- mv.visitLabel(l4);
- mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
- mv.visitLocalVariable("namespaceUri", "Ljava/lang/String;", null, l0, l4, 1);
- mv.visitLocalVariable("suggestion", "Ljava/lang/String;", null, l0, l4, 2);
- mv.visitLocalVariable("requirePrefix", "Z", null, l0, l4, 3);
- mv.visitLocalVariable("prefix", "Ljava/lang/String;", null, l1, l4, 4);
- mv.visitMaxs(2, 5);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V", null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(47, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(48, l1);
- mv.visitInsn(Opcodes.RETURN);
- l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l2, 0);
- mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(51, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
- mv.visitInsn(Opcodes.ARETURN);
- l1 = helper.createLabel();
-
- mv.visitLabel(l1);
- mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l1, 0);
-
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
- cw.visitEnd();
-
- byte[] bts = cw.toByteArray();
- return helper.loadClass(className,
- ref, bts);
- }
- //CHECKSTYLE:ON
-
public static JAXBContextProxy createJAXBContextProxy(final JAXBContext ctx) {
return createJAXBContextProxy(ctx, null, null);
}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java b/core/src/main/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java
new file mode 100644
index 0000000..f7cc719
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/ClassGeneratorClassLoader.java
@@ -0,0 +1,150 @@
+/**
+ * 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.common.spi;
+
+import java.lang.ref.WeakReference;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.common.util.WeakIdentityHashMap;
+
+/** Class loader used to store and retrieve class generated during runtime to avoid class generation each time.
+ * inherited class use asmHelper to generate bytes and use @see #loadClass(String, Class<?>, byte[])
+ * or @see #loadClass(String, ClassLoader, byte[]) to store generated class.Class can be generated during buildtime.
+ * equivalent class is @see org.apache.cxf.common.spi.GeneratedClassClassLoader
+ * @author olivier dufour
+ */
+public class ClassGeneratorClassLoader {
+ protected static final Map<Class<?>, WeakReference<TypeHelperClassLoader>> CLASS_MAP
+ = new WeakIdentityHashMap<>();
+ protected static final Map<ClassLoader, WeakReference<TypeHelperClassLoader>> LOADER_MAP
+ = new WeakIdentityHashMap<>();
+ protected final Bus bus;
+
+ public ClassGeneratorClassLoader(final Bus bus) {
+ this.bus = bus == null ? BusFactory.getDefaultBus() : bus;
+ }
+
+ protected Class<?> loadClass(String className, Class<?> cls, byte[] bytes) {
+ GeneratedClassClassLoaderCapture capture = bus.getExtension(GeneratedClassClassLoaderCapture.class);
+ if (capture != null) {
+ capture.capture(className, bytes);
+ }
+ TypeHelperClassLoader loader = getOrCreateLoader(cls);
+ synchronized (loader) {
+ Class<?> clz = loader.lookupDefinedClass(className);
+ if (clz == null) {
+ return loader.defineClass(className, bytes);
+ }
+ return clz;
+ }
+ }
+ protected Class<?> loadClass(String className, ClassLoader l, byte[] bytes) {
+ GeneratedClassClassLoaderCapture capture = bus.getExtension(GeneratedClassClassLoaderCapture.class);
+ if (capture != null) {
+ capture.capture(className, bytes);
+ }
+ TypeHelperClassLoader loader = getOrCreateLoader(l);
+ synchronized (loader) {
+ Class<?> clz = loader.lookupDefinedClass(className);
+ if (clz == null) {
+ return loader.defineClass(className, bytes);
+ }
+ return clz;
+ }
+ }
+ protected Class<?> findClass(String className, Class<?> cls) {
+ return getOrCreateLoader(cls).lookupDefinedClass(className);
+ }
+
+ protected Class<?> findClass(String className, ClassLoader classLoader) {
+ return getOrCreateLoader(classLoader).lookupDefinedClass(className);
+ }
+ private synchronized TypeHelperClassLoader getOrCreateLoader(Class<?> cls) {
+ WeakReference<TypeHelperClassLoader> ref = CLASS_MAP.get(cls);
+ TypeHelperClassLoader ret;
+ if (ref == null || ref.get() == null) {
+ ret = new TypeHelperClassLoader(cls.getClassLoader());
+ CLASS_MAP.put(cls, new WeakReference<TypeHelperClassLoader>(ret));
+ } else {
+ ret = ref.get();
+ }
+ return ret;
+ }
+ private synchronized TypeHelperClassLoader getOrCreateLoader(ClassLoader l) {
+ WeakReference<TypeHelperClassLoader> ref = LOADER_MAP.get(l);
+ TypeHelperClassLoader ret;
+ if (ref == null || ref.get() == null) {
+ ret = new TypeHelperClassLoader(l);
+ LOADER_MAP.put(l, new WeakReference<TypeHelperClassLoader>(ret));
+ } else {
+ ret = ref.get();
+ }
+ return ret;
+ }
+
+ public static class TypeHelperClassLoader extends ClassLoader {
+ ConcurrentHashMap<String, Class<?>> defined = new ConcurrentHashMap<>();
+
+ TypeHelperClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+ public Class<?> lookupDefinedClass(String name) {
+ return defined.get(StringUtils.slashesToPeriod(name));
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ if (name.endsWith("package-info")) {
+ return getParent().loadClass(name);
+ }
+ return super.findClass(name);
+ }
+
+ public Class<?> defineClass(String name, byte[] bytes) {
+ Class<?> ret = defined.get(StringUtils.slashesToPeriod(name));
+ if (ret != null) {
+ return ret;
+ }
+ if (name.endsWith("package-info")) {
+ String s = name.substring(0, name.length() - 13);
+ Package p = super.getPackage(s);
+ if (p == null) {
+ definePackage(StringUtils.slashesToPeriod(s),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null);
+ }
+ }
+
+ ret = defined.computeIfAbsent(StringUtils.slashesToPeriod(name),
+ key -> TypeHelperClassLoader.super.defineClass(key, bytes, 0, bytes.length));
+
+ return ret;
+ }
+ }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderProxyService.java b/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderProxyService.java
new file mode 100644
index 0000000..aed9922
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderProxyService.java
@@ -0,0 +1,58 @@
+/**
+ * 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.common.spi;
+
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.logging.LogUtils;
+
+public class ClassLoaderProxyService implements ClassLoaderService {
+ private static final Logger LOG = LogUtils.getL7dLogger(ClassLoaderProxyService.class);
+ private final NamespaceClassCreator srv;
+ public ClassLoaderProxyService(Bus bus) {
+ this(new NamespaceClassGenerator(bus));
+ }
+ public ClassLoaderProxyService(NamespaceClassCreator srv) {
+ this.srv = srv;
+ }
+
+ @Override
+ public Object createNamespaceWrapperInstance(Class<?> mcls, Map<String, String> map) {
+ Class<?> cls = srv.createNamespaceWrapperClass(mcls, map);
+ try {
+ return cls.getConstructor(Map.class).newInstance(map);
+ } catch (Throwable e) {
+ LOG.warning("NamespaceWrapper not found : " + e.toString());
+ return null;
+ }
+ }
+ public class LoadFirst extends ClassLoaderProxyService {
+ public LoadFirst(Bus bus) {
+ super(new GeneratedNamespaceClassLoader(bus));
+ }
+ }
+ public class GenerateJustInTime extends ClassLoaderProxyService {
+ public GenerateJustInTime(Bus bus) {
+ super(new NamespaceClassGenerator(bus));
+ }
+ }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderService.java b/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderService.java
new file mode 100644
index 0000000..1d1bd5c
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/ClassLoaderService.java
@@ -0,0 +1,26 @@
+/**
+ * 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.common.spi;
+
+import java.util.Map;
+
+public interface ClassLoaderService {
+ Object createNamespaceWrapperInstance(Class<?> mcls, Map<String, String> map);
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoader.java b/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoader.java
new file mode 100644
index 0000000..452c5fe
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoader.java
@@ -0,0 +1,115 @@
+/**
+ * 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.common.spi;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
+
+/** Class loader used to find class generated during build time to avoid class generation during runtime.
+ * inherited class implement same interface than generator class but find class in TypeHelperClassLoader
+ * Runtime class generator use @see org.apache.cxf.common.spi.ClassGeneratorClassLoader
+ * @author olivier dufour
+ */
+public class GeneratedClassClassLoader {
+ private static final Logger LOG = LogUtils.getL7dLogger(ClassLoaderProxyService.class);
+ protected final Bus bus;
+
+ public GeneratedClassClassLoader(Bus bus) {
+ this.bus = bus;
+ }
+ protected Class<?> findClass(String className, Class<?> callingClass) {
+ ClassLoader cl = getClassLoader();
+ try {
+ return cl.loadClass(className);
+ } catch (ClassNotFoundException e) {
+ //ignore and try with other class loader
+ }
+ try {
+ return ClassLoaderUtils.loadClass(className, callingClass);
+ } catch (ClassNotFoundException e) {
+ LOG.fine("Failed to load class :" + e.toString());
+ }
+ return null;
+ }
+ public TypeHelperClassLoader getClassLoader() {
+ TypeHelperClassLoader loader = bus.getExtension(TypeHelperClassLoader.class);
+ if (loader == null) {
+ loader = bus.getExtension(TypeHelperClassLoader.class);
+ if (loader == null) {
+ ClassLoader parent = bus.getExtension(ClassLoader.class);
+ if (parent == null) {
+ parent = Thread.currentThread().getContextClassLoader();
+ }
+ loader = new TypeHelperClassLoader(parent);
+ bus.setExtension(loader, TypeHelperClassLoader.class);
+ }
+ }
+ return loader;
+ }
+
+ public static class TypeHelperClassLoader extends ClassLoader {
+ ConcurrentHashMap<String, Class<?>> defined = new ConcurrentHashMap<>();
+
+ TypeHelperClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+ public Class<?> lookupDefinedClass(String name) {
+ return defined.get(StringUtils.slashesToPeriod(name));
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ if (name.endsWith("package-info")) {
+ return getParent().loadClass(name);
+ }
+ return super.findClass(name);
+ }
+
+ public Class<?> defineClass(String name, byte[] bytes) {
+ Class<?> ret = defined.get(StringUtils.slashesToPeriod(name));
+ if (ret != null) {
+ return ret;
+ }
+ if (name.endsWith("package-info")) {
+ String s = name.substring(0, name.length() - 13);
+ Package p = super.getPackage(s);
+ if (p == null) {
+ definePackage(StringUtils.slashesToPeriod(s),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null);
+ }
+ }
+
+ ret = defined.computeIfAbsent(StringUtils.slashesToPeriod(name),
+ key -> TypeHelperClassLoader.super.defineClass(key, bytes, 0, bytes.length));
+
+ return ret;
+ }
+ }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java b/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java
new file mode 100644
index 0000000..b71d582
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/GeneratedClassClassLoaderCapture.java
@@ -0,0 +1,36 @@
+/**
+ * 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.common.spi;
+
+/** Implement this interface to store class generated in order during build phase
+ * inject it back before runtime to avoid class generation.
+ * produce dot class file thanks to save method.
+ * You can check WrapperNamespaceClassGeneratorTest.testGeneratedFirst for usage
+ * Here is list of extensions to set in order to avoid class loading after generation during build time.
+ * bus.setExtension(new WrapperHelperClassLoader(bus), WrapperHelperCreator.class);
+ * bus.setExtension(new ExtensionClassLoader(bus), ExtensionClassCreator.class);
+ * bus.setExtension(new ExceptionClassLoader(bus), ExceptionClassCreator.class);
+ * bus.setExtension(new GeneratedWrapperClassLoader(bus), WrapperClassCreator.class);
+ * bus.setExtension(new FactoryClassLoader(bus), FactoryClassCreator.class);
+ * bus.setExtension(new GeneratedNamespaceClassLoader(bus), NamespaceClassCreator.class);
+ * @author olivier dufour
+ */
+public interface GeneratedClassClassLoaderCapture {
+ void capture(String className, byte[] bytes);
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/GeneratedNamespaceClassLoader.java b/core/src/main/java/org/apache/cxf/common/spi/GeneratedNamespaceClassLoader.java
new file mode 100644
index 0000000..1f3bf89
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/GeneratedNamespaceClassLoader.java
@@ -0,0 +1,51 @@
+/**
+ * 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.common.spi;
+
+import java.util.Map;
+
+import org.apache.cxf.Bus;
+
+/** If class has been generated during build time
+ * (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ * you can set class loader to avoid class generation during runtime:
+ * bus.setExtension(new GeneratedNamespaceClassLoader(bus), NamespaceClassCreator.class);
+ * @author olivier dufour
+ */
+public class GeneratedNamespaceClassLoader extends GeneratedClassClassLoader implements NamespaceClassCreator {
+ GeneratedNamespaceClassLoader(Bus bus) {
+ super(bus);
+ }
+ public synchronized Class<?> createNamespaceWrapperClass(Class<?> mcls, Map<String, String> map) {
+ String postFix = "";
+
+ if (mcls.getName().contains("eclipse")) {
+ return findClass("org.apache.cxf.jaxb.EclipseNamespaceMapper",
+ NamespaceClassCreator.class);
+ } else if (mcls.getName().contains(".internal")) {
+ postFix = "Internal";
+ } else if (mcls.getName().contains("com.sun")) {
+ postFix = "RI";
+ }
+ return findClass("org.apache.cxf.jaxb.NamespaceMapper" + postFix, NamespaceClassCreator.class);
+
+
+ }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassCreator.java b/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassCreator.java
new file mode 100644
index 0000000..c951e4b
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassCreator.java
@@ -0,0 +1,32 @@
+/**
+ * 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.common.spi;
+
+import java.util.Map;
+
+/**
+ * SPI interface to implement the proxy defining logic.
+ * It enables to switch from unsafe to classloader logic for instance for java >= 9.
+ */
+public interface NamespaceClassCreator {
+
+ Class<?> createNamespaceWrapperClass(Class<?> mcls, Map<String, String> map);
+
+}
diff --git a/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java b/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java
new file mode 100644
index 0000000..fbdc524
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/spi/NamespaceClassGenerator.java
@@ -0,0 +1,451 @@
+/**
+ * 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.common.spi;
+
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+
+public class NamespaceClassGenerator extends ClassGeneratorClassLoader implements NamespaceClassCreator {
+
+ private static final Logger LOG = LogUtils.getL7dLogger(ClassGeneratorClassLoader.class);
+ private final ASMHelper helper;
+
+ public NamespaceClassGenerator(Bus bus) {
+ super(bus);
+ helper = bus.getExtension(ASMHelper.class);
+ }
+
+ @Override
+ public synchronized Class<?> createNamespaceWrapperClass(Class<?> mcls, Map<String, String> map) {
+ String postFix = "";
+
+ if (mcls.getName().contains("eclipse")) {
+ return createEclipseNamespaceMapper(mcls, map);
+ } else if (mcls.getName().contains(".internal")) {
+ postFix = "Internal";
+ } else if (mcls.getName().contains("com.sun")) {
+ postFix = "RI";
+ }
+
+ String className = "org.apache.cxf.jaxb.NamespaceMapper";
+ className += postFix;
+ Class<?> cls = findClass(className, NamespaceClassCreator.class);
+ Throwable t = null;
+ if (cls == null) {
+ try {
+ byte[] bts = createNamespaceWrapperInternal(postFix);
+ className = "org.apache.cxf.jaxb.NamespaceMapper" + postFix;
+ return loadClass(className, NamespaceClassCreator.class, bts);
+ } catch (RuntimeException ex) {
+ // continue
+ t = ex;
+ }
+ }
+ if (cls == null
+ && (!mcls.getName().contains(".internal.") && mcls.getName().contains("com.sun"))) {
+ try {
+ cls = ClassLoaderUtils.loadClass("org.apache.cxf.common.jaxb.NamespaceMapper",
+ NamespaceClassCreator.class);
+ } catch (Throwable ex2) {
+ // ignore
+ t = ex2;
+ }
+ }
+ LOG.log(Level.INFO, "Could not create a NamespaceMapper compatible with Marshaller class " + mcls.getName(), t);
+ return cls;
+ }
+
+ private Class<?> createEclipseNamespaceMapper(Class<?> mcls, Map<String, String> map) {
+ String className = "org.apache.cxf.jaxb.EclipseNamespaceMapper";
+ Class<?> cls = findClass(className, NamespaceClassCreator.class);
+ if (cls != null) {
+ return cls;
+ }
+ byte[] bts = createEclipseNamespaceMapper();
+ //previous code use mcls instead of NamespaceClassGenerator.class
+ return loadClass(className, NamespaceClassCreator.class, bts);
+ }
+
+ /*
+ // This is the "prototype" for the ASM generated class below
+ public static class MapNamespacePrefixMapper2
+ extends org.eclipse.persistence.internal.oxm.record.namespaces.MapNamespacePrefixMapper {
+
+ String[] nsctxt;
+
+ public MapNamespacePrefixMapper2(Map<String, String> foo) {
+ super(foo);
+ }
+ public String[] getPreDeclaredNamespaceUris() {
+ String[] sup = super.getPreDeclaredNamespaceUris();
+ if (nsctxt == null) {
+ return sup;
+ }
+ List<String> s = new ArrayList<>(Arrays.asList(sup));
+ for (int x = 1; x < nsctxt.length; x = x + 2) {
+ s.remove(nsctxt[x]);
+ }
+ return s.toArray(new String[s.size()]);
+ }
+ public void setContextualNamespaceDecls(String[] f) {
+ nsctxt = f;
+ }
+ public String[] getContextualNamespaceDecls() {
+ return nsctxt;
+ }
+ }
+ */
+ //CHECKSTYLE:OFF
+ //bunch of really long ASM based methods that cannot be shortened easily
+ private byte[] createEclipseNamespaceMapper() {
+ OpcodesProxy Opcodes = helper.getOpCodes();
+ String slashedName = "org/apache/cxf/jaxb/EclipseNamespaceMapper";
+ ASMHelper.ClassWriter cw = helper.createClassWriter();
+ if (cw == null) {
+ return null;
+ }
+ String superName = "org/eclipse/persistence/internal/oxm/record/namespaces/MapNamespacePrefixMapper";
+ ASMHelper.FieldVisitor fv;
+ ASMHelper.MethodVisitor mv;
+ cw.visit(Opcodes.V1_6,
+ Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
+ slashedName, null,
+ superName, null);
+
+ cw.visitSource("EclipseNamespaceMapper.java", null);
+
+ fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
+ fv.visitEnd();
+
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/util/Map;)V",
+ "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
+ mv.visitCode();
+ ASMHelper.Label l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
+ superName, "<init>", "(Ljava/util/Map;)V", false);
+ ASMHelper.Label l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitInsn(Opcodes.RETURN);
+ ASMHelper.Label l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V",
+ null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(47, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(48, l1);
+ mv.visitInsn(Opcodes.RETURN);
+ l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l2, 0);
+ mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(51, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+ mv.visitInsn(Opcodes.ARETURN);
+ l1 = helper.createLabel();
+
+ mv.visitLabel(l1);
+ mv.visitLocalVariable("this", "L" + slashedName + ";", null, l0, l1, 0);
+
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(1036, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
+ superName,
+ "getPreDeclaredNamespaceUris", "()[Ljava/lang/String;", false);
+ mv.visitVarInsn(Opcodes.ASTORE, 1);
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(1037, l1);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+ l2 = helper.createLabel();
+ mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
+ ASMHelper.Label l3 = helper.createLabel();
+ mv.visitLabel(l3);
+ mv.visitLineNumber(1038, l3);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitInsn(Opcodes.ARETURN);
+ mv.visitLabel(l2);
+ mv.visitLineNumber(1040, l2);
+ mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"[Ljava/lang/String;"}, 0, null);
+ mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Arrays", "asList",
+ "([Ljava/lang/Object;)Ljava/util/List;", false);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>",
+ "(Ljava/util/Collection;)V", false);
+ mv.visitVarInsn(Opcodes.ASTORE, 2);
+ ASMHelper.Label l4 = helper.createLabel();
+ mv.visitLabel(l4);
+ mv.visitLineNumber(1041, l4);
+ mv.visitInsn(Opcodes.ICONST_1);
+ mv.visitVarInsn(Opcodes.ISTORE, 3);
+ ASMHelper.Label l5 = helper.createLabel();
+ mv.visitLabel(l5);
+ ASMHelper.Label l6 = helper.createLabel();
+ mv.visitJumpInsn(Opcodes.GOTO, l6);
+ ASMHelper.Label l7 = helper.createLabel();
+ mv.visitLabel(l7);
+ mv.visitLineNumber(1042, l7);
+ mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] {"java/util/List", Opcodes.INTEGER}, 0, null);
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, slashedName, "nsctxt", "[Ljava/lang/String;");
+ mv.visitVarInsn(Opcodes.ILOAD, 3);
+ mv.visitInsn(Opcodes.AALOAD);
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "remove", "(Ljava/lang/Object;)Z", true);
+ mv.visitInsn(Opcodes.POP);
+ ASMHelper.Label l8 = helper.createLabel();
+ mv.visitLabel(l8);
+ mv.visitLineNumber(1041, l8);
+ mv.visitIincInsn(3, 2);
+ mv.visitLabel(l6);
+ mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitVarInsn(Opcodes.ILOAD, 3);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD,
+ slashedName,
+ "nsctxt", "[Ljava/lang/String;");
+ mv.visitInsn(Opcodes.ARRAYLENGTH);
+ mv.visitJumpInsn(Opcodes.IF_ICMPLT, l7);
+ ASMHelper.Label l9 = helper.createLabel();
+ mv.visitLabel(l9);
+ mv.visitLineNumber(1044, l9);
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "size", "()I", true);
+ mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
+ "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", true);
+ mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/String;");
+ mv.visitInsn(Opcodes.ARETURN);
+ ASMHelper.Label l10 = helper.createLabel();
+ mv.visitLabel(l10);
+ mv.visitLocalVariable("this", "L" + slashedName + ";",
+ null, l0, l10, 0);
+ mv.visitLocalVariable("sup", "[Ljava/lang/String;", null, l1, l10, 1);
+ mv.visitLocalVariable("s", "Ljava/util/List;", "Ljava/util/List<Ljava/lang/String;>;", l4, l10, 2);
+ mv.visitLocalVariable("x", "I", null, l5, l9, 3);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ cw.visitEnd();
+
+ byte[] bts = cw.toByteArray();
+ return bts;
+ }
+
+ private byte[] createNamespaceWrapperInternal(String postFix) {
+
+ String superName = "com/sun/xml/"
+ + ("RI".equals(postFix) ? "" : "internal/")
+ + "bind/marshaller/NamespacePrefixMapper";
+ String postFixedName = "org/apache/cxf/jaxb/NamespaceMapper" + postFix;
+ ASMHelper.ClassWriter cw = helper.createClassWriter();
+ if (cw == null) {
+ return null;
+ }
+ ASMHelper.FieldVisitor fv;
+ ASMHelper.MethodVisitor mv;
+ OpcodesProxy Opcodes= helper.getOpCodes();
+ cw.visit(Opcodes.V1_6,
+ Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
+ postFixedName, null,
+ superName, null);
+
+ cw.visitSource("NamespaceMapper.java", null);
+
+ fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL,
+ "nspref", "Ljava/util/Map;",
+ "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;", null);
+ fv.visitEnd();
+
+ fv = cw.visitField(Opcodes.ACC_PRIVATE, "nsctxt", "[Ljava/lang/String;", null, null);
+ fv.visitEnd();
+
+ fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
+ "EMPTY_STRING", "[Ljava/lang/String;", null, null);
+ fv.visitEnd();
+
+ mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
+ mv.visitCode();
+ ASMHelper.Label l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(30, l0);
+ mv.visitInsn(Opcodes.ICONST_0);
+ mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
+ mv.visitFieldInsn(Opcodes.PUTSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
+ mv.visitInsn(Opcodes.RETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
+ "(Ljava/util/Map;)V",
+ "(Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;)V", null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(32, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, "<init>", "()V", false);
+ ASMHelper.Label l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(29, l1);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETSTATIC, postFixedName, "EMPTY_STRING", "[Ljava/lang/String;");
+ mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+ ASMHelper.Label l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(33, l2);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nspref", "Ljava/util/Map;");
+ ASMHelper.Label l3 = helper.createLabel();
+ mv.visitLabel(l3);
+ mv.visitLineNumber(34, l3);
+ mv.visitInsn(Opcodes.RETURN);
+ ASMHelper.Label l4 = helper.createLabel();
+ mv.visitLabel(l4);
+ mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
+ mv.visitLocalVariable("nspref",
+ "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;",
+ l0, l4, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPreferredPrefix",
+ "(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;",
+ null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(39, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nspref", "Ljava/util/Map;");
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map",
+ "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true);
+ mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
+ mv.visitVarInsn(Opcodes.ASTORE, 4);
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(40, l1);
+ mv.visitVarInsn(Opcodes.ALOAD, 4);
+ l2 = helper.createLabel();
+ mv.visitJumpInsn(Opcodes.IFNULL, l2);
+ l3 = helper.createLabel();
+ mv.visitLabel(l3);
+ mv.visitLineNumber(41, l3);
+ mv.visitVarInsn(Opcodes.ALOAD, 4);
+ mv.visitInsn(Opcodes.ARETURN);
+ mv.visitLabel(l2);
+ mv.visitLineNumber(43, l2);
+ mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
+ mv.visitVarInsn(Opcodes.ALOAD, 2);
+ mv.visitInsn(Opcodes.ARETURN);
+ l4 = helper.createLabel();
+ mv.visitLabel(l4);
+ mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l4, 0);
+ mv.visitLocalVariable("namespaceUri", "Ljava/lang/String;", null, l0, l4, 1);
+ mv.visitLocalVariable("suggestion", "Ljava/lang/String;", null, l0, l4, 2);
+ mv.visitLocalVariable("requirePrefix", "Z", null, l0, l4, 3);
+ mv.visitLocalVariable("prefix", "Ljava/lang/String;", null, l1, l4, 4);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setContextualNamespaceDecls", "([Ljava/lang/String;)V", null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(47, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(48, l1);
+ mv.visitInsn(Opcodes.RETURN);
+ l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l2, 0);
+ mv.visitLocalVariable("contextualNamespaceDecls", "[Ljava/lang/String;", null, l0, l2, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getContextualNamespaceDecls", "()[Ljava/lang/String;", null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(51, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, postFixedName, "nsctxt", "[Ljava/lang/String;");
+ mv.visitInsn(Opcodes.ARETURN);
+ l1 = helper.createLabel();
+
+ mv.visitLabel(l1);
+ mv.visitLocalVariable("this", "L" + postFixedName + ";", null, l0, l1, 0);
+
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+ //CHECKSTYLE:ON
+}
diff --git a/core/src/main/java/org/apache/cxf/common/util/ASMHelper.java b/core/src/main/java/org/apache/cxf/common/util/ASMHelper.java
index b08974b..16a79d9 100644
--- a/core/src/main/java/org/apache/cxf/common/util/ASMHelper.java
+++ b/core/src/main/java/org/apache/cxf/common/util/ASMHelper.java
@@ -19,447 +19,28 @@
package org.apache.cxf.common.util;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.util.ReflectionInvokationHandler.Optional;
import org.apache.cxf.common.util.ReflectionInvokationHandler.UnwrapParam;
import org.apache.cxf.common.util.ReflectionInvokationHandler.WrapReturn;
-public class ASMHelper {
- protected static final Map<Class<?>, String> PRIMITIVE_MAP = new HashMap<>();
- protected static final Map<Class<?>, String> NONPRIMITIVE_MAP = new HashMap<>();
- protected static final Map<Class<?>, Integer> PRIMITIVE_ZERO_MAP = new HashMap<>();
- protected static final Map<ClassLoader, WeakReference<TypeHelperClassLoader>> LOADER_MAP
- = new WeakIdentityHashMap<>();
- protected static final Map<Class<?>, WeakReference<TypeHelperClassLoader>> CLASS_MAP
- = new WeakIdentityHashMap<>();
+public interface ASMHelper {
+ String getClassCode(Class<?> cl);
+ String getClassCode(java.lang.reflect.Type type);
+ ClassWriter createClassWriter();
+ ASMType getType(String type);
+ Label createLabel();
+ OpcodesProxy getOpCodes();
+ Class<?> getASMClass() throws ClassNotFoundException;
+ String getMethodSignature(Method m);
+ String getNonPrimitive(Class<?> tp);
+ String getPrimitive(Class<?> tp);
- protected static boolean badASM;
- private static Class<?> cwClass;
-
- 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 static void tryClass(String s) {
- if (cwClass == null) {
- try {
- Class<?> c2 = ClassLoaderUtils.loadClass(s, ASMHelper.class);
-
- //old versions don't have this, but we need it
- Class<?> cls = ClassLoaderUtils.loadClass(c2.getPackage().getName() + ".MethodVisitor", c2);
- cls.getMethod("visitFrame", Integer.TYPE, Integer.TYPE,
- Object[].class, Integer.TYPE, Object[].class);
- cwClass = c2;
- } catch (Throwable t) {
- //ignore
- }
- }
- }
- private static Class<?> getASMClassWriterClass() {
- //force this to make sure the proper OSGi import is generated
- return org.objectweb.asm.ClassWriter.class;
- }
-
- private static synchronized Class<?> getASMClass() throws ClassNotFoundException {
- if (cwClass == null) {
- //try the "real" asm first, then the others
- tryClass("org.objectweb.asm.ClassWriter");
- tryClass("org.apache.xbean.asm9.ClassWriter");
- tryClass("org.apache.xbean.asm8.ClassWriter");
- tryClass("org.apache.xbean.asm7.ClassWriter");
- tryClass("org.apache.xbean.asm5.ClassWriter");
- tryClass("org.apache.xbean.asm6.ClassWriter");
- tryClass("org.apache.xbean.asm4.ClassWriter");
- tryClass("org.apache.xbean.asm.ClassWriter");
- tryClass("org.springframework.asm.ClassWriter");
- if (cwClass == null) {
- cwClass = getASMClassWriterClass();
- }
- }
- return cwClass;
- }
-
- public static class Opcodes {
- //CHECKSTYLE:OFF
- //Will use reflection to set these based on the package name and such
- //so we don't want them "final" or the compiler will optimize them out
- //to just "0" which we really don't want
- public static int ARETURN = 0;
- public static int ALOAD = 0;
- public static int IFNULL = 0;
- public static int CHECKCAST = 0;
- public static int INVOKEINTERFACE = 0;
- public static int GETFIELD = 0;
- public static int GETSTATIC = 0;
- public static int ASTORE = 0;
- public static int PUTFIELD = 0;
- public static int PUTSTATIC = 0;
- public static int RETURN = 0;
- public static int F_APPEND = 0;
- public static int F_SAME = 0;
- public static int F_SAME1 = 0;
- public static int INVOKESPECIAL = 0;
- public static int ACC_PUBLIC = 0;
- public static int ACC_FINAL = 0;
- public static int ACC_SUPER = 0;
- public static int ACC_PRIVATE = 0;
- public static int ACC_STATIC = 0;
- public static int V1_5 = 0;
- public static int V1_6 = 0;
- public static int V1_7 = 0;
- public static int ACC_ABSTRACT = 0;
- public static int ACC_INTERFACE = 0;
- public static int ACC_SYNTHETIC = 0;
- public static int ILOAD = 0;
- public static int ISTORE = 0;
- public static int AALOAD = 0;
- public static int ARRAYLENGTH = 0;
- public static int IRETURN = 0;
- public static int NEW = 0;
- public static int ANEWARRAY = 0;
- public static int DUP = 0;
- public static int ATHROW = 0;
- public static int INVOKEVIRTUAL = 0;
- public static int GOTO = 0;
- public static int POP = 0;
- public static int ACONST_NULL = 0;
- public static int IFNONNULL = 0;
- public static int SIPUSH = 0;
- public static int INVOKESTATIC = 0;
- public static int ICONST_0;
- public static int ICONST_1;
- public static int LCONST_0;
- public static int FCONST_0;
- public static int DCONST_0;
- public static int IF_ICMPLT = 0;
- public static java.lang.Integer INTEGER;
-
- //CHECKSTYLE:ON
- static {
- try {
- Class<?> cls = getASMClass();
- cls = ClassLoaderUtils.loadClass(cls.getPackage().getName() + ".Opcodes", cls);
- for (Field f1 : Opcodes.class.getDeclaredFields()) {
- Field f = cls.getDeclaredField(f1.getName());
- ReflectionUtil.setAccessible(f1).set(null, ReflectionUtil.setAccessible(f).get(null));
- }
- } catch (Throwable e) {
- //ignore
- }
-
- PRIMITIVE_ZERO_MAP.put(Byte.TYPE, Opcodes.ICONST_0);
- PRIMITIVE_ZERO_MAP.put(Boolean.TYPE, Opcodes.ICONST_0);
- PRIMITIVE_ZERO_MAP.put(Long.TYPE, Opcodes.LCONST_0);
- PRIMITIVE_ZERO_MAP.put(Integer.TYPE, Opcodes.ICONST_0);
- PRIMITIVE_ZERO_MAP.put(Short.TYPE, Opcodes.ICONST_0);
- PRIMITIVE_ZERO_MAP.put(Character.TYPE, Opcodes.ICONST_0);
- PRIMITIVE_ZERO_MAP.put(Float.TYPE, Opcodes.FCONST_0);
- PRIMITIVE_ZERO_MAP.put(Double.TYPE, Opcodes.DCONST_0);
- }
- }
-
- protected static String getMethodSignature(Method m) {
- StringBuilder buf = new StringBuilder("(");
- for (Class<?> cl : m.getParameterTypes()) {
- buf.append(getClassCode(cl));
- }
- buf.append(')');
- buf.append(getClassCode(m.getReturnType()));
-
- return buf.toString();
- }
-
- public 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 static String getClassCode(java.lang.reflect.Type type) {
- if (type instanceof Class) {
- return getClassCode((Class<?>)type);
- } else if (type instanceof GenericArrayType) {
- GenericArrayType at = (GenericArrayType)type;
- return "[" + getClassCode(at.getGenericComponentType());
- } else if (type instanceof TypeVariable) {
- TypeVariable<?> tv = (TypeVariable<?>)type;
- java.lang.reflect.Type[] bounds = tv.getBounds();
- if (bounds != null && bounds.length == 1) {
- return getClassCode(bounds[0]);
- }
- throw new IllegalArgumentException("Unable to determine type for: " + tv);
- } else if (type instanceof ParameterizedType) {
- ParameterizedType pt = (ParameterizedType)type;
- StringBuilder a = new StringBuilder(getClassCode(pt.getRawType()));
- if (!pt.getRawType().equals(Enum.class)) {
- a.setLength(a.length() - 1);
- a.append('<');
-
- for (java.lang.reflect.Type t : pt.getActualTypeArguments()) {
- a.append(getClassCode(t));
- }
- a.append(">;");
- }
- return a.toString();
- } else if (type instanceof WildcardType) {
- WildcardType wt = (WildcardType)type;
- StringBuilder a = new StringBuilder();
- java.lang.reflect.Type[] lowBounds = wt.getLowerBounds();
- java.lang.reflect.Type[] upBounds = wt.getUpperBounds();
- for (java.lang.reflect.Type t : upBounds) {
- a.append('+');
- a.append(getClassCode(t));
- }
- for (java.lang.reflect.Type t : lowBounds) {
- a.append('-');
- a.append(getClassCode(t));
- }
- return a.toString();
- }
- return null;
- }
-
-
- public ClassWriter createClassWriter() {
- Object newCw = null;
- if (!badASM) {
- if (cwClass == null) {
- try {
- cwClass = getASMClass();
- } catch (Throwable error) {
- badASM = true;
- throw new RuntimeException("No ASM ClassWriterFound", error);
- }
- }
- try {
- // ASM 1.5.x/2.x
- Constructor<?> cons
- = cwClass.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
- cwClass.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.
- badASM = true;
- } catch (Throwable t) {
- newCw = cons.newInstance(new Object[] {Boolean.TRUE});
- }
-
- } catch (Throwable e) {
- // ASM 3.x/4.x
- try {
- Constructor<?> cons
- = cwClass.getConstructor(new Class<?>[] {Integer.TYPE});
- int i = cwClass.getField("COMPUTE_MAXS").getInt(null);
- i |= cwClass.getField("COMPUTE_FRAMES").getInt(null);
- newCw = cons.newInstance(new Object[] {Integer.valueOf(i)});
- } catch (Throwable e1) {
- // ignore
- }
- }
- }
- if (newCw != null) {
- return ReflectionInvokationHandler.createProxyWrapper(newCw, ClassWriter.class);
- }
- return null;
- }
-
-
- public Class<?> loadClass(String className, Class<?> clz, byte[] bytes) {
- TypeHelperClassLoader loader = getTypeHelperClassLoader(clz);
- synchronized (loader) {
- Class<?> cls = loader.lookupDefinedClass(className);
- if (cls == null) {
- return loader.defineClass(className, bytes);
- }
- return cls;
- }
- }
- public Class<?> loadClass(String className, ClassLoader l, byte[] bytes) {
- TypeHelperClassLoader loader = getTypeHelperClassLoader(l);
- synchronized (loader) {
- Class<?> cls = loader.lookupDefinedClass(className);
- if (cls == null) {
- return loader.defineClass(className, bytes);
- }
- return cls;
- }
- }
- public Class<?> findClass(String className, Class<?> clz) {
- TypeHelperClassLoader loader = getTypeHelperClassLoader(clz);
- return loader.lookupDefinedClass(className);
- }
- public Class<?> findClass(String className, ClassLoader l) {
- TypeHelperClassLoader loader = getTypeHelperClassLoader(l);
- return loader.lookupDefinedClass(className);
- }
-
- private static synchronized TypeHelperClassLoader getTypeHelperClassLoader(ClassLoader l) {
- WeakReference<TypeHelperClassLoader> ref = LOADER_MAP.get(l);
- TypeHelperClassLoader ret;
- if (ref == null || ref.get() == null) {
- ret = new TypeHelperClassLoader(l);
- LOADER_MAP.put(l, new WeakReference<TypeHelperClassLoader>(ret));
- } else {
- ret = ref.get();
- }
- return ret;
- }
- private static synchronized TypeHelperClassLoader getTypeHelperClassLoader(Class<?> cls) {
- WeakReference<TypeHelperClassLoader> ref = CLASS_MAP.get(cls);
- TypeHelperClassLoader ret;
- if (ref == null || ref.get() == null) {
- ret = new TypeHelperClassLoader(cls.getClassLoader());
- CLASS_MAP.put(cls, new WeakReference<TypeHelperClassLoader>(ret));
- } else {
- ret = ref.get();
- }
- return ret;
- }
-
- public static class TypeHelperClassLoader extends ClassLoader {
- ConcurrentHashMap<String, Class<?>> defined = new ConcurrentHashMap<>();
-
- TypeHelperClassLoader(ClassLoader parent) {
- super(parent);
- }
- public Class<?> lookupDefinedClass(String name) {
- return defined.get(name.replace('/', '.'));
- }
-
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- if (name.endsWith("package-info")) {
- return getParent().loadClass(name);
- }
- return super.findClass(name);
- }
-
- public Class<?> defineClass(String name, byte[] bytes) {
- Class<?> ret = defined.get(name.replace('/', '.'));
- if (ret != null) {
- return ret;
- }
- 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);
- }
- }
-
- ret = super.defineClass(name.replace('/', '.'), bytes, 0, bytes.length);
- Class<?> tmpRet = defined.putIfAbsent(name.replace('/', '.'), ret);
- if (tmpRet != null) {
- ret = tmpRet;
- }
- return ret;
- }
- }
- public ASMType getType(final String type) {
- try {
- final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Type", cwClass);
- final Method m = cls.getMethod("getType", String.class);
- final Method m2 = cls.getMethod("getOpcode", Integer.TYPE);
- @SuppressWarnings("unused")
- ASMType t = new ASMType() {
- Object tp = ReflectionUtil.setAccessible(m).invoke(null, type);
- public Object getValue() {
- return tp;
- }
- public Class<?> realType() {
- return cls;
- }
- public int getOpcode(int ireturn) {
- try {
- return (Integer)ReflectionUtil.setAccessible(m2).invoke(tp, ireturn);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- };
- return t;
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
public interface ASMType {
int getOpcode(int ireturn);
}
- public Label createLabel() {
- try {
- final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Label",
- cwClass);
- @SuppressWarnings("unused")
- Label l = new Label() {
- Object l = cls.newInstance();
- public Object getValue() {
- return l;
- }
- public Class<?> realType() {
- return cls;
- }
- };
- return l;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
public interface ClassWriter {
@WrapReturn(AnnotationVisitor.class)
diff --git a/core/src/main/java/org/apache/cxf/common/util/ASMHelperImpl.java b/core/src/main/java/org/apache/cxf/common/util/ASMHelperImpl.java
new file mode 100644
index 0000000..f67a06d
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/util/ASMHelperImpl.java
@@ -0,0 +1,274 @@
+/**
+ * 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.common.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+
+
+public class ASMHelperImpl implements ASMHelper {
+ protected static final Map<Class<?>, String> PRIMITIVE_MAP = new HashMap<>();
+ protected static final Map<Class<?>, String> NONPRIMITIVE_MAP = new HashMap<>();
+ protected static final Map<Class<?>, Integer> PRIMITIVE_ZERO_MAP = new HashMap<>();
+
+ protected boolean badASM;
+ private Class<?> cwClass;
+
+ public ASMHelperImpl() {
+
+ }
+
+ 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 void tryClass(String s) {
+ if (cwClass == null) {
+ try {
+ Class<?> c2 = ClassLoaderUtils.loadClass(s, ASMHelperImpl.class);
+
+ //old versions don't have this, but we need it
+ Class<?> cls = ClassLoaderUtils.loadClass(c2.getPackage().getName() + ".MethodVisitor", c2);
+ cls.getMethod("visitFrame", Integer.TYPE, Integer.TYPE,
+ Object[].class, Integer.TYPE, Object[].class);
+ cwClass = c2;
+ } catch (Throwable t) {
+ //ignore
+ }
+ }
+ }
+ private Class<?> getASMClassWriterClass() {
+ //force this to make sure the proper OSGi import is generated
+ return org.objectweb.asm.ClassWriter.class;
+ }
+
+ public synchronized Class<?> getASMClass() throws ClassNotFoundException {
+ if (cwClass == null) {
+ //try the "real" asm first, then the others
+ tryClass("org.objectweb.asm.ClassWriter");
+ tryClass("org.apache.xbean.asm9.ClassWriter");
+ tryClass("org.apache.xbean.asm8.ClassWriter");
+ tryClass("org.apache.xbean.asm7.ClassWriter");
+ tryClass("org.apache.xbean.asm5.ClassWriter");
+ tryClass("org.apache.xbean.asm6.ClassWriter");
+ tryClass("org.apache.xbean.asm4.ClassWriter");
+ tryClass("org.apache.xbean.asm.ClassWriter");
+ tryClass("org.springframework.asm.ClassWriter");
+ if (cwClass == null) {
+ cwClass = getASMClassWriterClass();
+ }
+ }
+ return cwClass;
+ }
+ public OpcodesProxy getOpCodes() {
+ OpcodesProxy ops = new OpcodesProxy(this);
+ PRIMITIVE_ZERO_MAP.put(Byte.TYPE, ops.ICONST_0);
+ PRIMITIVE_ZERO_MAP.put(Boolean.TYPE, ops.ICONST_0);
+ PRIMITIVE_ZERO_MAP.put(Long.TYPE, ops.LCONST_0);
+ PRIMITIVE_ZERO_MAP.put(Integer.TYPE, ops.ICONST_0);
+ PRIMITIVE_ZERO_MAP.put(Short.TYPE, ops.ICONST_0);
+ PRIMITIVE_ZERO_MAP.put(Character.TYPE, ops.ICONST_0);
+ PRIMITIVE_ZERO_MAP.put(Float.TYPE, ops.FCONST_0);
+ PRIMITIVE_ZERO_MAP.put(Double.TYPE, ops.DCONST_0);
+ return ops;
+ }
+ public void setBadASM(boolean b) {
+ badASM = b;
+ }
+
+ public String getMethodSignature(Method m) {
+ StringBuilder buf = new StringBuilder("(");
+ for (Class<?> cl : m.getParameterTypes()) {
+ buf.append(getClassCode(cl));
+ }
+ buf.append(')');
+ buf.append(getClassCode(m.getReturnType()));
+
+ return buf.toString();
+ }
+
+ @Override
+ public String getNonPrimitive(Class<?> tp) {
+ return NONPRIMITIVE_MAP.get(tp);
+ }
+ @Override
+ public String getPrimitive(Class<?> tp) {
+ return PRIMITIVE_MAP.get(tp);
+ }
+
+
+
+
+ public 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" + StringUtils.periodToSlashes(cl.getName()) + ";";
+ }
+ public String getClassCode(java.lang.reflect.Type type) {
+ if (type instanceof Class) {
+ return getClassCode((Class<?>)type);
+ } else if (type instanceof GenericArrayType) {
+ GenericArrayType at = (GenericArrayType)type;
+ return "[" + getClassCode(at.getGenericComponentType());
+ } else if (type instanceof TypeVariable) {
+ TypeVariable<?> tv = (TypeVariable<?>)type;
+ java.lang.reflect.Type[] bounds = tv.getBounds();
+ if (bounds != null && bounds.length == 1) {
+ return getClassCode(bounds[0]);
+ }
+ throw new IllegalArgumentException("Unable to determine type for: " + tv);
+ } else if (type instanceof ParameterizedType) {
+ ParameterizedType pt = (ParameterizedType)type;
+ StringBuilder a = new StringBuilder(getClassCode(pt.getRawType()));
+ if (!pt.getRawType().equals(Enum.class)) {
+ a.setLength(a.length() - 1);
+ a.append('<');
+
+ for (java.lang.reflect.Type t : pt.getActualTypeArguments()) {
+ a.append(getClassCode(t));
+ }
+ a.append(">;");
+ }
+ return a.toString();
+ } else if (type instanceof WildcardType) {
+ WildcardType wt = (WildcardType)type;
+ StringBuilder a = new StringBuilder();
+ java.lang.reflect.Type[] lowBounds = wt.getLowerBounds();
+ java.lang.reflect.Type[] upBounds = wt.getUpperBounds();
+ for (java.lang.reflect.Type t : upBounds) {
+ a.append('+');
+ a.append(getClassCode(t));
+ }
+ for (java.lang.reflect.Type t : lowBounds) {
+ a.append('-');
+ a.append(getClassCode(t));
+ }
+ return a.toString();
+ }
+ return null;
+ }
+
+ public ClassWriter createClassWriter() {
+ Object newCw = null;
+ if (!badASM) {
+ if (cwClass == null) {
+ try {
+ cwClass = getASMClass();
+ } catch (Throwable error) {
+ badASM = true;
+ throw new RuntimeException("No ASM ClassWriterFound", error);
+ }
+ }
+ // ASM >= 3.x (since cxf is java 8 min we don't care of asm 1/2)
+ try {
+ Constructor<?> cons
+ = cwClass.getConstructor(new Class<?>[] {Integer.TYPE});
+ int i = cwClass.getField("COMPUTE_MAXS").getInt(null);
+ i |= cwClass.getField("COMPUTE_FRAMES").getInt(null);
+ newCw = cons.newInstance(new Object[] {Integer.valueOf(i)});
+ } catch (Throwable e1) {
+ // ignore
+ }
+ }
+ if (newCw != null) {
+ return ReflectionInvokationHandler.createProxyWrapper(newCw, ClassWriter.class);
+ }
+ return null;
+ }
+
+
+ public ASMType getType(final String type) {
+ try {
+ final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Type", cwClass);
+ final Method m = cls.getMethod("getType", String.class);
+ final Method m2 = cls.getMethod("getOpcode", Integer.TYPE);
+ @SuppressWarnings("unused")
+ ASMType t = new ASMType() {
+ Object tp = ReflectionUtil.setAccessible(m).invoke(null, type);
+ public Object getValue() {
+ return tp;
+ }
+ public Class<?> realType() {
+ return cls;
+ }
+ public int getOpcode(int ireturn) {
+ try {
+ return (Integer)ReflectionUtil.setAccessible(m2).invoke(tp, ireturn);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ return t;
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ public Label createLabel() {
+ try {
+ final Class<?> cls = ClassLoaderUtils.loadClass(cwClass.getPackage().getName() + ".Label",
+ cwClass);
+ @SuppressWarnings("unused")
+ Label l = new Label() {
+ Object l = cls.newInstance();
+ public Object getValue() {
+ return l;
+ }
+ public Class<?> realType() {
+ return cls;
+ }
+ };
+ return l;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/core/src/main/java/org/apache/cxf/common/util/OpcodesProxy.java b/core/src/main/java/org/apache/cxf/common/util/OpcodesProxy.java
new file mode 100644
index 0000000..9e6fc72
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/common/util/OpcodesProxy.java
@@ -0,0 +1,94 @@
+/**
+ * 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.common.util;
+
+import java.lang.reflect.Field;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+
+public class OpcodesProxy {
+ //CHECKSTYLE:OFF
+ //Will use reflection to set these based on the package name and such
+ //so we don't want them "final" or the compiler will optimize them out
+ //to just "0" which we really don't want
+ public int ARETURN = 0;
+ public int ALOAD = 0;
+ public int IFNULL = 0;
+ public int CHECKCAST = 0;
+ public int INVOKEINTERFACE = 0;
+ public int GETFIELD = 0;
+ public int GETSTATIC = 0;
+ public int ASTORE = 0;
+ public int PUTFIELD = 0;
+ public int PUTSTATIC = 0;
+ public int RETURN = 0;
+ public int F_APPEND = 0;
+ public int F_SAME = 0;
+ public int F_SAME1 = 0;
+ public int INVOKESPECIAL = 0;
+ public int ACC_PUBLIC = 0;
+ public int ACC_FINAL = 0;
+ public int ACC_SUPER = 0;
+ public int ACC_PRIVATE = 0;
+ public int ACC_STATIC = 0;
+ public int V1_5 = 0;
+ public int V1_6 = 0;
+ public int V1_7 = 0;
+ public int ACC_ABSTRACT = 0;
+ public int ACC_INTERFACE = 0;
+ public int ACC_SYNTHETIC = 0;
+ public int ILOAD = 0;
+ public int ISTORE = 0;
+ public int AALOAD = 0;
+ public int ARRAYLENGTH = 0;
+ public int IRETURN = 0;
+ public int NEW = 0;
+ public int ANEWARRAY = 0;
+ public int DUP = 0;
+ public int ATHROW = 0;
+ public int INVOKEVIRTUAL = 0;
+ public int GOTO = 0;
+ public int POP = 0;
+ public int ACONST_NULL = 0;
+ public int IFNONNULL = 0;
+ public int SIPUSH = 0;
+ public int INVOKESTATIC = 0;
+ public int ICONST_0;
+ public int ICONST_1;
+ public int LCONST_0;
+ public int FCONST_0;
+ public int DCONST_0;
+ public int IF_ICMPLT = 0;
+ public java.lang.Integer INTEGER;
+
+ public OpcodesProxy(ASMHelper helper) {
+ try {
+ Class<?> cls = helper.getASMClass();
+ cls = ClassLoaderUtils.loadClass(cls.getPackage().getName() + ".Opcodes", cls);
+ for (Field f1 : OpcodesProxy.class.getDeclaredFields()) {
+ Field f = cls.getDeclaredField(f1.getName());
+ ReflectionUtil.setAccessible(f1).set(this, ReflectionUtil.setAccessible(f).get(null));
+ }
+ } catch (Throwable e) {
+ //ignore
+ }
+ }
+ //CHECKSTYLE:ON
+}
diff --git a/core/src/main/java/org/apache/cxf/common/util/StringUtils.java b/core/src/main/java/org/apache/cxf/common/util/StringUtils.java
index 2da80a9..9f7c012 100644
--- a/core/src/main/java/org/apache/cxf/common/util/StringUtils.java
+++ b/core/src/main/java/org/apache/cxf/common/util/StringUtils.java
@@ -160,4 +160,18 @@ public final class StringUtils {
sb.append(HEX[(0xF0 & b) >> 4]);
sb.append(HEX[0x0F & b]);
}
+
+ public 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 slashesToPeriod(String s) {
+ return s.replace('/', '.');
+ }
+
}
diff --git a/core/src/main/resources/META-INF/cxf/bus-extensions.txt b/core/src/main/resources/META-INF/cxf/bus-extensions.txt
index f8e394b..3677c28 100644
--- a/core/src/main/resources/META-INF/cxf/bus-extensions.txt
+++ b/core/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -9,4 +9,6 @@ org.apache.cxf.bus.managers.ServerLifeCycleManagerImpl:org.apache.cxf.endpoint.S
org.apache.cxf.bus.managers.ClientLifeCycleManagerImpl:org.apache.cxf.endpoint.ClientLifeCycleManager:true
org.apache.cxf.bus.resource.ResourceManagerImpl:org.apache.cxf.resource.ResourceManager:true
org.apache.cxf.catalog.OASISCatalogManager:org.apache.cxf.catalog.OASISCatalogManager:true
+org.apache.cxf.common.util.ASMHelperImpl:org.apache.cxf.common.util.ASMHelper:true
+org.apache.cxf.common.spi.ClassLoaderProxyService:org.apache.cxf.common.spi.ClassLoaderService:true
diff --git a/core/src/test/java/org/apache/cxf/common/util/ASMHelperTest.java b/core/src/test/java/org/apache/cxf/common/util/ASMHelperTest.java
index a565ff1..a87b8d5 100644
--- a/core/src/test/java/org/apache/cxf/common/util/ASMHelperTest.java
+++ b/core/src/test/java/org/apache/cxf/common/util/ASMHelperTest.java
@@ -21,9 +21,15 @@ package org.apache.cxf.common.util;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+
import org.junit.Test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
public class ASMHelperTest {
@Test
@@ -32,10 +38,37 @@ public class ASMHelperTest {
EnumObject.class
});
Type[] types = method.getGenericParameterTypes();
- String classCode = ASMHelper.getClassCode(types[0]);
+ ASMHelper helper = new ASMHelperImpl();
+ String classCode = helper.getClassCode(types[0]);
assertEquals("Lorg/apache/cxf/common/util/ASMHelperTest$EnumObject<Ljava/lang/Enum;>;", classCode);
}
+ @Test
+ public void testLoader() throws Exception {
+ CustomLoader cl = new CustomLoader(new ExtensionManagerBus());
+ Class<?> clz = cl.createCustom();
+ assertNotNull(clz);
+ assertTrue(cl.isFound());
+ }
+ public class CustomLoader extends ClassGeneratorClassLoader {
+ public CustomLoader(Bus bus) {
+ super(bus);
+ }
+ public Class<?> createCustom() {
+ ASMHelper helper = new ASMHelperImpl();
+ ASMHelper.ClassWriter cw = helper.createClassWriter();
+ OpcodesProxy opCodes = helper.getOpCodes();
+ cw.visit(opCodes.V1_5, opCodes.ACC_PUBLIC + opCodes.ACC_SUPER, "test/testClass", null,
+ "java/lang/Object", null);
+ cw.visitEnd();
+
+ return loadClass("test.testClass", ASMHelperTest.class, cw.toByteArray());
+ }
+ public boolean isFound() {
+ Class<?> cls = findClass("test.testClass", ASMHelperTest.class);
+ return cls != null;
+ }
+ }
public class EnumObject<E extends Enum<E>> {
private String name;
diff --git a/parent/pom.xml b/parent/pom.xml
index 219b3ad..666d203 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -54,8 +54,8 @@
<!-- stuff related to ASM -->
<cxf.asm.groupId>org.ow2.asm</cxf.asm.groupId>
<cxf.asm.artifactId>asm</cxf.asm.artifactId>
- <cxf.asm.version>8.0.1</cxf.asm.version>
- <cxf.osgi.asm.version>[3.0,9)</cxf.osgi.asm.version>
+ <cxf.asm.version>9.0</cxf.asm.version>
+ <cxf.osgi.asm.version>[3.0,10)</cxf.osgi.asm.version>
<cxf.easymock.version>4.2</cxf.easymock.version>
<!-- OSGi related properties -->
<cxf.fragment.host />
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaConduit.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaConduit.java
index 5cc2e0c..f735624 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaConduit.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaConduit.java
@@ -238,7 +238,7 @@ public class CorbaConduit implements Conduit {
list = orb.create_list(arguments.length);
for (CorbaStreamable argument : arguments) {
- Any value = CorbaAnyHelper.createAny(orb);
+ Any value = CorbaAnyHelper.createAny(orb, message.getExchange().getBus());
argument.getObject().setIntoAny(value, argument, true);
list.add_value(argument.getName(), value, argument.getMode());
}
@@ -256,7 +256,7 @@ public class CorbaConduit implements Conduit {
CorbaStreamable retVal = message.getStreamableReturn();
NamedValue ret = null;
if (retVal != null) {
- Any returnAny = CorbaAnyHelper.createAny(orb);
+ Any returnAny = CorbaAnyHelper.createAny(orb, message.getExchange().getBus());
retVal.getObject().setIntoAny(returnAny, retVal, false);
ret = orb.create_named_value(retVal.getName(), returnAny, org.omg.CORBA.ARG_OUT.value);
} else {
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaServerConduit.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaServerConduit.java
index cfae928..d67f81b 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaServerConduit.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/CorbaServerConduit.java
@@ -120,7 +120,7 @@ public class CorbaServerConduit implements Conduit {
NVList list = inMsg.getList();
if (msg.getStreamableException() != null) {
- Any exAny = CorbaAnyHelper.createAny(orb);
+ Any exAny = CorbaAnyHelper.createAny(orb, exg.getBus());
CorbaStreamable exception = msg.getStreamableException();
exAny.insert_Streamable(exception);
request.set_exception(exAny);
@@ -140,7 +140,7 @@ public class CorbaServerConduit implements Conduit {
CorbaStreamable resultValue = msg.getStreamableReturn();
if (resultValue != null) {
- Any resultAny = CorbaAnyHelper.createAny(orb);
+ Any resultAny = CorbaAnyHelper.createAny(orb, exg.getBus());
resultValue.getObject().setIntoAny(resultAny, resultValue, true);
request.set_result(resultAny);
}
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/interceptors/CorbaStreamInInterceptor.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/interceptors/CorbaStreamInInterceptor.java
index a237bcf..98defae 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/interceptors/CorbaStreamInInterceptor.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/interceptors/CorbaStreamInInterceptor.java
@@ -87,6 +87,7 @@ public class CorbaStreamInInterceptor extends AbstractPhaseInterceptor<Message>
} else {
destination = (CorbaDestination)msg.getExchange().getDestination();
}
+
service = destination.getBindingInfo().getService();
CorbaMessage message = (CorbaMessage)msg;
@@ -298,7 +299,7 @@ public class CorbaStreamInInterceptor extends AbstractPhaseInterceptor<Message>
CorbaHandlerUtils.initializeObjectHandler(orb, paramName, paramIdlType, map, service);
streamables[i] = corbaMsg.createStreamableObject(obj, paramName);
- Any value = CorbaAnyHelper.createAny(orb);
+ Any value = CorbaAnyHelper.createAny(orb, corbaMsg.getExchange().getBus());
if ("in".equals(paramMode.value())) {
streamables[i].setMode(org.omg.CORBA.ARG_IN.value);
streamables[i].getObject().setIntoAny(value, streamables[i], false);
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaAnyHelper.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaAnyHelper.java
index fe50c1b..5337193 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaAnyHelper.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaAnyHelper.java
@@ -26,16 +26,11 @@ import java.util.Map;
import javax.xml.namespace.QName;
+import org.apache.cxf.Bus;
import org.apache.cxf.binding.corba.CorbaBindingException;
import org.apache.cxf.binding.corba.types.CorbaPrimitiveHandler;
import org.apache.cxf.binding.corba.wsdl.CorbaConstants;
import org.apache.cxf.binding.corba.wsdl.W3CConstants;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.FieldVisitor;
-import org.apache.cxf.common.util.ASMHelper.Label;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelper.Opcodes;
import org.omg.CORBA.Any;
import org.omg.CORBA.ORB;
import org.omg.CORBA.TCKind;
@@ -52,10 +47,10 @@ public final class CorbaAnyHelper {
//utility class
}
- public static Any createAny(ORB orb) {
+ public static Any createAny(ORB orb, Bus bus) {
Any value = orb.create_any();
if ("com.sun.corba.se.impl.corba.AnyImpl".equals(value.getClass().getName())) {
- value = createFixedAny(orb, value);
+ value = createFixedAny(orb, value, bus);
}
return value;
}
@@ -272,258 +267,21 @@ public final class CorbaAnyHelper {
IDL_TO_SCHEMA_TYPES.put(CorbaConstants.NT_CORBA_ANY, W3CConstants.NT_SCHEMA_ANYTYPE);
}
- private static Any createFixedAny(ORB orb, Any any) {
- createFixedAnyConstructor();
+ private static synchronized Any createFixedAny(ORB orb, Any any, Bus bus) {
+ if (fixedAnyConstructor == null) {
+ CorbaFixedAnyImplClassCreator corbaFixedAnyImplClassCreator =
+ bus.getExtension(CorbaFixedAnyImplClassCreator.class);
+ Class<?> c = corbaFixedAnyImplClassCreator.createFixedAnyClass();
+ try {
+ fixedAnyConstructor = c.getConstructor(ORB.class, Any.class);
+ } catch (Exception e) {
+ //shouldn't happen since we generated that constructor
+ }
+ }
try {
return (Any)fixedAnyConstructor.newInstance(orb, any);
} catch (Exception e) {
return any;
}
}
- private static synchronized void createFixedAnyConstructor() {
- if (fixedAnyConstructor != null) {
- return;
- }
-
- ASMHelper helper = new ASMHelper();
- ClassWriter cw = helper.createClassWriter();
- FieldVisitor fv;
-
- cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
- "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
- null, "com/sun/corba/se/impl/corba/AnyImpl", null);
-
- cw.visitSource("FixedAnyImpl.java", null);
-
- fv = cw.visitField(0, "obj", "Lorg/omg/CORBA/portable/Streamable;", null, null);
- fv.visitEnd();
- addFixedAnyConstructor(helper, cw);
- addInsertOverride(helper, cw);
- addExtractOverride(helper, cw);
- addWriteOverride(helper, cw);
- addReadOverride(helper, cw);
-
- cw.visitEnd();
-
- byte[] b = cw.toByteArray();
- Class<?> c = helper.loadClass("org.apache.cxf.binding.corba.utils.FixedAnyImpl",
- CorbaAnyHelper.class, b);
- try {
- fixedAnyConstructor = c.getConstructor(ORB.class, Any.class);
- } catch (Exception e) {
- //shouldn't happen since we generated that constructor
- }
- }
-
- private static void addReadOverride(ASMHelper helper, ClassWriter cw) {
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "read_value",
- "(Lorg/omg/CORBA/portable/InputStream;Lorg/omg/CORBA/TypeCode;)V",
- null, null);
- mv.visitCode();
- Label l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(54, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
- "obj", "Lorg/omg/CORBA/portable/Streamable;");
- Label l1 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.IFNULL, l1);
- Label l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLineNumber(55, l2);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
- "obj", "Lorg/omg/CORBA/portable/Streamable;");
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "org/omg/CORBA/portable/Streamable",
- "_read", "(Lorg/omg/CORBA/portable/InputStream;)V", true);
- Label l3 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.GOTO, l3);
- mv.visitLabel(l1);
- mv.visitLineNumber(57, l1);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
- "read_value",
- "(Lorg/omg/CORBA/portable/InputStream;Lorg/omg/CORBA/TypeCode;)V", false);
- mv.visitLabel(l3);
- mv.visitLineNumber(59, l3);
- mv.visitInsn(Opcodes.RETURN);
- Label l4 = helper.createLabel();
- mv.visitLabel(l4);
- mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
- null, l0, l4, 0);
- mv.visitLocalVariable("is", "Lorg/omg/CORBA/portable/InputStream;", null, l0, l4, 1);
- mv.visitLocalVariable("t", "Lorg/omg/CORBA/TypeCode;", null, l0, l4, 2);
- mv.visitMaxs(3, 3);
- mv.visitEnd();
- }
-
- private static void addWriteOverride(ASMHelper helper, ClassWriter cw) {
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "write_value",
- "(Lorg/omg/CORBA/portable/OutputStream;)V", null, null);
- mv.visitCode();
- Label l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(61, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
- "obj", "Lorg/omg/CORBA/portable/Streamable;");
- Label l1 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.IFNULL, l1);
- Label l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLineNumber(62, l2);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
- "obj", "Lorg/omg/CORBA/portable/Streamable;");
-
- Label l3 = helper.createLabel();
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "org/omg/CORBA/portable/Streamable",
- "_write", "(Lorg/omg/CORBA/portable/OutputStream;)V", true);
- mv.visitJumpInsn(Opcodes.GOTO, l3);
- mv.visitLabel(l1);
- mv.visitLineNumber(64, l1);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
- "write_value", "(Lorg/omg/CORBA/portable/OutputStream;)V", false);
- mv.visitLabel(l3);
- mv.visitLineNumber(66, l3);
- mv.visitInsn(Opcodes.RETURN);
- Label l4 = helper.createLabel();
- mv.visitLabel(l4);
- mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
- null, l0, l4, 0);
- mv.visitLocalVariable("os", "Lorg/omg/CORBA/portable/OutputStream;", null, l0, l4, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
-
- }
-
- private static void addExtractOverride(ASMHelper helper, ClassWriter cw) {
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "extract_Streamable",
- "()Lorg/omg/CORBA/portable/Streamable;", null, null);
- mv.visitCode();
- Label l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(47, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
- "obj", "Lorg/omg/CORBA/portable/Streamable;");
- Label l1 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.IFNULL, l1);
- Label l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLineNumber(48, l2);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
- "obj", "Lorg/omg/CORBA/portable/Streamable;");
- mv.visitInsn(Opcodes.ARETURN);
- mv.visitLabel(l1);
- mv.visitLineNumber(50, l1);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
- "extract_Streamable", "()Lorg/omg/CORBA/portable/Streamable;", false);
- mv.visitInsn(Opcodes.ARETURN);
- Label l3 = helper.createLabel();
- mv.visitLabel(l3);
- mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;", null, l0, l3, 0);
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
- }
-
- private static void addInsertOverride(ASMHelper helper, ClassWriter cw) {
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
- "insert_Streamable",
- "(Lorg/omg/CORBA/portable/Streamable;)V", null, null);
- mv.visitCode();
- Label l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(43, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
- "com/sun/corba/se/impl/corba/AnyImpl",
- "insert_Streamable",
- "(Lorg/omg/CORBA/portable/Streamable;)V", false);
- Label l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(44, l1);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitFieldInsn(Opcodes.PUTFIELD,
- "org/apache/cxf/binding/corba/utils/FixedAnyImpl", "obj",
- "Lorg/omg/CORBA/portable/Streamable;");
- Label l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLineNumber(45, l2);
- mv.visitInsn(Opcodes.RETURN);
- Label l3 = helper.createLabel();
- mv.visitLabel(l3);
- mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
- null, l0, l3, 0);
- mv.visitLocalVariable("s", "Lorg/omg/CORBA/portable/Streamable;", null, l0, l3, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
- }
-
- private static void addFixedAnyConstructor(ASMHelper helper, ClassWriter cw) {
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Lorg/omg/CORBA/ORB;)V", null, null);
- mv.visitCode();
- Label l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(36, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitTypeInsn(Opcodes.CHECKCAST, "com/sun/corba/se/spi/orb/ORB");
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
- "com/sun/corba/se/impl/corba/AnyImpl",
- "<init>", "(Lcom/sun/corba/se/spi/orb/ORB;)V", false);
- Label l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(37, l1);
- mv.visitInsn(Opcodes.RETURN);
- Label l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLocalVariable("this",
- "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
- null, l0, l2, 0);
- mv.visitLocalVariable("orb", "Lorg/omg/CORBA/ORB;", null, l0, l2, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
-
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
- "(Lorg/omg/CORBA/ORB;Lorg/omg/CORBA/Any;)V",
- null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(39, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitTypeInsn(Opcodes.CHECKCAST, "com/sun/corba/se/spi/orb/ORB");
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
- "com/sun/corba/se/impl/corba/AnyImpl",
- "<init>",
- "(Lcom/sun/corba/se/spi/orb/ORB;Lorg/omg/CORBA/Any;)V", false);
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(40, l1);
- mv.visitInsn(Opcodes.RETURN);
- l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
- null, l0, l2, 0);
- mv.visitLocalVariable("orb", "Lorg/omg/CORBA/ORB;", null, l0, l2, 1);
- mv.visitLocalVariable("any", "Lorg/omg/CORBA/Any;", null, l0, l2, 2);
- mv.visitMaxs(3, 3);
- mv.visitEnd();
-
- }
}
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreator.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreator.java
new file mode 100644
index 0000000..6134f09
--- /dev/null
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreator.java
@@ -0,0 +1,23 @@
+/**
+ * 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.binding.corba.utils;
+
+public interface CorbaFixedAnyImplClassCreator {
+ Class<?> createFixedAnyClass();
+}
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreatorProxyService.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreatorProxyService.java
new file mode 100644
index 0000000..bcdb1ca
--- /dev/null
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassCreatorProxyService.java
@@ -0,0 +1,48 @@
+/**
+ * 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.binding.corba.utils;
+
+import org.apache.cxf.Bus;
+
+public class CorbaFixedAnyImplClassCreatorProxyService implements CorbaFixedAnyImplClassCreator {
+ private final CorbaFixedAnyImplClassCreator srv;
+ public CorbaFixedAnyImplClassCreatorProxyService(Bus bus) {
+ this(new CorbaFixedAnyImplGenerator(bus));
+ }
+ public CorbaFixedAnyImplClassCreatorProxyService(CorbaFixedAnyImplClassCreator srv) {
+ super();
+ this.srv = srv;
+ }
+
+ @Override
+ public Class<?> createFixedAnyClass() {
+ return srv.createFixedAnyClass();
+ }
+
+ public class LoadFirst extends CorbaFixedAnyImplClassCreatorProxyService {
+ public LoadFirst(Bus bus) {
+ super(new CorbaFixedAnyImplClassLoader(bus));
+ }
+ }
+ public class GenerateJustInTime extends CorbaFixedAnyImplClassCreatorProxyService {
+ public GenerateJustInTime(Bus bus) {
+ super(new CorbaFixedAnyImplGenerator(bus));
+ }
+ }
+}
\ No newline at end of file
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassLoader.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassLoader.java
new file mode 100644
index 0000000..b56b666
--- /dev/null
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplClassLoader.java
@@ -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.binding.corba.utils;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+
+public class CorbaFixedAnyImplClassLoader extends GeneratedClassClassLoader implements CorbaFixedAnyImplClassCreator {
+
+ public CorbaFixedAnyImplClassLoader(Bus bus) {
+ super(bus);
+ }
+
+ @Override
+ public Class<?> createFixedAnyClass() {
+ String newClassName = "org.apache.cxf.binding.corba.utils.FixedAnyImpl";
+ return findClass(newClassName, CorbaFixedAnyImplClassLoader.class);
+ }
+}
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplGenerator.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplGenerator.java
new file mode 100644
index 0000000..36b3205
--- /dev/null
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/utils/CorbaFixedAnyImplGenerator.java
@@ -0,0 +1,276 @@
+/**
+ * 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.binding.corba.utils;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+
+public class CorbaFixedAnyImplGenerator extends ClassGeneratorClassLoader implements CorbaFixedAnyImplClassCreator {
+
+ public CorbaFixedAnyImplGenerator(Bus bus) {
+ super(bus);
+ }
+ public Class<?> createFixedAnyClass() {
+ ASMHelper helper = bus.getExtension(ASMHelper.class);
+ OpcodesProxy opCodes = helper.getOpCodes();
+ ASMHelper.ClassWriter cw = helper.createClassWriter();
+ ASMHelper.FieldVisitor fv;
+
+ cw.visit(opCodes.V1_6, opCodes.ACC_PUBLIC + opCodes.ACC_SUPER,
+ "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+ null, "com/sun/corba/se/impl/corba/AnyImpl", null);
+
+ cw.visitSource("FixedAnyImpl.java", null);
+
+ fv = cw.visitField(0, "obj", "Lorg/omg/CORBA/portable/Streamable;", null, null);
+ fv.visitEnd();
+ addFixedAnyConstructor(helper, cw);
+ addInsertOverride(helper, cw);
+ addExtractOverride(helper, cw);
+ addWriteOverride(helper, cw);
+ addReadOverride(helper, cw);
+
+ cw.visitEnd();
+
+ byte[] b = cw.toByteArray();
+ Class<?> c = loadClass("org.apache.cxf.binding.corba.utils.FixedAnyImpl",
+ CorbaFixedAnyImplGenerator.class, b);
+ return c;
+ }
+
+ private void addReadOverride(ASMHelper helper, ASMHelper.ClassWriter cw) {
+ OpcodesProxy opCodes = helper.getOpCodes();
+ ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "read_value",
+ "(Lorg/omg/CORBA/portable/InputStream;Lorg/omg/CORBA/TypeCode;)V",
+ null, null);
+ mv.visitCode();
+ ASMHelper.Label l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(54, l0);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+ "obj", "Lorg/omg/CORBA/portable/Streamable;");
+ ASMHelper.Label l1 = helper.createLabel();
+ mv.visitJumpInsn(opCodes.IFNULL, l1);
+ ASMHelper.Label l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(55, l2);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+ "obj", "Lorg/omg/CORBA/portable/Streamable;");
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "org/omg/CORBA/portable/Streamable",
+ "_read", "(Lorg/omg/CORBA/portable/InputStream;)V", true);
+ ASMHelper.Label l3 = helper.createLabel();
+ mv.visitJumpInsn(opCodes.GOTO, l3);
+ mv.visitLabel(l1);
+ mv.visitLineNumber(57, l1);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitVarInsn(opCodes.ALOAD, 2);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
+ "read_value",
+ "(Lorg/omg/CORBA/portable/InputStream;Lorg/omg/CORBA/TypeCode;)V", false);
+ mv.visitLabel(l3);
+ mv.visitLineNumber(59, l3);
+ mv.visitInsn(opCodes.RETURN);
+ ASMHelper.Label l4 = helper.createLabel();
+ mv.visitLabel(l4);
+ mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+ null, l0, l4, 0);
+ mv.visitLocalVariable("is", "Lorg/omg/CORBA/portable/InputStream;", null, l0, l4, 1);
+ mv.visitLocalVariable("t", "Lorg/omg/CORBA/TypeCode;", null, l0, l4, 2);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+
+ private void addWriteOverride(ASMHelper helper, ASMHelper.ClassWriter cw) {
+ OpcodesProxy opCodes = helper.getOpCodes();
+ ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "write_value",
+ "(Lorg/omg/CORBA/portable/OutputStream;)V", null, null);
+ mv.visitCode();
+ ASMHelper.Label l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(61, l0);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+ "obj", "Lorg/omg/CORBA/portable/Streamable;");
+ ASMHelper.Label l1 = helper.createLabel();
+ mv.visitJumpInsn(opCodes.IFNULL, l1);
+ ASMHelper.Label l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(62, l2);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+ "obj", "Lorg/omg/CORBA/portable/Streamable;");
+
+ ASMHelper.Label l3 = helper.createLabel();
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "org/omg/CORBA/portable/Streamable",
+ "_write", "(Lorg/omg/CORBA/portable/OutputStream;)V", true);
+ mv.visitJumpInsn(opCodes.GOTO, l3);
+ mv.visitLabel(l1);
+ mv.visitLineNumber(64, l1);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
+ "write_value", "(Lorg/omg/CORBA/portable/OutputStream;)V", false);
+ mv.visitLabel(l3);
+ mv.visitLineNumber(66, l3);
+ mv.visitInsn(opCodes.RETURN);
+ ASMHelper.Label l4 = helper.createLabel();
+ mv.visitLabel(l4);
+ mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+ null, l0, l4, 0);
+ mv.visitLocalVariable("os", "Lorg/omg/CORBA/portable/OutputStream;", null, l0, l4, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ }
+
+ private void addExtractOverride(ASMHelper helper, ASMHelper.ClassWriter cw) {
+ OpcodesProxy opCodes = helper.getOpCodes();
+ ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "extract_Streamable",
+ "()Lorg/omg/CORBA/portable/Streamable;", null, null);
+ mv.visitCode();
+ ASMHelper.Label l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(47, l0);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+ "obj", "Lorg/omg/CORBA/portable/Streamable;");
+ ASMHelper.Label l1 = helper.createLabel();
+ mv.visitJumpInsn(opCodes.IFNULL, l1);
+ ASMHelper.Label l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(48, l2);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitFieldInsn(opCodes.GETFIELD, "org/apache/cxf/binding/corba/utils/FixedAnyImpl",
+ "obj", "Lorg/omg/CORBA/portable/Streamable;");
+ mv.visitInsn(opCodes.ARETURN);
+ mv.visitLabel(l1);
+ mv.visitLineNumber(50, l1);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL, "com/sun/corba/se/impl/corba/AnyImpl",
+ "extract_Streamable", "()Lorg/omg/CORBA/portable/Streamable;", false);
+ mv.visitInsn(opCodes.ARETURN);
+ ASMHelper.Label l3 = helper.createLabel();
+ mv.visitLabel(l3);
+ mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;", null, l0, l3, 0);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ }
+
+ private void addInsertOverride(ASMHelper helper, ASMHelper.ClassWriter cw) {
+ OpcodesProxy opCodes = helper.getOpCodes();
+ ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC,
+ "insert_Streamable",
+ "(Lorg/omg/CORBA/portable/Streamable;)V", null, null);
+ mv.visitCode();
+ ASMHelper.Label l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(43, l0);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+ "com/sun/corba/se/impl/corba/AnyImpl",
+ "insert_Streamable",
+ "(Lorg/omg/CORBA/portable/Streamable;)V", false);
+ ASMHelper.Label l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(44, l1);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitFieldInsn(opCodes.PUTFIELD,
+ "org/apache/cxf/binding/corba/utils/FixedAnyImpl", "obj",
+ "Lorg/omg/CORBA/portable/Streamable;");
+ ASMHelper.Label l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(45, l2);
+ mv.visitInsn(opCodes.RETURN);
+ ASMHelper.Label l3 = helper.createLabel();
+ mv.visitLabel(l3);
+ mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+ null, l0, l3, 0);
+ mv.visitLocalVariable("s", "Lorg/omg/CORBA/portable/Streamable;", null, l0, l3, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+
+ private void addFixedAnyConstructor(ASMHelper helper, ASMHelper.ClassWriter cw) {
+ OpcodesProxy opCodes = helper.getOpCodes();
+ ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>", "(Lorg/omg/CORBA/ORB;)V", null, null);
+ mv.visitCode();
+ ASMHelper.Label l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(36, l0);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitTypeInsn(opCodes.CHECKCAST, "com/sun/corba/se/spi/orb/ORB");
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+ "com/sun/corba/se/impl/corba/AnyImpl",
+ "<init>", "(Lcom/sun/corba/se/spi/orb/ORB;)V", false);
+ ASMHelper.Label l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(37, l1);
+ mv.visitInsn(opCodes.RETURN);
+ ASMHelper.Label l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLocalVariable("this",
+ "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+ null, l0, l2, 0);
+ mv.visitLocalVariable("orb", "Lorg/omg/CORBA/ORB;", null, l0, l2, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+
+ mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>",
+ "(Lorg/omg/CORBA/ORB;Lorg/omg/CORBA/Any;)V",
+ null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(39, l0);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitTypeInsn(opCodes.CHECKCAST, "com/sun/corba/se/spi/orb/ORB");
+ mv.visitVarInsn(opCodes.ALOAD, 2);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+ "com/sun/corba/se/impl/corba/AnyImpl",
+ "<init>",
+ "(Lcom/sun/corba/se/spi/orb/ORB;Lorg/omg/CORBA/Any;)V", false);
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(40, l1);
+ mv.visitInsn(opCodes.RETURN);
+ l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLocalVariable("this", "Lorg/apache/cxf/binding/corba/utils/FixedAnyImpl;",
+ null, l0, l2, 0);
+ mv.visitLocalVariable("orb", "Lorg/omg/CORBA/ORB;", null, l0, l2, 1);
+ mv.visitLocalVariable("any", "Lorg/omg/CORBA/Any;", null, l0, l2, 2);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ }
+}
diff --git a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/wsdl/WSDLExtensionRegister.java b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/wsdl/WSDLExtensionRegister.java
index 2365d1c..b07c611 100644
--- a/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/wsdl/WSDLExtensionRegister.java
+++ b/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/wsdl/WSDLExtensionRegister.java
@@ -33,8 +33,10 @@ import org.apache.cxf.wsdl.WSDLManager;
@NoJSR250Annotations
public final class WSDLExtensionRegister implements WSDLExtensionLoader {
private static final String YOKO_NAMESPACE = "http://schemas.apache.org/yoko/bindings/corba";
+ private final Bus bus;
public WSDLExtensionRegister(Bus b) {
+ this.bus = b;
WSDLManager manager = b.getExtension(WSDLManager.class);
registerCXFExtensors(manager);
registerYokoCompatibleExtensors(manager);
@@ -68,7 +70,7 @@ public final class WSDLExtensionRegister implements WSDLExtensionLoader {
Class<?> parentType,
Class<?> elementType) {
try {
- JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+ JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(),
parentType,
elementType,
null,
@@ -83,7 +85,7 @@ public final class WSDLExtensionRegister implements WSDLExtensionLoader {
Class<?> parentType,
Class<?> elementType) {
try {
- JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+ JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(),
parentType,
elementType,
YOKO_NAMESPACE);
diff --git a/rt/bindings/corba/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/bindings/corba/src/main/resources/META-INF/cxf/bus-extensions.txt
index 7cd5d2e..c26c985 100644
--- a/rt/bindings/corba/src/main/resources/META-INF/cxf/bus-extensions.txt
+++ b/rt/bindings/corba/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -1,2 +1,3 @@
org.apache.cxf.binding.corba.CorbaBindingFactory::true
org.apache.cxf.binding.corba.wsdl.WSDLExtensionRegister::true
+org.apache.cxf.binding.corba.utils.CorbaFixedAnyImplClassCreatorProxyService:org.apache.cxf.binding.corba.utils.CorbaFixedAnyImplClassCreator:true
diff --git a/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaConduitTest.java b/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaConduitTest.java
index d413e77..3fc47fc 100644
--- a/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaConduitTest.java
+++ b/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaConduitTest.java
@@ -35,6 +35,7 @@ import org.apache.cxf.binding.corba.wsdl.OperationType;
import org.apache.cxf.binding.corba.wsdl.RaisesType;
import org.apache.cxf.binding.corba.wsdl.TypeMappingType;
import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.service.Service;
@@ -251,6 +252,9 @@ public class CorbaConduitTest {
public void testBuildArguments() throws Exception {
Message msg = new MessageImpl();
CorbaMessage message = new CorbaMessage(msg);
+ Exchange exchange = new ExchangeImpl();
+ exchange.put(Bus.class, bus);
+ message.setExchange(exchange);
CorbaStreamable[] arguments = new CorbaStreamable[1];
QName objName = new QName("object");
QName objIdlType = new QName(CorbaConstants.NU_WSDL_CORBA, "short", CorbaConstants.NP_WSDL_CORBA);
@@ -277,6 +281,9 @@ public class CorbaConduitTest {
public void testBuildReturn() throws Exception {
Message msg = new MessageImpl();
CorbaMessage message = new CorbaMessage(msg);
+ Exchange exchange = new ExchangeImpl();
+ exchange.put(Bus.class, bus);
+ message.setExchange(exchange);
QName objName = new QName("returnName");
QName objIdlType = new QName(CorbaConstants.NU_WSDL_CORBA, "short", CorbaConstants.NP_WSDL_CORBA);
diff --git a/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaServerConduitTest.java b/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaServerConduitTest.java
index e89f7a6..cefef33 100644
--- a/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaServerConduitTest.java
+++ b/rt/bindings/corba/src/test/java/org/apache/cxf/binding/corba/CorbaServerConduitTest.java
@@ -235,9 +235,12 @@ public class CorbaServerConduitTest {
EasyMock.expect(exchange.get(ServerRequest.class)).andReturn(request);
EasyMock.expect(exchange.isOneWay()).andReturn(false);
+
CorbaMessage inMsg = EasyMock.createMock(CorbaMessage.class);
EasyMock.expect(msg.getExchange()).andReturn(exchange);
EasyMock.expect(exchange.getInMessage()).andReturn(inMsg);
+ EasyMock.expect(exchange.getBus()).andReturn(bus);
+
EasyMock.expect(inMsg.getList()).andReturn(list);
QName objName = new QName("object");
@@ -274,6 +277,7 @@ public class CorbaServerConduitTest {
CorbaMessage msg = control.createMock(CorbaMessage.class);
Exchange exchange = control.createMock(Exchange.class);
ServerRequest request = control.createMock(ServerRequest.class);
+ EasyMock.expect(exchange.getBus()).andReturn(bus);
EasyMock.expect(msg.getExchange()).andReturn(exchange);
EasyMock.expect(exchange.get(ServerRequest.class)).andReturn(request);
diff --git a/rt/bindings/xml/src/main/java/org/apache/cxf/binding/xml/wsdl11/XMLWSDLExtensionLoader.java b/rt/bindings/xml/src/main/java/org/apache/cxf/binding/xml/wsdl11/XMLWSDLExtensionLoader.java
index 8d30118..7171680 100644
--- a/rt/bindings/xml/src/main/java/org/apache/cxf/binding/xml/wsdl11/XMLWSDLExtensionLoader.java
+++ b/rt/bindings/xml/src/main/java/org/apache/cxf/binding/xml/wsdl11/XMLWSDLExtensionLoader.java
@@ -33,15 +33,18 @@ import org.apache.cxf.wsdl.WSDLManager;
@NoJSR250Annotations
public final class XMLWSDLExtensionLoader implements WSDLExtensionLoader {
+ private Bus bus;
+
public XMLWSDLExtensionLoader(Bus b) {
setupBus(b);
}
public void setupBus(Bus b) {
+ this.bus = b;
WSDLManager manager = b.getExtension(WSDLManager.class);
registerExtensors(manager);
}
- public static void registerExtensors(WSDLManager manager) {
+ public void registerExtensors(WSDLManager manager) {
createExtensor(manager, javax.wsdl.BindingInput.class,
org.apache.cxf.bindings.xformat.XMLBindingMessageFormat.class);
createExtensor(manager, javax.wsdl.BindingOutput.class,
@@ -50,11 +53,11 @@ public final class XMLWSDLExtensionLoader implements WSDLExtensionLoader {
org.apache.cxf.bindings.xformat.XMLFormatBinding.class);
}
- public static void createExtensor(WSDLManager manager,
+ public void createExtensor(WSDLManager manager,
Class<?> parentType,
Class<?> elementType) {
try {
- JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+ JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(),
parentType,
elementType,
null,
diff --git a/rt/bindings/xml/src/test/java/org/apache/cxf/binding/xml/interceptor/TestBase.java b/rt/bindings/xml/src/test/java/org/apache/cxf/binding/xml/interceptor/TestBase.java
index c07071a..8c65242 100644
--- a/rt/bindings/xml/src/test/java/org/apache/cxf/binding/xml/interceptor/TestBase.java
+++ b/rt/bindings/xml/src/test/java/org/apache/cxf/binding/xml/interceptor/TestBase.java
@@ -77,7 +77,8 @@ public class TestBase {
Bus bus = BusFactory.getDefaultBus();
WSDLManagerImpl manager = new WSDLManagerImpl();
- XMLWSDLExtensionLoader.registerExtensors(manager);
+ XMLWSDLExtensionLoader loader = new XMLWSDLExtensionLoader(bus);
+ loader.registerExtensors(manager);
assertNotNull(bus.getExtension(WSDLManager.class));
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassCreator.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassCreator.java
new file mode 100644
index 0000000..e3ba1ab
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassCreator.java
@@ -0,0 +1,24 @@
+/**
+ * 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.jaxb;
+
+public interface FactoryClassCreator {
+ Class<?> createFactory(Class<?> cls);
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassGenerator.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassGenerator.java
new file mode 100644
index 0000000..c69b2b4
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassGenerator.java
@@ -0,0 +1,86 @@
+/**
+ * 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.jaxb;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+import org.apache.cxf.common.util.ReflectionUtil;
+import org.apache.cxf.common.util.StringUtils;
+
+
+public class FactoryClassGenerator extends ClassGeneratorClassLoader implements FactoryClassCreator {
+ private final ASMHelper helper;
+ FactoryClassGenerator(Bus bus) {
+ super(bus);
+ helper = bus.getExtension(ASMHelper.class);
+ }
+ @SuppressWarnings("unused")
+ public Class<?> createFactory(Class<?> cls) {
+ String newClassName = cls.getName() + "Factory";
+ Class<?> factoryClass = findClass(newClassName, cls);
+ if (factoryClass != null) {
+ return factoryClass;
+ }
+ Constructor<?> contructor = ReflectionUtil.getDeclaredConstructors(cls)[0];
+ OpcodesProxy opcodes = helper.getOpCodes();
+ ASMHelper.ClassWriter cw = helper.createClassWriter();
+ ASMHelper.MethodVisitor mv;
+
+ cw.visit(opcodes.V1_6, opcodes.ACC_PUBLIC + opcodes.ACC_SUPER,
+ StringUtils.periodToSlashes(newClassName), null, "java/lang/Object", null);
+
+ cw.visitSource(cls.getSimpleName() + "Factory" + ".java", null);
+
+ mv = cw.visitMethod(opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(opcodes.ALOAD, 0);
+ mv.visitMethodInsn(opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ mv.visitInsn(opcodes.RETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(opcodes.ACC_PUBLIC, "create" + cls.getSimpleName(),
+ "()L" + StringUtils.periodToSlashes(cls.getName()) + ";", null, null);
+ mv.visitCode();
+ String name = cls.getName().replace(".", "/");
+ mv.visitTypeInsn(opcodes.NEW, name);
+ mv.visitInsn(opcodes.DUP);
+ StringBuilder paraString = new StringBuilder(32).append("(");
+
+ for (Class<?> paraClass : contructor.getParameterTypes()) {
+ mv.visitInsn(opcodes.ACONST_NULL);
+ paraString.append("Ljava/lang/Object;");
+ }
+ paraString.append(")V");
+
+ mv.visitMethodInsn(opcodes.INVOKESPECIAL, name, "<init>", paraString.toString(), false);
+
+ mv.visitInsn(opcodes.ARETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ cw.visitEnd();
+ return loadClass(newClassName, cls, cw.toByteArray());
+ }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassLoader.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassLoader.java
new file mode 100644
index 0000000..5cbfd16
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassLoader.java
@@ -0,0 +1,40 @@
+/**
+ * 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.jaxb;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+
+/** If class has been generated during build time
+ * (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ * you can set class loader to avoid class generation during runtime:
+ * bus.setExtension(new FactoryClassLoader(bus), FactoryClassCreator.class);
+ * @author olivier dufour
+ */
+public class FactoryClassLoader extends GeneratedClassClassLoader implements FactoryClassCreator {
+ public FactoryClassLoader(Bus bus) {
+ super(bus);
+ }
+ @Override
+ public Class<?> createFactory(Class<?> cls) {
+ String newClassName = cls.getName() + "Factory";
+ return findClass(newClassName, cls);
+ }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassProxyService.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassProxyService.java
new file mode 100644
index 0000000..0d82b78
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/FactoryClassProxyService.java
@@ -0,0 +1,48 @@
+/**
+ * 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.jaxb;
+
+import org.apache.cxf.Bus;
+
+public class FactoryClassProxyService implements FactoryClassCreator {
+ private final FactoryClassCreator srv;
+ public FactoryClassProxyService(Bus bus) {
+ this(new FactoryClassGenerator(bus));
+ }
+ public FactoryClassProxyService(FactoryClassCreator srv) {
+ super();
+ this.srv = srv;
+ }
+
+ @Override
+ public Class<?> createFactory(Class<?> cls) {
+ return srv.createFactory(cls);
+ }
+
+ public class LoadFirst extends FactoryClassProxyService {
+ public LoadFirst(Bus bus) {
+ super(new FactoryClassLoader(bus));
+ }
+ }
+ public class GenerateJustInTime extends FactoryClassProxyService {
+ public GenerateJustInTime(Bus bus) {
+ super(new FactoryClassGenerator(bus));
+ }
+ }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
index 1038b7f..0dd420b 100644
--- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBContextInitializer.java
@@ -21,7 +21,6 @@ package org.apache.cxf.jaxb;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
@@ -48,13 +47,10 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
import javax.xml.namespace.QName;
+import org.apache.cxf.Bus;
import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.jaxb.JAXBUtils;
import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelper.Opcodes;
import org.apache.cxf.common.util.ReflectionUtil;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.service.ServiceModelVisitor;
@@ -73,15 +69,17 @@ class JAXBContextInitializer extends ServiceModelVisitor {
private Collection<Object> typeReferences;
private Set<Class<?>> globalAdapters = new HashSet<>();
private Map<String, Object> unmarshallerProperties;
+ private Bus bus;
- JAXBContextInitializer(ServiceInfo serviceInfo,
- Set<Class<?>> classes,
- Collection<Object> typeReferences,
- Map<String, Object> unmarshallerProperties) {
+ JAXBContextInitializer(Bus bus, ServiceInfo serviceInfo,
+ Set<Class<?>> classes,
+ Collection<Object> typeReferences,
+ Map<String, Object> unmarshallerProperties) {
super(serviceInfo);
this.classes = classes;
this.typeReferences = typeReferences;
this.unmarshallerProperties = unmarshallerProperties;
+ this.bus = bus;
}
@Override
@@ -328,8 +326,7 @@ class JAXBContextInitializer extends ServiceModelVisitor {
if (LOG.isLoggable(Level.INFO)) {
LOG.info("Class " + claz.getName() + " does not have a default constructor which JAXB requires.");
}
- //there is no init(), but other constructors
- Object factory = createFactory(claz, ReflectionUtil.getDeclaredConstructors(claz)[0]);
+ Object factory = createFactory(claz);
unmarshallerProperties.put("com.sun.xml.bind.ObjectFactory", factory);
cls = claz;
}
@@ -556,47 +553,10 @@ class JAXBContextInitializer extends ServiceModelVisitor {
}
@SuppressWarnings("unused")
- private Object createFactory(Class<?> cls, Constructor<?> contructor) {
- String newClassName = cls.getName() + "Factory";
- ASMHelper helper = new ASMHelper();
- ClassWriter cw = helper.createClassWriter();
- MethodVisitor mv;
-
- cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
- ASMHelper.periodToSlashes(newClassName), null, "java/lang/Object", null);
-
- cw.visitSource(cls.getSimpleName() + "Factory" + ".java", null);
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
- mv.visitCode();
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
- mv.visitInsn(Opcodes.RETURN);
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "create" + cls.getSimpleName(),
- "()L" + ASMHelper.periodToSlashes(cls.getName()) + ";", null, null);
- mv.visitCode();
- String name = cls.getName().replace(".", "/");
- mv.visitTypeInsn(Opcodes.NEW, name);
- mv.visitInsn(Opcodes.DUP);
- StringBuilder paraString = new StringBuilder(32).append("(");
-
- for (Class<?> paraClass : contructor.getParameterTypes()) {
- mv.visitInsn(Opcodes.ACONST_NULL);
- paraString.append("Ljava/lang/Object;");
- }
- paraString.append(")V");
-
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, name, "<init>", paraString.toString(), false);
-
- mv.visitInsn(Opcodes.ARETURN);
- mv.visitMaxs(1, 1);
- mv.visitEnd();
+ private Object createFactory(Class<?> cls) {
+ FactoryClassCreator creator = bus.getExtension(FactoryClassCreator.class);
- cw.visitEnd();
- Class<?> factoryClass = helper.loadClass(newClassName, cls, cw.toByteArray());
+ Class<?> factoryClass = creator.createFactory(cls);
try {
return factoryClass.newInstance();
} catch (Exception e) {
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java
index 1c0c92d..df435cd 100644
--- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBDataBinding.java
@@ -63,6 +63,7 @@ import org.w3c.dom.Node;
import org.xml.sax.InputSource;
+import org.apache.cxf.Bus;
import org.apache.cxf.common.injection.NoJSR250Annotations;
import org.apache.cxf.common.jaxb.JAXBBeanInfo;
import org.apache.cxf.common.jaxb.JAXBContextCache;
@@ -279,19 +280,19 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
Integer mtomThresholdInt = Integer.valueOf(getMtomThreshold());
if (c == XMLStreamWriter.class) {
DataWriterImpl<XMLStreamWriter> r
- = new DataWriterImpl<>(this, true);
+ = new DataWriterImpl<>(getBus(), this, true);
r.setMtomThreshold(mtomThresholdInt);
return (DataWriter<T>)r;
} else if (c == OutputStream.class) {
- DataWriterImpl<OutputStream> r = new DataWriterImpl<>(this, false);
+ DataWriterImpl<OutputStream> r = new DataWriterImpl<>(getBus(), this, false);
r.setMtomThreshold(mtomThresholdInt);
return (DataWriter<T>)r;
} else if (c == XMLEventWriter.class) {
- DataWriterImpl<XMLEventWriter> r = new DataWriterImpl<>(this, true);
+ DataWriterImpl<XMLEventWriter> r = new DataWriterImpl<>(getBus(), this, true);
r.setMtomThreshold(mtomThresholdInt);
return (DataWriter<T>)r;
} else if (c == Node.class) {
- DataWriterImpl<Node> r = new DataWriterImpl<>(this, false);
+ DataWriterImpl<Node> r = new DataWriterImpl<>(getBus(), this, false);
r.setMtomThreshold(mtomThresholdInt);
return (DataWriter<T>)r;
}
@@ -334,8 +335,8 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
contextClasses = new LinkedHashSet<>();
for (ServiceInfo serviceInfo : service.getServiceInfos()) {
- JAXBContextInitializer initializer
- = new JAXBContextInitializer(serviceInfo, contextClasses, typeRefs, this.getUnmarshallerProperties());
+ JAXBContextInitializer initializer = new JAXBContextInitializer(getBus(), serviceInfo, contextClasses,
+ typeRefs, this.getUnmarshallerProperties());
initializer.walk();
if (serviceInfo.getProperty("extra.class") != null) {
Set<Class<?>> exClasses = serviceInfo.getProperty("extra.class", Set.class);
@@ -801,7 +802,7 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
}
- return createWrapperHelper(wrapperType,
+ return createWrapperHelper(getBus(), wrapperType,
setMethods.toArray(new Method[0]),
getMethods.toArray(new Method[0]),
jaxbMethods.toArray(new Method[0]),
@@ -832,11 +833,11 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
}
- private static WrapperHelper createWrapperHelper(Class<?> wrapperType, Method[] setMethods,
+ private static WrapperHelper createWrapperHelper(Bus bus, Class<?> wrapperType, Method[] setMethods,
Method[] getMethods, Method[] jaxbMethods,
Field[] fields, Object objectFactory) {
- WrapperHelper wh = compileWrapperHelper(wrapperType, setMethods, getMethods, jaxbMethods, fields,
+ WrapperHelper wh = compileWrapperHelper(bus, wrapperType, setMethods, getMethods, jaxbMethods, fields,
objectFactory);
if (wh == null) {
@@ -846,11 +847,17 @@ public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding
return wh;
}
- private static WrapperHelper compileWrapperHelper(Class<?> wrapperType, Method[] setMethods,
+ private static WrapperHelper compileWrapperHelper(Bus bus, Class<?> wrapperType, Method[] setMethods,
Method[] getMethods, Method[] jaxbMethods,
Field[] fields, Object objectFactory) {
- return WrapperHelperCompiler.compileWrapperHelper(wrapperType, setMethods, getMethods,
- jaxbMethods, fields, objectFactory);
+ try {
+ WrapperHelperCreator creator = bus.getExtension(WrapperHelperCreator.class);
+ return creator.compile(wrapperType, setMethods, getMethods,
+ jaxbMethods, fields, objectFactory);
+ } catch (Throwable t) {
+ // Some error - probably a bad version of ASM or similar
+ return null;
+ }
}
}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassGenerator.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassGenerator.java
new file mode 100644
index 0000000..c01d6c4
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassGenerator.java
@@ -0,0 +1,451 @@
+/**
+ * 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.jaxb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import javax.xml.bind.JAXBElement;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.databinding.WrapperHelper;
+
+public final class WrapperHelperClassGenerator extends ClassGeneratorClassLoader implements WrapperHelperCreator {
+
+ WrapperHelperClassGenerator(Bus bus) {
+ super(bus);
+ }
+
+ public WrapperHelper compile(Class<?> wrapperType, Method[] setMethods,
+ Method[] getMethods, Method[] jaxbMethods,
+ Field[] fields, Object objectFactory) {
+ ASMHelper asmhelper = bus.getExtension(ASMHelper.class);
+ ASMHelper.ClassWriter cw = asmhelper.createClassWriter();
+
+ if (cw == null) {
+ return null;
+ }
+ int count = 1;
+ String newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
+ newClassName = newClassName.replaceAll("\\$", ".");
+ newClassName = StringUtils.periodToSlashes(newClassName);
+
+ Class<?> cls = findClass(StringUtils.slashesToPeriod(newClassName), wrapperType);
+ while (cls != null) {
+ try {
+ WrapperHelper helper = WrapperHelper.class.cast(cls.newInstance());
+ if (!helper.getSignature().equals(computeSignature(setMethods, getMethods))) {
+ count++;
+ newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
+ newClassName = newClassName.replaceAll("\\$", ".");
+ newClassName = StringUtils.periodToSlashes(newClassName);
+ cls = findClass(StringUtils.slashesToPeriod(newClassName), wrapperType);
+ } else {
+ return helper;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ OpcodesProxy opCodes = asmhelper.getOpCodes();
+
+ cw.visit(opCodes.V1_5,
+ opCodes.ACC_PUBLIC | opCodes.ACC_SUPER,
+ newClassName,
+ null,
+ "java/lang/Object",
+ new String[] {StringUtils.periodToSlashes(WrapperHelper.class.getName())});
+
+ addConstructor(newClassName, objectFactory == null ? null : objectFactory.getClass(), asmhelper, cw);
+ boolean b = addSignature(setMethods, getMethods, asmhelper, cw);
+ if (b) {
+ b = addCreateWrapperObject(newClassName,
+ objectFactory == null ? null : objectFactory.getClass(),
+ wrapperType, setMethods, getMethods, jaxbMethods, fields, asmhelper, cw);
+ }
+ if (b) {
+ b = addGetWrapperParts(newClassName, wrapperType, getMethods, fields, asmhelper, cw);
+ }
+
+ try {
+ if (b) {
+ cw.visitEnd();
+ byte[] bt = cw.toByteArray();
+ Class<?> cl = loadClass(StringUtils.slashesToPeriod(newClassName), wrapperType, bt);
+ Object o = cl.newInstance();
+ return WrapperHelper.class.cast(o);
+ }
+ } catch (Throwable e) {
+ // ignore, we'll just fall down to reflection based
+ }
+ return null;
+ }
+
+ public static String computeSignature(Method[] setMethods, Method[] getMethods) {
+ 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(',');
+ }
+ }
+ return b.toString();
+ }
+
+ private boolean addSignature(Method[] setMethods, Method[] getMethods,
+ ASMHelper asmhelper, ASMHelper.ClassWriter cw) {
+ OpcodesProxy opCodes = asmhelper.getOpCodes();
+ String sig = computeSignature(setMethods, getMethods);
+ ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC,
+ "getSignature", "()Ljava/lang/String;", null, null);
+ mv.visitCode();
+ mv.visitLdcInsn(sig);
+ ASMHelper.Label l0 = asmhelper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(100, l0);
+ mv.visitInsn(opCodes.ARETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ return true;
+ }
+
+ private void addConstructor(String newClassName, Class<?> objectFactoryCls,
+ ASMHelper asmhelper, ASMHelper.ClassWriter cw) {
+
+ if (objectFactoryCls != null) {
+ String ofName = "L" + StringUtils.periodToSlashes(objectFactoryCls.getName()) + ";";
+ ASMHelper.FieldVisitor fv = cw.visitField(0, "factory",
+ ofName,
+ null, null);
+ fv.visitEnd();
+ }
+ OpcodesProxy opCodes = asmhelper.getOpCodes();
+
+ ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ ASMHelper.Label l0 = asmhelper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(102, l0);
+
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+ "java/lang/Object",
+ "<init>",
+ "()V", false);
+ if (objectFactoryCls != null) {
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitTypeInsn(opCodes.NEW, StringUtils.periodToSlashes(objectFactoryCls.getName()));
+ mv.visitInsn(opCodes.DUP);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+ StringUtils.periodToSlashes(objectFactoryCls.getName()),
+ "<init>", "()V", false);
+ mv.visitFieldInsn(opCodes.PUTFIELD, StringUtils.periodToSlashes(newClassName),
+ "factory", "L" + StringUtils.periodToSlashes(objectFactoryCls.getName()) + ";");
+ }
+
+ mv.visitInsn(opCodes.RETURN);
+
+ ASMHelper.Label l1 = asmhelper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(103, l0);
+
+ mv.visitLocalVariable("this", "L" + newClassName + ";", null, l0, l1, 0);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+ //CHECKSTYLE:OFF
+ private boolean addCreateWrapperObject(String newClassName, Class<?> objectFactoryClass,
+ Class<?> wrapperType, Method[] setMethods,
+ Method[] getMethods, Method[] jaxbMethods,
+ Field[] fields, ASMHelper asmhelper, ASMHelper.ClassWriter cw) {
+
+ OpcodesProxy opCodes = asmhelper.getOpCodes();
+ ASMHelper.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();
+ ASMHelper.Label lBegin = asmhelper.createLabel();
+ mv.visitLabel(lBegin);
+ mv.visitLineNumber(104, lBegin);
+
+ mv.visitTypeInsn(opCodes.NEW, StringUtils.periodToSlashes(wrapperType.getName()));
+ mv.visitInsn(opCodes.DUP);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL, StringUtils.periodToSlashes(wrapperType.getName()),
+ "<init>", "()V", false);
+ mv.visitVarInsn(opCodes.ASTORE, 2);
+
+ for (int x = 0; x < setMethods.length; x++) {
+ if (getMethods[x] == null) {
+ if (setMethods[x] == null
+ && fields[x] == null) {
+ // null placeholder
+ continue;
+ }
+ return false;
+ }
+ Class<?> tp = getMethods[x].getReturnType();
+ mv.visitVarInsn(opCodes.ALOAD, 2);
+
+ if (List.class.isAssignableFrom(tp)) {
+ doCollection(mv, x, wrapperType, setMethods, getMethods, asmhelper);
+ } else {
+ if (JAXBElement.class.isAssignableFrom(tp)) {
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitFieldInsn(opCodes.GETFIELD, StringUtils.periodToSlashes(newClassName),
+ "factory",
+ "L" + StringUtils.periodToSlashes(objectFactoryClass.getName()) + ";");
+ }
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitIntInsn(opCodes.SIPUSH, x);
+ mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true);
+
+ if (tp.isPrimitive()) {
+ mv.visitTypeInsn(opCodes.CHECKCAST, asmhelper.getNonPrimitive(tp));
+ ASMHelper.Label l45 = asmhelper.createLabel();
+ ASMHelper.Label l46 = asmhelper.createLabel();
+ mv.visitInsn(opCodes.DUP);
+ mv.visitJumpInsn(opCodes.IFNULL, l45);
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL, asmhelper.getNonPrimitive(tp),
+ tp.getName() + "Value", "()" + asmhelper.getPrimitive(tp), false);
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+ StringUtils.periodToSlashes(wrapperType.getName()),
+ setMethods[x].getName(), "(" + asmhelper.getClassCode(tp) + ")V", false);
+ mv.visitJumpInsn(opCodes.GOTO, l46);
+ mv.visitLabel(l45);
+ mv.visitInsn(opCodes.POP);
+ mv.visitLabel(l46);
+ } else if (JAXBElement.class.isAssignableFrom(tp)) {
+ mv.visitTypeInsn(opCodes.CHECKCAST,
+ StringUtils.periodToSlashes(jaxbMethods[x].getParameterTypes()[0].getName()));
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL, StringUtils.periodToSlashes(objectFactoryClass.getName()),
+ jaxbMethods[x].getName(),
+ asmhelper.getMethodSignature(jaxbMethods[x]), false);
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+ StringUtils.periodToSlashes(wrapperType.getName()),
+ setMethods[x].getName(), "(" + asmhelper.getClassCode(tp) + ")V", false);
+ } else if (tp.isArray()) {
+ mv.visitTypeInsn(opCodes.CHECKCAST, asmhelper.getClassCode(tp));
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+ StringUtils.periodToSlashes(wrapperType.getName()),
+ setMethods[x].getName(), "(" + asmhelper.getClassCode(tp) + ")V", false);
+ } else {
+ mv.visitTypeInsn(opCodes.CHECKCAST, StringUtils.periodToSlashes(tp.getName()));
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+ StringUtils.periodToSlashes(wrapperType.getName()),
+ setMethods[x].getName(), "(" + asmhelper.getClassCode(tp) + ")V", false);
+ }
+ }
+ }
+
+ mv.visitVarInsn(opCodes.ALOAD, 2);
+ mv.visitInsn(opCodes.ARETURN);
+
+ ASMHelper.Label lEnd = asmhelper.createLabel();
+ 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" + StringUtils.periodToSlashes(wrapperType.getName()) + ";",
+ null, lBegin, lEnd, 2);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ return true;
+ }
+ //CHECKSTYLE:ON
+ private void doCollection(ASMHelper.MethodVisitor mv, int x, Class<?> wrapperType, Method[] setMethods,
+ Method[] getMethods, ASMHelper asmhelper) {
+ // List aVal = obj.getA();
+ // List newA = (List)lst.get(99);
+ // if (aVal == null) {
+ // obj.setA(newA);
+ // } else if (newA != null) {
+ // aVal.addAll(newA);
+ // }
+
+ OpcodesProxy opCodes = asmhelper.getOpCodes();
+ ASMHelper.Label l3 = asmhelper.createLabel();
+ mv.visitLabel(l3);
+ mv.visitLineNumber(114, l3);
+
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+ StringUtils.periodToSlashes(wrapperType.getName()),
+ getMethods[x].getName(),
+ asmhelper.getMethodSignature(getMethods[x]), false);
+ mv.visitVarInsn(opCodes.ASTORE, 3);
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitIntInsn(opCodes.SIPUSH, x);
+ mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "java/util/List",
+ "get", "(I)Ljava/lang/Object;", true);
+ mv.visitTypeInsn(opCodes.CHECKCAST, "java/util/List");
+ mv.visitVarInsn(opCodes.ASTORE, 4);
+ mv.visitVarInsn(opCodes.ALOAD, 3);
+ ASMHelper.Label nonNullLabel = asmhelper.createLabel();
+ mv.visitJumpInsn(opCodes.IFNONNULL, nonNullLabel);
+
+ if (setMethods[x] == null) {
+ mv.visitTypeInsn(opCodes.NEW, "java/lang/RuntimeException");
+ mv.visitInsn(opCodes.DUP);
+ mv.visitLdcInsn(getMethods[x].getName() + " returned null and there isn't a set method.");
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL,
+ "java/lang/RuntimeException",
+ "<init>", "(Ljava/lang/String;)V", false);
+ mv.visitInsn(opCodes.ATHROW);
+ } else {
+ mv.visitVarInsn(opCodes.ALOAD, 2);
+ mv.visitVarInsn(opCodes.ALOAD, 4);
+ mv.visitTypeInsn(opCodes.CHECKCAST,
+ getMethods[x].getReturnType().getName().replace('.', '/'));
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+ StringUtils.periodToSlashes(wrapperType.getName()),
+ setMethods[x].getName(),
+ asmhelper.getMethodSignature(setMethods[x]), false);
+ }
+ ASMHelper.Label jumpOverLabel = asmhelper.createLabel();
+ mv.visitJumpInsn(opCodes.GOTO, jumpOverLabel);
+ mv.visitLabel(nonNullLabel);
+ mv.visitLineNumber(106, nonNullLabel);
+
+ mv.visitVarInsn(opCodes.ALOAD, 4);
+ mv.visitJumpInsn(opCodes.IFNULL, jumpOverLabel);
+ mv.visitVarInsn(opCodes.ALOAD, 3);
+ mv.visitVarInsn(opCodes.ALOAD, 4);
+ mv.visitMethodInsn(opCodes.INVOKEINTERFACE,
+ "java/util/List", "addAll", "(Ljava/util/Collection;)Z", true);
+ mv.visitInsn(opCodes.POP);
+ mv.visitLabel(jumpOverLabel);
+ mv.visitLineNumber(107, jumpOverLabel);
+ }
+
+ private boolean addGetWrapperParts(String newClassName, Class<?> wrapperClass, Method[] getMethods, Field[] fields,
+ ASMHelper asmhelper, ASMHelper.ClassWriter cw) {
+ OpcodesProxy opCodes = asmhelper.getOpCodes();
+ ASMHelper.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();
+ ASMHelper.Label lBegin = asmhelper.createLabel();
+ mv.visitLabel(lBegin);
+ mv.visitLineNumber(108, lBegin);
+
+ // the ret List
+ mv.visitTypeInsn(opCodes.NEW, "java/util/ArrayList");
+ mv.visitInsn(opCodes.DUP);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false);
+ mv.visitVarInsn(opCodes.ASTORE, 2);
+
+ // cast the Object to the wrapperType type
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitTypeInsn(opCodes.CHECKCAST, StringUtils.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) {
+ ASMHelper.Label l3 = asmhelper.createLabel();
+ mv.visitLabel(l3);
+ mv.visitLineNumber(200 + x, l3);
+
+ mv.visitVarInsn(opCodes.ALOAD, 2);
+ mv.visitInsn(opCodes.ACONST_NULL);
+ mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "java/util/List",
+ "add", "(Ljava/lang/Object;)Z", true);
+ mv.visitInsn(opCodes.POP);
+ } else {
+ ASMHelper.Label l3 = asmhelper.createLabel();
+ mv.visitLabel(l3);
+ mv.visitLineNumber(250 + x, l3);
+
+ mv.visitVarInsn(opCodes.ALOAD, 2);
+ mv.visitVarInsn(opCodes.ALOAD, 3);
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+ StringUtils.periodToSlashes(wrapperClass.getName()),
+ method.getName(),
+ asmhelper.getMethodSignature(method), false);
+ if (method.getReturnType().isPrimitive()) {
+ // wrap into Object type
+ createObjectWrapper(mv, method.getReturnType(), asmhelper);
+ }
+ if (JAXBElement.class.isAssignableFrom(method.getReturnType())) {
+ ASMHelper.Label jumpOverLabel = asmhelper.createLabel();
+ mv.visitInsn(opCodes.DUP);
+ mv.visitJumpInsn(opCodes.IFNULL, jumpOverLabel);
+
+ mv.visitMethodInsn(opCodes.INVOKEVIRTUAL,
+ "javax/xml/bind/JAXBElement",
+ "getValue", "()Ljava/lang/Object;", false);
+ mv.visitLabel(jumpOverLabel);
+ }
+
+ mv.visitMethodInsn(opCodes.INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
+ mv.visitInsn(opCodes.POP);
+ }
+ }
+
+ // return the list
+ ASMHelper.Label l2 = asmhelper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(108, l2);
+ mv.visitVarInsn(opCodes.ALOAD, 2);
+ mv.visitInsn(opCodes.ARETURN);
+
+
+ ASMHelper.Label lEnd = asmhelper.createLabel();
+ 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" + StringUtils.periodToSlashes(wrapperClass.getName()) + ";",
+ null, lBegin, lEnd, 3);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ return true;
+ }
+
+
+
+
+ private void createObjectWrapper(ASMHelper.MethodVisitor mv, Class<?> cl, ASMHelper asmhelper) {
+ OpcodesProxy opCodes = asmhelper.getOpCodes();
+ mv.visitMethodInsn(opCodes.INVOKESTATIC, asmhelper.getNonPrimitive(cl),
+ "valueOf", "(" + asmhelper.getPrimitive(cl) + ")L"
+ + asmhelper.getNonPrimitive(cl) + ";", false);
+ }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassLoader.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassLoader.java
new file mode 100644
index 0000000..ab8a585
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperClassLoader.java
@@ -0,0 +1,64 @@
+/**
+ * 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.jaxb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+import org.apache.cxf.databinding.WrapperHelper;
+
+/** If class has been generated during build time
+ * (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ * you can set class loader to avoid class generation during runtime:
+ * bus.setExtension(new WrapperHelperClassLoader(bus), WrapperHelperCreator.class);
+ * @author olivier dufour
+ */
+public class WrapperHelperClassLoader extends GeneratedClassClassLoader implements WrapperHelperCreator {
+ public WrapperHelperClassLoader(Bus bus) {
+ super(bus);
+ }
+
+ @Override
+ public WrapperHelper compile(Class<?> wrapperType, Method[] setMethods, Method[] getMethods,
+ Method[] jaxbMethods, Field[] fields, Object objectFactory) {
+
+ int count = 1;
+ String newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
+
+ Class<?> cls = findClass(newClassName, wrapperType);
+ while (cls != null) {
+ try {
+ WrapperHelper helper = WrapperHelper.class.cast(cls.getDeclaredConstructor().newInstance());
+ if (!helper.getSignature().equals(
+ WrapperHelperClassGenerator.computeSignature(setMethods, getMethods))) {
+ count++;
+ newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
+ cls = findClass(newClassName, wrapperType);
+ } else {
+ return helper;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ return null;
+ }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCompiler.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCompiler.java
deleted file mode 100644
index 540e0b4..0000000
--- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCompiler.java
+++ /dev/null
@@ -1,475 +0,0 @@
-/**
- * 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.jaxb;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.List;
-
-import javax.xml.bind.JAXBElement;
-
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.databinding.WrapperHelper;
-
-final class WrapperHelperCompiler extends ASMHelper {
-
-
- final Class<?> wrapperType;
- final Method[] setMethods;
- final Method[] getMethods;
- final Method[] jaxbMethods;
- final Field[] fields;
- final Object objectFactory;
- final ClassWriter cw;
-
- private WrapperHelperCompiler(Class<?> wrapperType,
- Method[] setMethods,
- Method[] getMethods,
- Method[] jaxbMethods,
- Field[] fields,
- Object objectFactory) {
- this.wrapperType = wrapperType;
- this.setMethods = setMethods;
- this.getMethods = getMethods;
- this.jaxbMethods = jaxbMethods;
- this.fields = fields;
- this.objectFactory = objectFactory;
- cw = createClassWriter();
- }
-
- static WrapperHelper compileWrapperHelper(Class<?> wrapperType,
- Method[] setMethods,
- Method[] getMethods,
- Method[] jaxbMethods,
- Field[] fields,
- Object objectFactory) {
- try {
- return new WrapperHelperCompiler(wrapperType,
- setMethods,
- getMethods,
- jaxbMethods,
- fields,
- objectFactory).compile();
-
- } catch (Throwable t) {
- // Some error - probably a bad version of ASM or similar
- }
- return null;
- }
-
-
-
-
-
- public WrapperHelper compile() {
- if (cw == null) {
- return null;
- }
- int count = 1;
- String newClassName = wrapperType.getName() + "_WrapperTypeHelper" + count;
- newClassName = newClassName.replaceAll("\\$", ".");
- newClassName = periodToSlashes(newClassName);
-
- Class<?> cls = super.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 = super.findClass(newClassName.replace('/', '.'), wrapperType);
- } else {
- return helper;
- }
- } catch (Exception e) {
- return null;
- }
- }
-
-
-
- cw.visit(Opcodes.V1_5,
- Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER,
- newClassName,
- null,
- "java/lang/Object",
- new String[] {periodToSlashes(WrapperHelper.class.getName())});
-
- addConstructor(newClassName, objectFactory == null ? null : objectFactory.getClass());
- boolean b = addSignature();
- if (b) {
- b = addCreateWrapperObject(newClassName,
- objectFactory == null ? null : objectFactory.getClass());
- }
- if (b) {
- b = addGetWrapperParts(newClassName, wrapperType);
- }
-
- try {
- if (b) {
- cw.visitEnd();
- byte[] bt = cw.toByteArray();
- Class<?> cl = loadClass(newClassName.replace('/', '.'), wrapperType, bt);
- Object o = cl.newInstance();
- return WrapperHelper.class.cast(o);
- }
- } catch (Throwable e) {
- // ignore, we'll just fall down to reflection based
- }
- return null;
- }
-
- 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(',');
- }
- }
- return b.toString();
- }
-
- private boolean addSignature() {
- String sig = computeSignature();
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
- "getSignature", "()Ljava/lang/String;", null, null);
- mv.visitCode();
- mv.visitLdcInsn(sig);
- Label l0 = createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(100, l0);
- mv.visitInsn(Opcodes.ARETURN);
- mv.visitMaxs(0, 0);
- mv.visitEnd();
- return true;
- }
-
- private void addConstructor(String newClassName,
- Class<?> objectFactoryCls) {
-
- if (objectFactoryCls != null) {
- String ofName = "L" + periodToSlashes(objectFactoryCls.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 = createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(102, l0);
-
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
- "java/lang/Object",
- "<init>",
- "()V", false);
- if (objectFactoryCls != null) {
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitTypeInsn(Opcodes.NEW, periodToSlashes(objectFactoryCls.getName()));
- mv.visitInsn(Opcodes.DUP);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
- periodToSlashes(objectFactoryCls.getName()),
- "<init>", "()V", false);
- mv.visitFieldInsn(Opcodes.PUTFIELD, periodToSlashes(newClassName),
- "factory", "L" + periodToSlashes(objectFactoryCls.getName()) + ";");
- }
-
- mv.visitInsn(Opcodes.RETURN);
-
- Label l1 = createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(103, l0);
-
- mv.visitLocalVariable("this", "L" + newClassName + ";", null, l0, l1, 0);
- mv.visitMaxs(0, 0);
- mv.visitEnd();
- }
-
- private boolean addCreateWrapperObject(String newClassName,
- Class<?> objectFactoryClass) {
-
- 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 = createLabel();
- mv.visitLabel(lBegin);
- mv.visitLineNumber(104, lBegin);
-
- mv.visitTypeInsn(Opcodes.NEW, periodToSlashes(wrapperType.getName()));
- mv.visitInsn(Opcodes.DUP);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, periodToSlashes(wrapperType.getName()),
- "<init>", "()V", false);
- mv.visitVarInsn(Opcodes.ASTORE, 2);
-
- for (int x = 0; x < setMethods.length; x++) {
- if (getMethods[x] == null) {
- if (setMethods[x] == null
- && fields[x] == null) {
- // null placeholder
- continue;
- }
- return false;
- }
- Class<?> tp = getMethods[x].getReturnType();
- mv.visitVarInsn(Opcodes.ALOAD, 2);
-
- if (List.class.isAssignableFrom(tp)) {
- doCollection(mv, x);
- } else {
- if (JAXBElement.class.isAssignableFrom(tp)) {
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, periodToSlashes(newClassName),
- "factory",
- "L" + periodToSlashes(objectFactoryClass.getName()) + ";");
- }
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitIntInsn(Opcodes.SIPUSH, x);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true);
-
- if (tp.isPrimitive()) {
- mv.visitTypeInsn(Opcodes.CHECKCAST, NONPRIMITIVE_MAP.get(tp));
- Label l45 = createLabel();
- Label l46 = createLabel();
- mv.visitInsn(Opcodes.DUP);
- mv.visitJumpInsn(Opcodes.IFNULL, l45);
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, NONPRIMITIVE_MAP.get(tp),
- tp.getName() + "Value", "()" + PRIMITIVE_MAP.get(tp), false);
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
- periodToSlashes(wrapperType.getName()),
- setMethods[x].getName(), "(" + getClassCode(tp) + ")V", false);
- mv.visitJumpInsn(Opcodes.GOTO, l46);
- mv.visitLabel(l45);
- mv.visitInsn(Opcodes.POP);
- mv.visitLabel(l46);
- } else if (JAXBElement.class.isAssignableFrom(tp)) {
- mv.visitTypeInsn(Opcodes.CHECKCAST,
- periodToSlashes(jaxbMethods[x].getParameterTypes()[0].getName()));
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, periodToSlashes(objectFactoryClass.getName()),
- jaxbMethods[x].getName(),
- getMethodSignature(jaxbMethods[x]), false);
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
- periodToSlashes(wrapperType.getName()),
- setMethods[x].getName(), "(" + getClassCode(tp) + ")V", false);
- } else if (tp.isArray()) {
- mv.visitTypeInsn(Opcodes.CHECKCAST, getClassCode(tp));
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
- periodToSlashes(wrapperType.getName()),
- setMethods[x].getName(), "(" + getClassCode(tp) + ")V", false);
- } else {
- mv.visitTypeInsn(Opcodes.CHECKCAST, periodToSlashes(tp.getName()));
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
- periodToSlashes(wrapperType.getName()),
- setMethods[x].getName(), "(" + getClassCode(tp) + ")V", false);
- }
- }
- }
-
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitInsn(Opcodes.ARETURN);
-
- Label lEnd = createLabel();
- 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(wrapperType.getName()) + ";",
- null, lBegin, lEnd, 2);
- mv.visitMaxs(0, 0);
- mv.visitEnd();
- return true;
- }
-
- private void doCollection(MethodVisitor mv, int x) {
- // List aVal = obj.getA();
- // List newA = (List)lst.get(99);
- // if (aVal == null) {
- // obj.setA(newA);
- // } else if (newA != null) {
- // aVal.addAll(newA);
- // }
-
- Label l3 = createLabel();
- mv.visitLabel(l3);
- mv.visitLineNumber(114, l3);
-
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
- periodToSlashes(wrapperType.getName()),
- getMethods[x].getName(),
- getMethodSignature(getMethods[x]), false);
- mv.visitVarInsn(Opcodes.ASTORE, 3);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitIntInsn(Opcodes.SIPUSH, x);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
- "get", "(I)Ljava/lang/Object;", true);
- mv.visitTypeInsn(Opcodes.CHECKCAST, "java/util/List");
- mv.visitVarInsn(Opcodes.ASTORE, 4);
- mv.visitVarInsn(Opcodes.ALOAD, 3);
- Label nonNullLabel = createLabel();
- mv.visitJumpInsn(Opcodes.IFNONNULL, nonNullLabel);
-
- if (setMethods[x] == null) {
- mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
- mv.visitInsn(Opcodes.DUP);
- mv.visitLdcInsn(getMethods[x].getName() + " returned null and there isn't a set method.");
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
- "java/lang/RuntimeException",
- "<init>", "(Ljava/lang/String;)V", false);
- mv.visitInsn(Opcodes.ATHROW);
- } 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(),
- getMethodSignature(setMethods[x]), false);
- }
- Label jumpOverLabel = createLabel();
- mv.visitJumpInsn(Opcodes.GOTO, jumpOverLabel);
- mv.visitLabel(nonNullLabel);
- mv.visitLineNumber(106, nonNullLabel);
-
- mv.visitVarInsn(Opcodes.ALOAD, 4);
- mv.visitJumpInsn(Opcodes.IFNULL, jumpOverLabel);
- mv.visitVarInsn(Opcodes.ALOAD, 3);
- mv.visitVarInsn(Opcodes.ALOAD, 4);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE,
- "java/util/List", "addAll", "(Ljava/util/Collection;)Z", true);
- mv.visitInsn(Opcodes.POP);
- mv.visitLabel(jumpOverLabel);
- mv.visitLineNumber(107, jumpOverLabel);
- }
-
- private boolean addGetWrapperParts(String newClassName,
- Class<?> wrapperClass) {
- 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 = createLabel();
- mv.visitLabel(lBegin);
- mv.visitLineNumber(108, lBegin);
-
- // the ret List
- mv.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
- mv.visitInsn(Opcodes.DUP);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false);
- 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) {
- Label l3 = createLabel();
- mv.visitLabel(l3);
- mv.visitLineNumber(200 + x, l3);
-
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitInsn(Opcodes.ACONST_NULL);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List",
- "add", "(Ljava/lang/Object;)Z", true);
- mv.visitInsn(Opcodes.POP);
- } else {
- Label l3 = createLabel();
- mv.visitLabel(l3);
- mv.visitLineNumber(250 + x, l3);
-
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitVarInsn(Opcodes.ALOAD, 3);
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
- periodToSlashes(wrapperClass.getName()),
- method.getName(),
- getMethodSignature(method), false);
- if (method.getReturnType().isPrimitive()) {
- // wrap into Object type
- createObjectWrapper(mv, method.getReturnType());
- }
- if (JAXBElement.class.isAssignableFrom(method.getReturnType())) {
- Label jumpOverLabel = createLabel();
- mv.visitInsn(Opcodes.DUP);
- mv.visitJumpInsn(Opcodes.IFNULL, jumpOverLabel);
-
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
- "javax/xml/bind/JAXBElement",
- "getValue", "()Ljava/lang/Object;", false);
- mv.visitLabel(jumpOverLabel);
- }
-
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
- mv.visitInsn(Opcodes.POP);
- }
- }
-
- // return the list
- Label l2 = createLabel();
- mv.visitLabel(l2);
- mv.visitLineNumber(108, l2);
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitInsn(Opcodes.ARETURN);
-
-
- Label lEnd = createLabel();
- 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 void createObjectWrapper(MethodVisitor mv, Class<?> cl) {
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, NONPRIMITIVE_MAP.get(cl),
- "valueOf", "(" + PRIMITIVE_MAP.get(cl) + ")L"
- + NONPRIMITIVE_MAP.get(cl) + ";", false);
- }
-}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCreator.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCreator.java
new file mode 100644
index 0000000..188bf04
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperCreator.java
@@ -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.jaxb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.cxf.databinding.WrapperHelper;
+
+public interface WrapperHelperCreator {
+ WrapperHelper compile(Class<?> wrapperType, Method[] setMethods,
+ Method[] getMethods, Method[] jaxbMethods,
+ Field[] fields, Object objectFactory);
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperProxyService.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperProxyService.java
new file mode 100644
index 0000000..5205264
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/WrapperHelperProxyService.java
@@ -0,0 +1,53 @@
+/**
+ * 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.jaxb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.databinding.WrapperHelper;
+
+public class WrapperHelperProxyService implements WrapperHelperCreator {
+ private final WrapperHelperCreator srv;
+ public WrapperHelperProxyService(Bus bus) {
+ this(new WrapperHelperClassGenerator(bus));
+ }
+ public WrapperHelperProxyService(WrapperHelperCreator srv) {
+ super();
+ this.srv = srv;
+ }
+
+ @Override
+ public WrapperHelper compile(Class<?> wrapperType, Method[] setMethods, Method[] getMethods,
+ Method[] jaxbMethods, Field[] fields, Object objectFactory) {
+ return srv.compile(wrapperType, setMethods, getMethods, jaxbMethods, fields, objectFactory);
+ }
+
+ public class LoadFirst extends WrapperHelperProxyService {
+ public LoadFirst(Bus bus) {
+ super(new WrapperHelperClassLoader(bus));
+ }
+ }
+ public class GenerateJustInTime extends WrapperHelperProxyService {
+ public GenerateJustInTime(Bus bus) {
+ super(new WrapperHelperClassGenerator(bus));
+ }
+ }
+}
diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java
index 3186c78..0db8a6e 100644
--- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java
+++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/io/DataWriterImpl.java
@@ -39,6 +39,7 @@ import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.attachment.AttachmentMarshaller;
+import org.apache.cxf.Bus;
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.jaxb.JAXBUtils;
import org.apache.cxf.common.logging.LogUtils;
@@ -61,14 +62,16 @@ public class DataWriterImpl<T> extends JAXBDataBase implements DataWriter<T> {
boolean setEventHandler = true;
boolean noEscape;
private JAXBDataBinding databinding;
+ private Bus bus;
- public DataWriterImpl(JAXBDataBinding binding) {
- this(binding, false);
+ public DataWriterImpl(Bus bus, JAXBDataBinding binding) {
+ this(bus, binding, false);
}
- public DataWriterImpl(JAXBDataBinding binding, boolean noEsc) {
+ public DataWriterImpl(Bus bus, JAXBDataBinding binding, boolean noEsc) {
super(binding.getContext());
databinding = binding;
noEscape = noEsc;
+ this.bus = bus;
}
public void write(Object obj, T output) {
@@ -154,7 +157,7 @@ public class DataWriterImpl<T> extends JAXBDataBase implements DataWriter<T> {
final Map<String, String> nsctxt = databinding.getContextualNamespaceMap();
// set the prefix mapper if either of the prefix map is configured
if (nspref != null || nsctxt != null) {
- Object mapper = JAXBUtils.setNamespaceMapper(nspref != null ? nspref : nsctxt, marshaller);
+ Object mapper = JAXBUtils.setNamespaceMapper(bus, nspref != null ? nspref : nsctxt, marshaller);
if (nsctxt != null) {
setContextualNamespaceDecls(mapper, nsctxt);
}
diff --git a/rt/databinding/jaxb/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/databinding/jaxb/src/main/resources/META-INF/cxf/bus-extensions.txt
new file mode 100644
index 0000000..a1d4c21
--- /dev/null
+++ b/rt/databinding/jaxb/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -0,0 +1,2 @@
+org.apache.cxf.jaxb.WrapperHelperProxyService:org.apache.cxf.jaxb.WrapperHelperCreator:true
+org.apache.cxf.jaxb.FactoryClassProxyService:org.apache.cxf.jaxb.FactoryClassCreator:true
\ No newline at end of file
diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java
index 22a49a8..2ed593f 100644
--- a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java
+++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java
@@ -54,8 +54,10 @@ import org.w3c.dom.Node;
import org.apache.cxf.Bus;
import org.apache.cxf.binding.BindingFactoryManager;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.ASMHelperImpl;
import org.apache.cxf.common.util.ReflectionUtil;
import org.apache.cxf.databinding.DataReader;
import org.apache.cxf.databinding.DataWriter;
@@ -247,10 +249,15 @@ public class JAXBDataBindingTest {
return;
}
}
+ Bus b = new ExtensionManagerBus();
+ ASMHelper helper = new ASMHelperImpl();
+ b.setExtension(helper, ASMHelper.class);
+ FactoryClassCreator extr = new FactoryClassProxyService(b);
+ b.setExtension(extr, FactoryClassCreator.class);
try {
if (!asm) {
- ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelper.class, "badASM"))
- .set(null, Boolean.TRUE);
+ ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelperImpl.class, "badASM"))
+ .set(helper, Boolean.TRUE);
}
JAXBDataBinding db = createJaxbContext(internal);
@@ -267,8 +274,8 @@ public class JAXBDataBindingTest {
assertTrue("Failed to map namespace " + xml, xml.contains("greenland=\"uri:ultima:thule"));
} finally {
if (!asm) {
- ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelper.class, "badASM"))
- .set(null, Boolean.FALSE);
+ ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelperImpl.class, "badASM"))
+ .set(helper, Boolean.FALSE);
}
}
}
@@ -300,7 +307,11 @@ public class JAXBDataBindingTest {
Set<Class<?>> classes = new HashSet<>();
Collection<Object> typeReferences = new ArrayList<>();
Map<String, Object> props = new HashMap<>();
- JAXBContextInitializer init = new JAXBContextInitializer(null, classes, typeReferences, props);
+ Bus b = new ExtensionManagerBus();
+ b.setExtension(new ASMHelperImpl(), ASMHelper.class);
+ FactoryClassCreator extr = new FactoryClassProxyService(b);
+ b.setExtension(extr, FactoryClassCreator.class);
+ JAXBContextInitializer init = new JAXBContextInitializer(b, null, classes, typeReferences, props);
init.addClass(Type2.class);
assertEquals(2, classes.size());
}
@@ -344,7 +355,11 @@ public class JAXBDataBindingTest {
Set<Class<?>> classes = new HashSet<>();
Collection<Object> typeReferences = new ArrayList<>();
Map<String, Object> props = new HashMap<>();
- JAXBContextInitializer init = new JAXBContextInitializer(null, classes, typeReferences, props);
+ Bus b = new ExtensionManagerBus();
+ b.setExtension(new ASMHelperImpl(), ASMHelper.class);
+ FactoryClassCreator extr = new FactoryClassProxyService(b);
+ b.setExtension(extr, FactoryClassCreator.class);
+ JAXBContextInitializer init = new JAXBContextInitializer(b, null, classes, typeReferences, props);
init.addClass(sampleClassInDefaultPackage);
assertEquals(1, classes.size());
}
diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBEncoderDecoderTest.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBEncoderDecoderTest.java
index 98e8d21..e19f798 100644
--- a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBEncoderDecoderTest.java
+++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBEncoderDecoderTest.java
@@ -50,6 +50,8 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
import org.apache.cxf.common.jaxb.JAXBUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
@@ -251,7 +253,8 @@ public class JAXBEncoderDecoderTest {
opFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
XMLEventWriter writer = opFactory.createXMLEventWriter(stringWriter);
Marshaller m = context.createMarshaller();
- JAXBUtils.setNamespaceMapper(mapper, m);
+ Bus bus = new ExtensionManagerBus();
+ JAXBUtils.setNamespaceMapper(bus, mapper, m);
JAXBEncoderDecoder.marshall(m, testObject, part, writer);
writer.flush();
writer.close();
diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java
index 819ae32..78256f9 100644
--- a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java
+++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBUtilsTest.java
@@ -27,6 +27,8 @@ import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
import org.apache.cxf.common.jaxb.JAXBUtils;
import org.apache.cxf.common.util.ReflectionUtil;
import org.apache.hello_world_soap_http.types.GreetMe;
@@ -172,7 +174,8 @@ public class JAXBUtilsTest {
Marshaller marshaller = ctx.createMarshaller();
Map<String, String> nspref = new HashMap<>();
nspref.put("http://cxf.apache.org/hello_world_soap_http/types", "x");
- JAXBUtils.setNamespaceMapper(nspref, marshaller);
+ Bus bus = new ExtensionManagerBus();
+ JAXBUtils.setNamespaceMapper(bus, nspref, marshaller);
String mapperkey = null;
if (marshaller.getClass().getName().contains(".internal.")) {
mapperkey = "com.sun.xml.internal.bind.namespacePrefixMapper";
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
index a9500e5..ff5353d 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
@@ -166,7 +166,7 @@ public abstract class AbstractJAXBProvider<T> extends AbstractConfigurableProvid
protected void setNamespaceMapper(Marshaller ms,
Map<String, String> map) throws Exception {
- Object nsMapper = JAXBUtils.setNamespaceMapper(map, ms);
+ Object nsMapper = JAXBUtils.setNamespaceMapper(getBus(), map, ms);
if (nsMapper != null && namespaceMapperPropertyName != null) {
setMarshallerProp(ms, nsMapper, namespaceMapperPropertyName, null);
}
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
index bcd851e..d4b2ad2 100644
--- a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/WrapperClassGenerator.java
@@ -19,7 +19,6 @@
package org.apache.cxf.jaxws;
-
import java.lang.annotation.Annotation;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
@@ -42,12 +41,16 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
import javax.xml.namespace.QName;
import javax.xml.ws.Holder;
+import org.apache.cxf.Bus;
import org.apache.cxf.common.jaxb.JAXBUtils;
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
import org.apache.cxf.common.util.PackageUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.JavaUtils;
+import org.apache.cxf.jaxws.spi.WrapperClassCreator;
import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
import org.apache.cxf.service.model.InterfaceInfo;
import org.apache.cxf.service.model.MessageInfo;
@@ -56,19 +59,15 @@ import org.apache.cxf.service.model.OperationInfo;
import org.apache.cxf.service.model.SchemaInfo;
import org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean;
-public final class WrapperClassGenerator extends ASMHelper {
+public final class WrapperClassGenerator extends ClassGeneratorClassLoader implements WrapperClassCreator {
public static final String DEFAULT_PACKAGE_NAME = "defaultnamespace";
private static final Logger LOG = LogUtils.getL7dLogger(WrapperClassGenerator.class);
- private Set<Class<?>> wrapperBeans = new LinkedHashSet<>();
- private InterfaceInfo interfaceInfo;
- private boolean qualified;
- private JaxWsServiceFactoryBean factory;
-
- public WrapperClassGenerator(JaxWsServiceFactoryBean fact, InterfaceInfo inf, boolean q) {
- factory = fact;
- interfaceInfo = inf;
- qualified = q;
+ private final ASMHelper helper;
+
+ public WrapperClassGenerator(Bus bus) {
+ super(bus);
+ helper = bus.getExtension(ASMHelper.class);
}
private String getPackageName(Method method) {
@@ -109,7 +108,8 @@ public final class WrapperClassGenerator extends ASMHelper {
return list;
}
- public Set<Class<?>> generate() {
+ public Set<Class<?>> generate(JaxWsServiceFactoryBean factory, InterfaceInfo interfaceInfo, boolean qualified) {
+ Set<Class<?>> wrapperBeans = new LinkedHashSet<>();
for (OperationInfo opInfo : interfaceInfo.getOperations()) {
if (opInfo.isUnwrappedCapable()) {
Method method = (Method)opInfo.getProperty(ReflectionServiceFactoryBean.METHOD);
@@ -123,7 +123,11 @@ public final class WrapperClassGenerator extends ASMHelper {
messageInfo,
opInfo,
method,
- true);
+ true,
+ wrapperBeans,
+ factory,
+ interfaceInfo,
+ qualified);
}
MessageInfo messageInfo = opInfo.getUnwrappedOperation().getOutput();
if (messageInfo != null) {
@@ -133,22 +137,30 @@ public final class WrapperClassGenerator extends ASMHelper {
messageInfo,
opInfo,
method,
- false);
+ false,
+ wrapperBeans,
+ factory,
+ interfaceInfo,
+ qualified);
}
}
}
}
return wrapperBeans;
}
-
+ //CHECKSTYLE:OFF
private void createWrapperClass(MessagePartInfo wrapperPart,
MessageInfo messageInfo,
OperationInfo op,
Method method,
- boolean isRequest) {
+ boolean isRequest,
+ Set<Class<?>> wrapperBeans,
+ JaxWsServiceFactoryBean factory,
+ InterfaceInfo interfaceInfo,
+ boolean qualified) {
- ClassWriter cw = createClassWriter();
+ ASMHelper.ClassWriter cw = helper.createClassWriter();
if (cw == null) {
LOG.warning(op.getName() + " requires a wrapper bean but problems with"
+ " ASM has prevented creating one. Operation may not work correctly.");
@@ -166,8 +178,8 @@ public final class WrapperClassGenerator extends ASMHelper {
String pname = pkg + ".package-info";
Class<?> def = findClass(pname, method.getDeclaringClass());
if (def == null) {
- generatePackageInfo(pname, wrapperElement.getNamespaceURI(),
- method.getDeclaringClass());
+ generatePackageInfo(pname, wrapperElement.getNamespaceURI(), method.getDeclaringClass(), method,
+ interfaceInfo, qualified);
}
def = findClass(className, method.getDeclaringClass());
@@ -184,11 +196,12 @@ public final class WrapperClassGenerator extends ASMHelper {
return;
}
}
- String classFileName = periodToSlashes(className);
- cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, classFileName, null,
+ String classFileName = StringUtils.periodToSlashes(className);
+ OpcodesProxy opCodes = helper.getOpCodes();
+ 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);
+ ASMHelper.AnnotationVisitor av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlRootElement;", true);
av0.visit("name", wrapperElement.getLocalPart());
av0.visit("namespace", wrapperElement.getNamespaceURI());
av0.visitEnd();
@@ -207,21 +220,21 @@ public final class WrapperClassGenerator extends ASMHelper {
av0.visitEnd();
// add constructor
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
- Label lbegin = createLabel();
+ ASMHelper.Label lbegin = helper.createLabel();
mv.visitLabel(lbegin);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
- mv.visitInsn(Opcodes.RETURN);
- Label lend = createLabel();
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ mv.visitInsn(opCodes.RETURN);
+ ASMHelper.Label lend = helper.createLabel();
mv.visitLabel(lend);
mv.visitLocalVariable("this", "L" + classFileName + ";", null, lbegin, lend, 0);
- mv.visitMaxs(1, 1);
+ mv.visitMaxs(0, 0);
mv.visitEnd();
for (MessagePartInfo mpi : messageInfo.getMessageParts()) {
- generateMessagePart(cw, mpi, method, classFileName);
+ generateMessagePart(cw, mpi, method, classFileName, factory);
}
cw.visitEnd();
@@ -230,11 +243,13 @@ public final class WrapperClassGenerator extends ASMHelper {
wrapperPart.setTypeClass(clz);
wrapperBeans.add(clz);
}
-
- private void generatePackageInfo(String className, String ns, Class<?> clz) {
- ClassWriter cw = createClassWriter();
- String classFileName = periodToSlashes(className);
- cw.visit(Opcodes.V1_5, Opcodes.ACC_ABSTRACT + Opcodes.ACC_INTERFACE, classFileName, null,
+ //CHECKSTYLE:ON
+ private void generatePackageInfo(String className, String ns, Class<?> clz, Method method,
+ InterfaceInfo interfaceInfo, boolean qualified) {
+ ASMHelper.ClassWriter cw = helper.createClassWriter();
+ String classFileName = StringUtils.periodToSlashes(className);
+ OpcodesProxy opCodes = helper.getOpCodes();
+ cw.visit(opCodes.V1_5, opCodes.ACC_ABSTRACT + opCodes.ACC_INTERFACE, classFileName, null,
"java/lang/Object", null);
boolean q = qualified;
@@ -242,10 +257,10 @@ public final class WrapperClassGenerator extends ASMHelper {
if (si != null) {
q = si.isElementFormQualified();
}
- AnnotationVisitor av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlSchema;", true);
+ ASMHelper.AnnotationVisitor av0 = cw.visitAnnotation("Ljavax/xml/bind/annotation/XmlSchema;", true);
av0.visit("namespace", ns);
av0.visitEnum("elementFormDefault",
- getClassCode(XmlNsForm.class),
+ helper.getClassCode(XmlNsForm.class),
q ? "QUALIFIED" : "UNQUALIFIED");
av0.visitEnd();
@@ -264,35 +279,36 @@ public final class WrapperClassGenerator extends ASMHelper {
}
cw.visitEnd();
- loadClass(className, clz, cw.toByteArray());
+ loadClass(className, method.getDeclaringClass(), cw.toByteArray());
}
- private void generateXmlJavaTypeAdapters(AnnotationVisitor av, XmlJavaTypeAdapters adapters) {
- AnnotationVisitor av1 = av.visitArray("value");
+ private void generateXmlJavaTypeAdapters(ASMHelper.AnnotationVisitor av, XmlJavaTypeAdapters adapters) {
+ ASMHelper.AnnotationVisitor av1 = av.visitArray("value");
for (XmlJavaTypeAdapter adapter : adapters.value()) {
- AnnotationVisitor av2
+ ASMHelper.AnnotationVisitor av2
= av1.visitAnnotation(null, "Ljavax/xml/bind/annotation/adapters/XmlJavaTypeAdapter;");
generateXmlJavaTypeAdapter(av2, adapter);
av2.visitEnd();
}
av1.visitEnd();
}
- private void generateXmlJavaTypeAdapter(AnnotationVisitor av, XmlJavaTypeAdapter adapter) {
+ private void generateXmlJavaTypeAdapter(ASMHelper.AnnotationVisitor av, XmlJavaTypeAdapter adapter) {
if (adapter.value() != null) {
- av.visit("value", getType(getClassCode(adapter.value())));
+ av.visit("value", helper.getType(helper.getClassCode(adapter.value())));
}
if (adapter.type() != javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT.class) {
- av.visit("type", getType(getClassCode(adapter.type())));
+ av.visit("type", helper.getType(helper.getClassCode(adapter.type())));
}
}
- private void generateMessagePart(ClassWriter cw, MessagePartInfo mpi,
- Method method, String className) {
+ private void generateMessagePart(ASMHelper.ClassWriter cw, MessagePartInfo mpi,
+ Method method, String className, JaxWsServiceFactoryBean factory) {
if (Boolean.TRUE.equals(mpi.getProperty(ReflectionServiceFactoryBean.HEADER))) {
return;
}
- String classFileName = periodToSlashes(className);
+ OpcodesProxy opCodes = helper.getOpCodes();
+ String classFileName = StringUtils.periodToSlashes(className);
String name = mpi.getName().getLocalPart();
Class<?> clz = mpi.getTypeClass();
Object obj = mpi.getProperty(ReflectionServiceFactoryBean.RAW_CLASS);
@@ -307,7 +323,7 @@ public final class WrapperClassGenerator extends ASMHelper {
genericType = tp.getActualTypeArguments()[0];
}
}
- String classCode = getClassCode(clz);
+ String classCode = helper.getClassCode(clz);
String fieldDescriptor = null;
if (genericType instanceof ParameterizedType) {
@@ -317,24 +333,24 @@ public final class WrapperClassGenerator extends ASMHelper {
java.lang.reflect.Type[] types = ptype.getActualTypeArguments();
if (types.length > 0) {
if (types[0] instanceof Class) {
- fieldDescriptor = getClassCode(genericType);
+ fieldDescriptor = helper.getClassCode(genericType);
} else if (types[0] instanceof GenericArrayType) {
- fieldDescriptor = getClassCode(genericType);
+ fieldDescriptor = helper.getClassCode(genericType);
} else if (Collection.class.isAssignableFrom(clz)) {
- fieldDescriptor = getClassCode(genericType);
+ fieldDescriptor = helper.getClassCode(genericType);
} else if (types[0] instanceof ParameterizedType) {
- classCode = getClassCode(((ParameterizedType)types[0]).getRawType());
- fieldDescriptor = getClassCode(genericType);
+ classCode = helper.getClassCode(((ParameterizedType)types[0]).getRawType());
+ fieldDescriptor = helper.getClassCode(genericType);
}
}
} else {
- classCode = getClassCode(((ParameterizedType)genericType).getRawType());
- fieldDescriptor = getClassCode(genericType);
+ classCode = helper.getClassCode(((ParameterizedType)genericType).getRawType());
+ fieldDescriptor = helper.getClassCode(genericType);
}
}
String fieldName = JavaUtils.isJavaKeyword(name) ? JavaUtils.makeNonJavaKeyword(name) : name;
- FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE,
+ ASMHelper.FieldVisitor fv = cw.visitField(opCodes.ACC_PRIVATE,
fieldName,
classCode,
fieldDescriptor,
@@ -344,7 +360,7 @@ public final class WrapperClassGenerator extends ASMHelper {
List<Annotation> jaxbAnnos = getJaxbAnnos(mpi);
if (!addJAXBAnnotations(fv, jaxbAnnos, name)) {
- AnnotationVisitor av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlElement;", true);
+ ASMHelper.AnnotationVisitor av0 = fv.visitAnnotation("Ljavax/xml/bind/annotation/XmlElement;", true);
av0.visit("name", name);
if (Boolean.TRUE.equals(factory.isWrapperPartQualified(mpi))) {
av0.visit("namespace", mpi.getConcreteName().getNamespaceURI());
@@ -360,35 +376,35 @@ public final class WrapperClassGenerator extends ASMHelper {
fv.visitEnd();
String methodName = JAXBUtils.nameToIdentifier(name, JAXBUtils.IdentifierType.GETTER);
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, "()" + classCode,
+ ASMHelper.MethodVisitor mv = cw.visitMethod(opCodes.ACC_PUBLIC, methodName, "()" + classCode,
fieldDescriptor == null ? null : "()" + fieldDescriptor,
null);
mv.visitCode();
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, classFileName, fieldName, classCode);
- mv.visitInsn(getType(classCode).getOpcode(Opcodes.IRETURN));
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitFieldInsn(opCodes.GETFIELD, classFileName, fieldName, classCode);
+ mv.visitInsn(helper.getType(classCode).getOpcode(opCodes.IRETURN));
mv.visitMaxs(0, 0);
mv.visitEnd();
methodName = JAXBUtils.nameToIdentifier(name, JAXBUtils.IdentifierType.SETTER);
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, methodName, "(" + classCode + ")V",
+ mv = cw.visitMethod(opCodes.ACC_PUBLIC, methodName, "(" + classCode + ")V",
fieldDescriptor == null ? null : "(" + fieldDescriptor + ")V", null);
mv.visitCode();
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- ASMType setType = getType(classCode);
- mv.visitVarInsn(setType.getOpcode(Opcodes.ILOAD), 1);
- mv.visitFieldInsn(Opcodes.PUTFIELD, className, fieldName, classCode);
- mv.visitInsn(Opcodes.RETURN);
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ ASMHelper.ASMType setType = helper.getType(classCode);
+ mv.visitVarInsn(setType.getOpcode(opCodes.ILOAD), 1);
+ mv.visitFieldInsn(opCodes.PUTFIELD, className, fieldName, classCode);
+ mv.visitInsn(opCodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
- private boolean addJAXBAnnotations(FieldVisitor fv,
+ private boolean addJAXBAnnotations(ASMHelper.FieldVisitor fv,
List<Annotation> jaxbAnnos,
String name) {
- AnnotationVisitor av0;
+ ASMHelper.AnnotationVisitor av0;
boolean addedEl = false;
for (Annotation ann : jaxbAnnos) {
if (ann instanceof XmlMimeType) {
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreator.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreator.java
new file mode 100644
index 0000000..4d3992d
--- /dev/null
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreator.java
@@ -0,0 +1,28 @@
+/**
+ * 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.spi;
+
+import java.util.Set;
+
+import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
+import org.apache.cxf.service.model.InterfaceInfo;
+
+public interface WrapperClassCreator {
+ Set<Class<?>> generate(JaxWsServiceFactoryBean fact, InterfaceInfo inf, boolean q);
+}
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreatorProxyService.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreatorProxyService.java
new file mode 100644
index 0000000..75ea8db
--- /dev/null
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassCreatorProxyService.java
@@ -0,0 +1,53 @@
+/**
+ * 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.spi;
+
+import java.util.Set;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxws.WrapperClassGenerator;
+import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
+import org.apache.cxf.service.model.InterfaceInfo;
+
+public class WrapperClassCreatorProxyService implements WrapperClassCreator {
+ private final WrapperClassCreator srv;
+ public WrapperClassCreatorProxyService(final Bus bus) {
+ this(new WrapperClassGenerator(bus));
+ }
+ public WrapperClassCreatorProxyService(WrapperClassCreator srv) {
+ super();
+ this.srv = srv;
+ }
+
+ @Override
+ public Set<Class<?>> generate(JaxWsServiceFactoryBean fact, InterfaceInfo inf, boolean q) {
+ return srv.generate(fact, inf, q);
+ }
+
+ public class LoadFirst extends WrapperClassCreatorProxyService {
+ public LoadFirst(Bus bus) {
+ super(new WrapperClassLoader(bus));
+ }
+ }
+ public class GenerateJustInTime extends WrapperClassCreatorProxyService {
+ public GenerateJustInTime(final Bus bus) {
+ super(new WrapperClassGenerator(bus));
+ }
+ }
+}
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassLoader.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassLoader.java
new file mode 100644
index 0000000..dfaf195
--- /dev/null
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/spi/WrapperClassLoader.java
@@ -0,0 +1,119 @@
+/**
+ * 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.spi;
+
+import java.lang.reflect.Method;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+import org.apache.cxf.common.util.PackageUtils;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.jaxws.WrapperClassGenerator;
+import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
+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.wsdl.service.factory.ReflectionServiceFactoryBean;
+
+/** If class has been generated during build time
+ * (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ * you can set class loader to avoid class generation during runtime:
+ * bus.setExtension(new GeneratedWrapperClassLoader(bus), WrapperClassCreator.class);
+ * @author olivier dufour
+ */
+public class WrapperClassLoader extends GeneratedClassClassLoader implements WrapperClassCreator {
+ public WrapperClassLoader(Bus bus) {
+ super(bus);
+ }
+
+ @Override
+ public Set<Class<?>> generate(JaxWsServiceFactoryBean factory, InterfaceInfo interfaceInfo, boolean q) {
+ Set<Class<?>> wrapperBeans = new LinkedHashSet<>();
+ for (OperationInfo opInfo : interfaceInfo.getOperations()) {
+ if (opInfo.isUnwrappedCapable()) {
+ Method method = (Method)opInfo.getProperty(ReflectionServiceFactoryBean.METHOD);
+ if (method == null) {
+ continue;
+ }
+ MessagePartInfo inf = opInfo.getInput().getFirstMessagePart();
+ if (inf.getTypeClass() == null) {
+ MessageInfo messageInfo = opInfo.getUnwrappedOperation().getInput();
+ wrapperBeans.add(createWrapperClass(inf,
+ messageInfo,
+ opInfo,
+ method,
+ true,
+ factory));
+ }
+ MessageInfo messageInfo = opInfo.getUnwrappedOperation().getOutput();
+ if (messageInfo != null) {
+ inf = opInfo.getOutput().getFirstMessagePart();
+ if (inf.getTypeClass() == null) {
+ wrapperBeans.add(createWrapperClass(inf,
+ messageInfo,
+ opInfo,
+ method,
+ false,
+ factory));
+ }
+ }
+ }
+ }
+ return wrapperBeans;
+ }
+
+ private Class<?> createWrapperClass(MessagePartInfo wrapperPart,
+ MessageInfo messageInfo,
+ OperationInfo op,
+ Method method,
+ boolean isRequest,
+ JaxWsServiceFactoryBean factory) {
+ boolean anonymous = factory.getAnonymousWrapperTypes();
+
+ String pkg = getPackageName(method) + ".jaxws_asm" + (anonymous ? "_an" : "");
+ String className = pkg + "."
+ + StringUtils.capitalize(op.getName().getLocalPart());
+ if (!isRequest) {
+ className = className + "Response";
+ }
+
+ Class<?> def = findClass(className, method.getDeclaringClass());
+ 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);
+ return def;
+ }
+ }
+ //throw new ClassNotFoundException(origClassName);
+ return null;
+ }
+ private String getPackageName(Method method) {
+ String pkg = PackageUtils.getPackageName(method.getDeclaringClass());
+ return pkg.length() == 0 ? WrapperClassGenerator.DEFAULT_PACKAGE_NAME : pkg;
+ }
+}
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
index 4e98839..2153c64 100644
--- a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/JaxWsServiceFactoryBean.java
@@ -68,8 +68,8 @@ import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.jaxws.JAXWSMethodDispatcher;
import org.apache.cxf.jaxws.JAXWSMethodInvoker;
import org.apache.cxf.jaxws.JAXWSProviderMethodDispatcher;
-import org.apache.cxf.jaxws.WrapperClassGenerator;
import org.apache.cxf.jaxws.interceptors.WebFaultOutInterceptor;
+import org.apache.cxf.jaxws.spi.WrapperClassCreator;
import org.apache.cxf.service.factory.FactoryBeanListener;
import org.apache.cxf.service.factory.FactoryBeanListener.Event;
import org.apache.cxf.service.factory.ServiceConstructionException;
@@ -666,10 +666,10 @@ public class JaxWsServiceFactoryBean extends ReflectionServiceFactoryBean {
if (b.getClass().getName().endsWith("JAXBDataBinding")
&& schemaLocations == null) {
ServiceInfo serviceInfo = getService().getServiceInfos().get(0);
- WrapperClassGenerator wrapperGen = new WrapperClassGenerator(this,
- serviceInfo.getInterface(),
- getQualifyWrapperSchema());
- return wrapperGen.generate();
+ WrapperClassCreator wrapperGen = getBus().getExtension(WrapperClassCreator.class);
+ return wrapperGen.generate(this,
+ serviceInfo.getInterface(),
+ getQualifyWrapperSchema());
}
return Collections.emptySet();
}
diff --git a/rt/frontend/jaxws/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/frontend/jaxws/src/main/resources/META-INF/cxf/bus-extensions.txt
index 5bec1e5..ea4dc9d 100644
--- a/rt/frontend/jaxws/src/main/resources/META-INF/cxf/bus-extensions.txt
+++ b/rt/frontend/jaxws/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -1 +1,2 @@
org.apache.cxf.jaxws.context.WebServiceContextResourceResolver::true
+org.apache.cxf.jaxws.spi.WrapperClassCreatorProxyService:org.apache.cxf.jaxws.spi.WrapperClassCreator:true
\ No newline at end of file
diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperNamespaceClassGeneratorTest.java
similarity index 62%
rename from rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java
rename to rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperNamespaceClassGeneratorTest.java
index fe788c7..1d98893 100644
--- a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperClassGeneratorTest.java
+++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/WrapperNamespaceClassGeneratorTest.java
@@ -21,14 +21,23 @@ package org.apache.cxf.jaxws;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
+import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+import org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture;
import org.apache.cxf.databinding.WrapperHelper;
import org.apache.cxf.jaxb.JAXBDataBinding;
+import org.apache.cxf.jaxb.JAXBWrapperHelper;
+import org.apache.cxf.jaxb.WrapperHelperClassLoader;
+import org.apache.cxf.jaxb.WrapperHelperCreator;
+import org.apache.cxf.jaxws.service.AddNumbers2Impl;
import org.apache.cxf.jaxws.service.AddNumbersImpl;
import org.apache.cxf.jaxws.support.JaxWsImplementorInfo;
import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
@@ -39,9 +48,10 @@ import org.apache.cxf.service.model.ServiceInfo;
import org.junit.After;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-public class WrapperClassGeneratorTest {
+public class WrapperNamespaceClassGeneratorTest {
@After
public void tearDown() {
@@ -119,5 +129,60 @@ public class WrapperClassGeneratorTest {
assertTrue("The generated response wrapper class is not correct", bout.toString().contains(expected));
}
+ public static class Capture implements GeneratedClassClassLoaderCapture {
+ private final Map<String, byte[]> sources;
+ public Capture() {
+ sources = new HashMap<>();
+ }
+ public void capture(String className, byte[] bytes) {
+ sources.put(className, bytes);
+ }
+
+ public void restore(GeneratedClassClassLoader.TypeHelperClassLoader cl) {
+ for (Map.Entry<String, byte[]> cls : sources.entrySet()) {
+ cl.defineClass(cls.getKey(), cls.getValue());
+ }
+ }
+ }
+
+ @org.junit.Test
+ public void testGeneratedFirst() throws Exception {
+ JaxWsImplementorInfo implInfo =
+ new JaxWsImplementorInfo(AddNumbers2Impl.class);
+ JaxWsServiceFactoryBean jaxwsFac = new JaxWsServiceFactoryBean(implInfo);
+ Bus bus = BusFactory.getDefaultBus();
+ jaxwsFac.setBus(bus);
+ Capture c = new Capture();
+ bus.setExtension(c, GeneratedClassClassLoaderCapture.class);
+ Service service = jaxwsFac.create();
+
+
+ ServiceInfo serviceInfo = service.getServiceInfos().get(0);
+
+ InterfaceInfo interfaceInfo = serviceInfo.getInterface();
+ OperationInfo inf = interfaceInfo.getOperations().iterator().next();
+ Class<?> requestClass = inf.getInput().getMessagePart(0).getTypeClass();
+ // 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});
+
+ // generate class and store it to class loader
+ WrapperHelper wh = new JAXBDataBinding().createWrapperHelper(requestClass, null,
+ partNames, elTypeNames, partClasses);
+
+ // now no more generation is allowed
+ WrapperHelperClassLoader wrapperHelperClassLoader = new WrapperHelperClassLoader(bus);
+
+ GeneratedClassClassLoader.TypeHelperClassLoader cl = wrapperHelperClassLoader.getClassLoader();
+ c.restore(cl);
+
+ bus.setExtension(wrapperHelperClassLoader, WrapperHelperCreator.class);
+
+ wh = new JAXBDataBinding().createWrapperHelper(requestClass, null,
+ partNames, elTypeNames, partClasses);
+
+ assertFalse("Precompiled class not loaded", wh instanceof JAXBWrapperHelper);
+ }
}
\ No newline at end of file
diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2.java b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2.java
new file mode 100644
index 0000000..236cd56
--- /dev/null
+++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2.java
@@ -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 AddNumbers2 {
+ @WebMethod
+ List<Integer> addListNumbers(
+ @WebParam
+ @XmlList
+ List<String> arg);
+}
diff --git a/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2Impl.java b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2Impl.java
new file mode 100644
index 0000000..6804f7a
--- /dev/null
+++ b/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/service/AddNumbers2Impl.java
@@ -0,0 +1,36 @@
+/**
+ * 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.ArrayList;
+import java.util.List;
+
+@javax.jws.WebService(endpointInterface = "org.apache.cxf.jaxws.service.AddNumbers2")
+public class AddNumbers2Impl implements AddNumbers2 {
+
+ public List<Integer> addListNumbers(List<String> arg) {
+ List<Integer> res = new ArrayList<>();
+ res.add(100);
+ res.add(200);
+ return res;
+
+ }
+
+}
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java
index e8e8d41..514b2f7 100644
--- a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java
@@ -431,7 +431,7 @@ public class DynamicClientFactory {
// Setup the new classloader!
ClassLoaderUtils.setThreadContextClassloader(cl);
- TypeClassInitializer visitor = new TypeClassInitializer(svcfo,
+ TypeClassInitializer visitor = new TypeClassInitializer(bus, svcfo,
intermediateModel,
allowWrapperOps());
visitor.walk();
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreator.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreator.java
new file mode 100644
index 0000000..4fd60e5
--- /dev/null
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreator.java
@@ -0,0 +1,23 @@
+/**
+ * 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.endpoint.dynamic;
+
+public interface ExceptionClassCreator {
+ Class<?> createExceptionClass(Class<?> bean);
+}
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreatorProxyService.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreatorProxyService.java
new file mode 100644
index 0000000..0fb73d8
--- /dev/null
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassCreatorProxyService.java
@@ -0,0 +1,48 @@
+/**
+ * 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.endpoint.dynamic;
+
+import org.apache.cxf.Bus;
+
+public class ExceptionClassCreatorProxyService implements ExceptionClassCreator {
+ private final ExceptionClassCreator srv;
+ public ExceptionClassCreatorProxyService(Bus bus) {
+ this(new ExceptionClassGenerator(bus));
+ }
+ public ExceptionClassCreatorProxyService(ExceptionClassCreator srv) {
+ super();
+ this.srv = srv;
+ }
+
+ @Override
+ public Class<?> createExceptionClass(Class<?> bean) {
+ return srv.createExceptionClass(bean);
+ }
+
+ public class LoadFirst extends ExceptionClassCreatorProxyService {
+ public LoadFirst(Bus bus) {
+ super(new ExceptionClassLoader(bus));
+ }
+ }
+ public class GenerateJustInTime extends ExceptionClassCreatorProxyService {
+ public GenerateJustInTime(Bus bus) {
+ super(new ExceptionClassGenerator(bus));
+ }
+ }
+}
\ No newline at end of file
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassGenerator.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassGenerator.java
new file mode 100644
index 0000000..0621e68
--- /dev/null
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassGenerator.java
@@ -0,0 +1,95 @@
+/**
+ * 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.endpoint.dynamic;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+import org.apache.cxf.common.util.StringUtils;
+
+public class ExceptionClassGenerator extends ClassGeneratorClassLoader implements ExceptionClassCreator {
+ private final ASMHelper helper;
+
+ public ExceptionClassGenerator(Bus bus) {
+ super(bus);
+ this.helper = bus.getExtension(ASMHelper.class);
+ }
+ @Override
+ public Class<?> createExceptionClass(Class<?> bean) {
+ String newClassName = bean.getName() + "_Exception";
+ newClassName = newClassName.replaceAll("\\$", ".");
+ newClassName = StringUtils.periodToSlashes(newClassName);
+
+ Class<?> cls = findClass(StringUtils.slashesToPeriod(newClassName), bean);
+ if (cls == null) {
+ ASMHelper.ClassWriter cw = helper.createClassWriter();
+ OpcodesProxy opCodes = helper.getOpCodes();
+
+ cw.visit(opCodes.V1_5,
+ opCodes.ACC_PUBLIC | opCodes.ACC_SUPER,
+ newClassName,
+ null,
+ "java/lang/Exception",
+ null);
+
+ ASMHelper.FieldVisitor fv;
+ ASMHelper.MethodVisitor mv;
+
+ String beanClassCode = helper.getClassCode(bean);
+ fv = cw.visitField(0, "faultInfo", beanClassCode, null, null);
+ fv.visitEnd();
+
+
+ mv = cw.visitMethod(opCodes.ACC_PUBLIC, "<init>",
+ "(Ljava/lang/String;" + beanClassCode + ")V", null, null);
+ mv.visitCode();
+ mv.visitLabel(helper.createLabel());
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitVarInsn(opCodes.ALOAD, 1);
+ mv.visitMethodInsn(opCodes.INVOKESPECIAL, "java/lang/Exception",
+ "<init>", "(Ljava/lang/String;)V", false);
+ mv.visitLabel(helper.createLabel());
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitVarInsn(opCodes.ALOAD, 2);
+ mv.visitFieldInsn(opCodes.PUTFIELD, newClassName, "faultInfo", beanClassCode);
+ mv.visitLabel(helper.createLabel());
+ mv.visitInsn(opCodes.RETURN);
+ mv.visitLabel(helper.createLabel());
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(opCodes.ACC_PUBLIC, "getFaultInfo",
+ "()" + beanClassCode, null, null);
+ mv.visitCode();
+ mv.visitLabel(helper.createLabel());
+ mv.visitVarInsn(opCodes.ALOAD, 0);
+ mv.visitFieldInsn(opCodes.GETFIELD, newClassName, "faultInfo", beanClassCode);
+ mv.visitInsn(opCodes.ARETURN);
+ mv.visitLabel(helper.createLabel());
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ cw.visitEnd();
+
+ return loadClass(bean.getName() + "_Exception", bean, cw.toByteArray());
+ }
+ return cls;
+ }
+}
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassLoader.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassLoader.java
new file mode 100644
index 0000000..de05276
--- /dev/null
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/ExceptionClassLoader.java
@@ -0,0 +1,42 @@
+/**
+ * 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.endpoint.dynamic;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+
+/** If class has been generated during build time
+ * (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ * you can set class loader to avoid class generation during runtime:
+ * bus.setExtension(new ExceptionClassLoader(bus), ExceptionClassCreator.class);
+ * @author olivier dufour
+ */
+public class ExceptionClassLoader extends GeneratedClassClassLoader implements ExceptionClassCreator {
+
+ public ExceptionClassLoader(Bus bus) {
+ super(bus);
+ }
+
+ @Override
+ public Class<?> createExceptionClass(Class<?> bean) {
+ String newClassName = bean.getName() + "_Exception";
+ return findClass(newClassName, bean);
+
+ }
+}
diff --git a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/TypeClassInitializer.java b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/TypeClassInitializer.java
index 67a5d9a..3ba3cf7 100644
--- a/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/TypeClassInitializer.java
+++ b/rt/frontend/simple/src/main/java/org/apache/cxf/endpoint/dynamic/TypeClassInitializer.java
@@ -24,6 +24,7 @@ import java.util.logging.Logger;
import javax.xml.namespace.QName;
+import org.apache.cxf.Bus;
import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.jaxb.JAXBUtils.JType;
@@ -31,7 +32,6 @@ import org.apache.cxf.common.jaxb.JAXBUtils.Mapping;
import org.apache.cxf.common.jaxb.JAXBUtils.S2JJAXBModel;
import org.apache.cxf.common.jaxb.JAXBUtils.TypeAndAnnotation;
import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.util.ASMHelper;
import org.apache.cxf.common.util.PrimitiveUtils;
import org.apache.cxf.service.ServiceModelVisitor;
import org.apache.cxf.service.factory.ServiceConstructionException;
@@ -48,13 +48,15 @@ public class TypeClassInitializer extends ServiceModelVisitor {
S2JJAXBModel model;
boolean allowWrapperOperations;
boolean isFault;
+ Bus bus;
- public TypeClassInitializer(ServiceInfo serviceInfo,
+ public TypeClassInitializer(Bus bus, ServiceInfo serviceInfo,
S2JJAXBModel model,
boolean allowWr) {
super(serviceInfo);
this.model = model;
this.allowWrapperOperations = allowWr;
+ this.bus = bus;
}
@Override
@@ -162,7 +164,8 @@ public class TypeClassInitializer extends ServiceModelVisitor {
}
private Class<?> createFaultClass(Class<?> cls) {
- return new ExceptionCreator().createExceptionClass(cls);
+ ExceptionClassCreator exceptionClassCreator = bus.getExtension(ExceptionClassCreator.class);
+ return exceptionClassCreator.createExceptionClass(cls);
}
private Class<?> getClassByName(JType jType) throws ClassNotFoundException {
@@ -182,65 +185,4 @@ public class TypeClassInitializer extends ServiceModelVisitor {
isFault = false;
}
-
- private static class ExceptionCreator extends ASMHelper {
- public Class<?> createExceptionClass(Class<?> bean) {
- String newClassName = bean.getName() + "_Exception";
- newClassName = newClassName.replaceAll("\\$", ".");
- newClassName = periodToSlashes(newClassName);
-
- Class<?> cls = super.findClass(newClassName.replace('/', '.'), bean);
- if (cls == null) {
- ClassWriter cw = createClassWriter();
- cw.visit(Opcodes.V1_5,
- Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER,
- newClassName,
- null,
- "java/lang/Exception",
- null);
-
- FieldVisitor fv;
- MethodVisitor mv;
-
- String beanClassCode = getClassCode(bean);
- fv = cw.visitField(0, "faultInfo", beanClassCode, null, null);
- fv.visitEnd();
-
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
- "(Ljava/lang/String;" + beanClassCode + ")V", null, null);
- mv.visitCode();
- mv.visitLabel(createLabel());
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Exception",
- "<init>", "(Ljava/lang/String;)V", false);
- mv.visitLabel(createLabel());
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 2);
- mv.visitFieldInsn(Opcodes.PUTFIELD, newClassName, "faultInfo", beanClassCode);
- mv.visitLabel(createLabel());
- mv.visitInsn(Opcodes.RETURN);
- mv.visitLabel(createLabel());
- mv.visitMaxs(2, 3);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getFaultInfo",
- "()" + beanClassCode, null, null);
- mv.visitCode();
- mv.visitLabel(createLabel());
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, newClassName, "faultInfo", beanClassCode);
- mv.visitInsn(Opcodes.ARETURN);
- mv.visitLabel(createLabel());
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
- cw.visitEnd();
-
- return super.loadClass(bean.getName() + "_Exception", bean, cw.toByteArray());
- }
- return cls;
- }
- }
}
diff --git a/rt/frontend/simple/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/frontend/simple/src/main/resources/META-INF/cxf/bus-extensions.txt
new file mode 100644
index 0000000..746ec08
--- /dev/null
+++ b/rt/frontend/simple/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -0,0 +1 @@
+org.apache.cxf.endpoint.dynamic.ExceptionClassCreatorProxyService:org.apache.cxf.endpoint.dynamic.ExceptionClassCreator:true
\ No newline at end of file
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPWSDLExtensionLoader.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPWSDLExtensionLoader.java
index b2078b5..73dcfea 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPWSDLExtensionLoader.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPWSDLExtensionLoader.java
@@ -37,18 +37,18 @@ public final class HTTPWSDLExtensionLoader implements WSDLExtensionLoader {
public HTTPWSDLExtensionLoader(Bus b) {
WSDLManager manager = b.getExtension(WSDLManager.class);
- createExtensor(manager, javax.wsdl.Port.class,
+ createExtensor(b, manager, javax.wsdl.Port.class,
org.apache.cxf.transports.http.configuration.HTTPClientPolicy.class);
- createExtensor(manager, javax.wsdl.Port.class,
+ createExtensor(b, manager, javax.wsdl.Port.class,
org.apache.cxf.transports.http.configuration.HTTPServerPolicy.class);
- createExtensor(manager, javax.wsdl.Port.class,
+ createExtensor(b, manager, javax.wsdl.Port.class,
AddressType.class);
}
- public void createExtensor(WSDLManager manager,
+ public void createExtensor(Bus b, WSDLManager manager,
Class<?> parentType,
Class<?> elementType) {
try {
- JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+ JAXBExtensionHelper.addExtensions(b, manager.getExtensionRegistry(),
parentType,
elementType, null,
this.getClass().getClassLoader());
diff --git a/rt/transports/jms/src/main/java/org/apache/cxf/transport/jms/wsdl11/JMSWSDLExtensionLoader.java b/rt/transports/jms/src/main/java/org/apache/cxf/transport/jms/wsdl11/JMSWSDLExtensionLoader.java
index 2b1c7a7..13dfa3c 100644
--- a/rt/transports/jms/src/main/java/org/apache/cxf/transport/jms/wsdl11/JMSWSDLExtensionLoader.java
+++ b/rt/transports/jms/src/main/java/org/apache/cxf/transport/jms/wsdl11/JMSWSDLExtensionLoader.java
@@ -52,8 +52,10 @@ public final class JMSWSDLExtensionLoader implements WSDLExtensionLoader {
TimeToLiveType.class,
TopicReplyToNameType.class
};
+ private final Bus bus;
public JMSWSDLExtensionLoader(Bus b) {
+ this.bus = b;
WSDLManager manager = b.getExtension(WSDLManager.class);
for (Class<?> extensor : EXTENSORS) {
addExtensions(manager, javax.wsdl.Binding.class, extensor);
@@ -64,7 +66,7 @@ public final class JMSWSDLExtensionLoader implements WSDLExtensionLoader {
public void addExtensions(WSDLManager manager, Class<?> parentType, Class<?> elementType) {
try {
- JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(), parentType, elementType, null,
+ JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(), parentType, elementType, null,
this.getClass().getClassLoader());
} catch (JAXBException e) {
// ignore, won't support XML
diff --git a/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/impl/AddressingWSDLExtensionLoader.java b/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/impl/AddressingWSDLExtensionLoader.java
index 100abf8..037b0a1 100644
--- a/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/impl/AddressingWSDLExtensionLoader.java
+++ b/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/impl/AddressingWSDLExtensionLoader.java
@@ -33,7 +33,10 @@ import org.apache.cxf.wsdl.WSDLManager;
@NoJSR250Annotations
public final class AddressingWSDLExtensionLoader implements WSDLExtensionLoader {
+ private final Bus bus;
+
public AddressingWSDLExtensionLoader(Bus b) {
+ this.bus = b;
WSDLManager manager = b.getExtension(WSDLManager.class);
createExtensor(manager, javax.wsdl.Binding.class,
@@ -43,7 +46,7 @@ public final class AddressingWSDLExtensionLoader implements WSDLExtensionLoader
Class<?> parentType,
Class<?> elementType) {
try {
- JAXBExtensionHelper.addExtensions(manager.getExtensionRegistry(),
+ JAXBExtensionHelper.addExtensions(bus, manager.getExtensionRegistry(),
parentType,
elementType, null,
this.getClass().getClassLoader());
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreator.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreator.java
new file mode 100644
index 0000000..b58474a
--- /dev/null
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreator.java
@@ -0,0 +1,25 @@
+/**
+ * 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.wsdl;
+
+import javax.xml.namespace.QName;
+
+public interface ExtensionClassCreator {
+ Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader);
+}
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreatorProxyService.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreatorProxyService.java
new file mode 100644
index 0000000..03cf42d
--- /dev/null
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassCreatorProxyService.java
@@ -0,0 +1,50 @@
+/**
+ * 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.wsdl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+
+public class ExtensionClassCreatorProxyService implements ExtensionClassCreator {
+ private final ExtensionClassCreator srv;
+ public ExtensionClassCreatorProxyService(Bus bus) {
+ this(new ExtensionClassGenerator(bus));
+ }
+ public ExtensionClassCreatorProxyService(ExtensionClassCreator srv) {
+ super();
+ this.srv = srv;
+ }
+
+ @Override
+ public Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader) {
+ return srv.createExtensionClass(cls, qname, loader);
+ }
+
+ public class LoadFirst extends ExtensionClassCreatorProxyService {
+ public LoadFirst(Bus bus) {
+ super(new ExtensionClassLoader(bus));
+ }
+ }
+ public class GenerateJustInTime extends ExtensionClassCreatorProxyService {
+ public GenerateJustInTime(Bus bus) {
+ super(new ExtensionClassGenerator(bus));
+ }
+ }
+}
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassGenerator.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassGenerator.java
new file mode 100644
index 0000000..5596762
--- /dev/null
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassGenerator.java
@@ -0,0 +1,294 @@
+/**
+ * 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.wsdl;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.ClassGeneratorClassLoader;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.OpcodesProxy;
+import org.apache.cxf.common.util.StringUtils;
+
+public class ExtensionClassGenerator extends ClassGeneratorClassLoader implements ExtensionClassCreator {
+
+ public ExtensionClassGenerator(Bus bus) {
+ super(bus);
+ }
+ //CHECKSTYLE:OFF - very complicated ASM code
+ public Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader) {
+
+ String className = StringUtils.periodToSlashes(cls.getName());
+ ASMHelper helper = bus.getExtension(ASMHelper.class);
+ OpcodesProxy Opcodes = helper.getOpCodes();
+
+ Class<?> extClass = findClass(className + "Extensibility", loader);
+ if (extClass != null) {
+ return extClass;
+ }
+
+ ASMHelper.ClassWriter cw = helper.createClassWriter();
+ ASMHelper.FieldVisitor fv;
+ ASMHelper.MethodVisitor mv;
+ ASMHelper.AnnotationVisitor av0;
+
+ cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER + Opcodes.ACC_SYNTHETIC,
+ className + "Extensibility", null,
+ className,
+ new String[] {"javax/wsdl/extensions/ExtensibilityElement"});
+
+ cw.visitSource(cls.getSimpleName() + "Extensibility.java", null);
+
+ fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
+ "WSDL_REQUIRED", "Ljavax/xml/namespace/QName;", null, null);
+ fv.visitEnd();
+ fv = cw.visitField(0, "qn", "Ljavax/xml/namespace/QName;", null, null);
+ fv.visitEnd();
+
+
+ boolean hasAttributes = false;
+ try {
+ Method m = cls.getDeclaredMethod("getOtherAttributes");
+ if (m != null && m.getReturnType() == Map.class){
+ hasAttributes = true;
+ }
+ } catch (Throwable t) {
+ //ignore
+ }
+ if (hasAttributes) {
+ mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
+ mv.visitCode();
+ ASMHelper.Label l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(64, l0);
+ mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName");
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitLdcInsn("http://schemas.xmlsoap.org/wsdl/");
+ mv.visitLdcInsn("required");
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName", "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;)V", false);
+ mv.visitFieldInsn(Opcodes.PUTSTATIC, className + "Extensibility", "WSDL_REQUIRED",
+ "Ljavax/xml/namespace/QName;");
+ mv.visitInsn(Opcodes.RETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ } else {
+ fv = cw.visitField(Opcodes.ACC_PRIVATE, "required", "Ljava/lang/Boolean;", null, null);
+ fv.visitEnd();
+ }
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ ASMHelper.Label l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(33, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", "()V", false);
+ ASMHelper.Label l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(31, l1);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName");
+ mv.visitInsn(Opcodes.DUP);
+
+ mv.visitLdcInsn(qname.getNamespaceURI());
+ mv.visitLdcInsn(qname.getLocalPart());
+
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName",
+ "<init>", "(Ljava/lang/String;Ljava/lang/String;)V", false);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility",
+ "qn", "Ljavax/xml/namespace/QName;");
+ ASMHelper.Label l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(34, l2);
+ mv.visitInsn(Opcodes.RETURN);
+ ASMHelper.Label l3 = helper.createLabel();
+ mv.visitLabel(l3);
+
+ mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l3, 0);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setElementType", "(Ljavax/xml/namespace/QName;)V", null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(37, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility", "qn", "Ljavax/xml/namespace/QName;");
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(38, l1);
+ mv.visitInsn(Opcodes.RETURN);
+ l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l2, 0);
+ mv.visitLocalVariable("elementType", "Ljavax/xml/namespace/QName;", null, l0, l2, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getElementType", "()Ljavax/xml/namespace/QName;", null, null);
+ av0 = mv.visitAnnotation("Ljavax/xml/bind/annotation/XmlTransient;", true);
+ av0.visitEnd();
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(40, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, className + "Extensibility", "qn", "Ljavax/xml/namespace/QName;");
+ mv.visitInsn(Opcodes.ARETURN);
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l1, 0);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ if (hasAttributes) {
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getRequired", "()Ljava/lang/Boolean;", null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(66, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
+ "()Ljava/util/Map;", false);
+ mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
+ "Ljavax/xml/namespace/QName;");
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "get",
+ "(Ljava/lang/Object;)Ljava/lang/Object;", true);
+ mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
+ mv.visitVarInsn(Opcodes.ASTORE, 1);
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(67, l1);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ l2 = helper.createLabel();
+ mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ l3 = helper.createLabel();
+ mv.visitJumpInsn(Opcodes.GOTO, l3);
+ mv.visitLabel(l2);
+ mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
+ "(Ljava/lang/String;)Ljava/lang/Boolean;", false);
+ mv.visitLabel(l3);
+ mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Boolean"});
+ mv.visitInsn(Opcodes.ARETURN);
+ ASMHelper.Label l4 = helper.createLabel();
+ mv.visitLabel(l4);
+ mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l4, 0);
+ mv.visitLocalVariable("s", "Ljava/lang/String;", null, l1, l4, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setRequired", "(Ljava/lang/Boolean;)V", null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(76, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ l1 = helper.createLabel();
+ mv.visitJumpInsn(Opcodes.IFNONNULL, l1);
+ l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLineNumber(77, l2);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
+ "()Ljava/util/Map;", false);
+ mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
+ "Ljavax/xml/namespace/QName;");
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "remove",
+ "(Ljava/lang/Object;)Ljava/lang/Object;", true);
+ mv.visitInsn(Opcodes.POP);
+ l3 = helper.createLabel();
+ mv.visitLabel(l3);
+ mv.visitLineNumber(78, l3);
+ l4 = helper.createLabel();
+ mv.visitJumpInsn(Opcodes.GOTO, l4);
+ mv.visitLabel(l1);
+ mv.visitLineNumber(79, l1);
+ mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
+ "()Ljava/util/Map;", false);
+ mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
+ "Ljavax/xml/namespace/QName;");
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "toString", "()Ljava/lang/String;", false);
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
+ mv.visitInsn(Opcodes.POP);
+ mv.visitLabel(l4);
+ mv.visitLineNumber(81, l4);
+ mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+ mv.visitInsn(Opcodes.RETURN);
+ ASMHelper.Label l5 = helper.createLabel();
+ mv.visitLabel(l5);
+ mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l5, 0);
+ mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l5, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ } else {
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getRequired", "()Ljava/lang/Boolean;", null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(68, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitFieldInsn(Opcodes.GETFIELD, className + "Extensibility", "required", "Ljava/lang/Boolean;");
+ mv.visitInsn(Opcodes.ARETURN);
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l1, 0);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+
+ mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setRequired", "(Ljava/lang/Boolean;)V", null, null);
+ mv.visitCode();
+ l0 = helper.createLabel();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(71, l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility", "required", "Ljava/lang/Boolean;");
+ l1 = helper.createLabel();
+ mv.visitLabel(l1);
+ mv.visitLineNumber(72, l1);
+ mv.visitInsn(Opcodes.RETURN);
+ l2 = helper.createLabel();
+ mv.visitLabel(l2);
+ mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l2, 0);
+ mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l2, 1);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+
+ cw.visitEnd();
+
+ byte[] bytes = cw.toByteArray();
+ return loadClass(className + "Extensibility", loader, bytes);
+ }
+}
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassLoader.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassLoader.java
new file mode 100644
index 0000000..5d16380
--- /dev/null
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/ExtensionClassLoader.java
@@ -0,0 +1,43 @@
+/**
+ * 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.wsdl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.spi.GeneratedClassClassLoader;
+
+/** If class has been generated during build time
+ * (use @see org.apache.cxf.common.spi.GeneratedClassClassLoaderCapture capture to save bytes)
+ * you can set class loader to avoid class generation during runtime:
+ * bus.setExtension(new ExtensionClassLoader(bus), ExtensionClassCreator.class);
+ * @author olivier dufour
+ */
+public class ExtensionClassLoader extends GeneratedClassClassLoader implements ExtensionClassCreator {
+
+ public ExtensionClassLoader(Bus bus) {
+ super(bus);
+ }
+
+ @Override
+ public Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader) {
+ return findClass(cls.getName() + "Extensibility", ExtensionClassLoader.class);
+ }
+}
diff --git a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/JAXBExtensionHelper.java b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/JAXBExtensionHelper.java
index c31d336..c8b6478 100644
--- a/rt/wsdl/src/main/java/org/apache/cxf/wsdl/JAXBExtensionHelper.java
+++ b/rt/wsdl/src/main/java/org/apache/cxf/wsdl/JAXBExtensionHelper.java
@@ -63,18 +63,12 @@ import javax.xml.stream.util.StreamReaderDelegate;
import org.w3c.dom.Element;
+import org.apache.cxf.Bus;
import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.jaxb.JAXBContextCache;
import org.apache.cxf.common.jaxb.JAXBContextCache.CachedContextAndSchemas;
import org.apache.cxf.common.jaxb.JAXBUtils;
import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.common.util.ASMHelper;
-import org.apache.cxf.common.util.ASMHelper.AnnotationVisitor;
-import org.apache.cxf.common.util.ASMHelper.ClassWriter;
-import org.apache.cxf.common.util.ASMHelper.FieldVisitor;
-import org.apache.cxf.common.util.ASMHelper.Label;
-import org.apache.cxf.common.util.ASMHelper.MethodVisitor;
-import org.apache.cxf.common.util.ASMHelper.Opcodes;
import org.apache.cxf.common.util.PackageUtils;
import org.apache.cxf.common.util.ReflectionUtil;
import org.apache.cxf.common.util.StringUtils;
@@ -82,7 +76,6 @@ import org.apache.cxf.staxutils.PrettyPrintXMLStreamWriter;
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.cxf.staxutils.transform.OutTransformWriter;
-
/**
* JAXBExtensionHelper
*/
@@ -99,13 +92,15 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
private JAXBContext marshalContext;
private JAXBContext unmarshalContext;
private Set<Class<?>> classes;
+ private Bus bus;
- public JAXBExtensionHelper(Class<?> cls,
+ public JAXBExtensionHelper(Bus bus, Class<?> cls,
String ns) {
typeClass = cls;
namespace = ns;
extensionClass = cls;
+ this.bus = bus;
}
void setJaxbNamespace(String ns) {
@@ -138,16 +133,16 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
}
- public static void addExtensions(ExtensionRegistry registry, String parentType, String elementType)
+ public static void addExtensions(Bus b, ExtensionRegistry registry, String parentType, String elementType)
throws JAXBException, ClassNotFoundException {
Class<?> parentTypeClass = ClassLoaderUtils.loadClass(parentType, JAXBExtensionHelper.class);
Class<? extends ExtensibilityElement> elementTypeClass =
ClassLoaderUtils.loadClass(elementType, JAXBExtensionHelper.class)
.asSubclass(ExtensibilityElement.class);
- addExtensions(registry, parentTypeClass, elementTypeClass, null);
+ addExtensions(b, registry, parentTypeClass, elementTypeClass, null);
}
- public static void addExtensions(ExtensionRegistry registry,
+ public static void addExtensions(Bus b, ExtensionRegistry registry,
String parentType,
String elementType,
String namespace)
@@ -157,27 +152,28 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
Class<? extends ExtensibilityElement> elementTypeClass =
ClassLoaderUtils.loadClass(elementType, JAXBExtensionHelper.class)
.asSubclass(ExtensibilityElement.class);
- addExtensions(registry, parentTypeClass, elementTypeClass, namespace);
+ addExtensions(b, registry, parentTypeClass, elementTypeClass, namespace);
}
- public static void addExtensions(ExtensionRegistry registry,
+ public static void addExtensions(Bus b, ExtensionRegistry registry,
Class<?> parentType,
Class<?> cls)
throws JAXBException {
- addExtensions(registry, parentType, cls, null);
+ addExtensions(b, registry, parentType, cls, null);
}
- public static void addExtensions(ExtensionRegistry registry,
+ public static void addExtensions(Bus b, ExtensionRegistry registry,
Class<?> parentType,
Class<?> cls,
String namespace) throws JAXBException {
- addExtensions(registry, parentType, cls, namespace, cls.getClassLoader());
+ addExtensions(b, registry, parentType, cls, namespace, cls.getClassLoader());
}
- public static void addExtensions(ExtensionRegistry registry,
+ public static void addExtensions(Bus b, ExtensionRegistry registry,
Class<?> parentType,
Class<?> cls,
String namespace,
ClassLoader loader) throws JAXBException {
- JAXBExtensionHelper helper = new JAXBExtensionHelper(cls, namespace);
+ JAXBExtensionHelper helper = new JAXBExtensionHelper(b, cls, namespace);
+ ExtensionClassCreator extensionClassCreator = b.getExtension(ExtensionClassCreator.class);
boolean found = false;
Class<?> extCls = cls;
try {
@@ -197,7 +193,7 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
}
QName elementType = new QName(ns, name);
if (!ExtensibilityElement.class.isAssignableFrom(extCls)) {
- extCls = createExtensionClass(cls, elementType, loader);
+ extCls = extensionClassCreator.createExtensionClass(cls, elementType, loader);
helper.setExtensionClass(extCls);
}
registry.registerDeserializer(parentType, elementType, helper);
@@ -234,7 +230,7 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
}
QName elementType = new QName(ns, name);
if (!ExtensibilityElement.class.isAssignableFrom(extCls)) {
- extCls = createExtensionClass(cls, elementType, loader);
+ extCls = extensionClassCreator.createExtensionClass(cls, elementType, loader);
helper.setExtensionClass(extCls);
}
registry.registerDeserializer(parentType, elementType, helper);
@@ -326,7 +322,7 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)ent;
nspref.put((String)entry.getValue(), (String)entry.getKey());
}
- JAXBUtils.setNamespaceMapper(nspref, u);
+ JAXBUtils.setNamespaceMapper(bus, nspref, u);
u.marshal(mObj, writer);
writer.flush();
} catch (Exception ex) {
@@ -453,260 +449,5 @@ public class JAXBExtensionHelper implements ExtensionSerializer, ExtensionDeseri
};
- //CHECKSTYLE:OFF - very complicated ASM code
- private static Class<?> createExtensionClass(Class<?> cls, QName qname, ClassLoader loader) {
-
- String className = ASMHelper.periodToSlashes(cls.getName());
- ASMHelper helper = new ASMHelper();
- Class<?> extClass = helper.findClass(className + "Extensibility", loader);
- if (extClass != null) {
- return extClass;
- }
-
- ClassWriter cw = helper.createClassWriter();
- FieldVisitor fv;
- MethodVisitor mv;
- AnnotationVisitor av0;
-
- cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER + Opcodes.ACC_SYNTHETIC,
- className + "Extensibility", null,
- className,
- new String[] {"javax/wsdl/extensions/ExtensibilityElement"});
-
- cw.visitSource(cls.getSimpleName() + "Extensibility.java", null);
-
- fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
- "WSDL_REQUIRED", "Ljavax/xml/namespace/QName;", null, null);
- fv.visitEnd();
- fv = cw.visitField(0, "qn", "Ljavax/xml/namespace/QName;", null, null);
- fv.visitEnd();
-
-
- boolean hasAttributes = false;
- try {
- Method m = cls.getDeclaredMethod("getOtherAttributes");
- if (m != null && m.getReturnType() == Map.class){
- hasAttributes = true;
- }
- } catch (Throwable t) {
- //ignore
- }
- if (hasAttributes) {
- mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
- mv.visitCode();
- Label l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(64, l0);
- mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName");
- mv.visitInsn(Opcodes.DUP);
- mv.visitLdcInsn("http://schemas.xmlsoap.org/wsdl/");
- mv.visitLdcInsn("required");
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName", "<init>",
- "(Ljava/lang/String;Ljava/lang/String;)V", false);
- mv.visitFieldInsn(Opcodes.PUTSTATIC, className + "Extensibility", "WSDL_REQUIRED",
- "Ljavax/xml/namespace/QName;");
- mv.visitInsn(Opcodes.RETURN);
- mv.visitMaxs(4, 0);
- mv.visitEnd();
- } else {
- fv = cw.visitField(Opcodes.ACC_PRIVATE, "required", "Ljava/lang/Boolean;", null, null);
- fv.visitEnd();
- }
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
- mv.visitCode();
- Label l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(33, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, className, "<init>", "()V", false);
- Label l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(31, l1);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitTypeInsn(Opcodes.NEW, "javax/xml/namespace/QName");
- mv.visitInsn(Opcodes.DUP);
-
- mv.visitLdcInsn(qname.getNamespaceURI());
- mv.visitLdcInsn(qname.getLocalPart());
-
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/xml/namespace/QName",
- "<init>", "(Ljava/lang/String;Ljava/lang/String;)V", false);
- mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility",
- "qn", "Ljavax/xml/namespace/QName;");
- Label l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLineNumber(34, l2);
- mv.visitInsn(Opcodes.RETURN);
- Label l3 = helper.createLabel();
- mv.visitLabel(l3);
-
- mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l3, 0);
- mv.visitMaxs(5, 1);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setElementType", "(Ljavax/xml/namespace/QName;)V", null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(37, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility", "qn", "Ljavax/xml/namespace/QName;");
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(38, l1);
- mv.visitInsn(Opcodes.RETURN);
- l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l2, 0);
- mv.visitLocalVariable("elementType", "Ljavax/xml/namespace/QName;", null, l0, l2, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getElementType", "()Ljavax/xml/namespace/QName;", null, null);
- av0 = mv.visitAnnotation("Ljavax/xml/bind/annotation/XmlTransient;", true);
- av0.visitEnd();
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(40, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, className + "Extensibility", "qn", "Ljavax/xml/namespace/QName;");
- mv.visitInsn(Opcodes.ARETURN);
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l1, 0);
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
- if (hasAttributes) {
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getRequired", "()Ljava/lang/Boolean;", null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(66, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
- "()Ljava/util/Map;", false);
- mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
- "Ljavax/xml/namespace/QName;");
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "get",
- "(Ljava/lang/Object;)Ljava/lang/Object;", true);
- mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
- mv.visitVarInsn(Opcodes.ASTORE, 1);
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(67, l1);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- l2 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.IFNONNULL, l2);
- mv.visitInsn(Opcodes.ACONST_NULL);
- l3 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.GOTO, l3);
- mv.visitLabel(l2);
- mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {"java/lang/String"}, 0, null);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
- "(Ljava/lang/String;)Ljava/lang/Boolean;", false);
- mv.visitLabel(l3);
- mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Boolean"});
- mv.visitInsn(Opcodes.ARETURN);
- Label l4 = helper.createLabel();
- mv.visitLabel(l4);
- mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l4, 0);
- mv.visitLocalVariable("s", "Ljava/lang/String;", null, l1, l4, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
-
-
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setRequired", "(Ljava/lang/Boolean;)V", null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(76, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- l1 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.IFNONNULL, l1);
- l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLineNumber(77, l2);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
- "()Ljava/util/Map;", false);
- mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
- "Ljavax/xml/namespace/QName;");
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "remove",
- "(Ljava/lang/Object;)Ljava/lang/Object;", true);
- mv.visitInsn(Opcodes.POP);
- l3 = helper.createLabel();
- mv.visitLabel(l3);
- mv.visitLineNumber(78, l3);
- l4 = helper.createLabel();
- mv.visitJumpInsn(Opcodes.GOTO, l4);
- mv.visitLabel(l1);
- mv.visitLineNumber(79, l1);
- mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className + "Extensibility", "getOtherAttributes",
- "()Ljava/util/Map;", false);
- mv.visitFieldInsn(Opcodes.GETSTATIC, className + "Extensibility", "WSDL_REQUIRED",
- "Ljavax/xml/namespace/QName;");
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "toString", "()Ljava/lang/String;", false);
- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Map", "put",
- "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true);
- mv.visitInsn(Opcodes.POP);
- mv.visitLabel(l4);
- mv.visitLineNumber(81, l4);
- mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
- mv.visitInsn(Opcodes.RETURN);
- Label l5 = helper.createLabel();
- mv.visitLabel(l5);
- mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l5, 0);
- mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l5, 1);
- mv.visitMaxs(3, 2);
- mv.visitEnd();
- } else {
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getRequired", "()Ljava/lang/Boolean;", null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(68, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, className + "Extensibility", "required", "Ljava/lang/Boolean;");
- mv.visitInsn(Opcodes.ARETURN);
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l1, 0);
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
- mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setRequired", "(Ljava/lang/Boolean;)V", null, null);
- mv.visitCode();
- l0 = helper.createLabel();
- mv.visitLabel(l0);
- mv.visitLineNumber(71, l0);
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitFieldInsn(Opcodes.PUTFIELD, className + "Extensibility", "required", "Ljava/lang/Boolean;");
- l1 = helper.createLabel();
- mv.visitLabel(l1);
- mv.visitLineNumber(72, l1);
- mv.visitInsn(Opcodes.RETURN);
- l2 = helper.createLabel();
- mv.visitLabel(l2);
- mv.visitLocalVariable("this", "L" + className + "Extensibility;", null, l0, l2, 0);
- mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l2, 1);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
- }
-
- cw.visitEnd();
-
- byte[] bytes = cw.toByteArray();
- return helper.loadClass(className + "Extensibility", loader, bytes);
- }
}
diff --git a/rt/wsdl/src/main/resources/META-INF/cxf/bus-extensions.txt b/rt/wsdl/src/main/resources/META-INF/cxf/bus-extensions.txt
index c69b655..3ce9b5b 100644
--- a/rt/wsdl/src/main/resources/META-INF/cxf/bus-extensions.txt
+++ b/rt/wsdl/src/main/resources/META-INF/cxf/bus-extensions.txt
@@ -1,2 +1,2 @@
org.apache.cxf.wsdl11.WSDLManagerImpl:org.apache.cxf.wsdl.WSDLManager:true
-
+org.apache.cxf.wsdl.ExtensionClassCreatorProxyService:org.apache.cxf.wsdl.ExtensionClassCreator:true
diff --git a/rt/wsdl/src/test/java/org/apache/cxf/wsdl/JAXBExtensionHelperTest.java b/rt/wsdl/src/test/java/org/apache/cxf/wsdl/JAXBExtensionHelperTest.java
index fd569d0..f07d88a 100644
--- a/rt/wsdl/src/test/java/org/apache/cxf/wsdl/JAXBExtensionHelperTest.java
+++ b/rt/wsdl/src/test/java/org/apache/cxf/wsdl/JAXBExtensionHelperTest.java
@@ -37,9 +37,13 @@ import javax.xml.namespace.QName;
import org.xml.sax.InputSource;
+import org.apache.cxf.Bus;
import org.apache.cxf.abc.test.AnotherPolicyType;
import org.apache.cxf.abc.test.NewServiceType;
import org.apache.cxf.abc.test.TestPolicyType;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
+import org.apache.cxf.common.util.ASMHelper;
+import org.apache.cxf.common.util.ASMHelperImpl;
import org.junit.Before;
import org.junit.Test;
@@ -58,6 +62,8 @@ public class JAXBExtensionHelperTest {
private ExtensionRegistry registry;
+ private Bus bus;
+
@Before
public void setUp() throws Exception {
@@ -68,19 +74,24 @@ public class JAXBExtensionHelperTest {
if (registry == null) {
registry = wsdlFactory.newPopulatedExtensionRegistry();
}
+ bus = new ExtensionManagerBus();
+ bus.setExtension(new ASMHelperImpl(), ASMHelper.class);
+ ExtensionClassCreator extr = new ExtensionClassGenerator(bus);
+ bus.setExtension(extr, ExtensionClassCreator.class);
}
@Test
public void testAddTestExtension() throws Exception {
- JAXBExtensionHelper.addExtensions(registry, "javax.wsdl.Port",
- "org.apache.cxf.abc.test.TestPolicyType");
- JAXBExtensionHelper.addExtensions(registry, "javax.wsdl.Port",
- "org.apache.cxf.abc.test.AnotherPolicyType");
+ JAXBExtensionHelper.addExtensions(bus, registry, "javax.wsdl.Port",
+ "org.apache.cxf.abc.test.TestPolicyType");
+
+ JAXBExtensionHelper.addExtensions(bus, registry, "javax.wsdl.Port",
+ "org.apache.cxf.abc.test.AnotherPolicyType");
- JAXBExtensionHelper.addExtensions(registry, "javax.wsdl.Definition",
- "org.apache.cxf.abc.test.NewServiceType");
+ JAXBExtensionHelper.addExtensions(bus, registry, "javax.wsdl.Definition",
+ "org.apache.cxf.abc.test.NewServiceType");
String file = this.getClass().getResource("/wsdl/test_ext.wsdl").toURI().toString();
@@ -92,8 +103,8 @@ public class JAXBExtensionHelperTest {
@Test
public void testPrettyPrintXMLStreamWriter() throws Exception {
- JAXBExtensionHelper.addExtensions(registry, "javax.wsdl.Definition",
- "org.apache.cxf.abc.test.NewServiceType");
+ JAXBExtensionHelper.addExtensions(bus, registry, "javax.wsdl.Definition",
+ "org.apache.cxf.abc.test.NewServiceType");
String file = this.getClass().getResource("/wsdl/test_ext.wsdl").toURI().toString();
@@ -114,13 +125,13 @@ public class JAXBExtensionHelperTest {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
- JAXBExtensionHelper helper = new JAXBExtensionHelper(NewServiceType.class, null);
+ JAXBExtensionHelper helper = new JAXBExtensionHelper(bus, NewServiceType.class, null);
helper.marshall(javax.wsdl.Definition.class,
- new QName("http://cxf.apache.org/test/hello_world", "newService"),
- newService,
- new PrintWriter(stream),
- wsdlDefinition,
- registry);
+ new QName("http://cxf.apache.org/test/hello_world", "newService"),
+ newService,
+ new PrintWriter(stream),
+ wsdlDefinition,
+ registry);
BufferedReader reader = new BufferedReader(new StringReader(new String(stream.toByteArray())));
String actual = reader.readLine();
int spaces = 0;
@@ -139,17 +150,17 @@ public class JAXBExtensionHelperTest {
@Test
public void testMappedNamespace() throws Exception {
- JAXBExtensionHelper.addExtensions(registry, javax.wsdl.Port.class,
- org.apache.cxf.abc.test.TestPolicyType.class,
- "http://cxf.apache.org/abc/test/remapped");
+ JAXBExtensionHelper.addExtensions(bus, registry, javax.wsdl.Port.class,
+ org.apache.cxf.abc.test.TestPolicyType.class,
+ "http://cxf.apache.org/abc/test/remapped");
- JAXBExtensionHelper.addExtensions(registry, javax.wsdl.Port.class,
- org.apache.cxf.abc.test.AnotherPolicyType.class,
- "http://cxf.apache.org/abc/test/remapped");
+ JAXBExtensionHelper.addExtensions(bus, registry, javax.wsdl.Port.class,
+ org.apache.cxf.abc.test.AnotherPolicyType.class,
+ "http://cxf.apache.org/abc/test/remapped");
- JAXBExtensionHelper.addExtensions(registry, javax.wsdl.Definition.class,
- org.apache.cxf.abc.test.NewServiceType.class,
- "http://cxf.apache.org/abc/test/remapped");
+ JAXBExtensionHelper.addExtensions(bus, registry, javax.wsdl.Definition.class,
+ org.apache.cxf.abc.test.NewServiceType.class,
+ "http://cxf.apache.org/abc/test/remapped");
String file = this.getClass().getResource("/wsdl/test_ext_remapped.wsdl").toURI().toString();
wsdlReader.setExtensionRegistry(registry);
@@ -159,13 +170,13 @@ public class JAXBExtensionHelperTest {
StringWriter out = new StringWriter();
wsdlFactory.newWSDLWriter().writeWSDL(wsdlDefinition, out);
wsdlDefinition = wsdlReader.readWSDL(null,
- new InputSource(new StringReader(out.toString())));
+ new InputSource(new StringReader(out.toString())));
checkTestExt();
}
private void checkTestExt() throws Exception {
Service s = wsdlDefinition.getService(new QName("http://cxf.apache.org/test/hello_world",
- "HelloWorldService"));
+ "HelloWorldService"));
Port p = s.getPort("HelloWorldPort");
List<?> extPortList = p.getExtensibilityElements();
@@ -177,7 +188,7 @@ public class JAXBExtensionHelperTest {
} else if (ext instanceof AnotherPolicyType) {
ap = (AnotherPolicyType) ext;
} else if (ext instanceof UnknownExtensibilityElement) {
- UnknownExtensibilityElement e = (UnknownExtensibilityElement)ext;
+ UnknownExtensibilityElement e = (UnknownExtensibilityElement) ext;
System.out.println(e.getElementType());
}
}
@@ -187,7 +198,7 @@ public class JAXBExtensionHelperTest {
assertEquals("Unexpected value for TestPolicyType intAttr", 30, tp.getIntAttr());
assertEquals("Unexpected value for TestPolicyType stringAttr", "hello", tp.getStringAttr());
assertTrue("Unexpected value for AnotherPolicyType floatAttr",
- Math.abs(0.1F - ap.getFloatAttr()) < 0.5E-5);
+ Math.abs(0.1F - ap.getFloatAttr()) < 0.5E-5);
}
private void checkSpaces(String actual, int spaces) {
@@ -196,7 +207,7 @@ public class JAXBExtensionHelperTest {
space += " ";
}
assertTrue("Indentation level not proper when marshalling a extension element;" + actual,
- actual.startsWith(space));
+ actual.startsWith(space));
}
}
\ No newline at end of file
diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerMiscTest.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerMiscTest.java
index 78807ea..c75e6e0 100644
--- a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerMiscTest.java
+++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerMiscTest.java
@@ -22,7 +22,7 @@ package org.apache.cxf.systest.jaxws;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.StringReader;
-import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.math.BigInteger;
import java.net.HttpURLConnection;
@@ -99,6 +99,7 @@ public class ClientServerMiscTest extends AbstractBusClientServerTestBase {
@BeforeClass
public static void startServers() throws Exception {
+ createStaticBus();
assertTrue("server did not launch correctly", launchServer(ServerMisc.class, true));
}
@@ -419,9 +420,11 @@ public class ClientServerMiscTest extends AbstractBusClientServerTestBase {
}
private void setASM(boolean b) throws Exception {
- Field f = ASMHelper.class.getDeclaredField("badASM");
- ReflectionUtil.setAccessible(f);
- f.set(null, !b);
+
+ ASMHelper helper = getBus().getExtension(ASMHelper.class);
+ Method m = helper.getClass().getMethod("setBadASM", Boolean.TYPE);
+ ReflectionUtil.setAccessible(m);
+ m.invoke(helper, !b);
}
@Test
@@ -608,7 +611,7 @@ public class ClientServerMiscTest extends AbstractBusClientServerTestBase {
assertEquals(3, ints.length);
assertEquals(1, ints[0]);
- if (new ASMHelper().createClassWriter() != null) {
+ if (getBus().getExtension(ASMHelper.class).createClassWriter() != null) {
//doing the type adapter things and such really
//requires the ASM generated helper classes
assertEquals("Val", port.createBar("Val").getName());