Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source
   * Copyright 2010, 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 static org.jboss.classfilewriter.util.DescriptorUtils.isPrimitive;
 import static org.jboss.classfilewriter.util.DescriptorUtils.isWide;
 import static org.jboss.classfilewriter.util.DescriptorUtils.makeDescriptor;
 
 import java.util.Set;
 
 
Factory for producing subclasses that are used by the combined interceptors and decorators stack.

Author(s):
Marius Bogoevici
 
 public class InterceptedSubclassFactory<T> extends ProxyFactory<T> {
     // Default proxy class name suffix
     public static final String PROXY_SUFFIX = "Subclass";
 
     private static final String SUPER_DELEGATE_SUFFIX = "$$super";
 
 
     private final Set<MethodSignatureenhancedMethodSignatures;
 
     private final Class<?> proxiedBeanType;
 
     public InterceptedSubclassFactory(String contextIdClass<?> proxiedBeanTypeSet<? extends TypetypeClosureBean<?> beanSet<MethodSignatureenhancedMethodSignaturesSet<MethodSignatureinterceptedMethodSignatures) {
         this(contextIdproxiedBeanTypetypeClosuregetProxyName(contextIdproxiedBeanTypetypeClosurebean), beanenhancedMethodSignaturesinterceptedMethodSignatures);
     }

    
Creates a new proxy factory when the name of the proxy class is already known, such as during de-serialization

Parameters:
proxiedBeanType the super-class for this proxy class
typeClosure the bean types of the bean
enhancedMethodSignatures a restricted set of methods that need to be intercepted
 
 
     public InterceptedSubclassFactory(String contextIdClass<?> proxiedBeanTypeSet<? extends TypetypeClosureString proxyNameBean<?> beanSet<MethodSignatureenhancedMethodSignaturesSet<MethodSignatureinterceptedMethodSignatures) {
         super(contextIdproxiedBeanTypetypeClosureproxyNamebeantrue);
         this. = enhancedMethodSignatures;
         this. = interceptedMethodSignatures;
         this. = proxiedBeanType;
     }
 
     @Override
     public void addInterfacesFromTypeClosure(Set<? extends TypetypeClosureClass<?> proxiedBeanType) {
         for (Class<?> c : proxiedBeanType.getInterfaces()) {
             addInterface(c);
         }
     }

    
Returns a suffix to append to the name of the proxy class. The name already consists of <class-name>_$$_Weld, to which the suffix is added. This allows the creation of different types of proxies for the same class.

Returns:
a name suffix
    protected String getProxyNameSuffix() {
        return ;
    }
    @Override
    protected void addMethods(ClassFile proxyClassTypeClassMethod staticConstructor) {
        // Add all class methods for interception
        addMethodsFromClass(proxyClassTypestaticConstructor);
        // Add special proxy methods
        addSpecialMethods(proxyClassTypestaticConstructor);
    }
    @Override
    protected void addMethodsFromClass(ClassFile proxyClassTypeClassMethod staticConstructor) {
        try {
            final Set<MethodSignaturefinalMethods = new HashSet<MethodSignature>();
            final Set<MethodSignatureprocessedBridgeMethods = new HashSet<MethodSignature>();
            // Add all methods from the class hierarchy
            Class<?> cls = getBeanType();
            while (cls != null) {
                Set<MethodSignaturedeclaredBridgeMethods = new HashSet<MethodSignature>();
                for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(cls))) {
                    final MethodSignatureImpl methodSignature = new MethodSignatureImpl(method);
                    if (!Modifier.isFinal(method.getModifiers()) && !method.isBridge() && .contains(methodSignature)
                            && !finalMethods.contains(methodSignature) && !processedBridgeMethods.contains(methodSignature)) {
                        try {
                            final MethodInformation methodInfo = new RuntimeMethodInformation(method);
                            if (.contains(methodSignature)) {
                                // create delegate-to-super method
                                int modifiers = (method.getModifiers() | . | .) & ~. & ~.;
                                ClassMethod delegatingMethod = proxyClassType.addMethod(modifiersmethod.getName() + , DescriptorUtils.makeDescriptor(method.getReturnType()),
                                        DescriptorUtils.parameterDescriptors(method.getParameterTypes()));
                                delegatingMethod.addCheckedExceptions((Class<? extends Exception>[]) method.getExceptionTypes());
                                createDelegateToSuper(delegatingMethodmethodInfo);
                                // this method is intercepted
                                // override a subclass method to delegate to method handler
                                ClassMethod classMethod = proxyClassType.addMethod(method);
                                addConstructedGuardToMethodBody(classMethod);
                                createForwardingMethodBody(classMethodmethodInfostaticConstructor);
                                ..addingMethodToProxy(method);
                            } else {
                                // this method is not intercepted
                                // we still need to override and push InterceptionDecorationContext stack to prevent full interception
                                ClassMethod classMethod = proxyClassType.addMethod(method);
                                new RunWithinInterceptionDecorationContextGenerator(classMethodthis) {
                                    @Override
                                    void doWork(CodeAttribute bClassMethod method) {
                                        // build the bytecode that invokes the super class method directly
                                        b.aload(0);
                                        // create the method invocation
                                        b.loadMethodParameters();
                                        b.invokespecial(methodInfo.getDeclaringClass(), methodInfo.getName(), methodInfo.getDescriptor());
                                        // leave the result on top of the stack
                                    }
                                    @Override
                                    void doReturn(CodeAttribute bClassMethod method) {
                                        // assumes doWork() result is on top of the stack
                                        b.returnInstruction();
                                    }
                                }.runStartIfNotOnTop();
                            }
                        } 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();
            }
            for (Class<?> c : getAdditionalInterfaces()) {
                for (Method method : c.getMethods()) {
                    MethodSignature signature = new MethodSignatureImpl(method);
                    if (.contains(signature) && !processedBridgeMethods.contains(signature)) {
                        try {
                            MethodInformation methodInformation = new RuntimeMethodInformation(method);
                            final ClassMethod classMethod = proxyClassType.addMethod(method);
                            createSpecialMethodBody(classMethodmethodInformationstaticConstructor);
                            ..addingMethodToProxy(method);
                        } catch (DuplicateMemberException e) {
                        }
                    }
                    if (method.isBridge()) {
                        processedBridgeMethods.add(signature);
                    }
                }
            }
        } catch (Exception e) {
            throw new WeldException(e);
        }
    }
    protected void createForwardingMethodBody(ClassMethod classMethodMethodInformation methodClassMethod staticConstructor) {
        createInterceptorBody(classMethodmethodtruestaticConstructor);
    }

    
Creates the given method on the proxy class where the implementation forwards the call directly to the method handler.

the generated bytecode is equivalent to:

return (RetType) methodHandler.invoke(this,param1,param2);

Parameters:
methodInfo any JLR method
delegateToSuper
Returns:
the method byte code
    protected void createInterceptorBody(ClassMethod methodMethodInformation methodInfoboolean delegateToSuperClassMethod staticConstructor) {
        invokeMethodHandler(methodmethodInfotruedelegateToSuperstaticConstructor);
    }
    private void createDelegateToSuper(ClassMethod classMethodMethodInformation method) {
        CodeAttribute b = classMethod.getCodeAttribute();
        // first generate the invokespecial call to the super class method
        b.aload(0);
        b.loadMethodParameters();
        b.invokespecial(classMethod.getClassFile().getSuperclass(), method.getName(), method.getDescriptor());
        b.returnInstruction();
    }

    
calls methodHandler.invoke for a given method

Parameters:
methodInfo declaring class of the method
addReturnInstruction set to true you want to return the result of
bytecodeMethodResolver The method resolver
addProceed
    protected void invokeMethodHandler(ClassMethod methodMethodInformation methodInfoboolean addReturnInstructionBytecodeMethodResolver bytecodeMethodResolverboolean addProceedClassMethod staticConstructor) {
        // now we need to build the bytecode. The order we do this in is as
        // follows:
        // load methodHandler
        // dup the methodhandler
        // invoke isDisabledHandler on the method handler to figure out of this is
        // a self invocation.
        // load this
        // load the method object
        // load the proceed method that invokes the superclass version of the
        // current method
        // create a new array the same size as the number of parameters
        // push our parameter values into the array
        // invokeinterface the invoke method
        // add checkcast to cast the result to the return type, or unbox if
        // primitive
        // add an appropriate return instruction
        final CodeAttribute b = method.getCodeAttribute();
        b.aload(0);
        getMethodHandlerField(method.getClassFile(), b);
        // this is a self invocation optimisation
        // test to see if this is a self invocation, and if so invokespecial the
        // superclass method directly
        if (addProceed) {
            b.dup();
            // get the Stack
            b.invokestatic(InterceptionDecorationContext.class.getName(), "getStack""()" + DescriptorUtils.makeDescriptor(Stack.class));
            b.dupX1(); // Handler, Stack -> Stack, Handler, Stack
            b.invokevirtual("isDisabledHandler""(" + DescriptorUtils.makeDescriptor(Stack.class) + ")" + .);
            b.iconst(0);
            BranchEnd invokeSuperDirectly = b.ifIcmpeq();
            // now build the bytecode that invokes the super class method
            b.pop2(); // pop Stack and Handler
            b.aload(0);
            // create the method invocation
            b.loadMethodParameters();
            b.invokespecial(methodInfo.getDeclaringClass(), methodInfo.getName(), methodInfo.getDescriptor());
            b.returnInstruction();
            b.branchEnd(invokeSuperDirectly);
        } else {
            b.aconstNull();
        }
        b.aload(0);
        bytecodeMethodResolver.getDeclaredMethod(methodmethodInfo.getDeclaringClass(), methodInfo.getName(), methodInfo.getParameterTypes(), staticConstructor);
        if (addProceed) {
            bytecodeMethodResolver.getDeclaredMethod(methodmethod.getClassFile().getName(), methodInfo.getName() + methodInfo.getParameterTypes(), staticConstructor);
        } else {
            b.aconstNull();
        }
        b.iconst(methodInfo.getParameterTypes().length);
        b.anewarray("java.lang.Object");
        int localVariableCount = 1;
        for (int i = 0; i < methodInfo.getParameterTypes().length; ++i) {
            String typeString = methodInfo.getParameterTypes()[i];
            b.dup(); // duplicate the array reference
            b.iconst(i);
            // load the parameter value
            BytecodeUtils.addLoadInstruction(btypeStringlocalVariableCount);
            // box the parameter if necessary
            Boxing.boxIfNessesary(btypeString);
            // and store it in the array
            b.aastore();
            if (isWide(typeString)) {
                localVariableCount = localVariableCount + 2;
            } else {
                localVariableCount++;
            }
        }
        // now we have all our arguments on the stack
        // lets invoke the method
        if (addReturnInstruction) {
            // now we need to return the appropriate type
            if (methodInfo.getReturnType().equals(.)) {
                b.returnInstruction();
            } else if (isPrimitive(methodInfo.getReturnType())) {
                Boxing.unbox(b,method.getReturnType());
                b.returnInstruction();
            } else {
                String castType = methodInfo.getReturnType();
                if (!methodInfo.getReturnType().startsWith("[")) {
                    castType = methodInfo.getReturnType().substring(1).substring(0, methodInfo.getReturnType().length() - 2);
                }
                b.checkcast(castType);
                b.returnInstruction();
            }
        }
    }

    
Adds methods requiring special implementations rather than just delegation.

Parameters:
proxyClassType the Javassist class description for the proxy type
    protected void addSpecialMethods(ClassFile proxyClassTypeClassMethod staticConstructor) {
        try {
            // Add special methods for interceptors
            for (Method method : LifecycleMixin.class.getMethods()) {
                ..addingMethodToProxy(method);
                MethodInformation methodInfo = new RuntimeMethodInformation(method);
                createInterceptorBody(proxyClassType.addMethod(method), methodInfofalsestaticConstructor);
            }
            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);
        }
    }
    private static void generateGetTargetInstanceBody(ClassMethod method) {
        final CodeAttribute b = method.getCodeAttribute();
        b.aload(0);
        b.returnInstruction();
    }
    private static void generateGetTargetClassBody(ClassMethod method) {
        final CodeAttribute b = method.getCodeAttribute();
        BytecodeUtils.pushClassType(bmethod.getClassFile().getSuperclass());
        b.returnInstruction();
    }
    @Override
    public Class<?> getBeanType() {
        return ;
    }
    @Override
    protected boolean isCreatingProxy() {
        return false;
    }
    @Override
    protected Class<? extends MethodHandlergetMethodHandlerType() {
    }
New to GrepCode? Check out our FAQ X