Home » apache-openwebbeans-1.0.0-incubating-M3-sources » org.apache.webbeans.decorator » [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.decorator;
   15   
   16   import java.io.Serializable;
   17   import java.lang.annotation.Annotation;
   18   import java.lang.reflect.Field;
   19   import java.lang.reflect.Method;
   20   import java.lang.reflect.Type;
   21   import java.util.HashSet;
   22   import java.util.Set;
   23   
   24   import javax.decorator.Decorates;
   25   import javax.enterprise.context.spi.CreationalContext;
   26   import javax.enterprise.inject.spi.Decorator;
   27   import javax.enterprise.inject.spi.InjectionPoint;
   28   
   29   import org.apache.webbeans.component.AbstractBean;
   30   import org.apache.webbeans.component.ManagedBean;
   31   import org.apache.webbeans.component.WebBeansType;
   32   import org.apache.webbeans.exception.WebBeansException;
   33   import org.apache.webbeans.inject.InjectableField;
   34   import org.apache.webbeans.inject.InjectableMethods;
   35   import org.apache.webbeans.logger.WebBeansLogger;
   36   import org.apache.webbeans.proxy.JavassistProxyFactory;
   37   import org.apache.webbeans.util.AnnotationUtil;
   38   import org.apache.webbeans.util.ClassUtil;
   39   
   40   /**
   41    * Defines decorators. It wraps the bean instance related
   42    * with decorator class. Actually, each decorator is an instance
   43    * of the {@link ManagedBean}.
   44    * 
   45    * @version $Rev$ $Date$
   46    *
   47    * @param <T> decorator type info
   48    */
   49   public class WebBeansDecorator<T> extends AbstractBean<T> implements Decorator<T>
   50   {
   51       private static WebBeansLogger logger = WebBeansLogger.getLogger(WebBeansDecorator.class);
   52   
   53       /** Decorator class */
   54       private Class<?> clazz;
   55   
   56       /** Decorates api types */
   57       private Set<Type> decoratedTypes = new HashSet<Type>();
   58   
   59       /** Delegate field class type */
   60       protected Type delegateType;
   61   
   62       /** Delegate field bindings */
   63       protected Set<Annotation> delegateBindings = new HashSet<Annotation>();
   64   
   65       /** Wrapped bean*/
   66       private AbstractBean<T> wrappedBean;
   67       
   68       /**Creational context*/
   69       private CreationalContext<Object> creationalContext;
   70   
   71       /**
   72        * Creates a new decorator bean instance with the given wrapped bean.
   73        * @param delegateComponent delegate bean instance
   74        */
   75       public WebBeansDecorator(AbstractBean<T> wrappedBean)
   76       {
   77           super(WebBeansType.DECORATOR,wrappedBean.getReturnType());
   78           
   79           this.wrappedBean = wrappedBean;
   80           this.clazz = wrappedBean.getReturnType();
   81   
   82           init();
   83       }
   84   
   85       protected void init()
   86       {
   87           ClassUtil.setInterfaceTypeHierarchy(this.decoratedTypes, this.clazz);
   88   
   89           if (this.decoratedTypes.contains(Serializable.class))
   90           {
   91               this.decoratedTypes.remove(Serializable.class);
   92           }
   93   
   94           initDelegate();
   95       }
   96   
   97       protected void initDelegate()
   98       {
   99           Field field = ClassUtil.getFieldWithAnnotation(this.clazz, Decorates.class);
  100           
  101           if(field == null)
  102           {
  103               initDelegateRecursively(this.clazz);
  104           }
  105           else
  106           {
  107               initDelegateInternal(field);
  108           }
  109       }
  110       
  111       private void initDelegateRecursively(Class<?> delegateClazz)
  112       {
  113           Class<?> superClazz = delegateClazz.getSuperclass();
  114           if(!superClazz.equals(Object.class))
  115           {
  116               Field field = ClassUtil.getFieldWithAnnotation(superClazz, Decorates.class);
  117               if(field != null)
  118               {
  119                   initDelegateInternal(field);
  120               }
  121               else
  122               {
  123                   initDelegateRecursively(superClazz);
  124               }
  125           }
  126       }
  127       
  128       private void initDelegateInternal(Field field)
  129       {
  130           this.delegateType = field.getGenericType();
  131   
  132           Annotation[] anns = field.getAnnotations();
  133   
  134           for (Annotation ann : anns)
  135           {
  136               if (AnnotationUtil.isQualifierAnnotation(ann.annotationType()))
  137               {
  138                   this.delegateBindings.add(ann);
  139               }
  140           }
  141           
  142       }
  143   
  144       public boolean isDecoratorMatch(Set<Type> apiType, Set<Annotation> annotation)
  145       {
  146           boolean foundApi = false;
  147           for (Type t : apiType)
  148           {           
  149           	//TODO Check for generic
  150               if (this.delegateType.equals(t))
  151               {
  152                   foundApi = true;
  153                   break;
  154               }
  155           }
  156   
  157           boolean allBindingsOk = false;
  158           if (foundApi)
  159           {
  160               for (Annotation annot : annotation)
  161               {
  162                   boolean bindingOk = false;
  163                   for (Annotation bindingType : delegateBindings)
  164                   {
  165                       if (AnnotationUtil.isAnnotationMemberExist(bindingType.annotationType(), annot, bindingType))
  166                       {
  167                           bindingOk = true;
  168                           break;
  169                       }
  170                   }
  171   
  172                   if (bindingOk)
  173                   {
  174                       allBindingsOk = true;
  175                   }
  176                   else
  177                   {
  178                       allBindingsOk = false;
  179                       break;
  180                   }
  181               }
  182           }
  183   
  184           if (!allBindingsOk)
  185           {
  186               return false;
  187           }
  188   
  189           return true;
  190       }
  191   
  192       @Override
  193       public Set<Annotation> getDelegateBindings()
  194       {
  195           return delegateBindings;
  196       }
  197   
  198       @Override
  199       public Type getDelegateType()
  200       {
  201           return delegateType;
  202       }
  203   
  204       public void setDelegate(Object instance, Object delegate)
  205       {
  206           Field field = ClassUtil.getFieldWithAnnotation(getClazz(), Decorates.class);
  207           if (!field.isAccessible())
  208           {
  209               field.setAccessible(true);
  210           }
  211   
  212           try
  213           {
  214               field.set(instance, delegate);
  215   
  216           }
  217           catch (IllegalArgumentException e)
  218           {
  219               logger.error("Delegate field is not found on the given decorator class : " + instance.getClass().getName(), e);
  220               throw new WebBeansException(e);
  221   
  222           }
  223           catch (IllegalAccessException e)
  224           {
  225               logger.error("Illegal access exception for field " + field.getName() + " in decorator class : " + instance.getClass().getName(), e);
  226           }
  227   
  228       }
  229   
  230       
  231       @SuppressWarnings("unchecked")    
  232       protected  T createInstance(CreationalContext<T> creationalContext)
  233       {
  234           T proxy = (T)JavassistProxyFactory.createNewProxyInstance(this);
  235           
  236           this.wrappedBean.setCreationalContext(creationalContext);
  237   
  238           return proxy;
  239           
  240       }
  241   
  242       public void setInjections(Object proxy)
  243       {
  244           // Set injected fields
  245           ManagedBean<T> delegate = (ManagedBean<T>) this.wrappedBean;
  246   
  247           Set<Field> injectedFields = delegate.getInjectedFields();
  248           for (Field injectedField : injectedFields)
  249           {
  250               boolean isDecorates = injectedField.isAnnotationPresent(Decorates.class);
  251   
  252               if (!isDecorates)
  253               {
  254                   InjectableField ife = new InjectableField(injectedField, proxy, this.wrappedBean,this.creationalContext);
  255                   ife.doInjection();
  256               }
  257           }
  258   
  259           Set<Method> injectedMethods = delegate.getInjectedMethods();
  260           for (Method injectedMethod : injectedMethods)
  261           {
  262               @SuppressWarnings("unchecked")
  263               InjectableMethods<?> ife = new InjectableMethods(injectedMethod, proxy, this.wrappedBean,this.creationalContext);
  264               ife.doInjection();
  265           }
  266       }
  267   
  268       public void destroy(T instance,CreationalContext<T> context)
  269       {
  270           wrappedBean.destroy(instance,context);
  271       }
  272   
  273       @Override
  274       public Set<Annotation> getQualifiers()
  275       {
  276           return wrappedBean.getQualifiers();
  277       }
  278   
  279       @Override
  280       public Class<? extends Annotation> getDeploymentType()
  281       {
  282           return wrappedBean.getDeploymentType();
  283       }
  284   
  285       @Override
  286       public String getName()
  287       {
  288           return wrappedBean.getName();
  289       }
  290   
  291       @Override
  292       public Class<? extends Annotation> getScope()
  293       {
  294           return wrappedBean.getScope();
  295       }
  296   
  297       
  298       public Set<Type> getTypes()
  299       {
  300           return wrappedBean.getTypes();
  301       }
  302   
  303       @Override
  304       public boolean isNullable()
  305       {
  306           return wrappedBean.isNullable();
  307       }
  308   
  309       @Override
  310       public boolean isSerializable()
  311       {
  312           return wrappedBean.isSerializable();
  313       }
  314   
  315       /**
  316        * @return the delegateComponent
  317        */
  318       public AbstractBean<T> getDelegateComponent()
  319       {
  320           return wrappedBean;
  321       }
  322       
  323       public Set<InjectionPoint> getInjectionPoints()
  324       {
  325           return wrappedBean.getInjectionPoints();
  326       }
  327   
  328       /**
  329        * @return the clazz
  330        */
  331       public Class<?> getClazz()
  332       {
  333           return clazz;
  334       }
  335   
  336       /*
  337        * (non-Javadoc)
  338        * @see java.lang.Object#hashCode()
  339        */
  340       @Override
  341       public int hashCode()
  342       {
  343           final int prime = 31;
  344           int result = 1;
  345           result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());
  346           return result;
  347       }
  348   
  349       /*
  350        * (non-Javadoc)
  351        * @see java.lang.Object#equals(java.lang.Object)
  352        */
  353       @Override
  354       public boolean equals(Object obj)
  355       {
  356           if (this == obj)
  357               return true;
  358           if (obj == null)
  359               return false;
  360           if (getClass() != obj.getClass())
  361               return false;
  362           final WebBeansDecorator<?> other = (WebBeansDecorator<?>) obj;
  363           if (clazz == null)
  364           {
  365               if (other.clazz != null)
  366                   return false;
  367           }
  368           else if (!clazz.equals(other.clazz))
  369               return false;
  370           return true;
  371       }
  372   
  373       @Override
  374       public Class<?> getBeanClass()
  375       {
  376           return this.wrappedBean.getBeanClass();
  377       }
  378   
  379   	@Override
  380   	public Set<Class<? extends Annotation>> getStereotypes() 
  381   	{
  382   		return this.wrappedBean.getStereotypes();
  383   	}
  384   
  385   	@Override
  386   	public Set<Type> getDecoratedTypes() {
  387   		return this.wrappedBean.getTypes();
  388   	}
  389   
  390       @Override
  391       public boolean isAlternative()
  392       {
  393           return this.wrappedBean.isAlternative();
  394       }
  395   
  396   
  397   }

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