Repository: deltaspike Updated Branches: refs/heads/master 0b5c027c6 -> 4d6aadc54
http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/api/DeltaSpikeProxyFactory.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/api/DeltaSpikeProxyFactory.java b/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/api/DeltaSpikeProxyFactory.java new file mode 100644 index 0000000..a0fb274 --- /dev/null +++ b/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/api/DeltaSpikeProxyFactory.java @@ -0,0 +1,288 @@ +/* + * 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.api; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import javax.interceptor.InterceptorBinding; +import org.apache.deltaspike.core.util.ClassUtils; +import org.apache.deltaspike.core.util.ServiceUtils; +import org.apache.deltaspike.proxy.spi.ProxyClassGenerator; + +public abstract class DeltaSpikeProxyFactory +{ + private static final String SUPER_ACCESSOR_METHOD_SUFFIX = "$super"; + + public <T> Class<T> getProxyClass(Class<T> targetClass, + Class<? extends InvocationHandler> delegateInvocationHandlerClass) + { + // check if a proxy is already defined for this class + Class<T> proxyClass = ClassUtils.tryToLoadClassForName(constructProxyClassName(targetClass), targetClass); + if (proxyClass == null) + { + proxyClass = createProxyClass(targetClass.getClassLoader(), targetClass, delegateInvocationHandlerClass); + } + + return proxyClass; + } + + private synchronized <T> Class<T> createProxyClass(ClassLoader classLoader, Class<T> targetClass, + Class<? extends InvocationHandler> delegateInvocationHandlerClass) + { + Class<T> proxyClass = ClassUtils.tryToLoadClassForName(constructProxyClassName(targetClass), targetClass); + if (proxyClass == null) + { + ArrayList<Method> allMethods = collectAllMethods(targetClass); + ArrayList<Method> interceptMethods = filterInterceptMethods(targetClass, allMethods); + ArrayList<Method> delegateMethods = getDelegateMethods(targetClass, allMethods); + + // check if a interceptor is defined on class level. if not, skip interceptor methods + if (delegateMethods != null + && interceptMethods.size() > 0 + && !containsInterceptorBinding(targetClass.getDeclaredAnnotations())) + { + // loop every method and check if a interceptor is defined on the method -> otherwise don't overwrite + // interceptMethods + Iterator<Method> iterator = interceptMethods.iterator(); + while (iterator.hasNext()) + { + Method method = iterator.next(); + if (!containsInterceptorBinding(method.getDeclaredAnnotations())) + { + iterator.remove(); + } + } + } + + List<ProxyClassGenerator> proxyClassGeneratorList = + ServiceUtils.loadServiceImplementations(ProxyClassGenerator.class); + + if (proxyClassGeneratorList.size() != 1) + { + throw new IllegalStateException(proxyClassGeneratorList.size() + + " implementations of " + ProxyClassGenerator.class.getName() + + " found. It's just allowed to use one implementation."); + } + + proxyClass = proxyClassGeneratorList.iterator().next().generateProxyClass(classLoader, + targetClass, + delegateInvocationHandlerClass, + getProxyClassSuffix(), + SUPER_ACCESSOR_METHOD_SUFFIX, + getAdditionalInterfacesToImplement(targetClass), + delegateMethods == null ? new Method[0] + : delegateMethods.toArray(new Method[delegateMethods.size()]), + interceptMethods == null ? new Method[0] + : interceptMethods.toArray(new Method[interceptMethods.size()])); + } + + return proxyClass; + } + + // TODO stereotypes + protected boolean containsInterceptorBinding(Annotation[] annotations) + { + for (Annotation annotation : annotations) + { + if (annotation.annotationType().isAnnotationPresent(InterceptorBinding.class)) + { + return true; + } + } + + return false; + } + + protected String constructProxyClassName(Class<?> clazz) + { + return clazz.getName() + getProxyClassSuffix(); + } + + protected static String constructSuperAccessorMethodName(Method method) + { + return method.getName() + SUPER_ACCESSOR_METHOD_SUFFIX; + } + + public static Method getSuperAccessorMethod(Object proxy, Method method) throws NoSuchMethodException + { + return proxy.getClass().getMethod( + constructSuperAccessorMethodName(method), + method.getParameterTypes()); + } + + /** + * Checks if the given class is DS proxy class. + * + * @param clazz + * @return + */ + public boolean isProxyClass(Class<?> clazz) + { + return clazz.getName().endsWith(getProxyClassSuffix()); + } + + protected boolean hasSameSignature(Method a, Method b) + { + return a.getName().equals(b.getName()) + && a.getReturnType().equals(b.getReturnType()) + && Arrays.equals(a.getParameterTypes(), b.getParameterTypes()); + } + + protected boolean ignoreMethod(Method method, List<Method> methods) + { + // we have no interest in generics bridge methods + if (method.isBridge()) + { + return true; + } + + // we do not proxy finalize() + if ("finalize".equals(method.getName())) + { + return true; + } + + // same method... + if (methods.contains(method)) + { + return true; + } + + // check if a method with the same signature is already available + for (Method currentMethod : methods) + { + if (hasSameSignature(currentMethod, method)) + { + return true; + } + } + + return false; + } + + protected ArrayList<Method> collectAllMethods(Class<?> clazz) + { + ArrayList<Method> methods = new ArrayList<Method>(); + for (Method method : clazz.getDeclaredMethods()) + { + if (!ignoreMethod(method, methods)) + { + methods.add(method); + } + } + for (Method method : clazz.getMethods()) + { + if (!ignoreMethod(method, methods)) + { + methods.add(method); + } + } + + // collect methods from abstract super classes... + Class currentSuperClass = clazz.getSuperclass(); + while (currentSuperClass != null) + { + if (Modifier.isAbstract(currentSuperClass.getModifiers())) + { + for (Method method : currentSuperClass.getDeclaredMethods()) + { + if (!ignoreMethod(method, methods)) + { + methods.add(method); + } + } + for (Method method : currentSuperClass.getMethods()) + { + if (!ignoreMethod(method, methods)) + { + methods.add(method); + } + } + } + currentSuperClass = currentSuperClass.getSuperclass(); + } + + // sort out somewhere implemented abstract methods + Class currentClass = clazz; + while (currentClass != null) + { + Iterator<Method> methodIterator = methods.iterator(); + while (methodIterator.hasNext()) + { + Method method = methodIterator.next(); + if (Modifier.isAbstract(method.getModifiers())) + { + try + { + Method foundMethod = currentClass.getMethod(method.getName(), method.getParameterTypes()); + // if method is implementent in the current class -> remove it + if (foundMethod != null && !Modifier.isAbstract(foundMethod.getModifiers())) + { + methodIterator.remove(); + } + } + catch (Exception e) + { + // ignore... + } + } + } + + currentClass = currentClass.getSuperclass(); + } + + return methods; + } + + protected ArrayList<Method> filterInterceptMethods(Class<?> targetClass, ArrayList<Method> allMethods) + { + ArrayList<Method> methods = new ArrayList<Method>(); + + Iterator<Method> it = allMethods.iterator(); + while (it.hasNext()) + { + Method method = it.next(); + + if (Modifier.isPublic(method.getModifiers()) + && !Modifier.isFinal(method.getModifiers()) + && !Modifier.isAbstract(method.getModifiers())) + { + methods.add(method); + } + } + + return methods; + } + + protected Class<?>[] getAdditionalInterfacesToImplement(Class<?> targetClass) + { + return null; + } + + protected abstract ArrayList<Method> getDelegateMethods(Class<?> targetClass, ArrayList<Method> allMethods); + + protected abstract String getProxyClassSuffix(); +} + http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/DeltaSpikeProxy.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/DeltaSpikeProxy.java b/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/DeltaSpikeProxy.java new file mode 100644 index 0000000..d58b87d --- /dev/null +++ b/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/DeltaSpikeProxy.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.spi; + +import java.lang.reflect.InvocationHandler; + +/** + * Interface which will automatically be implemented by the proxy instance. + */ +public interface DeltaSpikeProxy +{ + void setDelegateInvocationHandler(InvocationHandler delegateInvocationHandler); + + InvocationHandler getDelegateInvocationHandler(); +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/ProxyClassGenerator.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/ProxyClassGenerator.java b/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/ProxyClassGenerator.java new file mode 100644 index 0000000..5898e7a --- /dev/null +++ b/deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/ProxyClassGenerator.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.spi; + +import java.lang.reflect.InvocationHandler; + +public interface ProxyClassGenerator +{ + <T> Class<T> generateProxyClass(ClassLoader classLoader, + Class<T> targetClass, + Class<? extends InvocationHandler> delegateInvocationHandlerClass, + String suffix, + String superAccessorMethodSuffix, + Class<?>[] additionalInterfaces, + java.lang.reflect.Method[] delegateMethods, + java.lang.reflect.Method[] interceptMethods); +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/api/src/main/resources/META-INF/beans.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/api/src/main/resources/META-INF/beans.xml b/deltaspike/modules/proxy/api/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000..4070730 --- /dev/null +++ b/deltaspike/modules/proxy/api/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/4d6aadc5/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 new file mode 100644 index 0000000..c17ae0d --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/pom.xml @@ -0,0 +1,100 @@ +<?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.3.1-SNAPSHOT</version> + </parent> + + <artifactId>deltaspike-proxy-module-impl-asm5</artifactId> + + <name>Apache DeltaSpike Proxy-Module Impl ASM5</name> + + <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> + </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> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/AsmProxyClassGenerator.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/AsmProxyClassGenerator.java b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/AsmProxyClassGenerator.java new file mode 100644 index 0000000..c33d11c --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/AsmProxyClassGenerator.java @@ -0,0 +1,467 @@ +/* + * 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 org.apache.deltaspike.proxy.impl.invocation.DelegateManualInvocationHandler; +import org.apache.deltaspike.proxy.impl.invocation.InterceptManualInvocationHandler; + +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.ProxyClassGenerator; +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; + +@Typed +public class AsmProxyClassGenerator implements ProxyClassGenerator +{ + private static final String FIELDNAME_DELEGATE_INVOCATION_HANDLER = "delegateInvocationHandler"; + + private static final Type TYPE_CLASS = Type.getType(Class.class); + private static final Type TYPE_OBJECT = Type.getType(Object.class); + + public <T> Class<T> generateProxyClass(ClassLoader classLoader, + Class<T> targetClass, + Class<? extends InvocationHandler> delegateInvocationHandlerClass, + String suffix, + String superAccessorMethodSuffix, + Class<?>[] additionalInterfaces, + java.lang.reflect.Method[] delegateMethods, + java.lang.reflect.Method[] interceptMethods) + { + String proxyName = targetClass.getCanonicalName() + suffix; + String classFileName = proxyName.replace('.', '/'); + + byte[] proxyBytes = generateProxyClassBytes(targetClass, delegateInvocationHandlerClass, + classFileName, superAccessorMethodSuffix, additionalInterfaces, delegateMethods, interceptMethods); + + Class<T> proxyClass = (Class<T>) loadClass(classLoader, proxyName, proxyBytes, + targetClass.getProtectionDomain()); + + return proxyClass; + } + + private static byte[] generateProxyClassBytes(Class<?> targetClass, + Class<? extends InvocationHandler> delegateInvocationHandlerClass, + 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); + Type delegateInvocationHandlerType = Type.getType(delegateInvocationHandlerClass); + + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); + cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, proxyType.getInternalName(), null, + superType.getInternalName(), interfaces); + + // copy annotations + for (Annotation annotation : targetClass.getDeclaredAnnotations()) + { + cw.visitAnnotation(Type.getDescriptor(annotation.annotationType()), true).visitEnd(); + } + + defineInvocationHandlerField(cw, delegateInvocationHandlerType); + defineDefaultConstructor(cw, proxyType, superType); + defineDelegateInvocationHandlerConstructor(cw, proxyType, superType, delegateInvocationHandlerType); + defineDeltaSpikeProxyMethods(cw, proxyType, delegateInvocationHandlerType); + + for (java.lang.reflect.Method method : delegateMethods) + { + defineMethod(cw, method, DelegateManualInvocationHandler.class); + } + + for (java.lang.reflect.Method method : interceptMethods) + { + defineSuperAccessorMethod(cw, method, superType, superAccessorMethodSuffix); + defineMethod(cw, method, InterceptManualInvocationHandler.class); + } + + return cw.toByteArray(); + } + + private static void defineInvocationHandlerField(ClassWriter cw, Type delegateInvocationHandlerType) + { + // generates + // private MyInvocationHandler delegateInvocationHandler; + cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_DELEGATE_INVOCATION_HANDLER, + delegateInvocationHandlerType.getDescriptor(), null, null).visitEnd(); + } + + 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 defineDelegateInvocationHandlerConstructor(ClassWriter cw, Type proxyType, Type superType, + Type delegateInvocationHandlerType) + { + GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, + new Method("<init>", Type.VOID_TYPE, new Type[] { delegateInvocationHandlerType }), + null, + null, + cw); + + mg.visitCode(); + + // invoke super constructor + mg.loadThis(); + mg.invokeConstructor(superType, Method.getMethod("void <init> ()")); + + // set invocation handler + mg.loadThis(); + mg.loadArg(0); + mg.putField(proxyType, FIELDNAME_DELEGATE_INVOCATION_HANDLER, delegateInvocationHandlerType); + + mg.returnValue(); + mg.endMethod(); + + mg.visitEnd(); + } + + private static void defineDeltaSpikeProxyMethods(ClassWriter cw, Type proxyType, Type delegateInvocationHandlerType) + { + try + { + // implement #setDelegateInvocationHandler + Method asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod( + "setDelegateInvocationHandler", InvocationHandler.class)); + GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); + + mg.visitCode(); + + mg.loadThis(); + mg.loadArg(0); + mg.checkCast(delegateInvocationHandlerType); + mg.putField(proxyType, FIELDNAME_DELEGATE_INVOCATION_HANDLER, delegateInvocationHandlerType); + 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, delegateInvocationHandlerType); + 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, + Class manualInvocationHandlerClass) + { + 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(); + loadCurrentMethod(mg, method, methodType); + loadArguments(mg, method, methodType); + + // invoke our ProxyInvocationHandler + mg.invokeStatic(Type.getType(manualInvocationHandlerClass), + Method.getMethod("Object staticInvoke(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.size() > 0) + { + 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(10, 10); + 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/4d6aadc5/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java new file mode 100644 index 0000000..6760bc2 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/AbstractManualInvocationHandler.java @@ -0,0 +1,114 @@ +/* + * 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.invocation; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import javax.enterprise.inject.Typed; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.InterceptionType; +import javax.enterprise.inject.spi.Interceptor; +import javax.interceptor.InterceptorBinding; +import org.apache.deltaspike.core.api.provider.BeanManagerProvider; + +@Typed +public abstract class AbstractManualInvocationHandler implements InvocationHandler +{ + @Override + public Object invoke(Object proxy, Method method, Object[] parameters) throws Throwable + { + // check if interceptors are defined, otherwise just call the original logik + List<Interceptor<?>> interceptors = resolveInterceptors(proxy, method); + if (interceptors != null && interceptors.size() > 0) + { + try + { + ManualInvocationContext invocationContext = + new ManualInvocationContext(this, interceptors, proxy, method, parameters, null); + + Object returnValue = invocationContext.proceed(); + + if (invocationContext.isProceedOriginal()) + { + return invocationContext.getProceedOriginalReturnValue(); + } + + return returnValue; + } + catch (ManualInvocationThrowableWrapperException e) + { + throw e.getCause(); + } + } + + return proceedOriginal(proxy, method, parameters); + } + + /** + * Calls the original logic after invoking the interceptor chain. + * + * @param proxy The current proxy instance. + * @param method The current invoked method. + * @param parameters The method parameter. + * @return The original value from the original method. + * @throws Throwable + */ + protected abstract Object proceedOriginal(Object proxy, Method method, Object[] parameters) throws Throwable; + + protected List<Interceptor<?>> resolveInterceptors(Object instance, Method method) + { + Annotation[] interceptorBindings = extractInterceptorBindings(instance, method); + if (interceptorBindings.length > 0) + { + BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); + return beanManager.resolveInterceptors(InterceptionType.AROUND_INVOKE, interceptorBindings); + } + + return null; + } + + // TODO stereotypes + protected Annotation[] extractInterceptorBindings(Object instance, Method method) + { + ArrayList<Annotation> bindings = new ArrayList<Annotation>(); + + for (Annotation annotation : instance.getClass().getDeclaredAnnotations()) + { + if (annotation.annotationType().isAnnotationPresent(InterceptorBinding.class) + && !bindings.contains(annotation)) + { + bindings.add(annotation); + } + } + + for (Annotation annotation : method.getDeclaredAnnotations()) + { + if (annotation.annotationType().isAnnotationPresent(InterceptorBinding.class) + && !bindings.contains(annotation)) + { + bindings.add(annotation); + } + } + + return bindings.toArray(new Annotation[bindings.size()]); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/DelegateManualInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/DelegateManualInvocationHandler.java b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/DelegateManualInvocationHandler.java new file mode 100644 index 0000000..d247253 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/DelegateManualInvocationHandler.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.deltaspike.proxy.impl.invocation; + +import org.apache.deltaspike.proxy.spi.DeltaSpikeProxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +import javax.enterprise.inject.Typed; + +/** + * {@link AbstractManualInvocationHandler} which delegates the method call to the defined {@link InvocationHandler} + * in {@link DeltaSpikeProxy#getDelegateInvocationHandler()}. + */ +@Typed +public class DelegateManualInvocationHandler extends AbstractManualInvocationHandler +{ + private static final DelegateManualInvocationHandler INSTANCE = new DelegateManualInvocationHandler(); + + public static Object staticInvoke(Object proxy, Method method, Object[] parameters) throws Throwable + { + return INSTANCE.invoke(proxy, method, parameters); + } + + @Override + protected Object proceedOriginal(Object proxy, Method method, Object[] parameters) throws Throwable + { + InvocationHandler delegateInvocationHandler = ((DeltaSpikeProxy) proxy).getDelegateInvocationHandler(); + return delegateInvocationHandler.invoke(proxy, method, parameters); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/InterceptManualInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/InterceptManualInvocationHandler.java b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/InterceptManualInvocationHandler.java new file mode 100644 index 0000000..17e23ae --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/InterceptManualInvocationHandler.java @@ -0,0 +1,55 @@ +/* + * 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.invocation; + +import org.apache.deltaspike.proxy.api.DeltaSpikeProxyFactory; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import javax.enterprise.inject.Typed; + +/** + * {@link AbstractManualInvocationHandler} which just delegates to the original method after invoking interceptors. + */ +@Typed +public class InterceptManualInvocationHandler extends AbstractManualInvocationHandler +{ + private static final InterceptManualInvocationHandler INSTANCE = new InterceptManualInvocationHandler(); + + public static Object staticInvoke(Object proxy, Method method, Object[] parameters) throws Throwable + { + return INSTANCE.invoke(proxy, method, parameters); + } + + @Override + protected Object proceedOriginal(Object proxy, Method method, Object[] parameters) throws Throwable + { + try + { + Method superAccessorMethod = DeltaSpikeProxyFactory.getSuperAccessorMethod(proxy, method); + return superAccessorMethod.invoke(proxy, parameters); + } + catch (InvocationTargetException e) + { + // rethrow original exception + throw e.getCause(); + } + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/ManualInvocationContext.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/ManualInvocationContext.java b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/ManualInvocationContext.java new file mode 100644 index 0000000..30c9339 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/ManualInvocationContext.java @@ -0,0 +1,191 @@ +/* + * 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.invocation; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.Typed; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.InterceptionType; +import javax.enterprise.inject.spi.Interceptor; +import javax.interceptor.InvocationContext; +import org.apache.deltaspike.core.api.provider.BeanManagerProvider; + +/** + * {@link InvocationContext} implementation to support manual interceptor invocation before invoking the + * original logic via the given {@link AbstractManualInvocationHandler}. + */ +@Typed +public class ManualInvocationContext<T, H> implements InvocationContext +{ + protected List<Interceptor<H>> interceptors; + protected int interceptorIndex; + protected T target; + protected Method method; + protected Object[] parameters; + protected Map<String, Object> contextData; + protected Object timer; + protected AbstractManualInvocationHandler manualInvocationHandler; + + protected BeanManager beanManager; + + protected boolean proceedOriginal; + protected Object proceedOriginalReturnValue; + + public ManualInvocationContext(AbstractManualInvocationHandler manualInvocationHandler, + List<Interceptor<H>> interceptors, T target, Method method, Object[] parameters, Object timer) + { + this.manualInvocationHandler = manualInvocationHandler; + this.interceptors = interceptors; + this.target = target; + this.method = method; + this.parameters = parameters; + this.timer = timer; + + this.interceptorIndex = 0; + } + + @Override + public Object getTarget() + { + return target; + } + + @Override + public Method getMethod() + { + return method; + } + + @Override + public Object[] getParameters() + { + return parameters; + } + + @Override + public void setParameters(Object[] os) + { + parameters = os; + } + + @Override + public Map<String, Object> getContextData() + { + if (contextData == null) + { + contextData = new HashMap<String, Object>(); + } + return contextData; + } + + @Override + public Object proceed() throws Exception + { + if (proceedOriginal) + { + return null; + } + + if (interceptors.size() > interceptorIndex) + { + Interceptor<H> interceptor = null; + CreationalContext<H> creationalContext = null; + H interceptorInstance = null; + + try + { + // lazy init beanManager + if (beanManager == null) + { + beanManager = BeanManagerProvider.getInstance().getBeanManager(); + } + + interceptor = interceptors.get(interceptorIndex++); + creationalContext = beanManager.createCreationalContext(interceptor); + interceptorInstance = interceptor.create(creationalContext); + + return interceptor.intercept(InterceptionType.AROUND_INVOKE, interceptorInstance, this); + } + finally + { + if (creationalContext != null) + { + if (interceptorInstance != null && interceptor != null) + { + interceptor.destroy(interceptorInstance, creationalContext); + } + + creationalContext.release(); + } + } + } + + + // workaround for OWB 1.1, otherwise we could just return the proceedOriginalReturnValue here + try + { + proceedOriginal = true; + proceedOriginalReturnValue = manualInvocationHandler.proceedOriginal(target, method, parameters); + } + catch (Exception e) + { + throw e; + } + catch (Throwable e) + { + // wrap the Throwable here as interceptors declared only "throws Exception" + throw new ManualInvocationThrowableWrapperException(e); + } + + return null; + } + + @Override + public Object getTimer() + { + return timer; + } + + // @Override + // CDI 1.1 compatibility + public Constructor getConstructor() + { + return null; + } + + public boolean isProceedOriginal() + { + return proceedOriginal; + } + + public Object getProceedOriginalReturnValue() + { + return proceedOriginalReturnValue; + } + + public void setProceedOriginalReturnValue(Object proceedOriginalReturnValue) + { + this.proceedOriginalReturnValue = proceedOriginalReturnValue; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/ManualInvocationThrowableWrapperException.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/ManualInvocationThrowableWrapperException.java b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/ManualInvocationThrowableWrapperException.java new file mode 100644 index 0000000..2a14f44 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/src/main/java/org/apache/deltaspike/proxy/impl/invocation/ManualInvocationThrowableWrapperException.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.invocation; + +/** + * Wrapper exception to wrap and pass trough the original {@link Throwable} because + * the {@link javax.interceptor.InvocationContext#proceed()} method only declares "throws Exception". + */ +public class ManualInvocationThrowableWrapperException extends Exception +{ + public ManualInvocationThrowableWrapperException(Throwable e) + { + super(e); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/impl-asm5/src/main/resources/META-INF/beans.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/resources/META-INF/beans.xml b/deltaspike/modules/proxy/impl-asm5/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000..4070730 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/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/4d6aadc5/deltaspike/modules/proxy/impl-asm5/src/main/resources/META-INF/services/org.apache.deltaspike.proxy.spi.ProxyClassGenerator ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/impl-asm5/src/main/resources/META-INF/services/org.apache.deltaspike.proxy.spi.ProxyClassGenerator b/deltaspike/modules/proxy/impl-asm5/src/main/resources/META-INF/services/org.apache.deltaspike.proxy.spi.ProxyClassGenerator new file mode 100644 index 0000000..803e350 --- /dev/null +++ b/deltaspike/modules/proxy/impl-asm5/src/main/resources/META-INF/services/org.apache.deltaspike.proxy.spi.ProxyClassGenerator @@ -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.AsmProxyClassGenerator \ No newline at end of file http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/modules/proxy/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/proxy/pom.xml b/deltaspike/modules/proxy/pom.xml new file mode 100644 index 0000000..7ec3af4 --- /dev/null +++ b/deltaspike/modules/proxy/pom.xml @@ -0,0 +1,40 @@ +<?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>modules-project</artifactId> + <version>1.3.1-SNAPSHOT</version> + </parent> + + <groupId>org.apache.deltaspike.modules</groupId> + <artifactId>proxy-module-project</artifactId> + <version>1.3.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>Apache DeltaSpike Proxy-Module</name> + + <modules> + <module>api</module> + <module>impl-asm5</module> + </modules> +</project> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/4d6aadc5/deltaspike/parent/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/parent/pom.xml b/deltaspike/parent/pom.xml index ef749a0..9115065 100644 --- a/deltaspike/parent/pom.xml +++ b/deltaspike/parent/pom.xml @@ -571,6 +571,12 @@ <scope>compile</scope> </dependency> + <dependency> + <groupId>org.apache.deltaspike.modules</groupId> + <artifactId>deltaspike-proxy-module-impl-asm5</artifactId> + <version>${project.version}</version> + <scope>runtime</scope> + </dependency> <!-- Dependencies for Java-SE --> <dependency>