Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source
   * Copyright 2008, Red Hat, Inc. and/or its affiliates, and individual contributors
   * by the @authors tag. See the copyright.txt in the distribution for a
   * full listing of individual contributors.
   *
   * Licensed 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.jboss.weld.bean.proxy;
 
 import java.util.Set;
 
 
This special proxy factory is mostly used for abstract decorators. When a delegate field is injected, the abstract methods directly invoke the corresponding method on the delegate. All other cases forward the calls to the org.jboss.weld.bean.proxy.BeanInstance for further processing.

Author(s):
David Allen
Stuart Douglas
 
 public class DecoratorProxyFactory<T> extends ProxyFactory<T> {
     public static final String PROXY_SUFFIX = "DecoratorProxy";
     private static final String INIT_MH_METHOD_NAME = "_initMH";
     private final WeldInjectionPointAttributes<?, ?> delegateInjectionPoint;
     private final Field delegateField;
 
     public DecoratorProxyFactory(String contextIdClass<T> proxyTypeWeldInjectionPointAttributes<?, ?> delegateInjectionPointBean<?> bean) {
         super(contextIdproxyType, Collections.<Type>emptySet(), bean);
         this. = delegateInjectionPoint;
         if (delegateInjectionPoint instanceof FieldInjectionPoint<?, ?>) {
              = (Field) ((FieldInjectionPoint<?, ?>) delegateInjectionPoint).getMember();
         } else {
              = null;
         }
     }

    
calls _initMH on the method handler and then stores the result in the methodHandler field as then new methodHandler
 
     private void addHandlerInitializerMethod(ClassFile proxyClassTypeClassMethod staticConstructorthrows Exception {
         final CodeAttribute b = classMethod.getCodeAttribute();
         b.aload(0);
         StaticMethodInformation methodInfo = new StaticMethodInformation(new Class[] { Object.class }, void.class,
                 classMethod.getClassFile().getName());
         invokeMethodHandler(classMethodmethodInfofalsestaticConstructor);
         b.checkcast(MethodHandler.class);
         b.putfield(classMethod.getClassFile().getName(), , DescriptorUtils.makeDescriptor(MethodHandler.class));
         b.returnInstruction();
 
     }
 
     @Override
     protected void addAdditionalInterfaces(Set<Class<?>> interfaces) {
         interfaces.add(DecoratorProxy.class);
     }
 
     @Override
     protected void addMethodsFromClass(ClassFile proxyClassTypeClassMethod staticConstructor) {
        Method initializerMethod = null;
        int delegateParameterPosition = -1;
        if ( instanceof ParameterInjectionPoint<?, ?>) {
            ParameterInjectionPoint<?, ?> parameterIP = (ParameterInjectionPoint<?, ?>) ;
            if (parameterIP.getMember() instanceof Method) {
                initializerMethod = ((MethodparameterIP.getMember());
                delegateParameterPosition = parameterIP.getAnnotated().getPosition();
            }
        }
        try {
            if (delegateParameterPosition >= 0) {
                addHandlerInitializerMethod(proxyClassTypestaticConstructor);
            }
            Class<?> cls = getBeanType();
            Set<Methodmethods = new LinkedHashSet<Method>();
            decoratorMethods(clsmethods);
            for (Method method : methods) {
                MethodInformation methodInfo = new RuntimeMethodInformation(method);
                if (!method.getDeclaringClass().getName().equals("java.lang.Object") || method.getName().equals("toString")) {
                    if ((delegateParameterPosition >= 0) && (initializerMethod.equals(method))) {
                        createDelegateInitializerCode(proxyClassType.addMethod(method), methodInfodelegateParameterPosition);
                    }
                    // exclude bridge methods
                    if (Modifier.isAbstract(method.getModifiers())) {
                         createAbstractMethodCode(proxyClassType.addMethod(method), methodInfostaticConstructor);
                    }
                }
            }
        } catch (Exception e) {
            throw new WeldException(e);
        }
    }
    private void decoratorMethods(Class<?> clsSet<Methodall) {
        if (cls == null) {
            return;
        }
        all.addAll(Arrays.asList(AccessController.doPrivileged(new GetDeclaredMethodsAction(cls))));
        decoratorMethods(cls.getSuperclass(), all);
        // by now we should have all declared methods, let's only add the missing ones
        for (Class<?> ifc : cls.getInterfaces()) {
            Method[] methods = ifc.getMethods();
            for (Method m : methods) {
                boolean isEqual = false;
                for (Method a : all) {
                    if (isEqual(ma)) {
                        isEqual = true;
                        break;
                    }
                }
                if (!isEqual) {
                    all.add(m);
                }
            }
        }
    }
    // m is more generic than a
    private static boolean isEqual(Method mMethod a) {
        if (m.getName().equals(a.getName()) && m.getParameterTypes().length == a.getParameterTypes().length && m.getReturnType().isAssignableFrom(a.getReturnType())) {
            for (int i = 0; i < m.getParameterTypes().lengthi++) {
                if (!(m.getParameterTypes()[i].isAssignableFrom(a.getParameterTypes()[i]))) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    @Override
    protected String getProxyNameSuffix() {
        return ;
    }
    private void createAbstractMethodCode(ClassMethod classMethodMethodInformation methodClassMethod staticConstructor) {
        if (( != null) && (!Modifier.isPrivate(.getModifiers()))) {
            // Call the corresponding method directly on the delegate
            final CodeAttribute b = classMethod.getCodeAttribute();
            // load the delegate field
            b.aload(0);
            b.getfield(classMethod.getClassFile().getName(), .getName(), DescriptorUtils.makeDescriptor(.getType()));
            // load the parameters
            b.loadMethodParameters();
            // invoke the delegate method
            b.invokeinterface(.getType().getName(), method.getName(), method.getDescriptor());
            // return the value if applicable
            b.returnInstruction();
        } else {
            if (!Modifier.isPrivate(method.getMethod().getModifiers())) {
                // if it is a parameter injection point we need to initialize the
                // injection point then handle the method with the method handler
                // this is slightly different to a normal method handler call, as we pass
                // in a TargetInstanceBytecodeMethodResolver. This resolver uses the
                // method handler to call getTargetClass to get the correct class type to
                // resolve the method with, and then resolves this method
                invokeMethodHandler(classMethodmethodtruestaticConstructor);
            } else {
                // if the delegate is private we need to use the method handler
                createInterceptorBody(classMethodmethodstaticConstructor);
            }
        }
    }

    
When creates the delegate initializer code when the delegate is injected into a method.

super initializer method is called first, and then _initMH is called

Parameters:
initializerMethodInfo
delegateParameterPosition
Returns:
    private void createDelegateInitializerCode(ClassMethod classMethodMethodInformation initializerMethodInfoint delegateParameterPosition) {
        final CodeAttribute b = classMethod.getCodeAttribute();
        // we need to push all the parameters on the stack to call the corresponding
        // superclass arguments
        b.aload(0); // load this
        int localVariables = 1;
        int actualDelegateParameterPosition = 0;
        for (int i = 0; i < initializerMethodInfo.getMethod().getParameterTypes().length; ++i) {
            if (i == delegateParameterPosition) {
                // figure out the actual position of the delegate in the local
                // variables
                actualDelegateParameterPosition = localVariables;
            }
            Class<?> type = initializerMethodInfo.getMethod().getParameterTypes()[i];
            BytecodeUtils.addLoadInstruction(b, DescriptorUtils.makeDescriptor(type), localVariables);
            if (type == long.class || type == double.class) {
                localVariables = localVariables + 2;
            } else {
                localVariables++;
            }
        }
        b.invokespecial(classMethod.getClassFile().getSuperclass(), initializerMethodInfo.getName(), initializerMethodInfo.getDescriptor());
        // if this method returns a value it is now sitting on top of the stack
        // we will leave it there are return it later
        // now we need to call _initMH
        b.aload(0); // load this
        b.aload(actualDelegateParameterPosition); // load the delegate
        // return the object from the top of the stack that we got from calling
        // the superclass method earlier
        b.returnInstruction();
    }
    protected class TargetInstanceBytecodeMethodResolver implements BytecodeMethodResolver {
        private static final String JAVA_LANG_CLASS_CLASS_NAME = "java.lang.Class";
        public void getDeclaredMethod(ClassMethod classMethodString declaringClassString methodNameString[] parameterTypesClassMethod staticConstructor) {
            // get the correct class type to use to resolve the method
            MethodInformation methodInfo = new StaticMethodInformation("getTargetClass"new String[0], TargetInstanceProxy.class.getName());
            invokeMethodHandler(classMethodmethodInfofalsestaticConstructor);
            CodeAttribute code = classMethod.getCodeAttribute();
            code.checkcast("java/lang/Class");
            // now we have the class on the stack
            code.ldc(methodName);
            // now we need to load the parameter types into an array
            code.iconst(parameterTypes.length);
            code.anewarray();
            for (int i = 0; i < parameterTypes.length; ++i) {
                code.dup(); // duplicate the array reference
                code.iconst(i);
                // now load the class object
                String type = parameterTypes[i];
                BytecodeUtils.pushClassType(codetype);
                // and store it in the array
                code.aastore();
            }
            code.invokestatic(GetDeclaredMethodAction.class.getName(), "wrapException""(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/security/PrivilegedAction;");
            code.invokestatic(AccessController.class.getName(), "doPrivileged""(Ljava/security/PrivilegedAction;)Ljava/lang/Object;");
            code.checkcast(Method.class);
        }
    }
New to GrepCode? Check out our FAQ X