Package org.jboss.ejb3.interceptors.container

Source Code of org.jboss.ejb3.interceptors.container.AbstractContainer

/*
* 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.container;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.jboss.aop.Advisor;
import org.jboss.aop.AspectManager;
import org.jboss.aop.Domain;
import org.jboss.aop.DomainDefinition;
import org.jboss.aop.MethodInfo;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.advice.PerVmAdvice;
import org.jboss.aop.annotation.AnnotationRepository;
import org.jboss.aop.joinpoint.ConstructionInvocation;
import org.jboss.aop.joinpoint.MethodInvocation;
import org.jboss.aop.util.MethodHashing;
import org.jboss.ejb3.interceptors.InterceptorFactoryRef;
import org.jboss.ejb3.interceptors.annotation.AnnotationAdvisor;
import org.jboss.ejb3.interceptors.annotation.AnnotationAdvisorSupport;
import org.jboss.ejb3.interceptors.aop.InterceptorsFactory;
import org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor;
import org.jboss.ejb3.interceptors.lang.ClassHelper;
import org.jboss.logging.Logger;

/**
* The base of all containers. Provides functions to allow for object
* construction and invocation with interception.
*
* Note that it's up to the actual implementation to expose any methods.
*
* @author <a href="mailto:carlo.dewolf@jboss.com">Carlo de Wolf</a>
* @version $Revision: 69210 $
*/
public abstract class AbstractContainer<T, C extends AbstractContainer<T, C>> extends AnnotationAdvisorSupport implements AnnotationAdvisor
{
   private static final Logger log = Logger.getLogger(AbstractContainer.class);
  
   private ManagedObjectAdvisor<T, C> advisor;
  
   /**
    * For a completely customized startup.
    *
    * Note that before construction ends advisor must be set!
    */
   protected AbstractContainer()
   {
     
   }
  
   protected AbstractContainer(String name, Domain domain, Class<? extends T> beanClass)
   {
      initializeAdvisor(name, domain, beanClass);
   }
  
   protected AbstractContainer(String name, String domainName, Class<? extends T> beanClass)
   {
      this(name, getDomain(domainName), beanClass);
   }
  
   protected T construct(Constructor<? extends T> constructor, Object ... initargs)
   {
      int idx = advisor.getConstructorIndex(constructor);
      assert idx != -1 : "can't find constructor in the advisor";
      try
      {
         T targetObject = (T) advisor.invokeNew(initargs, idx);
        
         Interceptor interceptors[] = advisor.getConstructionInfos()[idx].getInterceptors();
         ConstructionInvocation invocation = new ConstructionInvocation(interceptors, constructor, initargs);
         invocation.setAdvisor(advisor);
         invocation.setTargetObject(targetObject);
         invocation.invokeNext();
        
         return targetObject;
      }
      catch(Throwable t)
      {
         // TODO: disect
         if(t instanceof RuntimeException)
            throw (RuntimeException) t;
         throw new RuntimeException(t);
      }
   }
  
   protected Object createInterceptor(Class<?> interceptorClass) throws InstantiationException, IllegalAccessException
   {
      return interceptorClass.newInstance();
   }
  
   protected void destroy(T bean)
   {
      try
      {
         // TODO: speed up
         List<Interceptor> interceptors = new ArrayList<Interceptor>(InterceptorsFactory.getPreDestroys(advisor));
         interceptors.add(0, PerVmAdvice.generateInterceptor(null, new InvocationContextInterceptor(), "setup"));
        
         DestructionInvocation invocation = new DestructionInvocation(interceptors.toArray(new Interceptor[0]));
         invocation.setAdvisor(advisor);
         invocation.setTargetObject(bean);
         invocation.invokeNext();
      }
      catch(Throwable t)
      {
         // TODO: disect
         if(t instanceof RuntimeException)
            throw (RuntimeException) t;
         throw new RuntimeException(t);
      }
   }
  
   /**
    * Finalize construction of the abstract container by setting the advisor.
    *
    * @param name       the name of the advisor
    * @param domain     the domain for the advisor
    * @param beanClass  the class being advised
    */
   protected void initializeAdvisor(String name, Domain domain, Class<? extends T> beanClass)
   {
      initializeAdvisor(name, domain, beanClass, null);
   }
  
   protected void initializeAdvisor(String name, Domain domain, Class<? extends T> beanClass, AnnotationRepository annotations)
   {
      if(this.advisor != null) throw new IllegalStateException("advisor already set to " + advisor);
     
      assert name != null : "name is null";
      assert domain != null : "domain is null";
      assert beanClass != null : "beanClass is null";
     
      // Decouple setting the advisor and initializing it, so interceptors
      // can get it.
      this.advisor = new ManagedObjectAdvisor<T, C>((C) this, name, domain, annotations);
      advisor.getAnnotations().addClassAnnotation(InterceptorFactoryRef.class, new InterceptorFactoryRefImpl(ContainerInterceptorFactory.class));
      advisor.initialize(beanClass);
   }
  
   protected final ManagedObjectAdvisor<T, C> getAdvisor()
   {
      if(advisor == null) throw new IllegalStateException("advisor has not been initialized");
      return advisor;
   }
  
   @SuppressWarnings("unchecked")
   protected Class<? extends T> getBeanClass()
   {
      return getAdvisor().getClazz();
   }
  
   @SuppressWarnings("unchecked")
   public static <C extends AbstractContainer<?, ?>> C getContainer(Advisor advisor)
   {
      return (C) ((ManagedObjectAdvisor) advisor).getContainer();
   }
  
   /*
    * TODO: this should not be here, it's an AspectManager helper function.
    */
   protected static final Domain getDomain(String domainName)
   {
      DomainDefinition domainDefinition = AspectManager.instance().getContainer(domainName);
      if(domainDefinition == null)
         throw new IllegalArgumentException("Domain definition '" + domainName + "' can not be found");
     
      final Domain domain = (Domain) domainDefinition.getManager();
      return domain;
   }
  
   /**
    * Call a method upon a target object with all interceptors in place.
    *
    * @param target     the target to invoke upon
    * @param method     the method to invoke
    * @param arguments  arguments to the method
    * @return           return value of the method
    * @throws Throwable if anything goes wrong
    */
   protected Object invoke(T target, Method method, Object arguments[]) throws Throwable
   {
      long methodHash = MethodHashing.calculateHash(method);
      MethodInfo info = getAdvisor().getMethodInfo(methodHash);
      if(info == null)
         throw new IllegalArgumentException("method " + method + " is not under advisement by " + this);
      MethodInvocation invocation = new MethodInvocation(info, info.getInterceptors());
      invocation.setArguments(arguments);
      invocation.setTargetObject(target);
      return invocation.invokeNext();
   }
  
   /**
    * A convenient, but unchecked and slow method to call a method upon a target.
    *
    * (Slow method)
    *
    * @param <R>        the return type
    * @param target     the target to invoke upon
    * @param methodName the method name to invoke
    * @param args       the arguments to the method
    * @return           the return value
    * @throws Throwable if anything goes wrong
    */
   @SuppressWarnings("unchecked")
   protected <R> R invoke(T target, String methodName, Object ... args) throws Throwable
   {
      Method method = ClassHelper.getMethod(target.getClass(), methodName);
      return (R) invoke(target, method, args);
   }
}
TOP

Related Classes of org.jboss.ejb3.interceptors.container.AbstractContainer

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.