Home » apache-openwebbeans-1.0.0-incubating-M3-sources » org.apache.webbeans.intercept.webbeans » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements. See the NOTICE file distributed with this
    4    * work for additional information regarding copyright ownership. The ASF
    5    * licenses this file to You under the Apache License, Version 2.0 (the
    6    * "License"); you may not use this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
    9    * or agreed to in writing, software distributed under the License is
   10    * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   11    * KIND, either express or implied. See the License for the specific language
   12    * governing permissions and limitations under the License.
   13    */
   14   package org.apache.webbeans.intercept.webbeans;
   15   
   16   import java.lang.annotation.Annotation;
   17   import java.lang.reflect.Field;
   18   import java.lang.reflect.Method;
   19   import java.lang.reflect.Type;
   20   import java.util.HashMap;
   21   import java.util.HashSet;
   22   import java.util.Iterator;
   23   import java.util.List;
   24   import java.util.Map;
   25   import java.util.Set;
   26   
   27   import javax.enterprise.context.spi.CreationalContext;
   28   import javax.enterprise.inject.NonBinding;
   29   import javax.enterprise.inject.spi.InjectionPoint;
   30   import javax.enterprise.inject.spi.InterceptionType;
   31   import javax.enterprise.inject.spi.Interceptor;
   32   import javax.interceptor.InvocationContext;
   33   
   34   import org.apache.webbeans.component.AbstractBean;
   35   import org.apache.webbeans.component.ManagedBean;
   36   import org.apache.webbeans.component.WebBeansType;
   37   import org.apache.webbeans.exception.WebBeansConfigurationException;
   38   import org.apache.webbeans.exception.WebBeansException;
   39   import org.apache.webbeans.inject.InjectableField;
   40   import org.apache.webbeans.inject.InjectableMethods;
   41   import org.apache.webbeans.intercept.InterceptorUtil;
   42   import org.apache.webbeans.intercept.WebBeansInterceptorConfig;
   43   import org.apache.webbeans.logger.WebBeansLogger;
   44   import org.apache.webbeans.proxy.JavassistProxyFactory;
   45   import org.apache.webbeans.util.AnnotationUtil;
   46   import org.apache.webbeans.util.WebBeansUtil;
   47   import org.apache.webbeans.xml.XMLAnnotationTypeManager;
   48   
   49   /**
   50    * Defines the webbeans specific interceptors.
   51    * <p>
   52    * WebBeans interceotor classes has at least one {@link javax.interceptor.InterceptorBinding}
   53    * annotation. It can be defined on the class or method level at the component.
   54    * WebBeans interceptors are called after the EJB related interceptors are
   55    * called in the chain. Semantics of the interceptors are specified by the EJB
   56    * specificatin.
   57    * </p>
   58    * 
   59    * @version $Rev$ $Date$
   60    */
   61   public class WebBeansInterceptor<T> extends AbstractBean<T> implements Interceptor<T>
   62   {
   63   	private static final WebBeansLogger logger = WebBeansLogger.getLogger(WebBeansInterceptor.class);
   64   	
   65       /** InterceptorBindingTypes exist on the interceptor class */
   66       private Map<Class<? extends Annotation>, Annotation> interceptorBindingSet = new HashMap<Class<? extends Annotation>, Annotation>();
   67   
   68       /** Interceptor class */
   69       private Class<?> clazz;
   70   
   71       /** Simple Web Beans component */
   72       private AbstractBean<T> delegateComponent;
   73       
   74       private CreationalContext<T> creationalContext;
   75   
   76       public WebBeansInterceptor(AbstractBean<T> delegateComponent)
   77       {
   78           super(WebBeansType.INTERCEPTOR,delegateComponent.getReturnType());
   79           
   80           this.delegateComponent = delegateComponent;
   81           this.clazz = getDelegate().getReturnType();
   82   
   83       }
   84   
   85       public AbstractBean<T> getDelegate()
   86       {
   87           return this.delegateComponent;
   88       }
   89   
   90       /**
   91        * Add new binding type to the interceptor.
   92        * 
   93        * @param binding interceptor binding annotation. class
   94        * @param annot binding type annotation
   95        */
   96       public void addInterceptorBinding(Class<? extends Annotation> binding, Annotation annot)
   97       {
   98           Method[] methods = binding.getDeclaredMethods();
   99   
  100           for (Method method : methods)
  101           {
  102               Class<?> clazz = method.getReturnType();
  103               if (clazz.isArray() || clazz.isAnnotation())
  104               {
  105                   if (!AnnotationUtil.isAnnotationExist(method.getAnnotations(), NonBinding.class))
  106                   {
  107                       throw new WebBeansConfigurationException("Interceptor definition class : " + getClazz().getName() + " @InterceptorBinding : " + binding.getName() + " must have @NonBinding valued members for its array-valued and annotation valued members");
  108                   }
  109               }
  110           }
  111   
  112           interceptorBindingSet.put(binding, annot);
  113       }
  114   
  115       /**
  116        * Checks whether this interceptor has given binding types with
  117        * {@link NonBinding} member values.
  118        * 
  119        * @param bindingTypes binding types
  120        * @param annots binding types annots.
  121        * @return true if binding types exist ow false
  122        */
  123       public boolean isBindingExist(List<Class<? extends Annotation>> bindingTypes, List<Annotation> annots)
  124       {
  125           boolean result = false;
  126   
  127           if (bindingTypes != null && annots != null && (bindingTypes.size() == annots.size()))
  128           {
  129               int i = 0;
  130               for (Class<? extends Annotation> bindingType : bindingTypes)
  131               {
  132                   if (this.interceptorBindingSet.containsKey(bindingType))
  133                   {
  134                       Annotation target = this.interceptorBindingSet.get(bindingType);
  135                       if (AnnotationUtil.isAnnotationMemberExist(bindingType, annots.get(i), target))
  136                       {
  137                           result = true;
  138                       }
  139                       else
  140                       {
  141                           return false;
  142                       }
  143                   }
  144                   else
  145                   {
  146                       return false;
  147                   }
  148   
  149                   i++;
  150               }
  151           }
  152   
  153           return result;
  154       }
  155   
  156       /**
  157        * Gets the interceptor class.
  158        * 
  159        * @return interceptor class
  160        */
  161       public Class<?> getClazz()
  162       {
  163           return clazz;
  164       }
  165   
  166       public Set<Interceptor<?>> getMetaInceptors()
  167       {
  168           Set<Interceptor<?>> set = new HashSet<Interceptor<?>>();
  169   
  170           Set<Class<? extends Annotation>> keys = interceptorBindingSet.keySet();
  171           Iterator<Class<? extends Annotation>> it = keys.iterator();
  172   
  173           while (it.hasNext())
  174           {
  175               Class<? extends Annotation> clazzAnnot = it.next();
  176               Set<Annotation> declared = null;
  177               Annotation[] anns = null;
  178   
  179               if (XMLAnnotationTypeManager.getInstance().isInterceptorBindingTypeExist(clazzAnnot))
  180               {
  181                   declared = XMLAnnotationTypeManager.getInstance().getInterceptorBindingTypeInherites(clazzAnnot);
  182                   anns = new Annotation[declared.size()];
  183                   anns = declared.toArray(anns);
  184               }
  185   
  186               else if (AnnotationUtil.isInterceptorBindingMetaAnnotationExist(clazzAnnot.getDeclaredAnnotations()))
  187               {
  188                   anns = AnnotationUtil.getInterceptorBindingMetaAnnotations(clazzAnnot.getDeclaredAnnotations());
  189               }
  190   
  191               /*
  192                * For example: @InterceptorBinding @Transactional @Action
  193                * public @interface ActionTransactional @ActionTransactional
  194                * @Production { }
  195                */
  196   
  197               if (anns != null && anns.length > 0)
  198               {
  199                   // For example : @Transactional @Action Interceptor
  200                   Set<Interceptor<?>> metas = WebBeansInterceptorConfig.findDeployedWebBeansInterceptor(anns);
  201                   set.addAll(metas);
  202   
  203                   // For each @Transactional and @Action Interceptor
  204                   for (Annotation ann : anns)
  205                   {
  206                       Annotation[] simple = new Annotation[1];
  207                       simple[0] = ann;
  208                       metas = WebBeansInterceptorConfig.findDeployedWebBeansInterceptor(simple);
  209                       set.addAll(metas);
  210                   }
  211   
  212               }
  213   
  214           }
  215   
  216           return set;
  217       }
  218   
  219       /**
  220        * Sets interceptor class.
  221        * 
  222        * @param clazz class instance
  223        */
  224       public void setClazz(Class<?> clazz)
  225       {
  226           this.clazz = clazz;
  227       }
  228   
  229       @Override
  230       public Set<Annotation> getInterceptorBindings()
  231       {
  232           Set<Annotation> set = new HashSet<Annotation>();
  233           Set<Class<? extends Annotation>> keySet = this.interceptorBindingSet.keySet();
  234           Iterator<Class<? extends Annotation>> itSet = keySet.iterator();
  235   
  236           while (itSet.hasNext())
  237           {
  238               set.add(this.interceptorBindingSet.get(itSet.next()));
  239           }
  240   
  241           return set;
  242       }
  243   
  244       public Method getMethod(InterceptionType type)
  245       {
  246           Class<? extends Annotation> interceptorTypeAnnotationClazz = InterceptorUtil.getInterceptorAnnotationClazz(type);
  247           Method method = WebBeansUtil.checkCommonAnnotationCriterias(getClazz(), interceptorTypeAnnotationClazz, true);
  248   
  249           return method;
  250       }
  251   
  252       
  253       @SuppressWarnings("unchecked")
  254       protected T createInstance(CreationalContext<T> creationalContext)
  255       {
  256           T proxy = (T)JavassistProxyFactory.createNewProxyInstance(this);
  257           
  258           this.delegateComponent.setCreationalContext(creationalContext);
  259   
  260           return proxy;
  261           
  262       }
  263   
  264       public void setInjections(Object proxy)
  265       {
  266           // Set injected fields
  267           ManagedBean<T> delegate = (ManagedBean<T>) this.delegateComponent;
  268   
  269           Set<Field> injectedFields = delegate.getInjectedFields();
  270           for (Field injectedField : injectedFields)
  271           {
  272               InjectableField ife = new InjectableField(injectedField, proxy, this.delegateComponent,creationalContext);
  273               ife.doInjection();
  274           }
  275   
  276           Set<Method> injectedMethods = delegate.getInjectedMethods();
  277           for (Method injectedMethod : injectedMethods)
  278           {
  279               @SuppressWarnings("unchecked")
  280               InjectableMethods<?> ife = new InjectableMethods(injectedMethod, proxy, this.delegateComponent,creationalContext);
  281               ife.doInjection();
  282           }
  283   
  284       }
  285   
  286       public void destroy(T instance,CreationalContext<T> context)
  287       {
  288           delegateComponent.destroy(instance,context);
  289       }
  290   
  291       @Override
  292       public Set<Annotation> getQualifiers()
  293       {
  294           return delegateComponent.getQualifiers();
  295       }
  296   
  297       @Override
  298       public Class<? extends Annotation> getDeploymentType()
  299       {
  300           return delegateComponent.getDeploymentType();
  301       }
  302   
  303       @Override
  304       public String getName()
  305       {
  306           return delegateComponent.getName();
  307       }
  308   
  309       @Override
  310       public Class<? extends Annotation> getScope()
  311       {
  312           return delegateComponent.getScope();
  313       }
  314   
  315       public Set<Type> getTypes()
  316       {
  317           return delegateComponent.getTypes();
  318       }
  319       
  320       public Set<InjectionPoint> getInjectionPoints()
  321       {
  322           return delegateComponent.getInjectionPoints();
  323       }
  324   
  325       /*
  326        * (non-Javadoc)
  327        * @see java.lang.Object#equals(java.lang.Object)
  328        */
  329       @Override
  330       public boolean equals(Object obj)
  331       {
  332           if (this == obj)
  333               return true;
  334   
  335           WebBeansInterceptor<?> o = null;
  336   
  337           if (obj instanceof WebBeansInterceptor)
  338           {
  339               o = (WebBeansInterceptor<?>) obj;
  340   
  341               if (o.clazz != null && this.clazz != null)
  342               {
  343                   return o.clazz.equals(this.clazz);
  344               }
  345   
  346           }
  347   
  348           return false;
  349       }
  350   
  351       /*
  352        * (non-Javadoc)
  353        * @see java.lang.Object#hashCode()
  354        */
  355       @Override
  356       public int hashCode()
  357       {
  358           return this.clazz != null ? clazz.hashCode() : 0;
  359       }
  360   
  361       /*
  362        * (non-Javadoc)
  363        * @see java.lang.Object#toString()
  364        */
  365       @Override
  366       public String toString()
  367       {
  368           return "WebBeans Interceptor with class : " + "[" + this.clazz.getName() + "]";
  369       }
  370   
  371       @Override
  372       public boolean isNullable()
  373       {
  374           return delegateComponent.isNullable();
  375       }
  376   
  377       @Override
  378       public boolean isSerializable()
  379       {
  380           return delegateComponent.isSerializable();
  381       }
  382   
  383       @Override
  384       public Class<?> getBeanClass()
  385       {
  386           return this.delegateComponent.getBeanClass();
  387       }
  388   
  389   	@Override
  390   	public Set<Class<? extends Annotation>> getStereotypes() 
  391   	{ 
  392   		return this.delegateComponent.getStereotypes();
  393   	}
  394   
  395   	@Override
  396   	public Object intercept(InterceptionType type, T instance,InvocationContext ctx) 
  397   	{
  398   		Method method = getMethod(type);
  399   		try 
  400   		{
  401   			method.invoke(instance,new Object[]{ctx});
  402   		} 
  403   		catch (Exception e)
  404   		{
  405   			logger.error(e);
  406   			throw new WebBeansException(e);
  407   		}
  408   		
  409   		return null;
  410   	}
  411   
  412   	@Override
  413   	public boolean intercepts(InterceptionType type) 
  414   	{
  415   		Method method = getMethod(type);
  416   		
  417   		return method != null ? true : false;
  418   	}
  419   
  420       @Override
  421       public boolean isAlternative()
  422       {
  423           return this.delegateComponent.isAlternative();
  424       }
  425   }

Home » apache-openwebbeans-1.0.0-incubating-M3-sources » org.apache.webbeans.intercept.webbeans » [javadoc | source]