Search in sources :

Example 6 with MethodInformation

use of org.jboss.weld.util.bytecode.MethodInformation in project core by weld.

the class InterceptedProxyFactory method addMethodsFromClass.

@Override
protected void addMethodsFromClass(ClassFile proxyClassType, ClassMethod staticConstructor) {
    try {
        final Set<MethodSignature> finalMethods = new HashSet<MethodSignature>();
        final Set<MethodSignature> processedBridgeMethods = new HashSet<MethodSignature>();
        // Add all methods from the class hierarchy
        Class<?> cls = getBeanType();
        while (cls != null) {
            Set<MethodSignature> declaredBridgeMethods = new HashSet<MethodSignature>();
            for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(cls))) {
                final MethodSignatureImpl methodSignature = new MethodSignatureImpl(method);
                if (isMethodAccepted(method, getProxySuperclass()) && enhancedMethodSignatures.contains(methodSignature) && !finalMethods.contains(methodSignature) && !processedBridgeMethods.contains(methodSignature)) {
                    try {
                        final MethodInformation methodInfo = new RuntimeMethodInformation(method);
                        ClassMethod classMethod = proxyClassType.addMethod(method);
                        if (interceptedMethodSignatures.contains(methodSignature)) {
                            // this method is intercepted
                            final CodeAttribute b = classMethod.getCodeAttribute();
                            b.aload(0);
                            getMethodHandlerField(classMethod.getClassFile(), b);
                            // get the Stack
                            b.invokestatic(InterceptionDecorationContext.class.getName(), "getStack", "()" + DescriptorUtils.makeDescriptor(Stack.class));
                            b.aload(0);
                            DEFAULT_METHOD_RESOLVER.getDeclaredMethod(classMethod, methodInfo.getDeclaringClass(), method.getName(), methodInfo.getParameterTypes(), staticConstructor);
                            b.dup();
                            // Params
                            b.iconst(method.getParameterTypes().length);
                            b.anewarray(JAVA_LANG_OBJECT);
                            int localVariableCount = 1;
                            for (int i = 0; i < method.getParameterTypes().length; ++i) {
                                String typeString = methodInfo.getParameterTypes()[i];
                                // duplicate the array reference
                                b.dup();
                                b.iconst(i);
                                // load the parameter value
                                BytecodeUtils.addLoadInstruction(b, typeString, localVariableCount);
                                // box the parameter if necessary
                                Boxing.boxIfNessesary(b, typeString);
                                // and store it in the array
                                b.aastore();
                                if (isWide(typeString)) {
                                    localVariableCount = localVariableCount + 2;
                                } else {
                                    localVariableCount++;
                                }
                            }
                            b.invokeinterface(StackAwareMethodHandler.class.getName(), INVOKE_METHOD_NAME, LJAVA_LANG_OBJECT, InterceptedSubclassFactory.INVOKE_METHOD_PARAMETERS);
                            if (methodInfo.getReturnType().equals(BytecodeUtils.VOID_CLASS_DESCRIPTOR)) {
                                b.returnInstruction();
                            } else if (isPrimitive(methodInfo.getReturnType())) {
                                Boxing.unbox(b, classMethod.getReturnType());
                                b.returnInstruction();
                            } else {
                                b.checkcast(BytecodeUtils.getName(methodInfo.getReturnType()));
                                b.returnInstruction();
                            }
                            BeanLogger.LOG.addingMethodToProxy(method);
                        } else {
                            final CodeAttribute b = classMethod.getCodeAttribute();
                            b.aload(0);
                            getMethodHandlerField(classMethod.getClassFile(), b);
                            b.aload(0);
                            DEFAULT_METHOD_RESOLVER.getDeclaredMethod(classMethod, methodInfo.getDeclaringClass(), method.getName(), methodInfo.getParameterTypes(), staticConstructor);
                            b.aconstNull();
                            b.iconst(method.getParameterTypes().length);
                            b.anewarray(JAVA_LANG_OBJECT);
                            int localVariableCount = 1;
                            for (int i = 0; i < method.getParameterTypes().length; ++i) {
                                String typeString = methodInfo.getParameterTypes()[i];
                                // duplicate the array reference
                                b.dup();
                                b.iconst(i);
                                // load the parameter value
                                BytecodeUtils.addLoadInstruction(b, typeString, localVariableCount);
                                // box the parameter if necessary
                                Boxing.boxIfNessesary(b, typeString);
                                // and store it in the array
                                b.aastore();
                                if (isWide(typeString)) {
                                    localVariableCount = localVariableCount + 2;
                                } else {
                                    localVariableCount++;
                                }
                            }
                            b.invokeinterface(MethodHandler.class.getName(), INVOKE_METHOD_NAME, LJAVA_LANG_OBJECT, new String[] { LJAVA_LANG_OBJECT, LJAVA_LANG_REFLECT_METHOD, LJAVA_LANG_REFLECT_METHOD, "[" + LJAVA_LANG_OBJECT });
                            if (methodInfo.getReturnType().equals(BytecodeUtils.VOID_CLASS_DESCRIPTOR)) {
                                b.returnInstruction();
                            } else if (isPrimitive(methodInfo.getReturnType())) {
                                Boxing.unbox(b, classMethod.getReturnType());
                                b.returnInstruction();
                            } else {
                                b.checkcast(BytecodeUtils.getName(methodInfo.getReturnType()));
                                b.returnInstruction();
                            }
                        }
                    } catch (DuplicateMemberException e) {
                    // do nothing. This will happen if superclass methods have
                    // been overridden
                    }
                } else {
                    if (Modifier.isFinal(method.getModifiers())) {
                        finalMethods.add(methodSignature);
                    }
                    if (method.isBridge()) {
                        declaredBridgeMethods.add(methodSignature);
                    }
                }
            }
            processedBridgeMethods.addAll(declaredBridgeMethods);
            cls = cls.getSuperclass();
        }
    } catch (Exception e) {
        throw new WeldException(e);
    }
}
Also used : DuplicateMemberException(org.jboss.classfilewriter.DuplicateMemberException) WeldException(org.jboss.weld.exceptions.WeldException) MethodSignature(org.jboss.weld.annotated.enhanced.MethodSignature) ClassMethod(org.jboss.classfilewriter.ClassMethod) Method(java.lang.reflect.Method) DuplicateMemberException(org.jboss.classfilewriter.DuplicateMemberException) WeldException(org.jboss.weld.exceptions.WeldException) MethodSignatureImpl(org.jboss.weld.annotated.enhanced.jlr.MethodSignatureImpl) MethodInformation(org.jboss.weld.util.bytecode.MethodInformation) RuntimeMethodInformation(org.jboss.weld.util.bytecode.RuntimeMethodInformation) CodeAttribute(org.jboss.classfilewriter.code.CodeAttribute) GetDeclaredMethodsAction(org.jboss.weld.security.GetDeclaredMethodsAction) RuntimeMethodInformation(org.jboss.weld.util.bytecode.RuntimeMethodInformation) ClassMethod(org.jboss.classfilewriter.ClassMethod) HashSet(java.util.HashSet)

Example 7 with MethodInformation

use of org.jboss.weld.util.bytecode.MethodInformation in project core by weld.

the class InterceptedSubclassFactory method addSpecialMethods.

/**
 * Adds methods requiring special implementations rather than just
 * delegation.
 *
 * @param proxyClassType the Javassist class description for the proxy type
 */
protected void addSpecialMethods(ClassFile proxyClassType, ClassMethod staticConstructor) {
    try {
        // Add special methods for interceptors
        for (Method method : LifecycleMixin.class.getMethods()) {
            BeanLogger.LOG.addingMethodToProxy(method);
            MethodInformation methodInfo = new RuntimeMethodInformation(method);
            createInterceptorBody(proxyClassType.addMethod(method), methodInfo, false, staticConstructor);
        }
        Method getInstanceMethod = TargetInstanceProxy.class.getMethod("getTargetInstance");
        Method getInstanceClassMethod = TargetInstanceProxy.class.getMethod("getTargetClass");
        generateGetTargetInstanceBody(proxyClassType.addMethod(getInstanceMethod));
        generateGetTargetClassBody(proxyClassType.addMethod(getInstanceClassMethod));
        Method setMethodHandlerMethod = ProxyObject.class.getMethod("setHandler", MethodHandler.class);
        generateSetMethodHandlerBody(proxyClassType.addMethod(setMethodHandlerMethod));
        Method getMethodHandlerMethod = ProxyObject.class.getMethod("getHandler");
        generateGetMethodHandlerBody(proxyClassType.addMethod(getMethodHandlerMethod));
    } catch (Exception e) {
        throw new WeldException(e);
    }
}
Also used : WeldException(org.jboss.weld.exceptions.WeldException) MethodInformation(org.jboss.weld.util.bytecode.MethodInformation) RuntimeMethodInformation(org.jboss.weld.util.bytecode.RuntimeMethodInformation) RuntimeMethodInformation(org.jboss.weld.util.bytecode.RuntimeMethodInformation) ClassMethod(org.jboss.classfilewriter.ClassMethod) Method(java.lang.reflect.Method) WeldException(org.jboss.weld.exceptions.WeldException) DuplicateMemberException(org.jboss.classfilewriter.DuplicateMemberException)

Example 8 with MethodInformation

use of org.jboss.weld.util.bytecode.MethodInformation in project core by weld.

the class ProxyFactory method addSpecialMethods.

/**
 * Adds methods requiring special implementations rather than just
 * delegation.
 *
 * @param proxyClassType the Javassist class description for the proxy type
 */
protected void addSpecialMethods(ClassFile proxyClassType, ClassMethod staticConstructor) {
    try {
        // Add special methods for interceptors
        for (Method method : LifecycleMixin.class.getMethods()) {
            BeanLogger.LOG.addingMethodToProxy(method);
            MethodInformation methodInfo = new RuntimeMethodInformation(method);
            final ClassMethod classMethod = proxyClassType.addMethod(method);
            createInterceptorBody(classMethod, methodInfo, staticConstructor);
        }
        Method getInstanceMethod = TargetInstanceProxy.class.getMethod("getTargetInstance");
        Method getInstanceClassMethod = TargetInstanceProxy.class.getMethod("getTargetClass");
        MethodInformation getInstanceMethodInfo = new RuntimeMethodInformation(getInstanceMethod);
        createInterceptorBody(proxyClassType.addMethod(getInstanceMethod), getInstanceMethodInfo, staticConstructor);
        MethodInformation getInstanceClassMethodInfo = new RuntimeMethodInformation(getInstanceClassMethod);
        createInterceptorBody(proxyClassType.addMethod(getInstanceClassMethod), getInstanceClassMethodInfo, staticConstructor);
        Method setMethodHandlerMethod = ProxyObject.class.getMethod("setHandler", MethodHandler.class);
        generateSetMethodHandlerBody(proxyClassType.addMethod(setMethodHandlerMethod));
        Method getMethodHandlerMethod = ProxyObject.class.getMethod("getHandler");
        generateGetMethodHandlerBody(proxyClassType.addMethod(getMethodHandlerMethod));
    } catch (Exception e) {
        throw new WeldException(e);
    }
}
Also used : WeldException(org.jboss.weld.exceptions.WeldException) RuntimeMethodInformation(org.jboss.weld.util.bytecode.RuntimeMethodInformation) MethodInformation(org.jboss.weld.util.bytecode.MethodInformation) RuntimeMethodInformation(org.jboss.weld.util.bytecode.RuntimeMethodInformation) ClassMethod(org.jboss.classfilewriter.ClassMethod) Method(java.lang.reflect.Method) ClassMethod(org.jboss.classfilewriter.ClassMethod) DuplicateMemberException(org.jboss.classfilewriter.DuplicateMemberException) DefinitionException(org.jboss.weld.exceptions.DefinitionException) WeldException(org.jboss.weld.exceptions.WeldException) IOException(java.io.IOException)

Aggregations

Method (java.lang.reflect.Method)8 ClassMethod (org.jboss.classfilewriter.ClassMethod)8 MethodInformation (org.jboss.weld.util.bytecode.MethodInformation)8 RuntimeMethodInformation (org.jboss.weld.util.bytecode.RuntimeMethodInformation)8 WeldException (org.jboss.weld.exceptions.WeldException)7 DuplicateMemberException (org.jboss.classfilewriter.DuplicateMemberException)6 GetDeclaredMethodsAction (org.jboss.weld.security.GetDeclaredMethodsAction)3 IOException (java.io.IOException)2 HashSet (java.util.HashSet)2 CodeAttribute (org.jboss.classfilewriter.code.CodeAttribute)2 MethodSignature (org.jboss.weld.annotated.enhanced.MethodSignature)2 MethodSignatureImpl (org.jboss.weld.annotated.enhanced.jlr.MethodSignatureImpl)2 DefinitionException (org.jboss.weld.exceptions.DefinitionException)2 LinkedHashSet (java.util.LinkedHashSet)1 FieldInjectionPoint (org.jboss.weld.injection.FieldInjectionPoint)1 ParameterInjectionPoint (org.jboss.weld.injection.ParameterInjectionPoint)1 StaticMethodInformation (org.jboss.weld.util.bytecode.StaticMethodInformation)1