Package org.ow2.easybeans.enhancer.interceptors

Source Code of org.ow2.easybeans.enhancer.interceptors.EasyBeansInvocationContextFactory

/**
* EasyBeans
* Copyright (C) 2008-2009 Bull S.A.S.
* Contact: easybeans@ow2.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id: EasyBeansInvocationContextFactory.java 5369 2010-02-24 14:58:19Z benoitf $
* --------------------------------------------------------------------------
*/

package org.ow2.easybeans.enhancer.interceptors;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.ow2.easybeans.api.EasyBeansInvocationContext;
import org.ow2.easybeans.api.bean.EasyBeansBean;
import org.ow2.easybeans.api.interceptor.EZBInterceptorInvoker;
import org.ow2.easybeans.api.interceptor.EZBInterceptorManager;
import org.ow2.easybeans.api.interceptor.EZBInterceptorManagerFactory;
import org.ow2.easybeans.api.interceptor.EZBInvocationContextFactory;
import org.ow2.easybeans.deployment.metadata.ejbjar.EasyBeansEjbJarClassMetadata;
import org.ow2.easybeans.deployment.metadata.ejbjar.EasyBeansEjbJarMethodMetadata;
import org.ow2.easybeans.enhancer.lib.MethodRenamer;
import org.ow2.util.ee.metadata.ejbjar.api.IJClassInterceptor;
import org.ow2.util.ee.metadata.ejbjar.api.InterceptorType;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;
import org.ow2.util.scan.api.metadata.structures.JMethod;

/**
* This class will manage the creation of the invocation context objects.
* @author Florent Benoit
*/
public class EasyBeansInvocationContextFactory implements EZBInvocationContextFactory {

    /**
     * Logger.
     */
    private static final Log LOGGER = LogFactory.getLog(EasyBeansInvocationContextFactory.class);

    /**
     * Map between the signature of a method and all invokers defined for this
     * method. (for each interceptor type)
     */
    private Map<String, Map<String, List<EZBInterceptorInvoker>>> methodsInterceptorInvokerList;

    /**
     * Map between the signature of a method and its java.lang.reflect.Method
     * object. (cache)
     */
    private Map<String, Method> methods;

    /**
     * List of classes that needs to be instantiate in the interceptor manager.
     */
    private List<String> interceptorClasses = null;

    /**
     * ClassLoader used to load classes.
     */
    private ClassLoader classLoader = null;

    /**
     * Build a new InvocationContext factory by analyzing each business method
     * and lifecycle method and creating the invokers.
     * @param classMetadata the metadata of the bean class that will be analyzed
     * @param classLoader the
     */
    public EasyBeansInvocationContextFactory(final EasyBeansEjbJarClassMetadata classMetadata, final ClassLoader classLoader) {
        this.classLoader = classLoader;

        // Init Map/List
        this.methodsInterceptorInvokerList = new HashMap<String, Map<String, List<EZBInterceptorInvoker>>>();
        this.methods = new HashMap<String, Method>();
        this.interceptorClasses = new ArrayList<String>();

        // Analyze each business method and build the invokers for each method /
        // bean method.
        Collection<EasyBeansEjbJarMethodMetadata> methodsMetadata = classMetadata.getMethodMetadataCollection();

        // Defines the types of interceptors to manage
        List<InterceptorType> interceptorTypes = new ArrayList<InterceptorType>();
        interceptorTypes.add(InterceptorType.AROUND_INVOKE);
        interceptorTypes.add(InterceptorType.POST_CONSTRUCT);
        interceptorTypes.add(InterceptorType.PRE_DESTROY);


        // Compute interceptors for each business method and for each kind of interceptor
        for (EasyBeansEjbJarMethodMetadata methodMetadata : methodsMetadata) {
            if (methodMetadata.isBusinessMethod() || methodMetadata.isLifeCycleMethod()) {

                // Ignore init/clinit methods
                if (methodMetadata.getJMethod().getName().startsWith("<")) {
                    continue;
                }

                // get signature
                String methodSignature = MethodHelper.getSignature(methodMetadata);

                // Build Map
                Map<String, List<EZBInterceptorInvoker>> interceptorTypeInvokers = new HashMap<String, List<EZBInterceptorInvoker>>();
                this.methodsInterceptorInvokerList.put(methodSignature, interceptorTypeInvokers);

                // Loop on some interceptor types
                for (InterceptorType interceptorType : interceptorTypes) {

                    // Get list of interceptors
                    List<IJClassInterceptor> allInterceptors = new MethodInterceptorsBuilder(methodMetadata, interceptorType).getAllInterceptors();

                    // build invokers
                    List<EZBInterceptorInvoker> invokers = new ArrayList<EZBInterceptorInvoker>();


                    // Store the invoker
                    interceptorTypeInvokers.put(interceptorType.toString(), invokers);

                    for (IJClassInterceptor interceptor : allInterceptors) {
                        String classname = interceptor.getClassName();
                        JMethod jMethod = interceptor.getJMethod();

                        // interceptor on the bean or outside ?
                        if (classMetadata.getClassName().equals(classname)) {
                            // interceptor is in the bean
                            // Add the invoker
                            invokers.add(new BeanInterceptorInvokerImpl(classname, jMethod, classLoader));
                        } else {
                            // outside of the bean
                            // Add the invoker
                            invokers.add(new StandaloneInterceptorInvokerImpl(classname, jMethod, classLoader));

                            // An interceptor instance will be required for this
                            // interceptor class
                            addInterceptorClass(classname);
                        }
                    }

                    // Add the method invocation call
                    JMethod interceptedMethod = methodMetadata.getJMethod();

                    String methodName = interceptedMethod.getName();
                    if (!methodMetadata.isLifeCycleMethod() && !methodName.contains("$generated")) {
                        methodName = MethodRenamer.encode(interceptedMethod.getName());
                    }

                    JMethod originalMethod = new JMethod(interceptedMethod.getAccess(), methodName, interceptedMethod.getDescriptor(), interceptedMethod.getSignature(), interceptedMethod
                            .getExceptions());
                    invokers.add(new BeanBusinessMethodInvokerImpl(classMetadata.getClassName(), originalMethod, classLoader));

                    // Put in cache the business methods of the bean
                    this.methods.put(methodSignature, MethodHelper.getMethod(classMetadata.getClassName(), methodMetadata
                            .getJMethod(), classLoader));
                }
            }
        }

    }

    /**
     * Add the given classname to the list of the classes that will be managed
     * by the interceptor manager.
     * @param classname the name of the class
     */
    protected void addInterceptorClass(final String classname) {
        // Add it if class is not yet in the list
        if (!this.interceptorClasses.contains(classname)) {
            this.interceptorClasses.add(classname);
        }
    }

    /**
     * Gets the interceptor manager factory.
     * @return an instance of the manager factory
     */
    public EZBInterceptorManagerFactory getInterceptorManagerFactory() {
        return new EasyBeansInterceptorManagerFactory(this.interceptorClasses, this.classLoader);
    }

    /**
     * Gets an invocation context for the given method.
     * @param instance the bean's instance
     * @param interceptorManager the manager of the interceptors
     * @param interceptorType the type of the interceptor
     * @param methodSignature the key in order to find data for the given method
     * @param parameters the parameters of the method
     * @return an invocation context implementation
     */
    public EasyBeansInvocationContext getContext(final EasyBeansBean instance, final EZBInterceptorManager interceptorManager,
            final String interceptorType, final String methodSignature, final Object... parameters) {
        LOGGER.debug("Calling getContext for instance ''{0}'', interceptor manager ''{1}'', type ''{2}'' signature ''{3}'' and parameters ''{4}'' with interceptor invoker list set to ''{5}''", instance, interceptorManager, interceptorType, methodSignature, parameters, this.methodsInterceptorInvokerList);
        return new DynamicInvocationContextImpl(instance, this.methodsInterceptorInvokerList.get(methodSignature).get(interceptorType),
                interceptorManager, !interceptorType.equals(InterceptorType.AROUND_INVOKE.toString()), this.methods.get(methodSignature), parameters);
    }

}
TOP

Related Classes of org.ow2.easybeans.enhancer.interceptors.EasyBeansInvocationContextFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.