Hmm, shouldn't we provide this as another module? I'm not super happy to have asm shade in core.
BTW can't we just use [proxy2]? we can still make the code evolving if needed. Romain Manni-Bucau @rmannibucau <https://twitter.com/rmannibucau> | Blog <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> | LinkedIn <https://www.linkedin.com/in/rmannibucau> | Tomitriber <http://www.tomitribe.com> ---------- Forwarded message ---------- From: <[email protected]> Date: 2015-03-15 20:50 GMT+01:00 Subject: [2/2] deltaspike git commit: DELTASPIKE-851 move proxy-handling to ds-core To: [email protected] DELTASPIKE-851 move proxy-handling to ds-core Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/fcf4d77d Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/fcf4d77d Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/fcf4d77d Branch: refs/heads/master Commit: fcf4d77d692971a6a93731e64d044f6cf1757d6c Parents: d3a21c0 Author: Thomas Andraschko <[email protected]> Authored: Sun Mar 15 20:50:24 2015 +0100 Committer: Thomas Andraschko <[email protected]> Committed: Sun Mar 15 20:50:24 2015 +0100 ---------------------------------------------------------------------- deltaspike/core/api/pom.xml | 57 +++ .../AbstractManualInvocationHandler.java | 104 +++++ .../invocation/ManualInvocationContext.java | 187 ++++++++ ...nualInvocationThrowableWrapperException.java | 27 ++ .../core/util/proxy/AsmProxyClassGenerator.java | 436 +++++++++++++++++++ .../core/util/proxy/DeltaSpikeProxy.java | 28 ++ .../DeltaSpikeProxyContextualLifecycle.java | 144 ++++++ .../core/util/proxy/DeltaSpikeProxyFactory.java | 274 ++++++++++++ .../DelegateManualInvocationHandler.java | 43 ++ .../InterceptManualInvocationHandler.java | 51 +++ deltaspike/modules/jsf/impl/pom.xml | 6 - .../InjectionAwareApplicationWrapper.java | 6 +- .../proxy/ConverterAndValidatorLifecycle.java | 132 ------ .../ConverterAndValidatorProxyExtension.java | 19 +- .../ConverterAndValidatorProxyFactory.java | 78 ++++ .../proxy/ConverterInvocationHandler.java | 13 +- .../proxy/DefaultPartialStateHolder.java | 3 + .../proxy/DelegatingMethodHandler.java | 58 --- .../injection/proxy/MethodHandlerProxy.java | 42 -- .../jsf/impl/injection/proxy/ProxyMarker.java | 23 - .../proxy/ValidatorInvocationHandler.java | 12 +- .../test/jsf/impl/util/ArchiveUtils.java | 1 - deltaspike/modules/partial-bean/impl/pom.xml | 56 --- .../impl/PartialBeanBindingExtension.java | 16 +- .../partialbean/impl/PartialBeanLifecycle.java | 142 ------ .../impl/PartialBeanProxyFactory.java | 62 +++ .../AbstractManualInvocationHandler.java | 104 ----- .../interception/ManualInvocationContext.java | 187 -------- ...nualInvocationThrowableWrapperException.java | 27 -- .../impl/proxy/AsmProxyClassGenerator.java | 423 ------------------ .../proxy/CallSuperManualInvocationHandler.java | 50 --- .../impl/proxy/PartialBeanProxy.java | 28 -- .../impl/proxy/PartialBeanProxyFactory.java | 263 ----------- .../proxy/RedirectManualInvocationHandler.java | 42 -- .../core/api/partialbean/util/ArchiveUtils.java | 7 - 35 files changed, 1510 insertions(+), 1641 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/core/api/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/pom.xml b/deltaspike/core/api/pom.xml index c5793f4..94b489d 100644 --- a/deltaspike/core/api/pom.xml +++ b/deltaspike/core/api/pom.xml @@ -33,6 +33,42 @@ <name>Apache DeltaSpike Core-API</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.core.util.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> + <properties> <deltaspike.osgi.export.pkg> org.apache.deltaspike.core.* @@ -46,5 +82,26 @@ </deltaspike.osgi.provide.capability> </properties> + <dependencies> + <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/fcf4d77d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/AbstractManualInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/AbstractManualInvocationHandler.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/AbstractManualInvocationHandler.java new file mode 100644 index 0000000..5e6fe33 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/AbstractManualInvocationHandler.java @@ -0,0 +1,104 @@ +/* + * 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.core.util.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 + { + 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); + } + + 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/fcf4d77d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/ManualInvocationContext.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/ManualInvocationContext.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/ManualInvocationContext.java new file mode 100644 index 0000000..c79f126 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/ManualInvocationContext.java @@ -0,0 +1,187 @@ +/* + * 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.core.util.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; + +@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/fcf4d77d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/ManualInvocationThrowableWrapperException.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/ManualInvocationThrowableWrapperException.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/ManualInvocationThrowableWrapperException.java new file mode 100644 index 0000000..f9df5e8 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/invocation/ManualInvocationThrowableWrapperException.java @@ -0,0 +1,27 @@ +/* + * 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.core.util.invocation; + +public class ManualInvocationThrowableWrapperException extends Exception +{ + public ManualInvocationThrowableWrapperException(Throwable e) + { + super(e); + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/AsmProxyClassGenerator.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/AsmProxyClassGenerator.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/AsmProxyClassGenerator.java new file mode 100644 index 0000000..a615372 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/AsmProxyClassGenerator.java @@ -0,0 +1,436 @@ +/* + * 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.core.util.proxy; + +import org.apache.deltaspike.core.util.proxy.invocation.InterceptManualInvocationHandler; +import org.apache.deltaspike.core.util.proxy.invocation.DelegateManualInvocationHandler; +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.UndeclaredThrowableException; +import java.util.ArrayList; +import java.util.Arrays; +import javax.enterprise.inject.Typed; +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 abstract class AsmProxyClassGenerator +{ + 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); + + private AsmProxyClassGenerator() + { + // prevent instantiation + } + + public static <T> Class<T> generateProxyClass(ClassLoader classLoader, + Class<T> targetClass, + Class<? extends InvocationHandler> invocationHandlerClass, + 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, invocationHandlerClass, + classFileName, superAccessorMethodSuffix, additionalInterfaces, delegateMethods, interceptMethods); + + Class<T> proxyClass = (Class<T>) loadClass(classLoader, proxyName, proxyBytes); + + return proxyClass; + } + + private static byte[] generateProxyClassBytes(Class<?> targetClass, + Class<? extends InvocationHandler> invocationHandlerClass, + 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 invocationHandlerType = Type.getType(invocationHandlerClass); + + 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, invocationHandlerType); + defineConstructor(cw, proxyType, superType); + defineDeltaSpikeProxyMethods(cw, proxyType, invocationHandlerType); + + 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 invocationHandlerType) + { + // generates + // private MyInvocationHandler delegateInvocationHandler; + cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_DELEGATE_INVOCATION_HANDLER, + invocationHandlerType.getDescriptor(), null, null).visitEnd(); + } + + private static void defineConstructor(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 defineDeltaSpikeProxyMethods(ClassWriter cw, Type proxyType, Type invocationHandlerType) + { + 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(invocationHandlerType); + mg.putField(proxyType, FIELDNAME_DELEGATE_INVOCATION_HANDLER, invocationHandlerType); + 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, invocationHandlerType); + 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) + { + // 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); + + // 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)); + } + 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/fcf4d77d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxy.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxy.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxy.java new file mode 100644 index 0000000..cb4b1f1 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxy.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.core.util.proxy; + +import java.lang.reflect.InvocationHandler; + +public interface DeltaSpikeProxy +{ + void setDelegateInvocationHandler(InvocationHandler redirectInvocationHandler); + + InvocationHandler getDelegateInvocationHandler(); +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxyContextualLifecycle.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxyContextualLifecycle.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxyContextualLifecycle.java new file mode 100644 index 0000000..2932502 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxyContextualLifecycle.java @@ -0,0 +1,144 @@ +/* + * 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.core.util.proxy; + +import java.lang.reflect.InvocationHandler; +import java.util.Set; +import javax.enterprise.context.Dependent; +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.spi.AnnotatedType; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.InjectionTarget; +import javax.enterprise.inject.spi.PassivationCapable; +import org.apache.deltaspike.core.api.provider.BeanManagerProvider; +import org.apache.deltaspike.core.api.provider.BeanProvider; +import org.apache.deltaspike.core.util.ExceptionUtils; +import org.apache.deltaspike.core.util.metadata.builder.ContextualLifecycle; + +public class DeltaSpikeProxyContextualLifecycle<T, H extends InvocationHandler> implements ContextualLifecycle<T> +{ + private final Class<T> proxyClass; + private final Class<H> delegateInvocationHandlerClass; + private final Class<T> targetClass; + + private InjectionTarget<T> injectionTarget; + private CreationalContext<?> creationalContextOfDependentHandler; + + public DeltaSpikeProxyContextualLifecycle(Class<T> targetClass, Class<H> delegateInvocationHandlerClass, + DeltaSpikeProxyFactory proxyFactory, BeanManager beanManager) + { + this.targetClass = targetClass; + this.delegateInvocationHandlerClass = delegateInvocationHandlerClass; + this.proxyClass = proxyFactory.getProxyClass(targetClass, delegateInvocationHandlerClass); + + if (!targetClass.isInterface()) + { + AnnotatedType<T> annotatedType = beanManager.createAnnotatedType(this.targetClass); + this.injectionTarget = beanManager.createInjectionTarget(annotatedType); + } + } + + @Override + public T create(Bean bean, CreationalContext creationalContext) + { + try + { + T instance = proxyClass.newInstance(); + + if (delegateInvocationHandlerClass != null) + { + H delegateInvocationHandler = instantiateDelegateInvocationHandler(); + ((DeltaSpikeProxy) instance).setDelegateInvocationHandler(delegateInvocationHandler); + } + + if (this.injectionTarget != null) + { + this.injectionTarget.inject(instance, creationalContext); + this.injectionTarget.postConstruct(instance); + } + + return instance; + } + catch (Exception e) + { + ExceptionUtils.throwAsRuntimeException(e); + } + + // can't happen + return null; + } + + @Override + public void destroy(Bean<T> bean, T instance, CreationalContext<T> creationalContext) + { + if (this.injectionTarget != null) + { + this.injectionTarget.preDestroy(instance); + } + + if (this.creationalContextOfDependentHandler != null) + { + this.creationalContextOfDependentHandler.release(); + } + + creationalContext.release(); + } + + protected H instantiateDelegateInvocationHandler() + { + Set<Bean<H>> handlerBeans = BeanProvider.getBeanDefinitions(this.delegateInvocationHandlerClass, false, true); + + if (handlerBeans.size() != 1) + { + StringBuilder beanInfo = new StringBuilder(); + for (Bean<H> bean : handlerBeans) + { + if (beanInfo.length() != 0) + { + beanInfo.append(", "); + } + beanInfo.append(bean); + + if (bean instanceof PassivationCapable) + { + beanInfo.append(" bean-id: ").append(((PassivationCapable)bean).getId()); + } + } + + throw new IllegalStateException(handlerBeans.size() + " beans found for " + + this.delegateInvocationHandlerClass + " found beans: " + beanInfo.toString()); + } + + Bean<H> handlerBean = handlerBeans.iterator().next(); + + BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); + CreationalContext<?> creationalContext = beanManager.createCreationalContext(handlerBean); + + H handlerInstance = (H) beanManager.getReference(handlerBean, + this.delegateInvocationHandlerClass, creationalContext); + + if (handlerBean.getScope().equals(Dependent.class)) + { + this.creationalContextOfDependentHandler = creationalContext; + } + + return handlerInstance; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxyFactory.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxyFactory.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxyFactory.java new file mode 100644 index 0000000..013733d --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/DeltaSpikeProxyFactory.java @@ -0,0 +1,274 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.deltaspike.core.util.proxy; + +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; + +public abstract class DeltaSpikeProxyFactory +{ + private static final String SUPER_ACCESSOR_METHOD_SUFFIX = "$super"; + + public <T> Class<T> getProxyClass(Class<T> targetClass, + Class<? extends InvocationHandler> invocationHandlerClass) + { + Class<T> proxyClass = ClassUtils.tryToLoadClassForName(constructProxyClassName(targetClass), targetClass); + if (proxyClass == null) + { + proxyClass = createProxyClass(targetClass.getClassLoader(), targetClass, invocationHandlerClass); + } + + return proxyClass; + } + + private synchronized <T> Class<T> createProxyClass(ClassLoader classLoader, Class<T> targetClass, + Class<? extends InvocationHandler> invocationHandlerClass) + { + 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 proxy + Iterator<Method> iterator = interceptMethods.iterator(); + while (iterator.hasNext()) + { + Method method = iterator.next(); + if (!containsInterceptorBinding(method.getDeclaredAnnotations())) + { + iterator.remove(); + } + } + } + + proxyClass = AsmProxyClassGenerator.generateProxyClass(classLoader, + targetClass, + invocationHandlerClass, + 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/fcf4d77d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/invocation/DelegateManualInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/invocation/DelegateManualInvocationHandler.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/invocation/DelegateManualInvocationHandler.java new file mode 100644 index 0000000..7a00819 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/invocation/DelegateManualInvocationHandler.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.deltaspike.core.util.proxy.invocation; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import javax.enterprise.inject.Typed; +import org.apache.deltaspike.core.util.invocation.AbstractManualInvocationHandler; +import org.apache.deltaspike.core.util.proxy.DeltaSpikeProxy; + +@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/fcf4d77d/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/invocation/InterceptManualInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/invocation/InterceptManualInvocationHandler.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/invocation/InterceptManualInvocationHandler.java new file mode 100644 index 0000000..77af318 --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/proxy/invocation/InterceptManualInvocationHandler.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.deltaspike.core.util.proxy.invocation; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import javax.enterprise.inject.Typed; +import org.apache.deltaspike.core.util.invocation.AbstractManualInvocationHandler; +import org.apache.deltaspike.core.util.proxy.DeltaSpikeProxyFactory; + +@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/fcf4d77d/deltaspike/modules/jsf/impl/pom.xml ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/pom.xml b/deltaspike/modules/jsf/impl/pom.xml index 0622730..b31dba3 100644 --- a/deltaspike/modules/jsf/impl/pom.xml +++ b/deltaspike/modules/jsf/impl/pom.xml @@ -141,12 +141,6 @@ <type>pom</type> <scope>test</scope> </dependency> - <dependency> - <groupId>org.javassist</groupId> - <artifactId>javassist</artifactId> - <version>3.18.2-GA</version> - <scope>test</scope> - </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java index a229f3d..928a6de 100644 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/InjectionAwareApplicationWrapper.java @@ -20,7 +20,6 @@ package org.apache.deltaspike.jsf.impl.injection; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; -import org.apache.deltaspike.jsf.impl.injection.proxy.ProxyMarker; import org.apache.deltaspike.jsf.impl.security.SecurityAwareViewHandler; import javax.faces.FacesException; @@ -31,6 +30,7 @@ import javax.faces.convert.Converter; import javax.faces.event.PreDestroyViewMapEvent; import javax.faces.event.SystemEvent; import javax.faces.validator.Validator; +import org.apache.deltaspike.core.util.proxy.DeltaSpikeProxy; public class InjectionAwareApplicationWrapper extends ApplicationWrapper { @@ -80,7 +80,7 @@ public class InjectionAwareApplicationWrapper extends ApplicationWrapper return defaultResult; } - if (result instanceof ProxyMarker || ProxyUtils.isProxiedClass(result.getClass())) + if (result instanceof DeltaSpikeProxy || ProxyUtils.isProxiedClass(result.getClass())) { return result; } @@ -114,7 +114,7 @@ public class InjectionAwareApplicationWrapper extends ApplicationWrapper return defaultResult; } - if (result instanceof ProxyMarker || ProxyUtils.isProxiedClass(result.getClass())) + if (result instanceof DeltaSpikeProxy || ProxyUtils.isProxiedClass(result.getClass())) { return result; } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorLifecycle.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorLifecycle.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorLifecycle.java deleted file mode 100644 index 90a3e6e..0000000 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorLifecycle.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.deltaspike.jsf.impl.injection.proxy; - -import org.apache.deltaspike.core.util.ClassUtils; -import org.apache.deltaspike.core.util.ExceptionUtils; -import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder; -import org.apache.deltaspike.core.util.metadata.builder.ContextualLifecycle; - -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.inject.spi.InjectionTarget; -import javax.faces.component.PartialStateHolder; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -class ConverterAndValidatorLifecycle<T, H extends InvocationHandler> implements ContextualLifecycle<T> -{ - private final Class<? extends T> generatedProxyClass; - - private final InjectionTarget<T> injectionTargetForGeneratedProxy; - private final Class<H> handlerClass; - - ConverterAndValidatorLifecycle(Class<T> originalClass, Class<H> handlerClass, BeanManager beanManager) - { - this.handlerClass = handlerClass; - - AnnotatedTypeBuilder<T> typeBuilder = new AnnotatedTypeBuilder<T>().readFromType(originalClass); - this.injectionTargetForGeneratedProxy = beanManager.createInjectionTarget(typeBuilder.create()); - - try - { - Object proxyFactory = ClassUtils.tryToInstantiateClassForName("javassist.util.proxy.ProxyFactory"); - - Method setSuperclassMethod = proxyFactory.getClass().getDeclaredMethod("setSuperclass", Class.class); - setSuperclassMethod.invoke(proxyFactory, originalClass); - - List<Class> interfaces = new ArrayList<Class>(); - Collections.addAll(interfaces, originalClass.getInterfaces()); - interfaces.add(ProxyMarker.class); - - if (!interfaces.contains(PartialStateHolder.class)) - { - interfaces.add(PartialStateHolder.class); - } - - Method method = proxyFactory.getClass().getMethod("setInterfaces", new Class[]{new Class[]{}.getClass()}); - method.invoke(proxyFactory, new Object[] {interfaces.toArray(new Class[interfaces.size()])}); - - Method createClassMethod = proxyFactory.getClass().getDeclaredMethod("createClass"); - - this.generatedProxyClass = ((Class<?>) createClassMethod.invoke(proxyFactory)).asSubclass(originalClass); - } - catch (Exception e) - { - throw ExceptionUtils.throwAsRuntimeException(e); - } - } - - public T create(Bean bean, CreationalContext creationalContext) - { - try - { - H handlerInstance = ClassUtils.tryToInstantiateClass(this.handlerClass); - T instance = createProxyInstance(handlerInstance); - - if (this.injectionTargetForGeneratedProxy != null) - { - this.injectionTargetForGeneratedProxy.inject(instance, creationalContext); - this.injectionTargetForGeneratedProxy.postConstruct(instance); - } - - return instance; - } - catch (Exception e) - { - ExceptionUtils.throwAsRuntimeException(e); - } - //can't happen - return null; - } - - private T createProxyInstance(H handlerInstance) throws Exception - { - T instance = this.generatedProxyClass.newInstance(); - - Class methodHandlerClass = ClassUtils.tryToLoadClassForName("javassist.util.proxy.MethodHandler"); - Method setHandlerMethod = ClassUtils.tryToLoadClassForName("javassist.util.proxy.ProxyObject") - .getDeclaredMethod("setHandler", methodHandlerClass); - - - MethodHandlerProxy methodHandlerProxy = new MethodHandlerProxy(); - methodHandlerProxy.setDelegatingMethodHandler(new DelegatingMethodHandler<H>(handlerInstance)); - - Object methodHandler = Proxy.newProxyInstance( - ClassUtils.getClassLoader(this), new Class[]{methodHandlerClass}, methodHandlerProxy); - - setHandlerMethod.invoke(instance, methodHandler); - return instance; - } - - public void destroy(Bean<T> bean, T instance, CreationalContext<T> creationalContext) - { - if (this.injectionTargetForGeneratedProxy != null) - { - this.injectionTargetForGeneratedProxy.preDestroy(instance); - } - - creationalContext.release(); - } -} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java index ea78ab8..1baca10 100644 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyExtension.java @@ -20,7 +20,6 @@ package org.apache.deltaspike.jsf.impl.injection.proxy; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; -import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.bean.BeanBuilder; import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder; @@ -41,6 +40,7 @@ import java.lang.reflect.Modifier; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; +import org.apache.deltaspike.core.util.proxy.DeltaSpikeProxyContextualLifecycle; public class ConverterAndValidatorProxyExtension implements Extension, Deactivatable { @@ -84,15 +84,6 @@ public class ConverterAndValidatorProxyExtension implements Extension, Deactivat return; } - Object proxyFactory = ClassUtils.tryToInstantiateClassForName("javassist.util.proxy.ProxyFactory"); - - if (proxyFactory == null) - { - LOG.warning("To use dependency-injection in converters/validators with properties, " + - "you have to add javassist to the application."); - return; - } - if (!(Modifier.isFinal(beanClass.getModifiers()))) { this.classesToProxy.add(beanClass); @@ -146,7 +137,6 @@ public class ConverterAndValidatorProxyExtension implements Extension, Deactivat return false; } - @SuppressWarnings("UnusedDeclaration") public <X> void createBeans(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { if (!this.isActivated) @@ -175,14 +165,13 @@ public class ConverterAndValidatorProxyExtension implements Extension, Deactivat AnnotatedType<T> annotatedType = new AnnotatedTypeBuilder<T>().readFromType(beanClass).create(); - ConverterAndValidatorLifecycle beanLifecycle = - new ConverterAndValidatorLifecycle(beanClass, invocationHandlerClass, beanManager); + DeltaSpikeProxyContextualLifecycle lifecycle = new DeltaSpikeProxyContextualLifecycle(beanClass, + invocationHandlerClass, ConverterAndValidatorProxyFactory.getInstance(), beanManager); BeanBuilder<T> beanBuilder = new BeanBuilder<T>(beanManager) .readFromType(annotatedType) .passivationCapable(true) - .beanLifecycle(beanLifecycle) - .addType(ProxyMarker.class); + .beanLifecycle(lifecycle); return beanBuilder.create(); } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyFactory.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyFactory.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyFactory.java new file mode 100644 index 0000000..aff0bb6 --- /dev/null +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterAndValidatorProxyFactory.java @@ -0,0 +1,78 @@ +/* + * 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.jsf.impl.injection.proxy; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.enterprise.inject.Typed; +import javax.faces.component.PartialStateHolder; +import javax.faces.component.StateHolder; +import org.apache.deltaspike.core.util.proxy.DeltaSpikeProxyFactory; + +@Typed +public class ConverterAndValidatorProxyFactory extends DeltaSpikeProxyFactory +{ + private static final ConverterAndValidatorProxyFactory INSTANCE = new ConverterAndValidatorProxyFactory(); + + public static ConverterAndValidatorProxyFactory getInstance() + { + return INSTANCE; + } + + @Override + protected String getProxyClassSuffix() + { + return "$$DSJsfProxy"; + } + + @Override + protected ArrayList<Method> getDelegateMethods(Class<?> targetClass, ArrayList<Method> allMethods) + { + List<Class<?>> interfaces = Arrays.asList(targetClass.getInterfaces()); + if (!interfaces.contains(PartialStateHolder.class)) + { + ArrayList<Method> delegateMethods = new ArrayList<Method>(); + delegateMethods.addAll(Arrays.asList(PartialStateHolder.class.getDeclaredMethods())); + delegateMethods.addAll(Arrays.asList(StateHolder.class.getDeclaredMethods())); + return delegateMethods; + } + if (!interfaces.contains(StateHolder.class)) + { + ArrayList<Method> delegateMethods = new ArrayList<Method>(); + delegateMethods.addAll(Arrays.asList(StateHolder.class.getDeclaredMethods())); + return delegateMethods; + } + + return null; + } + + @Override + protected Class<?>[] getAdditionalInterfacesToImplement(Class<?> targetClass) + { + List<Class<?>> interfaces = Arrays.asList(targetClass.getInterfaces()); + if (!interfaces.contains(PartialStateHolder.class)) + { + return new Class<?>[] { PartialStateHolder.class }; + } + + return null; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterInvocationHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterInvocationHandler.java index 6bf457c..ab42e5a 100644 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterInvocationHandler.java +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ConverterInvocationHandler.java @@ -18,7 +18,6 @@ */ package org.apache.deltaspike.jsf.impl.injection.proxy; -import javax.faces.component.PartialStateHolder; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @@ -29,15 +28,7 @@ public class ConverterInvocationHandler implements InvocationHandler @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // if the original class implements PartialStateHolder already, we won't get in here - if (PartialStateHolder.class.equals(method.getDeclaringClass())) - { - return method.invoke(defaultPartialStateHolder, args); - } - else - { - //shouldn't happen, because DelegatingMethodHandler delegates all methods to the real implementations - return method.invoke(proxy, args); - } + return method.invoke(defaultPartialStateHolder, args); + } } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DefaultPartialStateHolder.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DefaultPartialStateHolder.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DefaultPartialStateHolder.java index 70b2e95..9cf1396 100644 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DefaultPartialStateHolder.java +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DefaultPartialStateHolder.java @@ -54,16 +54,19 @@ public class DefaultPartialStateHolder implements PartialStateHolder this.transientValue = newTransientValue; } + @Override public void clearInitialState() { this.initialStateMarked = false; } + @Override public boolean initialStateMarked() { return this.initialStateMarked; } + @Override public void markInitialState() { this.initialStateMarked = true; http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DelegatingMethodHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DelegatingMethodHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DelegatingMethodHandler.java deleted file mode 100644 index 4f91252..0000000 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/DelegatingMethodHandler.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.deltaspike.jsf.impl.injection.proxy; - -import javax.faces.FacesException; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * Handler delegates to implemented methods, if they exist - */ -class DelegatingMethodHandler<T extends InvocationHandler> -{ - private final T handlerInstance; - - DelegatingMethodHandler(T handlerInstance) - { - this.handlerInstance = handlerInstance; - } - - //Signature given by javassist.util.proxy.MethodHandler#invoke - public Object invoke(Object target, Method method, Method proceedMethod, Object[] arguments) throws Throwable - { - try - { - if (proceedMethod != null) - { - return proceedMethod.invoke(target, arguments); - } - return this.handlerInstance.invoke(target, method, arguments); - } - catch (InvocationTargetException e) - { - if (e.getCause() instanceof FacesException) - { - throw e.getCause(); - } - throw e; - } - } -} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/MethodHandlerProxy.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/MethodHandlerProxy.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/MethodHandlerProxy.java deleted file mode 100644 index 0c02a3a..0000000 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/MethodHandlerProxy.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.deltaspike.jsf.impl.injection.proxy; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; - -//This indirection to create a proxy for javassist.util.proxy.MethodHandler is used as intermediate approach. -//Further details see comments in PartialBeanLifecycle -public class MethodHandlerProxy implements InvocationHandler -{ - private DelegatingMethodHandler delegatingMethodHandler; - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable - { - //hardcoding the following parameters is ok since MethodHandlerProxy is only used for - //javassist.util.proxy.MethodHandler which has one method with those parameters. - return delegatingMethodHandler.invoke(args[0], (Method)args[1], (Method)args[2], (Object[])args[3]); - } - - void setDelegatingMethodHandler(DelegatingMethodHandler delegatingMethodHandler) - { - this.delegatingMethodHandler = delegatingMethodHandler; - } -} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ProxyMarker.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ProxyMarker.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ProxyMarker.java deleted file mode 100644 index 2e1d9d3..0000000 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ProxyMarker.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.deltaspike.jsf.impl.injection.proxy; - -public interface ProxyMarker -{ -} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ValidatorInvocationHandler.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ValidatorInvocationHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ValidatorInvocationHandler.java index 3a2db36..54007a6 100644 --- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ValidatorInvocationHandler.java +++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/injection/proxy/ValidatorInvocationHandler.java @@ -18,7 +18,6 @@ */ package org.apache.deltaspike.jsf.impl.injection.proxy; -import javax.faces.component.PartialStateHolder; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @@ -29,15 +28,6 @@ public class ValidatorInvocationHandler implements InvocationHandler @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - // if the original class implements PartialStateHolder already, we won't get in here - if (PartialStateHolder.class.equals(method.getDeclaringClass())) - { - return method.invoke(defaultPartialStateHolder, args); - } - else - { - //shouldn't happen, because DelegatingMethodHandler delegates all methods to the real implementations - return method.invoke(proxy, args); - } + return method.invoke(defaultPartialStateHolder, args); } } http://git-wip-us.apache.org/repos/asf/deltaspike/blob/fcf4d77d/deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/util/ArchiveUtils.java ---------------------------------------------------------------------- diff --git a/deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/util/ArchiveUtils.java b/deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/util/ArchiveUtils.java index 24c057c..acbdf26 100644 --- a/deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/util/ArchiveUtils.java +++ b/deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/util/ArchiveUtils.java @@ -53,7 +53,6 @@ public class ArchiveUtils .addPackages(true, "org.jboss.arquillian.graphene") .addPackages(true, "org.jboss.arquillian.ajocado") .addPackages(true, "org.openqa.selenium") - .addPackages(true, "javassist") .addPackage(WebProfileCategory.class.getPackage()); JavaArchive[] coreArchives = ShrinkWrapArchiveUtil.getArchives(null
