FileDocCategorySizeDatePackage
InterceptorManager.javaAPI DocGlassfish v2 API27560Fri May 04 22:33:00 BST 2007com.sun.ejb.containers.interceptors

InterceptorManager

public class InterceptorManager extends Object
UserInterceptorsManager manages UserInterceptors. There is one instance of InterceptorManager per container.
author
Mahesh Kannan

Fields Summary
private com.sun.ejb.containers.BaseContainer
container
private com.sun.enterprise.deployment.EjbDescriptor
ejbDesc
private ClassLoader
loader
private Class
beanClass
private String
beanClassName
private Logger
_logger
private Class[]
interceptorClasses
private Class[]
serializableInterceptorClasses
private Map
instanceIndexMap
private boolean
methodInterceptorsExists
private String[]
pre30LCMethodNames
private Class[]
lcAnnotationClasses
private CallbackChainImpl[]
callbackChain
Constructors Summary
public InterceptorManager(Logger _logger, com.sun.ejb.containers.BaseContainer container, Class[] lcAnnotationClasses, String[] pre30LCMethodNames)



        
                                 
              
        this._logger = _logger;
        this.container = container;
        this.lcAnnotationClasses = lcAnnotationClasses;
        this.pre30LCMethodNames = pre30LCMethodNames;

        ejbDesc = container.getEjbDescriptor();
        loader = container.getClassLoader();
        beanClassName = ejbDesc.getEjbImplClassName();

        this.beanClass = loader.loadClass(beanClassName);
        buildInterceptorChain();
        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, "InterceptorManager: " + toString());
        }
    
Methods Summary
private voidbuildInterceptorChain()

        initInterceptorClassNames();
        initCallbackIndices();
    
private java.util.ListcreateCallbackInterceptors(com.sun.enterprise.deployment.LifecycleCallbackDescriptor.CallbackType eventType, com.sun.enterprise.deployment.EjbInterceptor inter)

        List<CallbackInterceptor> callbackList = new ArrayList<CallbackInterceptor>();
        
        List<LifecycleCallbackDescriptor> orderedCallbackMethods = 
            inter.getOrderedCallbackDescriptors(eventType, loader);

        String className = inter.getInterceptorClassName();


        for (LifecycleCallbackDescriptor callbackDesc : orderedCallbackMethods) {
            Method method = null;
            try {
                method = callbackDesc.getLifecycleCallbackMethodObject(loader);
            } catch(Exception e) {
                throw new IllegalStateException("No callback method of name " +
                   callbackDesc.getLifecycleCallbackMethod() 
                   + " found on class " + className, e);
	    }


            CallbackInterceptor interceptor = null;
            if (inter.getFromBeanClass()) {
                interceptor = new BeanCallbackInterceptor(method);
            } else {
                Integer bigInt = instanceIndexMap.get(className);
                int index = (bigInt == null) ? -1 : bigInt;
                if (index == -1) {
                    throw new IllegalStateException(getInternalErrorString(className));
                }
                interceptor = new CallbackInterceptor(index, method);
            }
            callbackList.add(interceptor);
        }
        return callbackList;
    
public java.lang.Object[]createInterceptorInstances()

        int size = serializableInterceptorClasses.length;
        Object[] interceptors = new Object[size];
        for (int index = 0; index < size; index++) {
            Class clazz = serializableInterceptorClasses[index];
            try {
                interceptors[index] = clazz.newInstance();
            } catch (IllegalAccessException illEx) {
                throw new RuntimeException(illEx);
            } catch (InstantiationException instEx) {
                throw new RuntimeException(instEx);
            }
        }

        return interceptors;
    
public com.sun.ejb.Invocation.InterceptorChaingetAroundInvokeChain(com.sun.enterprise.deployment.MethodDescriptor mDesc, java.lang.reflect.Method beanMethod)

        List<EjbInterceptor> list = ejbDesc.getAroundInvokeInterceptors(mDesc);
        ArrayList<AroundInvokeInterceptor> interceptors =
                new ArrayList<AroundInvokeInterceptor>();
        for (EjbInterceptor interceptor : list) {
            String className = interceptor.getInterceptorClassName();
            Set<LifecycleCallbackDescriptor> aroundInvokeDescs = 
                interceptor.getAroundInvokeDescriptors();
            if(aroundInvokeDescs.isEmpty() ) {
                continue;
            }

            List<LifecycleCallbackDescriptor> orderedAIInterceptors =
                new ArrayList<LifecycleCallbackDescriptor>();
            try {
                orderedAIInterceptors = interceptor.getOrderedAroundInvokeDescriptors(loader);
            } catch (Exception e) {
               throw new IllegalStateException("No AroundInvokeIntercetpors found "
                   + " on class " + className, e); 
            }

            Iterator<LifecycleCallbackDescriptor> aiIterator = orderedAIInterceptors.iterator();
            while (aiIterator.hasNext()) {
                LifecycleCallbackDescriptor aroundInvokeDesc = aiIterator.next();
                
                Method method = null;
                try {
                    method = aroundInvokeDesc.getLifecycleCallbackMethodObject(loader);
                } catch(Exception e) {
                   throw new IllegalStateException("No callback method of name " +
                           aroundInvokeDesc.getLifecycleCallbackMethod() 
                   + " found on class " + className, e); 
                }

                if (interceptor.getFromBeanClass()) {
                    interceptors.add(new BeanAroundInvokeInterceptor(method));
                } else {
                    Integer bigInt = instanceIndexMap.get(className);
                    int index = (bigInt == null) ? -1 : bigInt;
                    if (index == -1) {
                        throw new IllegalStateException(getInternalErrorString(className));
                    }
                    Class clazz = interceptorClasses[index];
                    _logger.log(Level.FINE, "*[md.getDeclaredMethod() => " 
                                + method + " FOR CLAZZ: " + clazz);  
                    interceptors.add(new AroundInvokeInterceptor(index, method));
                }
            }
        }

        AroundInvokeInterceptor[] inter = interceptors.toArray(
                new AroundInvokeInterceptor[interceptors.size()]);
        return new AroundInvokeChainImpl(container, inter);
    
private java.lang.StringgetInternalErrorString(java.lang.String className)

        StringBuilder sbldr = new StringBuilder("Internal error: ");
        sbldr.append(" className: ").append(className)
                .append(" is neither a bean class (")
                .append(beanClassName).append(") nor an ")
                .append("interceptor class (");
        for (Class cn : interceptorClasses) {
            sbldr.append(cn.getName()).append("; ");
        }
        sbldr.append(")");
        _logger.log(Level.INFO, "++ : " + sbldr.toString());
        return sbldr.toString();
    
public booleanhasInterceptors()

        return this.methodInterceptorsExists;
    
private voidinitCallbackIndices()


        int size = CallbackType.values().length;
        ArrayList[] callbacks = new ArrayList[size];
        boolean scanFor2xLifecycleMethods = true;

        for (CallbackType eventType : CallbackType.values()) {
            int index = eventType.ordinal();
            callbacks[index] = new ArrayList<CallbackInterceptor>();
            boolean scanForCallbacks = true;
            if (! (ejbDesc instanceof EjbSessionDescriptor)) {
                if ((eventType == CallbackType.PRE_PASSIVATE) ||
                        (eventType == CallbackType.POST_ACTIVATE)) {
                    scanForCallbacks = false;
                }
            }

            if (scanForCallbacks) {
                List<EjbInterceptor> callbackList = ejbDesc.getCallbackInterceptors(eventType);
                for (EjbInterceptor callback : callbackList) {
                    List<CallbackInterceptor> inters = createCallbackInterceptors(eventType, callback);
                    for (CallbackInterceptor inter : inters) {
                        callbacks[index].add(inter);
                    }
                }
            }

            if (callbacks[index].size() > 0) {
                scanFor2xLifecycleMethods = false;
            }
        }

        if (scanFor2xLifecycleMethods) {
            load2xLifecycleMethods(callbacks);
        }
        
        //The next set of lines are to handle the case where
        //  the app doesn't have a @PostConstruct or it 
        //  doesn't implement the EntrerpriseBean interface
        //  In this case we scan for ejbCreate() for MDBs and SLSBs
        boolean lookForEjbCreateMethod =
            (container instanceof StatelessSessionContainer)
            || (container instanceof MessageBeanContainer);

        if (lookForEjbCreateMethod) {
            loadOnlyEjbCreateMethod(callbacks);
        }
        
        callbackChain = new CallbackChainImpl[size];
        for (CallbackType eventType : CallbackType.values()) {
            int index = eventType.ordinal();
            CallbackInterceptor[] interceptors = (CallbackInterceptor[])
                    callbacks[index].toArray(new CallbackInterceptor[callbacks[index].size()]);
            callbackChain[index] = new CallbackChainImpl(container, interceptors);
        }

    
private voidinitInterceptorClassNames()

        Set<String> interceptorClassNames = ejbDesc.getInterceptorClassNames();
        int size = interceptorClassNames.size();
        interceptorClasses = new Class[size];
        serializableInterceptorClasses = new Class[size];
        int index = 0;
        for (String className : interceptorClassNames) {
        	Class interClass = loader.loadClass(className);
            interceptorClasses[index] = interClass;
            serializableInterceptorClasses[index] = interClass;
            instanceIndexMap.put(className, index);
            if (!Serializable.class.isAssignableFrom(interClass)) {
                serializableInterceptorClasses[index] = 
                    EJBUtils.loadGeneratedSerializableClass(loader, className);
            }
            index++;
        }
        methodInterceptorsExists = interceptorClassNames.size() > 0;

        if (ejbDesc.hasAroundInvokeMethod()) {
            methodInterceptorsExists = true;
        }
        instanceIndexMap.put(beanClassName, index++);
    
public java.lang.Objectintercept(com.sun.ejb.Invocation inv)

        return inv.getInterceptorChain().invokeNext(0, inv);
    
public booleanintercept(com.sun.enterprise.deployment.LifecycleCallbackDescriptor.CallbackType eventType, com.sun.ejb.containers.EJBContextImpl ctx)


        CallbackChainImpl chain = null;
        switch (eventType) {
            case POST_CONSTRUCT:
            case PRE_PASSIVATE:
            case POST_ACTIVATE:
            case PRE_DESTROY:
                chain = callbackChain[eventType.ordinal()];
                CallbackInvocationContext invContext = new
                    CallbackInvocationContext(ctx, chain);
                if (chain != null) {
                    chain.invokeNext(0, invContext);
                }
                break;
            default:
                throw new IllegalStateException("Invalid event type");
        }

        return true;
    
private voidload2xLifecycleMethods(java.util.ArrayList[] metaArray)


        if (javax.ejb.EnterpriseBean.class.isAssignableFrom(beanClass)) {
            int sz = lcAnnotationClasses.length;
            for (int i = 0; i < sz; i++) {
                if (pre30LCMethodNames[i] == null) {
                    continue;
                }
                try {
                    Method method = beanClass.getMethod(
                            pre30LCMethodNames[i], (Class[]) null);
                    if (method != null) {
                        CallbackInterceptor meta =
                                new BeanCallbackInterceptor(method);
                        metaArray[i].add(meta);
                        _logger.log(Level.FINE, "**## bean has 2.x LM: " + meta);
                    }
                } catch (NoSuchMethodException nsmEx) {
                    //TODO: Log exception
                    //Error for a 2.x bean????
                }
            }
        }
    
private voidloadOnlyEjbCreateMethod(java.util.ArrayList[] metaArray)

        int sz = lcAnnotationClasses.length;
        for (int i = 0; i < sz; i++) {
            if (lcAnnotationClasses[i] != PostConstruct.class) {
                continue;
            }

            boolean needToScan = true;
            if (metaArray[i] != null) {
                ArrayList<CallbackInterceptor> al = metaArray[i];
                needToScan =  (al.size() == 0);
            }
            
            if (! needToScan) {
                // We already have found a @PostConstruct method
                // So just ignore any ejbCreate() method
                break;
            } else {
                try {
                    Method method = beanClass.getMethod(pre30LCMethodNames[i],
                            (Class[]) null);
                    if (method != null) {
                        CallbackInterceptor meta = new BeanCallbackInterceptor(
                                method);
                        metaArray[i].add(meta);
                        _logger.log(Level.INFO,
                                "**##[ejbCreate] bean has 2.x style ejbCreate: " + meta);
                    }
                } catch (NoSuchMethodException nsmEx) {
                    // TODO: Log exception
                    //Error for a 2.x bean????
                }
            }
        }
    
public java.lang.StringtoString()

        StringBuilder sbldr = new StringBuilder();
        sbldr.append("##########################################################\n");
        sbldr.append("InterceptorManager<").append(beanClassName).append("> has ")
                .append(interceptorClasses.length).append(" interceptors");
        sbldr.append("\n\tbeanClassName: ").append(beanClassName);
        sbldr.append("\n\tInterceptors: ");
        for (Class clazz : interceptorClasses) {
            sbldr.append("\n\t\t").append(clazz.getName());
        }
        sbldr.append("\n\tCallback Interceptors: ");
        for (int i = 0; i < lcAnnotationClasses.length; i++) {
            CallbackChainImpl chain = callbackChain[i];
            sbldr.append("\n\t").append(i)
                    .append(": ").append(lcAnnotationClasses[i]);
            sbldr.append("\n\t\t").append(chain.toString());
        }
        sbldr.append("\n");
        sbldr.append("##########################################################\n");
        return sbldr.toString();