DELTASPIKE-1309 Upgrade ASM + renamed directories Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/028ec5bf Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/028ec5bf Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/028ec5bf
Branch: refs/heads/master Commit: 028ec5bf37a6122f9c93a93141dba043f6c1875e Parents: 83053ca Author: Thomas Andraschko <[email protected]> Authored: Tue Jan 9 21:47:41 2018 +0100 Committer: Thomas Andraschko <[email protected]> Committed: Tue Jan 9 21:47:41 2018 +0100 ---------------------------------------------------------------------- deltaspike/dist/bom/pom.xml | 2 +- deltaspike/dist/full/pom.xml | 2 +- .../src/main/distribution/modules-module.xml | 2 +- deltaspike/modules/jsf/impl-ee6/pom.xml | 2 +- deltaspike/modules/jsf/impl/pom.xml | 2 +- deltaspike/modules/partial-bean/impl/pom.xml | 8 +- deltaspike/modules/proxy/impl-asm/pom.xml | 132 +++++ .../impl/AsmDeltaSpikeProxyClassGenerator.java | 548 +++++++++++++++++++ .../impl/CopyAnnotationVisitorAdapter.java | 96 ++++ .../src/main/resources/META-INF/beans.xml | 23 + ...pike.proxy.spi.DeltaSpikeProxyClassGenerator | 20 + .../AsmDeltaSpikeProxyClassGenerator.xml | 25 + .../proxy/impl/AsmProxyClassGeneratorTest.java | 64 +++ .../deltaspike/proxy/impl/TestAnnotation.java | 34 ++ .../apache/deltaspike/proxy/impl/TestClass.java | 28 + .../proxy/impl/TestInvocationHandler.java | 31 ++ .../EnableInterceptorsTest.java | 90 +++ .../proxy/impl/enableinterceptors/MyBean.java | 59 ++ .../enableinterceptors/MyBeanInterceptor.java | 37 ++ .../MyBeanInterceptorBinding.java | 37 ++ .../impl/enableinterceptors/MyBeanProducer.java | 33 ++ .../test/proxy/impl/util/ArchiveUtils.java | 54 ++ deltaspike/modules/proxy/impl-asm5/pom.xml | 132 ----- .../impl/AsmDeltaSpikeProxyClassGenerator.java | 548 ------------------- .../impl/CopyAnnotationVisitorAdapter.java | 96 ---- .../src/main/resources/META-INF/beans.xml | 23 - ...pike.proxy.spi.DeltaSpikeProxyClassGenerator | 20 - .../AsmDeltaSpikeProxyClassGenerator.xml | 25 - .../proxy/impl/AsmProxyClassGeneratorTest.java | 64 --- .../deltaspike/proxy/impl/TestAnnotation.java | 34 -- .../apache/deltaspike/proxy/impl/TestClass.java | 28 - .../proxy/impl/TestInvocationHandler.java | 31 -- .../EnableInterceptorsTest.java | 90 --- .../proxy/impl/enableinterceptors/MyBean.java | 59 -- .../enableinterceptors/MyBeanInterceptor.java | 37 -- .../MyBeanInterceptorBinding.java | 37 -- .../impl/enableinterceptors/MyBeanProducer.java | 33 -- .../test/proxy/impl/util/ArchiveUtils.java | 54 -- deltaspike/modules/proxy/pom.xml | 2 +- deltaspike/parent/pom.xml | 2 +- documentation/src/main/asciidoc/proxy.adoc | 2 +- 41 files changed, 1323 insertions(+), 1323 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/dist/bom/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/dist/bom/pom.xml b/deltaspike/dist/bom/pom.xml index 5821db9..4c1418d 100644 --- a/deltaspike/dist/bom/pom.xml +++ b/deltaspike/dist/bom/pom.xml @@ -232,7 +232,7 @@ <dependency> <groupId>org.apache.deltaspike.modules</groupId> - <artifactId>deltaspike-proxy-module-impl-asm5</artifactId> + <artifactId>deltaspike-proxy-module-impl-asm</artifactId> <version>${project.version}</version> <scope>runtime</scope> </dependency> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/dist/full/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/dist/full/pom.xml b/deltaspike/dist/full/pom.xml index 96e9e42..3b2e96b 100644 --- a/deltaspike/dist/full/pom.xml +++ b/deltaspike/dist/full/pom.xml @@ -198,7 +198,7 @@ <dependency> <groupId>org.apache.deltaspike.modules</groupId> - <artifactId>deltaspike-proxy-module-impl-asm5</artifactId> + <artifactId>deltaspike-proxy-module-impl-asm</artifactId> <scope>runtime</scope> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/dist/full/src/main/distribution/modules-module.xml ---------------------------------------------------------------------- diff --git a/deltaspike/dist/full/src/main/distribution/modules-module.xml b/deltaspike/dist/full/src/main/distribution/modules-module.xml index 82423e6..eeae2b9 100644 --- a/deltaspike/dist/full/src/main/distribution/modules-module.xml +++ b/deltaspike/dist/full/src/main/distribution/modules-module.xml @@ -32,7 +32,7 @@ <resource-root path="deltaspike-partial-bean-module-api-${project.version}.jar"/> <resource-root path="deltaspike-partial-bean-module-impl-${project.version}.jar"/> <resource-root path="deltaspike-proxy-module-api-${project.version}.jar"/> - <resource-root path="deltaspike-proxy-module-impl-asm5-${project.version}.jar"/> + <resource-root path="deltaspike-proxy-module-impl-asm-${project.version}.jar"/> <resource-root path="deltaspike-security-module-api-${project.version}.jar"/> <resource-root path="deltaspike-security-module-impl-${project.version}.jar"/> <resource-root path="deltaspike-servlet-module-api-${project.version}.jar"/> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/jsf/impl-ee6/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl-ee6/pom.xml b/deltaspike/modules/jsf/impl-ee6/pom.xml index d51da26..7db0213 100644 --- a/deltaspike/modules/jsf/impl-ee6/pom.xml +++ b/deltaspike/modules/jsf/impl-ee6/pom.xml @@ -134,7 +134,7 @@ </dependency> <dependency> <groupId>org.apache.deltaspike.modules</groupId> - <artifactId>deltaspike-proxy-module-impl-asm5</artifactId> + <artifactId>deltaspike-proxy-module-impl-asm</artifactId> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/jsf/impl/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/pom.xml b/deltaspike/modules/jsf/impl/pom.xml index e080800..c0d0367 100644 --- a/deltaspike/modules/jsf/impl/pom.xml +++ b/deltaspike/modules/jsf/impl/pom.xml @@ -116,7 +116,7 @@ </dependency> <dependency> <groupId>org.apache.deltaspike.modules</groupId> - <artifactId>deltaspike-proxy-module-impl-asm5</artifactId> + <artifactId>deltaspike-proxy-module-impl-asm</artifactId> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/partial-bean/impl/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/partial-bean/impl/pom.xml b/deltaspike/modules/partial-bean/impl/pom.xml index db592c0..fb8f808 100644 --- a/deltaspike/modules/partial-bean/impl/pom.xml +++ b/deltaspike/modules/partial-bean/impl/pom.xml @@ -67,25 +67,25 @@ <dependency> <groupId>org.apache.deltaspike.modules</groupId> - <artifactId>deltaspike-proxy-module-impl-asm5</artifactId> + <artifactId>deltaspike-proxy-module-impl-asm</artifactId> </dependency> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> - <version>5.0.3</version> + <version>6.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm-commons</artifactId> - <version>5.0.3</version> + <version>6.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm-tree</artifactId> - <version>5.0.3</version> + <version>6.0</version> <scope>test</scope> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/pom.xml b/deltaspike/modules/proxy/impl-asm/pom.xml new file mode 100644 index 0000000..a9631a8 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/pom.xml @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.deltaspike.modules</groupId> + <artifactId>proxy-module-project</artifactId> + <version>1.8.2-SNAPSHOT</version> + </parent> + + <artifactId>deltaspike-proxy-module-impl-asm</artifactId> + <packaging>bundle</packaging> + + <name>Apache DeltaSpike Proxy-Module Impl ASM</name> + + <properties> + <deltaspike.osgi.export.pkg> + org.apache.deltaspike.proxy.impl.* + </deltaspike.osgi.export.pkg> + <deltaspike.osgi.import> + * + </deltaspike.osgi.import> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>3.1.0</version> + <configuration> + <shadedArtifactAttached>false</shadedArtifactAttached> + <createDependencyReducedPom>false</createDependencyReducedPom> + <promoteTransitiveDependencies>true</promoteTransitiveDependencies> + <relocations> + <relocation> + <pattern>org.objectweb.asm</pattern> + <shadedPattern>org.apache.deltaspike.proxy.asm</shadedPattern> + </relocation> + </relocations> + <artifactSet> + <includes> + <include>org.ow2.asm:asm</include> + <include>org.ow2.asm:asm-commons</include> + <include>org.ow2.asm:asm-tree</include> + </includes> + </artifactSet> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Service-Component>OSGI-INF/*</Service-Component> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.apache.deltaspike.core</groupId> + <artifactId>deltaspike-core-api</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.deltaspike.modules</groupId> + <artifactId>deltaspike-proxy-module-api</artifactId> + </dependency> + + <dependency> + <groupId>org.ow2.asm</groupId> + <artifactId>asm</artifactId> + <version>6.0</version> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.ow2.asm</groupId> + <artifactId>asm-commons</artifactId> + <version>6.0</version> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.ow2.asm</groupId> + <artifactId>asm-tree</artifactId> + <version>6.0</version> + <optional>true</optional> + </dependency> + + <dependency> + <groupId>org.apache.deltaspike.core</groupId> + <artifactId>deltaspike-core-impl</artifactId> + <scope>test</scope> + </dependency> + + <!-- Allows to easily create beans.xml files with certain content --> + <dependency> + <groupId>org.jboss.shrinkwrap.descriptors</groupId> + <artifactId>shrinkwrap-descriptors-impl-javaee</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/AsmDeltaSpikeProxyClassGenerator.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/AsmDeltaSpikeProxyClassGenerator.java b/deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/AsmDeltaSpikeProxyClassGenerator.java new file mode 100644 index 0000000..188ea30 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/AsmDeltaSpikeProxyClassGenerator.java @@ -0,0 +1,548 @@ +/* + * 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.deltaspike.proxy.impl; + +import org.apache.deltaspike.proxy.spi.DeltaSpikeProxy; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.UndeclaredThrowableException; +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.Arrays; + +import javax.enterprise.inject.Typed; + +import org.apache.deltaspike.proxy.spi.invocation.DeltaSpikeProxyInvocationHandler; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.GeneratorAdapter; +import org.objectweb.asm.commons.Method; +import org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator; + +@Typed +public class AsmDeltaSpikeProxyClassGenerator implements DeltaSpikeProxyClassGenerator +{ + private static final String FIELDNAME_INVOCATION_HANDLER = "invocationHandler"; + private static final String FIELDNAME_DELEGATE_INVOCATION_HANDLER = "delegateInvocationHandler"; + private static final String FIELDNAME_DELEGATE_METHODS = "delegateMethods"; + + private static final Type TYPE_CLASS = Type.getType(Class.class); + private static final Type TYPE_OBJECT = Type.getType(Object.class); + private static final Type TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER = + Type.getType(DeltaSpikeProxyInvocationHandler.class); + private static final Type TYPE_METHOD_ARRAY = Type.getType(java.lang.reflect.Method[].class); + private static final Type TYPE_INVOCATION_HANDLER = Type.getType(InvocationHandler.class); + + @Override + public <T> Class<T> generateProxyClass(ClassLoader classLoader, + Class<T> targetClass, + String suffix, + String superAccessorMethodSuffix, + Class<?>[] additionalInterfaces, + java.lang.reflect.Method[] delegateMethods, + java.lang.reflect.Method[] interceptMethods) + { + String proxyName = targetClass.getName() + suffix; + String classFileName = proxyName.replace('.', '/'); + + byte[] proxyBytes = generateProxyClassBytes(targetClass, + classFileName, superAccessorMethodSuffix, additionalInterfaces, delegateMethods, interceptMethods); + + Class<T> proxyClass = (Class<T>) loadClass(classLoader, proxyName, proxyBytes, + targetClass.getProtectionDomain()); + + return proxyClass; + } + + private static byte[] generateProxyClassBytes(Class<?> targetClass, + String proxyName, + String superAccessorMethodSuffix, + Class<?>[] additionalInterfaces, + java.lang.reflect.Method[] delegateMethods, + java.lang.reflect.Method[] interceptMethods) + { + Class<?> superClass = targetClass; + String[] interfaces = new String[] { }; + + if (targetClass.isInterface()) + { + superClass = Object.class; + interfaces = new String[] { Type.getInternalName(targetClass) }; + } + + // add DeltaSpikeProxy as interface + interfaces = Arrays.copyOf(interfaces, interfaces.length + 1); + interfaces[interfaces.length - 1] = Type.getInternalName(DeltaSpikeProxy.class); + + if (additionalInterfaces != null && additionalInterfaces.length > 0) + { + interfaces = Arrays.copyOf(interfaces, interfaces.length + additionalInterfaces.length); + for (int i = 0; i < additionalInterfaces.length; i++) + { + interfaces[(interfaces.length - 1) + i] = Type.getInternalName(additionalInterfaces[i]); + } + } + + Type superType = Type.getType(superClass); + Type proxyType = Type.getObjectType(proxyName); + + final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); + cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, proxyType.getInternalName(), null, + superType.getInternalName(), interfaces); + + + defineDefaultConstructor(cw, proxyType, superType); + defineDeltaSpikeProxyFields(cw); + defineDeltaSpikeProxyMethods(cw, proxyType); + + if (delegateMethods != null) + { + for (java.lang.reflect.Method method : delegateMethods) + { + defineMethod(cw, method, proxyType); + } + } + + if (interceptMethods != null) + { + for (java.lang.reflect.Method method : interceptMethods) + { + defineSuperAccessorMethod(cw, method, superType, superAccessorMethodSuffix); + defineMethod(cw, method, proxyType); + } + } + + // copy all annotations from the source class + try + { + // ClassVisitor to intercept all annotation visits on the class + ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) + { + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) + { + return new CopyAnnotationVisitorAdapter( + super.visitAnnotation(desc, visible), + cw.visitAnnotation(desc, visible)); + } + }; + + // visit class to proxy with our visitor to copy all annotations from the source class to our ClassWriter + String sourceClassFilename = targetClass.getName().replace('.', '/') + ".class"; + ClassReader cr = new ClassReader(targetClass.getClassLoader().getResourceAsStream(sourceClassFilename)); + cr.accept(cv, 0); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + + return cw.toByteArray(); + } + + private static void defineDefaultConstructor(ClassWriter cw, Type proxyType, Type superType) + { + GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, + new Method("<init>", Type.VOID_TYPE, new Type[]{ }), + null, + null, + cw); + + mg.visitCode(); + + // invoke super constructor + mg.loadThis(); + mg.invokeConstructor(superType, Method.getMethod("void <init> ()")); + mg.returnValue(); + mg.endMethod(); + + mg.visitEnd(); + } + + private static void defineDeltaSpikeProxyFields(ClassWriter cw) + { + // generates + // private DeltaSpikeProxyInvocationHandler invocationHandler; + cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_INVOCATION_HANDLER, + TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER.getDescriptor(), null, null).visitEnd(); + + // generates + // private MyInvocationHandler delegateInvocationHandler; + cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_DELEGATE_INVOCATION_HANDLER, + TYPE_INVOCATION_HANDLER.getDescriptor(), null, null).visitEnd(); + + // generates + // private Method[] delegateMethods; + cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_DELEGATE_METHODS, + TYPE_METHOD_ARRAY.getDescriptor(), null, null).visitEnd(); + } + + private static void defineDeltaSpikeProxyMethods(ClassWriter cw, Type proxyType) + { + try + { + // implement #setInvocationHandler + Method asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod( + "setInvocationHandler", DeltaSpikeProxyInvocationHandler.class)); + GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); + + mg.visitCode(); + + mg.loadThis(); + mg.loadArg(0); + mg.checkCast(TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER); + mg.putField(proxyType, FIELDNAME_INVOCATION_HANDLER, TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER); + mg.returnValue(); + + mg.visitMaxs(2, 1); + mg.visitEnd(); + + + // implement #getInvocationHandler + asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod("getInvocationHandler")); + mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); + + mg.visitCode(); + + mg.loadThis(); + mg.getField(proxyType, FIELDNAME_INVOCATION_HANDLER, TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER); + mg.returnValue(); + + mg.visitMaxs(2, 1); + mg.visitEnd(); + + + + + // implement #setDelegateInvocationHandler + asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod( + "setDelegateInvocationHandler", InvocationHandler.class)); + mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); + + mg.visitCode(); + + mg.loadThis(); + mg.loadArg(0); + mg.checkCast(TYPE_INVOCATION_HANDLER); + mg.putField(proxyType, FIELDNAME_DELEGATE_INVOCATION_HANDLER, TYPE_INVOCATION_HANDLER); + mg.returnValue(); + + mg.visitMaxs(2, 1); + mg.visitEnd(); + + + // implement #getDelegateInvocationHandler + asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod("getDelegateInvocationHandler")); + mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); + + mg.visitCode(); + + mg.loadThis(); + mg.getField(proxyType, FIELDNAME_DELEGATE_INVOCATION_HANDLER, TYPE_INVOCATION_HANDLER); + mg.returnValue(); + + mg.visitMaxs(2, 1); + mg.visitEnd(); + + + + + // implement #setDelegateMethods + asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod( + "setDelegateMethods", java.lang.reflect.Method[].class)); + mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); + + mg.visitCode(); + + mg.loadThis(); + mg.loadArg(0); + mg.checkCast(TYPE_METHOD_ARRAY); + mg.putField(proxyType, FIELDNAME_DELEGATE_METHODS, TYPE_METHOD_ARRAY); + mg.returnValue(); + + mg.visitMaxs(2, 1); + mg.visitEnd(); + + + // implement #getDelegateMethods + asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod("getDelegateMethods")); + mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); + + mg.visitCode(); + + mg.loadThis(); + mg.getField(proxyType, FIELDNAME_DELEGATE_METHODS, TYPE_METHOD_ARRAY); + mg.returnValue(); + + mg.visitMaxs(2, 1); + mg.visitEnd(); + } + catch (NoSuchMethodException e) + { + throw new IllegalStateException("Unable to implement " + DeltaSpikeProxy.class.getName(), e); + } + } + + private static void defineSuperAccessorMethod(ClassWriter cw, java.lang.reflect.Method method, Type superType, + String superAccessorMethodSuffix) + { + Method originalAsmMethod = Method.getMethod(method); + Method newAsmMethod = new Method(method.getName() + superAccessorMethodSuffix, + originalAsmMethod.getReturnType(), + originalAsmMethod.getArgumentTypes()); + GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, newAsmMethod, null, null, cw); + + mg.visitCode(); + + // call super method + mg.loadThis(); + mg.loadArgs(); + mg.visitMethodInsn(Opcodes.INVOKESPECIAL, + superType.getInternalName(), + method.getName(), + Type.getMethodDescriptor(method), + false); + mg.returnValue(); + + // finish the method + mg.endMethod(); + mg.visitMaxs(10, 10); + mg.visitEnd(); + } + + private static void defineMethod(ClassWriter cw, java.lang.reflect.Method method, Type proxyType) + { + Type methodType = Type.getType(method); + + ArrayList<Type> exceptionsToCatch = new ArrayList<Type>(); + for (Class<?> exception : method.getExceptionTypes()) + { + if (!RuntimeException.class.isAssignableFrom(exception)) + { + exceptionsToCatch.add(Type.getType(exception)); + } + } + + // push the method definition + int modifiers = (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED) & method.getModifiers(); + Method asmMethod = Method.getMethod(method); + GeneratorAdapter mg = new GeneratorAdapter(modifiers, + asmMethod, + null, + getTypes(method.getExceptionTypes()), + cw); + + // copy annotations + for (Annotation annotation : method.getDeclaredAnnotations()) + { + mg.visitAnnotation(Type.getDescriptor(annotation.annotationType()), true).visitEnd(); + } + + mg.visitCode(); + + Label tryBlockStart = mg.mark(); + + mg.loadThis(); + mg.getField(proxyType, FIELDNAME_INVOCATION_HANDLER, TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER); + mg.loadThis(); + loadCurrentMethod(mg, method, methodType); + loadArguments(mg, method, methodType); + + mg.invokeVirtual(TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER, + Method.getMethod("Object invoke(Object, java.lang.reflect.Method, Object[])")); + + // cast the result + mg.unbox(methodType.getReturnType()); + + // build try catch + Label tryBlockEnd = mg.mark(); + + // push return + mg.returnValue(); + + // catch runtime exceptions and rethrow it + Label rethrow = mg.mark(); + mg.visitVarInsn(Opcodes.ASTORE, 1); + mg.visitVarInsn(Opcodes.ALOAD, 1); + mg.throwException(); + mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrow, Type.getInternalName(RuntimeException.class)); + + // catch checked exceptions and rethrow it + boolean throwableCatched = false; + if (!exceptionsToCatch.isEmpty()) + { + rethrow = mg.mark(); + mg.visitVarInsn(Opcodes.ASTORE, 1); + mg.visitVarInsn(Opcodes.ALOAD, 1); + mg.throwException(); + + // catch declared exceptions and rethrow it... + for (Type exceptionType : exceptionsToCatch) + { + if (exceptionType.getClassName().equals(Throwable.class.getName())) + { + throwableCatched = true; + } + mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrow, exceptionType.getInternalName()); + } + } + + // if throwable isn't alreached cachted, catch it and wrap it with an UndeclaredThrowableException and throw it + if (!throwableCatched) + { + Type uteType = Type.getType(UndeclaredThrowableException.class); + Label wrapAndRethrow = mg.mark(); + + mg.visitVarInsn(Opcodes.ASTORE, 1); + mg.newInstance(uteType); + mg.dup(); + mg.visitVarInsn(Opcodes.ALOAD, 1); + mg.invokeConstructor(uteType, + Method.getMethod("void <init>(java.lang.Throwable)")); + mg.throwException(); + + mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, wrapAndRethrow, Type.getInternalName(Throwable.class)); + } + + // finish the method + mg.endMethod(); + mg.visitMaxs(12, 12); + mg.visitEnd(); + } + + /** + * Generates: + * <pre> + * Method method = + * method.getDeclaringClass().getMethod("methodName", new Class[] { args... }); + * </pre> + * @param mg + * @param method + * @param methodType + */ + private static void loadCurrentMethod(GeneratorAdapter mg, java.lang.reflect.Method method, Type methodType) + { + mg.push(Type.getType(method.getDeclaringClass())); + mg.push(method.getName()); + + // create the Class[] + mg.push(methodType.getArgumentTypes().length); + mg.newArray(TYPE_CLASS); + + // push parameters into array + for (int i = 0; i < methodType.getArgumentTypes().length; i++) + { + // keep copy of array on stack + mg.dup(); + + // push index onto stack + mg.push(i); + mg.push(methodType.getArgumentTypes()[i]); + mg.arrayStore(TYPE_CLASS); + } + + // invoke getMethod() with the method name and the array of types + mg.invokeVirtual(TYPE_CLASS, Method.getMethod("java.lang.reflect.Method getDeclaredMethod(String, Class[])")); + } + + /** + * Defines a new Object[] and push all method argmuments into the array. + * + * @param mg + * @param method + * @param methodType + */ + private static void loadArguments(GeneratorAdapter mg, java.lang.reflect.Method method, Type methodType) + { + // create the Object[] + mg.push(methodType.getArgumentTypes().length); + mg.newArray(TYPE_OBJECT); + + // push parameters into array + for (int i = 0; i < methodType.getArgumentTypes().length; i++) + { + // keep copy of array on stack + mg.dup(); + + // push index onto stack + mg.push(i); + + mg.loadArg(i); + mg.valueOf(methodType.getArgumentTypes()[i]); + mg.arrayStore(TYPE_OBJECT); + } + } + + private static Type[] getTypes(Class<?>... src) + { + Type[] result = new Type[src.length]; + for (int i = 0; i < result.length; i++) + { + result[i] = Type.getType(src[i]); + } + return result; + } + + /** + * Adapted from http://asm.ow2.org/doc/faq.html#Q5 + * + * @param b + * + * @return Class<?> + */ + private static Class<?> loadClass(ClassLoader loader, String className, byte[] b, + ProtectionDomain protectionDomain) + { + // override classDefine (as it is protected) and define the class. + try + { + java.lang.reflect.Method method = ClassLoader.class.getDeclaredMethod( + "defineClass", String.class, byte[].class, int.class, int.class, ProtectionDomain.class); + + // protected method invocation + boolean accessible = method.isAccessible(); + if (!accessible) + { + method.setAccessible(true); + } + try + { + return (Class<?>) method.invoke(loader, className, b, Integer.valueOf(0), Integer.valueOf(b.length), + protectionDomain); + } + finally + { + if (!accessible) + { + method.setAccessible(false); + } + } + } + catch (Exception e) + { + throw e instanceof RuntimeException ? ((RuntimeException) e) : new RuntimeException(e); + } + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/CopyAnnotationVisitorAdapter.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/CopyAnnotationVisitorAdapter.java b/deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/CopyAnnotationVisitorAdapter.java new file mode 100644 index 0000000..17dbedf --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/CopyAnnotationVisitorAdapter.java @@ -0,0 +1,96 @@ +/* + * 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.deltaspike.proxy.impl; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Opcodes; + +public class CopyAnnotationVisitorAdapter extends AnnotationVisitor +{ + private final AnnotationVisitor from; + private final AnnotationVisitor to; + + public CopyAnnotationVisitorAdapter(AnnotationVisitor from, AnnotationVisitor copyTo) + { + super(Opcodes.ASM5); + + this.from = from; + this.to = copyTo; + } + + @Override + public void visit(String name, Object value) + { + if (from != null) + { + from.visit(name, value); + } + to.visit(name, value); + } + + @Override + public void visitEnum(String name, String desc, String value) + { + if (from != null) + { + from.visitEnum(name, desc, value); + } + to.visitEnum(name, desc, value); + } + + @Override + public AnnotationVisitor visitAnnotation(String name, String desc) + { + if (from == null) + { + return new CopyAnnotationVisitorAdapter( + null, + to.visitAnnotation(name, desc)); + } + + return new CopyAnnotationVisitorAdapter( + from.visitAnnotation(name, desc), + to.visitAnnotation(name, desc)); + } + + @Override + public AnnotationVisitor visitArray(String name) + { + if (from == null) + { + return new CopyAnnotationVisitorAdapter( + null, + to.visitArray(name)); + } + + return new CopyAnnotationVisitorAdapter( + from.visitArray(name), + to.visitArray(name)); + } + + @Override + public void visitEnd() + { + if (from != null) + { + from.visitEnd(); + } + to.visitEnd(); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/beans.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/beans.xml b/deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000..a2308ff --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/beans.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<beans xmlns="http://java.sun.com/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> +</beans> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/services/org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/services/org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator b/deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/services/org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator new file mode 100644 index 0000000..47acd0b --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/services/org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator @@ -0,0 +1,20 @@ +# +# 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. +# + +org.apache.deltaspike.proxy.impl.AsmDeltaSpikeProxyClassGenerator \ No newline at end of file http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/main/resources/OSGI-INF/AsmDeltaSpikeProxyClassGenerator.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/main/resources/OSGI-INF/AsmDeltaSpikeProxyClassGenerator.xml b/deltaspike/modules/proxy/impl-asm/src/main/resources/OSGI-INF/AsmDeltaSpikeProxyClassGenerator.xml new file mode 100644 index 0000000..8f5877c --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/main/resources/OSGI-INF/AsmDeltaSpikeProxyClassGenerator.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="AsmDeltaSpikeProxyClassGenerator"> + <implementation class="org.apache.deltaspike.proxy.impl.AsmDeltaSpikeProxyClassGenerator"/> + <service> + <provide interface="org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator"/> + </service> +</scr:component> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/AsmProxyClassGeneratorTest.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/AsmProxyClassGeneratorTest.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/AsmProxyClassGeneratorTest.java new file mode 100644 index 0000000..9ccfec2 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/AsmProxyClassGeneratorTest.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.deltaspike.proxy.impl; + +import javax.inject.Named; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class AsmProxyClassGeneratorTest +{ + private static Class<? extends TestClass> proxyClass; + + @BeforeClass + public static void init() + { + AsmDeltaSpikeProxyClassGenerator asmProxyClassGenerator = new AsmDeltaSpikeProxyClassGenerator(); + proxyClass = asmProxyClassGenerator.generateProxyClass(TestClass.class.getClassLoader(), + TestClass.class, + "$Test", + "$super", + null, + null, + null); + } + + @Test + public void testCopyAnnotationValues() + { + Assert.assertEquals( + TestClass.class.getAnnotations().length, + proxyClass.getAnnotations().length); + + Assert.assertEquals( + TestClass.class.getAnnotation(Named.class).value(), + proxyClass.getAnnotation(Named.class).value()); + + Assert.assertEquals( + TestClass.class.getAnnotation(TestAnnotation.class).value1(), + proxyClass.getAnnotation(TestAnnotation.class).value1()); + Assert.assertEquals( + TestClass.class.getAnnotation(TestAnnotation.class).value2(), + proxyClass.getAnnotation(TestAnnotation.class).value2()); + Assert.assertEquals( + TestClass.class.getAnnotation(TestAnnotation.class).value3(), + proxyClass.getAnnotation(TestAnnotation.class).value3()); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestAnnotation.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestAnnotation.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestAnnotation.java new file mode 100644 index 0000000..0056ab9 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestAnnotation.java @@ -0,0 +1,34 @@ +/* + * 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.deltaspike.proxy.impl; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Documented +@Retention(value = RetentionPolicy.RUNTIME) +public @interface TestAnnotation +{ + int value1() default 13; + + Class value2() default TestAnnotation.class; + + String value3() default "tester"; +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestClass.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestClass.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestClass.java new file mode 100644 index 0000000..0df8b06 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestClass.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.deltaspike.proxy.impl; + +import javax.inject.Named; + +@Named("test") +@TestAnnotation(value2 = TestClass.class, value1 = 15) +public class TestClass +{ + +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestInvocationHandler.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestInvocationHandler.java new file mode 100644 index 0000000..e466839 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestInvocationHandler.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.deltaspike.proxy.impl; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +public class TestInvocationHandler implements InvocationHandler +{ + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable + { + return null; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/EnableInterceptorsTest.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/EnableInterceptorsTest.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/EnableInterceptorsTest.java new file mode 100644 index 0000000..adf4b09 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/EnableInterceptorsTest.java @@ -0,0 +1,90 @@ +/* + * 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.deltaspike.proxy.impl.enableinterceptors; + +import javax.inject.Inject; + +import org.apache.deltaspike.proxy.util.EnableInterceptorsInterceptor; +import org.apache.deltaspike.test.proxy.impl.util.ArchiveUtils; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.descriptor.api.Descriptors; +import org.jboss.shrinkwrap.descriptor.api.beans10.BeansDescriptor; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(Arquillian.class) +public class EnableInterceptorsTest +{ + @Deployment + public static WebArchive war() + { + String simpleName = EnableInterceptorsTest.class.getSimpleName(); + String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); + + // CDI 1.0/Weld 1.x needs EnableInterceptorsInterceptor + BeansDescriptor beansWithEnablingInterceptor = Descriptors.create(BeansDescriptor.class); + beansWithEnablingInterceptor.getOrCreateInterceptors().clazz(EnableInterceptorsInterceptor.class.getName()); + + // war archive needs MyBeanInterceptor enabled + BeansDescriptor beans = Descriptors.create(BeansDescriptor.class); + beans.getOrCreateInterceptors().clazz(MyBeanInterceptor.class.getName()); + + JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") + .addPackage(EnableInterceptorsTest.class.getPackage()) + .addAsManifestResource(new StringAsset(beansWithEnablingInterceptor.exportAsString()), "beans.xml"); + + return ShrinkWrap.create(WebArchive.class, archiveName + ".war") + .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndProxyArchive()) + .addAsLibraries(testJar) + .addAsWebInfResource(new StringAsset(beans.exportAsString()), "beans.xml"); + } + + @Inject + private MyBean myBean; + + @Test + public void testInterception() throws Exception + { + Assert.assertFalse(myBean.isIntercepted()); + Assert.assertFalse(myBean.isMethodCalled()); + + myBean.somethingIntercepted(); + + Assert.assertTrue(myBean.isIntercepted()); + Assert.assertTrue(myBean.isMethodCalled()); + } + + @Test + public void testNonInterception() throws Exception + { + Assert.assertFalse(myBean.isIntercepted()); + Assert.assertFalse(myBean.isMethodCalled()); + + myBean.somethingNotIntercepted(); + + Assert.assertFalse(myBean.isIntercepted()); + Assert.assertTrue(myBean.isMethodCalled()); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBean.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBean.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBean.java new file mode 100644 index 0000000..e1406e8 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBean.java @@ -0,0 +1,59 @@ +/* + * 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.deltaspike.proxy.impl.enableinterceptors; + +import org.apache.deltaspike.core.api.exclude.Exclude; + +@Exclude +public class MyBean +{ + private boolean intercepted; + private boolean methodCalled; + + public boolean isIntercepted() + { + return intercepted; + } + + public void setIntercepted(boolean intercepted) + { + this.intercepted = intercepted; + } + + public boolean isMethodCalled() + { + return methodCalled; + } + + public void setMethodCalled(boolean methodCalled) + { + this.methodCalled = methodCalled; + } + + @MyBeanInterceptorBinding + public void somethingIntercepted() + { + methodCalled = true; + } + + public void somethingNotIntercepted() + { + methodCalled = true; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanInterceptor.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanInterceptor.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanInterceptor.java new file mode 100644 index 0000000..edf53af --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanInterceptor.java @@ -0,0 +1,37 @@ +/* + * 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.deltaspike.proxy.impl.enableinterceptors; + +import java.io.Serializable; +import javax.interceptor.AroundInvoke; +import javax.interceptor.Interceptor; +import javax.interceptor.InvocationContext; + +@Interceptor +@MyBeanInterceptorBinding +public class MyBeanInterceptor implements Serializable +{ + @AroundInvoke + public Object wrapBeanCandidate(InvocationContext invocationContext) throws Exception + { + ((MyBean) invocationContext.getTarget()).setIntercepted(true); + + return invocationContext.proceed(); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanInterceptorBinding.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanInterceptorBinding.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanInterceptorBinding.java new file mode 100644 index 0000000..77fa1c8 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanInterceptorBinding.java @@ -0,0 +1,37 @@ +/* + * 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.deltaspike.proxy.impl.enableinterceptors; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.interceptor.InterceptorBinding; + +@InterceptorBinding +@Documented +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE, ElementType.METHOD }) +public @interface MyBeanInterceptorBinding +{ + +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanProducer.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanProducer.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanProducer.java new file mode 100644 index 0000000..4344222 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/enableinterceptors/MyBeanProducer.java @@ -0,0 +1,33 @@ +/* + * 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.deltaspike.proxy.impl.enableinterceptors; + +import javax.enterprise.inject.Produces; +import org.apache.deltaspike.proxy.api.EnableInterceptors; + +public class MyBeanProducer +{ + @Produces + @EnableInterceptors + public MyBean produce() + { + MyBean myBean = new MyBean(); + return myBean; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/test/proxy/impl/util/ArchiveUtils.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/test/proxy/impl/util/ArchiveUtils.java b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/test/proxy/impl/util/ArchiveUtils.java new file mode 100644 index 0000000..e772b6a --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/test/proxy/impl/util/ArchiveUtils.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.deltaspike.test.proxy.impl.util; + +import java.util.ArrayList; +import java.util.Arrays; +import org.apache.deltaspike.test.utils.ShrinkWrapArchiveUtil; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; + +public abstract class ArchiveUtils +{ + private ArchiveUtils() + { + } + + public static JavaArchive[] getDeltaSpikeCoreAndProxyArchive() + { + ArrayList<JavaArchive> result = new ArrayList<JavaArchive>(); + + JavaArchive[] temp; + + temp = ShrinkWrapArchiveUtil.getArchives(null, + "META-INF/beans.xml", + new String[] { "org.apache.deltaspike.core", + "org.apache.deltaspike.proxy", + "org.apache.deltaspike.test.category"}, + new String[] { "META-INF.apache-deltaspike.properties" }, + "ds-core_and_proxy"); + result.addAll(Arrays.asList(temp)); + + // add asm - it isn't shaded yet in the test phase + result.add(ShrinkWrap.create(JavaArchive.class, "ds-asm.jar") + .addPackages(true, "org.objectweb.asm")); + + return result.toArray(new JavaArchive[result.size()]); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/028ec5bf/deltaspike/modules/proxy/impl-asm5/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/pom.xml b/deltaspike/modules/proxy/impl-asm5/pom.xml deleted file mode 100644 index 3f16d3b..0000000 --- a/deltaspike/modules/proxy/impl-asm5/pom.xml +++ /dev/null @@ -1,132 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ 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. - --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.apache.deltaspike.modules</groupId> - <artifactId>proxy-module-project</artifactId> - <version>1.8.2-SNAPSHOT</version> - </parent> - - <artifactId>deltaspike-proxy-module-impl-asm5</artifactId> - <packaging>bundle</packaging> - - <name>Apache DeltaSpike Proxy-Module Impl ASM5</name> - - <properties> - <deltaspike.osgi.export.pkg> - org.apache.deltaspike.proxy.impl.* - </deltaspike.osgi.export.pkg> - <deltaspike.osgi.import> - * - </deltaspike.osgi.import> - </properties> - - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-shade-plugin</artifactId> - <version>2.3</version> - <configuration> - <shadedArtifactAttached>false</shadedArtifactAttached> - <createDependencyReducedPom>false</createDependencyReducedPom> - <promoteTransitiveDependencies>true</promoteTransitiveDependencies> - <relocations> - <relocation> - <pattern>org.objectweb.asm</pattern> - <shadedPattern>org.apache.deltaspike.proxy.asm5</shadedPattern> - </relocation> - </relocations> - <artifactSet> - <includes> - <include>org.ow2.asm:asm</include> - <include>org.ow2.asm:asm-commons</include> - <include>org.ow2.asm:asm-tree</include> - </includes> - </artifactSet> - </configuration> - <executions> - <execution> - <phase>package</phase> - <goals> - <goal>shade</goal> - </goals> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <configuration> - <instructions> - <Service-Component>OSGI-INF/*</Service-Component> - </instructions> - </configuration> - </plugin> - </plugins> - </build> - - <dependencies> - <dependency> - <groupId>org.apache.deltaspike.core</groupId> - <artifactId>deltaspike-core-api</artifactId> - </dependency> - - <dependency> - <groupId>org.apache.deltaspike.modules</groupId> - <artifactId>deltaspike-proxy-module-api</artifactId> - </dependency> - - <dependency> - <groupId>org.ow2.asm</groupId> - <artifactId>asm</artifactId> - <version>5.0.3</version> - <optional>true</optional> - </dependency> - <dependency> - <groupId>org.ow2.asm</groupId> - <artifactId>asm-commons</artifactId> - <version>5.0.3</version> - <optional>true</optional> - </dependency> - <dependency> - <groupId>org.ow2.asm</groupId> - <artifactId>asm-tree</artifactId> - <version>5.0.3</version> - <optional>true</optional> - </dependency> - - <dependency> - <groupId>org.apache.deltaspike.core</groupId> - <artifactId>deltaspike-core-impl</artifactId> - <scope>test</scope> - </dependency> - - <!-- Allows to easily create beans.xml files with certain content --> - <dependency> - <groupId>org.jboss.shrinkwrap.descriptors</groupId> - <artifactId>shrinkwrap-descriptors-impl-javaee</artifactId> - <scope>test</scope> - </dependency> - </dependencies> - -</project>
