Package org.jboss.ejb3.interceptors.aop

Source Code of org.jboss.ejb3.interceptors.aop.InterceptorsFactory

/*
* JBoss, Home of Professional Open Source.
* Copyright 2007, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
  *
* This 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 (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ejb3.interceptors.aop;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptors;

import org.jboss.aop.Advisor;
import org.jboss.aop.InstanceAdvisor;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.joinpoint.Invocation;
import org.jboss.aop.joinpoint.MethodInvocation;
import org.jboss.ejb3.interceptors.InterceptorFactory;
import org.jboss.ejb3.interceptors.InterceptorFactoryRef;
import org.jboss.ejb3.interceptors.aop.annotation.DefaultInterceptors;
import org.jboss.ejb3.interceptors.lang.ClassHelper;
import org.jboss.logging.Logger;

/**
* The interceptors factory analyzes the annotations and creates
* interceptor instances out of those. These are then attached
* to the advisor as meta data.
*
* Do not access this meta data directly, use the provided static
* methods herein.
*
* @author <a href="mailto:carlo.dewolf@jboss.com">Carlo de Wolf</a>
* @version $Revision: 69272 $
*/
public class InterceptorsFactory extends AbstractInterceptorFactory
{
   private static final Logger log = Logger.getLogger(InterceptorsFactory.class);
  
   // TODO: allow for extensions (/ new life-cycle annotations) (and PostActive, PrePassivate are part of stateful)
   /**
    * This defined the life-cycle annotations for which we build up
    * an interceptor chain.
    */
   @SuppressWarnings("unchecked")
   private static final Class<? extends Annotation> lifeCycleAnnotationClasses[] = (Class<? extends Annotation>[]) new Class<?>[] { PostActivate.class, PostConstruct.class, PreDestroy.class, PrePassivate.class };
  
   private List<? extends Interceptor> createInterceptors(Advisor advisor, InterceptorFactory interceptorFactory, Class<?>[] interceptorClasses, List<BusinessMethodInterceptorMethodInterceptor> interceptors, Map<Class<?>, Object> existingInterceptors, Map<Class<? extends Annotation>, List<Interceptor>> lifeCycleInterceptors) throws InstantiationException, IllegalAccessException
   {
      if(interceptorClasses != null)
      {
         for(Class<?> interceptorClass : interceptorClasses)
         {
            // TODO: what if I've specified the same interceptor twice? (throw an Exception?)
            Object interceptor = existingInterceptors.get(interceptorClass);
            if(interceptor == null)
            {
               interceptor = interceptorFactory.create(advisor, interceptorClass);
               existingInterceptors.put(interceptorClass, interceptor);
            }
            //Advisor interceptorAdvisor = ((Advised) interceptor)._getAdvisor();
            //Advisor interceptorAdvisor = advisor.getManager().getAdvisor(interceptorClass);
            //AnnotationAdvisor interceptorAdvisor = AnnotationAdvisorHelper.getAnnotationAdvisor(advisor, interceptor);
            ExtendedAdvisor interceptorAdvisor = ExtendedAdvisorHelper.getExtendedAdvisor(advisor, interceptor);
            log.debug("  interceptorAdvisor = " + interceptorAdvisor);
            // TODO: should be only non-overriden methods (EJB 3 12.4.1 last bullet)
            for(Method method : ClassHelper.getAllMethods(interceptorClass))
            {
               if(interceptorAdvisor.isAnnotationPresent(interceptorClass, method, AroundInvoke.class))
               {
                  interceptors.add(new BusinessMethodInterceptorMethodInterceptor(interceptor, method));
               }
               for(Class<? extends Annotation> lifeCycleAnnotationClass : lifeCycleAnnotationClasses)
               {
                  if(interceptorAdvisor.isAnnotationPresent(interceptorClass, method, lifeCycleAnnotationClass))
                  {
                     lifeCycleInterceptors.get(lifeCycleAnnotationClass).add(new LifecycleCallbackInterceptorMethodInterceptor(interceptor, method));
                  }
               }
            }
            //instanceAdvisor.appendInterceptorStack(stackName);
            //instanceAdvisor.appendInterceptor(new InvokeSpecInterceptorInterceptor());
         }
      }
      return interceptors;
   }
  
   public Object createPerInstance(Advisor advisor, InstanceAdvisor instanceAdvisor)
   {
      try
      {
         log.debug("createPerInstance");
         log.debug(" advisor " + advisor.getClass().getName());
         log.debug(" instanceAdvisor " + toString(instanceAdvisor));
        
         // TODO: the whole interceptor advisor & annotation stuff is butt ugly
        
         InterceptorFactoryRef interceptorFactoryRef = (InterceptorFactoryRef) advisor.resolveAnnotation(InterceptorFactoryRef.class);
         if(interceptorFactoryRef == null)
            throw new IllegalStateException("No InterceptorFactory specified on " + advisor.getName());
         log.debug("interceptor factory class = " + interceptorFactoryRef.value());
         InterceptorFactory interceptorFactory = interceptorFactoryRef.value().newInstance();
        
         Map<Class<?>, Object> interceptors = new HashMap<Class<?>, Object>();
        
         Map<Class<? extends Annotation>, List<Interceptor>> lifeCycleInterceptors = new HashMap<Class<? extends Annotation>, List<Interceptor>>();
         for(Class<? extends Annotation> lifeCycleAnnotationClass : lifeCycleAnnotationClasses)
         {
            List<Interceptor> list = new ArrayList<Interceptor>();
            lifeCycleInterceptors.put(lifeCycleAnnotationClass, list);
         }
        
         DefaultInterceptors defaultInterceptorsAnnotation = (DefaultInterceptors) advisor.resolveAnnotation(DefaultInterceptors.class);
         List<BusinessMethodInterceptorMethodInterceptor> defaultInterceptors = new ArrayList<BusinessMethodInterceptorMethodInterceptor>();
         if(defaultInterceptorsAnnotation != null)
            createInterceptors(advisor, interceptorFactory, defaultInterceptorsAnnotation.value(), defaultInterceptors, interceptors, lifeCycleInterceptors);
        
         log.debug("Found class interceptors " + defaultInterceptors);
         // Default Interceptors
         instanceAdvisor.getMetaData().addMetaData(InterceptorsFactory.class, "defaultInterceptors", defaultInterceptors);
        
         Interceptors interceptorsAnnotation = (Interceptors) advisor.resolveAnnotation(Interceptors.class);
         List<BusinessMethodInterceptorMethodInterceptor> classInterceptors = new ArrayList<BusinessMethodInterceptorMethodInterceptor>();
         if(interceptorsAnnotation != null)
            createInterceptors(advisor, interceptorFactory, interceptorsAnnotation.value(), classInterceptors, interceptors, lifeCycleInterceptors);
        
         log.debug("Found class interceptors " + classInterceptors);
         // Class Interceptors
         instanceAdvisor.getMetaData().addMetaData(InterceptorsFactory.class, "classInterceptors", classInterceptors);
        
         Class<?> beanClass = advisor.getClazz();
         List<Interceptor> beanInterceptors = new ArrayList<Interceptor>();
         for(Method beanMethod : ClassHelper.getAllMethods(beanClass))
         {
            interceptorsAnnotation = (Interceptors) advisor.resolveAnnotation(beanMethod, Interceptors.class);
            if(interceptorsAnnotation != null)
            {
               List<Interceptor> businessMethodInterceptors = new ArrayList<Interceptor>();
               // TODO: use visitors?
               for(Class<?> interceptorClass : interceptorsAnnotation.value())
               {
                  Object interceptor = interceptors.get(interceptorClass);
                  if(interceptor == null)
                  {
                     interceptor = interceptorFactory.create(advisor, interceptorClass);
                     interceptors.put(interceptorClass, interceptor);
                  }
                  //Advisor interceptorAdvisor = ((Advised) interceptor)._getAdvisor();
                  //Advisor interceptorAdvisor = advisor.getManager().getAdvisor(interceptorClass);
                  ExtendedAdvisor interceptorAdvisor = ExtendedAdvisorHelper.getExtendedAdvisor(advisor, interceptor);
                  for(Method method : ClassHelper.getAllMethods(interceptorClass))
                  {
                     /* EJB 3 12.7 footnote 57: no lifecycle callbacks on business method interceptors
                     if(interceptorAdvisor.isAnnotationPresent(interceptorClass, method, PostConstruct.class))
                     {
                        postConstructs.add(new LifecycleCallbackInterceptorMethodInterceptor(interceptor, method));
                     }
                     */
                     if(interceptorAdvisor.isAnnotationPresent(interceptorClass, method, AroundInvoke.class))
                     {
                        businessMethodInterceptors.add(new BusinessMethodInterceptorMethodInterceptor(interceptor, method));
                     }
                  }
               }
               instanceAdvisor.getMetaData().addMetaData(InterceptorsFactory.class, beanMethod, businessMethodInterceptors);
            }
           
            if(advisor.hasAnnotation(beanMethod, AroundInvoke.class))
            {
               beanInterceptors.add(new BusinessMethodBeanMethodInterceptor(beanMethod));
            }
            for(Class<? extends Annotation> lifeCycleAnnotationClass : lifeCycleAnnotationClasses)
            {
               if(advisor.hasAnnotation(beanMethod, lifeCycleAnnotationClass))
               {
                  lifeCycleInterceptors.get(lifeCycleAnnotationClass).add(new LifecycleCallbackBeanMethodInterceptor(beanMethod));
               }
            }
         }
         log.debug("Found bean interceptors " + beanInterceptors);
         instanceAdvisor.getMetaData().addMetaData(InterceptorsFactory.class, "beanInterceptors", beanInterceptors);
        
         log.debug("Found life cycle interceptors " + lifeCycleInterceptors);
         instanceAdvisor.getMetaData().addMetaData(InterceptorsFactory.class, "lifeCycleInterceptors", Collections.unmodifiableMap(lifeCycleInterceptors));
        
         return new NopInterceptor();
      }
      catch(InstantiationException e)
      {
         Throwable cause = e.getCause();
         if(cause instanceof Error)
            throw (Error) cause;
         if(cause instanceof RuntimeException)
            throw (RuntimeException) cause;
         throw new RuntimeException(e);
      }
      catch (IllegalAccessException e)
      {
         throw new RuntimeException(e);
      }
   }

   @SuppressWarnings("unchecked")
   public static List<Interceptor> getBeanInterceptors(InstanceAdvisor instanceAdvisor)
   {
      return (List<Interceptor>) instanceAdvisor.getMetaData().getMetaData(InterceptorsFactory.class, "beanInterceptors");
   }
  
   @SuppressWarnings("unchecked")
   @Deprecated
   public static Interceptor[] getBusinessMethodInterceptors(MethodInvocation invocation)
   {
      List<Interceptor> list = (List<Interceptor>) invocation.getMetaData(InterceptorsFactory.class, invocation.getActualMethod());
      if(list == null) return null;
      return list.toArray(new Interceptor[0]);
   }
  
   @SuppressWarnings("unchecked")
   public static List<Interceptor> getBusinessMethodInterceptors(InstanceAdvisor instanceAdvisor, Method businessMethod)
   {
      return (List<Interceptor>) instanceAdvisor.getMetaData().getMetaData(InterceptorsFactory.class, businessMethod);
   }
  
   @SuppressWarnings("unchecked")
   @Deprecated
   public static Interceptor[] getClassInterceptors(Invocation invocation)
   {
      return ((List<Interceptor>) invocation.getMetaData(InterceptorsFactory.class, "classInterceptors")).toArray(new Interceptor[0]);
   }
  
   @SuppressWarnings("unchecked")
   public static List<Interceptor> getClassInterceptors(InstanceAdvisor instanceAdvisor)
   {
      return (List<Interceptor>) instanceAdvisor.getMetaData().getMetaData(InterceptorsFactory.class, "classInterceptors");
   }
  
   @SuppressWarnings("unchecked")
   public static List<Interceptor> getDefaultInterceptors(InstanceAdvisor instanceAdvisor)
   {
      return (List<Interceptor>) instanceAdvisor.getMetaData().getMetaData(InterceptorsFactory.class, "defaultInterceptors");
   }
  
   @SuppressWarnings("unchecked")
   private static Map<Class<? extends Annotation>, List<Interceptor>> getLifeCycleInterceptors(InstanceAdvisor instanceAdvisor)
   {
      return (Map<Class<? extends Annotation>, List<Interceptor>>) instanceAdvisor.getMetaData().getMetaData(InterceptorsFactory.class, "lifeCycleInterceptors");
   }
  
   public static List<Interceptor> getLifeCycleInterceptors(InstanceAdvisor instanceAdvisor, Class<? extends Annotation> lifeCycleAnnotationClass)
   {
      return getLifeCycleInterceptors(instanceAdvisor).get(lifeCycleAnnotationClass);
   }
  
   /**
    * @deprecated use getLifeCycleInterceptors
    * @param instanceAdvisor
    * @return
    */
   @Deprecated
   public static List<Interceptor> getPreDestroys(InstanceAdvisor instanceAdvisor)
   {
      return getLifeCycleInterceptors(instanceAdvisor, PreDestroy.class);
   }
  
   private String toString(Object obj)
   {
      return obj.getClass().getName() + "@" + System.identityHashCode(obj);
   }
}
TOP

Related Classes of org.jboss.ejb3.interceptors.aop.InterceptorsFactory

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.