Home » apache-openwebbeans-1.0.0-incubating-M3-sources » org.apache.webbeans.xml » [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.xml;
   15   
   16   import java.lang.annotation.Annotation;
   17   import java.lang.reflect.Field;
   18   import java.lang.reflect.Method;
   19   import java.util.ArrayList;
   20   import java.util.HashSet;
   21   import java.util.Iterator;
   22   import java.util.List;
   23   import java.util.Set;
   24   
   25   import javax.annotation.PostConstruct;
   26   import javax.annotation.PreDestroy;
   27   import javax.decorator.Decorator;
   28   import javax.enterprise.context.NormalScope;
   29   import javax.inject.Named;
   30   import javax.inject.Scope;
   31   import javax.enterprise.inject.NonBinding;
   32   import javax.enterprise.inject.UnsatisfiedResolutionException;
   33   import javax.enterprise.inject.deployment.DeploymentType;
   34   import javax.enterprise.inject.deployment.Specializes;
   35   import javax.enterprise.inject.spi.Bean;
   36   import javax.enterprise.inject.spi.InjectionPoint;
   37   import javax.enterprise.inject.spi.Interceptor;
   38   import javax.interceptor.AroundInvoke;
   39   
   40   import org.apache.webbeans.WebBeansConstants;
   41   import org.apache.webbeans.component.AbstractBean;
   42   import org.apache.webbeans.component.xml.XMLManagedBean;
   43   import org.apache.webbeans.component.xml.XMLProducerBean;
   44   import org.apache.webbeans.container.InjectionResolver;
   45   import org.apache.webbeans.decorator.WebBeansDecoratorConfig;
   46   import org.apache.webbeans.event.NotificationManager;
   47   import org.apache.webbeans.event.TransactionalObserverType;
   48   import org.apache.webbeans.event.xml.BeanObserverXMLImpl;
   49   import org.apache.webbeans.exception.WebBeansConfigurationException;
   50   import org.apache.webbeans.exception.definition.NonexistentFieldException;
   51   import org.apache.webbeans.exception.definition.NonexistentTypeException;
   52   import org.apache.webbeans.inject.impl.InjectionPointFactory;
   53   import org.apache.webbeans.inject.xml.XMLInjectionModelType;
   54   import org.apache.webbeans.inject.xml.XMLInjectionPointModel;
   55   import org.apache.webbeans.intercept.InterceptorData;
   56   import org.apache.webbeans.intercept.InterceptorUtil;
   57   import org.apache.webbeans.intercept.WebBeansInterceptorConfig;
   58   import org.apache.webbeans.intercept.webbeans.WebBeansInterceptor;
   59   import org.apache.webbeans.proxy.JavassistProxyFactory;
   60   import org.apache.webbeans.util.AnnotationUtil;
   61   import org.apache.webbeans.util.Asserts;
   62   import org.apache.webbeans.util.ClassUtil;
   63   import org.apache.webbeans.util.WebBeansUtil;
   64   import org.dom4j.Element;
   65   
   66   @SuppressWarnings("unchecked")
   67   public final class XMLDefinitionUtil
   68   {
   69       private XMLDefinitionUtil()
   70       {
   71   
   72       }
   73   
   74       /**
   75        * Checks the conditions for simple webbeans class defined in the XML file.
   76        * 
   77        * @param clazz simple webbeans class declared in XML
   78        * @throws WebBeansConfigurationException if check is fail
   79        */
   80       public static void checkSimpleWebBeansInXML(Class<?> clazz, Element webBeanDecleration, String errorMessage) throws WebBeansConfigurationException
   81       {
   82           Asserts.nullCheckForClass(clazz);
   83           if (errorMessage == null)
   84           {
   85               errorMessage = "XML defined simple webbeans failed. ";
   86           }
   87   
   88           int modifier = clazz.getModifiers();
   89   
   90           if (ClassUtil.isDefinitionConstainsTypeVariables(clazz))
   91           {
   92               throw new WebBeansConfigurationException(errorMessage + "Simple WebBeans component implementation class : " + clazz.getName() + " can not be parametrized type");
   93           }
   94   
   95           if (!ClassUtil.isStatic(modifier) && ClassUtil.isInnerClazz(clazz))
   96           {
   97               throw new WebBeansConfigurationException(errorMessage + "Simple WebBeans component implementation class : " + clazz.getName() + " can not be non-static inner class");
   98           }
   99   
  100           if (clazz.isAnnotationPresent(javax.interceptor.Interceptor.class))
  101           {
  102               boolean found = XMLUtil.isElementChildExistWithWebBeansNameSpace(webBeanDecleration, WebBeansConstants.WEB_BEANS_XML_INTERCEPTOR_ELEMENT);
  103               if (!found)
  104               {
  105                   throw new WebBeansConfigurationException(errorMessage + "Simple WebBeans component implementation class : " + clazz.getName() + " must be declared as <Interceptor> element in the XML");
  106               }
  107           }
  108   
  109           if (clazz.isAnnotationPresent(Decorator.class))
  110           {
  111               boolean found = XMLUtil.isElementChildExistWithWebBeansNameSpace(webBeanDecleration, WebBeansConstants.WEB_BEANS_XML_DECORATOR_ELEMENT);
  112               if (!found)
  113               {
  114                   throw new WebBeansConfigurationException(errorMessage + "Simple WebBeans component implementation class : " + clazz.getName() + " must be declared as <Decorator> element in the XML");
  115               }
  116           }
  117   
  118       }
  119   
  120       public static void checkTypeMetaDataClasses(List<Class<? extends Annotation>> typeSet, String errorMessage)
  121       {
  122           if (typeSet != null && !typeSet.isEmpty())
  123           {
  124               Iterator<Class<? extends Annotation>> it = typeSet.iterator();
  125               while (it.hasNext())
  126               {
  127                   Class<? extends Annotation> clazz = it.next();
  128                   if (clazz.isAnnotationPresent(DeploymentType.class) 
  129                           || clazz.isAnnotationPresent(NormalScope.class) 
  130                           || clazz.isAnnotationPresent(Scope.class)
  131                           || AnnotationUtil.isQualifierAnnotation(clazz)
  132                           || AnnotationUtil.isInterceptorBindingAnnotation(clazz) 
  133                           || AnnotationUtil.isStereoTypeAnnotation(clazz) 
  134                           || clazz.equals(Named.class) 
  135                           || clazz.equals(Specializes.class) || clazz.equals(javax.interceptor.Interceptor.class) 
  136                           || clazz.equals(Decorator.class))
  137                   {
  138                       continue;
  139                   }
  140                   else
  141                   {
  142                       throw new WebBeansConfigurationException(errorMessage + " TypeLevelMeta data configuration is failed because of the class : " + clazz.getName() + " is not applicable type");
  143                   }
  144               }
  145           }
  146   
  147       }
  148   
  149       /**
  150        * Gets applicable annotation class for given defineType parameter from the
  151        * given annotation set.
  152        * 
  153        * @param component webbeans component
  154        * @param annotationSet type-level metadata annotation set
  155        * @param defineType annotation type class
  156        * @param errorMessage error message for the operation
  157        * @return applicable annotation class for given defineType parameter from
  158        *         the given set
  159        */
  160       public static <T> Class<? extends Annotation> defineXMLTypeMetaData(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet, Class<? extends Annotation> defineType, String errorMessage)
  161       {
  162           // Found annotation for given defineType parameter
  163           Class<? extends Annotation> metaType = null;
  164   
  165           Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
  166           boolean found = false;
  167           while (it.hasNext())
  168           {
  169               Class<? extends Annotation> temp = it.next();
  170               if (temp.isAnnotationPresent(defineType))
  171               {
  172                   if (found)
  173                   {
  174                       throw new WebBeansConfigurationException(errorMessage);
  175                   }
  176                   else
  177                   {
  178                       metaType = temp;
  179                       found = true;
  180                   }
  181               }
  182           }
  183   
  184           return metaType;
  185       }
  186   
  187       public static <T> boolean defineXMLBindingType(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList, String errorMessage)
  188       {
  189           Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
  190           boolean found = false;
  191           int i = 0;
  192           while (it.hasNext())
  193           {
  194               Class<? extends Annotation> temp = it.next();
  195               if (AnnotationUtil.isQualifierAnnotation(temp))
  196               {
  197                   Method[] methods = temp.getDeclaredMethods();
  198   
  199                   for (Method method : methods)
  200                   {
  201                       Class<?> clazz = method.getReturnType();
  202                       if (clazz.isArray() || clazz.isAnnotation())
  203                       {
  204                           if (!AnnotationUtil.isAnnotationExist(method.getAnnotations(), NonBinding.class))
  205                           {
  206                               throw new WebBeansConfigurationException(errorMessage + "WebBeans definition class : " + component.getReturnType().getName() + " @Qualifier : " + temp.getName() + " must have @NonBinding valued members for its array-valued and annotation valued members");
  207                           }
  208                       }
  209                   }
  210   
  211                   if (!found)
  212                   {
  213                       found = true;
  214                   }
  215   
  216                   component.addQualifier(XMLUtil.getXMLDefinedAnnotationMember(annotationElementList.get(i), temp, errorMessage));
  217               }
  218   
  219               i++;
  220           }
  221   
  222           return found;
  223       }
  224   
  225       public static <T> void defineXMLClassLevelInterceptorType(XMLManagedBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList, String errorMessage)
  226       {
  227           Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
  228   
  229           Set<Annotation> bindingTypeSet = new HashSet<Annotation>();
  230           int i = 0;
  231           while (it.hasNext())
  232           {
  233               Class<? extends Annotation> temp = it.next();
  234               if (AnnotationUtil.isInterceptorBindingAnnotation(temp))
  235               {
  236                   bindingTypeSet.add(XMLUtil.getXMLDefinedAnnotationMember(annotationElementList.get(i), temp, errorMessage));
  237               }
  238   
  239               i++;
  240           }
  241   
  242           Set<Annotation> stereoTypesSet = component.getOwbStereotypes();
  243           Annotation[] stereoTypes = new Annotation[stereoTypesSet.size()];
  244           stereoTypes = stereoTypesSet.toArray(stereoTypes);
  245           for (Annotation stero : stereoTypes)
  246           {
  247               if (AnnotationUtil.isInterceptorBindingMetaAnnotationExist(stero.annotationType().getDeclaredAnnotations()))
  248               {
  249                   Annotation[] steroInterceptorBindings = AnnotationUtil.getInterceptorBindingMetaAnnotations(stero.annotationType().getDeclaredAnnotations());
  250   
  251                   for (Annotation ann : steroInterceptorBindings)
  252                   {
  253                       bindingTypeSet.add(ann);
  254                   }
  255               }
  256           }
  257   
  258           Annotation[] anns = new Annotation[bindingTypeSet.size()];
  259           anns = bindingTypeSet.toArray(anns);
  260   
  261           Set<Interceptor<?>> set = WebBeansInterceptorConfig.findDeployedWebBeansInterceptor(anns);
  262   
  263           WebBeansInterceptorConfig.addComponentInterceptors(set, component.getInterceptorStack());
  264   
  265       }
  266   
  267       public static <T> void defineXMLMethodLevelInterceptorType(XMLManagedBean<T> component, Method interceptorMethod, Element interceptorMethodElement, String errorMessage)
  268       {
  269           List<Element> bindingTypes = interceptorMethodElement.elements();
  270           Set<Annotation> bindingTypesSet = new HashSet<Annotation>();
  271           for (Element bindingType : bindingTypes)
  272           {
  273               Class<? extends Annotation> annot = (Class<? extends Annotation>) XMLUtil.getElementJavaType(bindingType);
  274               Annotation bindingAnnot = XMLUtil.getXMLDefinedAnnotationMember(bindingType, annot, errorMessage);
  275   
  276               bindingTypesSet.add(bindingAnnot);
  277           }
  278   
  279           Annotation[] result = new Annotation[bindingTypesSet.size()];
  280           result = bindingTypesSet.toArray(result);
  281   
  282           Set<Interceptor<?>> setInterceptors = WebBeansInterceptorConfig.findDeployedWebBeansInterceptor(result);
  283           Iterator<Interceptor<?>> it = setInterceptors.iterator();
  284   
  285           List<InterceptorData> stack = component.getInterceptorStack();
  286           while (it.hasNext())
  287           {
  288               WebBeansInterceptor interceptor = (WebBeansInterceptor) it.next();
  289   
  290               WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), AroundInvoke.class, false, true, stack, interceptorMethod, true);
  291               WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), PostConstruct.class, false, true, stack, interceptorMethod, true);
  292               WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), PreDestroy.class, false, true, stack, interceptorMethod, true);
  293           }
  294   
  295       }
  296   
  297       /**
  298        * Configures the webbeans component stereotype.
  299        * 
  300        * @param component webbeans component
  301        * @param annotationSet set of type-level metadata annotation set
  302        */
  303       public static <T> void defineXMLStereoType(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet)
  304       {
  305           Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
  306           while (it.hasNext())
  307           {
  308               Class<? extends Annotation> temp = it.next();
  309               if (AnnotationUtil.isStereoTypeAnnotation(temp))
  310               {
  311                   component.addStereoType(JavassistProxyFactory.createNewAnnotationProxy(temp));
  312               }
  313           }
  314       }
  315   
  316       public static <T> boolean defineXMLName(AbstractBean<T> component, List<Class<? extends Annotation>> annotationSet)
  317       {
  318           Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
  319           while (it.hasNext())
  320           {
  321               Class<? extends Annotation> temp = it.next();
  322               if (temp.equals(Named.class))
  323               {
  324                   return true;
  325               }
  326           }
  327   
  328           return false;
  329       }
  330   
  331       public static <T> void defineXMLSpecializes(XMLManagedBean<T> component, List<Class<? extends Annotation>> annotationSet)
  332       {
  333           Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
  334           while (it.hasNext())
  335           {
  336               Class<? extends Annotation> temp = it.next();
  337               if (temp.equals(Specializes.class))
  338               {
  339                   XMLSpecializesManager.getInstance().addXMLSpecializeClass(temp);
  340               }
  341           }
  342       }
  343   
  344       public static <T> void defineXMLInterceptors(XMLManagedBean<T> component, List<Class<? extends Annotation>> annotationSet, List<Element> annotationElementList, String errorMessage)
  345       {
  346           Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
  347           boolean found = false;
  348   
  349           Set<Annotation> interceptorBindingTypes = new HashSet<Annotation>();
  350           int i = 0;
  351           while (it.hasNext())
  352           {
  353               Class<? extends Annotation> temp = it.next();
  354               if (temp.equals(javax.interceptor.Interceptor.class))
  355               {
  356                   if (found)
  357                   {
  358                       throw new WebBeansConfigurationException(errorMessage + "More than one <Interceptor> element exist for class : " + component.getReturnType().getName());
  359                   }
  360                   else
  361                   {
  362                       found = true;
  363                   }
  364               }
  365               else if (AnnotationUtil.isInterceptorBindingAnnotation(temp))
  366               {
  367                   Element annotationElement = annotationElementList.get(i);
  368                   Annotation bindingAnnotation = XMLUtil.getXMLDefinedAnnotationMember(annotationElement, temp, errorMessage);
  369                   interceptorBindingTypes.add(bindingAnnotation);
  370               }
  371   
  372               i++;
  373           }
  374   
  375           if (interceptorBindingTypes.size() == 0)
  376           {
  377               throw new WebBeansConfigurationException(errorMessage + "<Interceptor> decleration must have one interceptor binding type for class : " + component.getReturnType().getName());
  378           }
  379   
  380           Annotation[] anns = new Annotation[interceptorBindingTypes.size()];
  381           anns = interceptorBindingTypes.toArray(anns);
  382           InterceptorUtil.checkLifecycleConditions(component.getReturnType(), anns, errorMessage + "Lifecycle interceptor : " + component.getReturnType().getName() + " interceptor binding type must be defined as @Target{TYPE}");
  383   
  384           WebBeansInterceptorConfig.configureInterceptorClass((XMLManagedBean<Object>) component, anns);
  385       }
  386   
  387       public static <T> void defineXMLDecorators(XMLManagedBean<T> component, List<Class<? extends Annotation>> annotationSet, Element decoratorDecleration, String errorMessage)
  388       {
  389           Iterator<Class<? extends Annotation>> it = annotationSet.iterator();
  390           boolean found = false;
  391           while (it.hasNext())
  392           {
  393               Class<? extends Annotation> temp = it.next();
  394               if (temp.equals(Decorator.class))
  395               {
  396                   if (found)
  397                   {
  398                       throw new WebBeansConfigurationException(errorMessage + "More than one <Decorator> element exist");
  399                   }
  400                   else
  401                   {
  402                       found = true;
  403                   }
  404               }
  405           }
  406   
  407           if (found)
  408           {
  409               List<Element> childs = decoratorDecleration.elements();
  410               for (Element child : childs)
  411               {
  412                   if (XMLUtil.getElementNameSpace(child).equals(XMLUtil.getElementNameSpace(decoratorDecleration)) && XMLUtil.isElementHasDecoratesChild(child))
  413                   {
  414                       Field field = ClassUtil.getFieldWithName(component.getReturnType(), child.getName());
  415                       if (field == null)
  416                       {
  417                           throw new NonexistentFieldException(errorMessage + "Field with name : " + child.getName() + " not found in the decorator class : " + component.getReturnType().getName());
  418                       }
  419   
  420                       Element decorates = child.element(WebBeansConstants.WEB_BEANS_XML_DECORATES_ELEMENT);
  421                       Element type = (Element) decorates.elements().get(0);
  422   
  423                       Class<?> apType = XMLUtil.getElementJavaType(type);
  424   
  425                       if (!field.getType().isAssignableFrom(apType))
  426                       {
  427                           throw new WebBeansConfigurationException(errorMessage + "Field name : " + field.getName() + " xml defined class type must be assignable to the field actual class type");
  428                       }
  429   
  430                       XMLInjectionPointModel model = XMLUtil.getInjectionPointModel(type, errorMessage);
  431   
  432                       WebBeansDecoratorConfig.configureXMLDecoratorClass((AbstractBean<Object>) component, model);
  433                   }
  434                   else
  435                   {
  436                       throw new WebBeansConfigurationException(errorMessage + "Delegate decleration must defined exactly one child element with name Decorates");
  437                   }
  438               }
  439           }
  440       }
  441   
  442       /**
  443        * Returns newly created and configures xml webbeans producer component.
  444        * 
  445        * @param component webbeans component that defines producer method
  446        * @param producesMethod producer method
  447        * @param producerMethodElement produce method xml element
  448        * @param errorMessage error message
  449        * @return newly created and configures xml webbeans producer component.
  450        * @see XMLProducerBean
  451        */
  452       public static <T> XMLProducerBean<T> defineXMLProducerMethod(WebBeansXMLConfigurator configurator, XMLManagedBean<T> component, Method producesMethod, Element producerMethodElement, String errorMessage)
  453       {
  454           boolean producesDefined = false;
  455           List<Element> childElements = producerMethodElement.elements();
  456           Class<T> type = null;
  457           Element typeElement = null;
  458           Element arrayElement = null;
  459           List<Class<? extends Annotation>> memberLevelMetaData = new ArrayList<Class<? extends Annotation>>();
  460           List<Element> memberLevelElement = new ArrayList<Element>();
  461           List<XMLInjectionPointModel> injectedParameters = new ArrayList<XMLInjectionPointModel>();
  462   
  463           for (Element childElement : childElements)
  464           {
  465               if (XMLUtil.isElementInWebBeansNameSpaceWithName(childElement, WebBeansConstants.WEB_BEANS_XML_PRODUCES_ELEMENT))
  466               {
  467                   if (producesDefined == false)
  468                   {
  469                       producesDefined = true;
  470                   }
  471                   else
  472                   {
  473                       throw new WebBeansConfigurationException(errorMessage + "More than one <Produces> element is defined");
  474                   }
  475   
  476                   List<Element> producesElementChilds = childElement.elements();
  477                   boolean definedType = false;
  478   
  479                   for (Element producesElementChild : producesElementChilds)
  480                   {
  481                       if (producesElementChild.getName().equals(WebBeansConstants.WEB_BEANS_XML_ARRAY_ELEMENT))
  482                       {
  483                           arrayElement = producesElementChild;
  484                           definedType = true;
  485                       }
  486                       else
  487                       {
  488                           type = (Class<T>) XMLUtil.getElementJavaType(producesElementChild);
  489                           if (type == null)
  490                           {
  491                               throw new NonexistentTypeException(errorMessage + "Java type : " + XMLUtil.getElementJavaClassName(producesElementChild) + " does not exist in the <Produces> element child");
  492                           }
  493   
  494                           else if (type.isAnnotation())
  495                           {
  496                               memberLevelMetaData.add((Class<? extends Annotation>) type);
  497                               memberLevelElement.add(producesElementChild);
  498                           }
  499                           else
  500                           {
  501                               if (!type.isAssignableFrom(producesMethod.getReturnType()) && !producesMethod.getReturnType().isAssignableFrom(type))
  502                               {
  503                                   throw new WebBeansConfigurationException(errorMessage + "Defined returned method type is not compatible for producer method name : " + producesMethod.getName() + " in class : " + component.getReturnType().getName());
  504                               }
  505   
  506                               if (definedType)
  507                               {
  508                                   throw new WebBeansConfigurationException(errorMessage + "More than one Java type in the <Produces> element");
  509                               }
  510                               else
  511                               {
  512                                   typeElement = producesElementChild;
  513                                   definedType = true;
  514                               }
  515                           }
  516                       }
  517                   }
  518   
  519                   if (!definedType)
  520                   {
  521                       throw new WebBeansConfigurationException(errorMessage + "<Produces> element must define at least one java type child");
  522                   }
  523               }
  524               else
  525               {
  526                   XMLInjectionPointModel injectionPointModel = XMLUtil.getInjectionPointModel(childElement, errorMessage);
  527                   injectedParameters.add(injectionPointModel);
  528   
  529               }
  530           }
  531   
  532           XMLProducerBean<T> producerComponentImpl = configureProducerMethod(component, producesMethod, injectedParameters, type, arrayElement, typeElement, errorMessage);
  533   
  534           configureProducerTypeLevelMetaData(configurator, producerComponentImpl, producesMethod, producerMethodElement, memberLevelMetaData, memberLevelElement, component, errorMessage);
  535   
  536           return producerComponentImpl;
  537       }
  538   
  539       /**
  540        * Configures and returns the newly created producer method webbeans
  541        * component.
  542        * 
  543        * @param parentComponent producer method webbeans parent component
  544        * @param producesMethod producer method
  545        * @param injectedParameters injected parameters of the producer method
  546        * @param type java class type of the producer method return type, null if
  547        *            the return type is defined as an Array element.
  548        * @param arrayElement if the return type is array type, this parameter is
  549        *            the Array element definition
  550        * @param typeElement if the return type is a Java type, this parameter is
  551        *            the Java type element
  552        * @param errorMessage error message
  553        * @return new xml defines producer method component
  554        * @see XMLProducerBean
  555        */
  556       private static <T> XMLProducerBean<T> configureProducerMethod(AbstractBean<?> parentComponent, Method producesMethod, List<XMLInjectionPointModel> injectedParameters, Class<T> type, Element arrayElement, Element typeElement, String errorMessage)
  557       {
  558           /* New producer webbeans component */
  559           XMLProducerBean<T> producerComponentImpl = new XMLProducerBean<T>(parentComponent, type);
  560   
  561           /* Check return type is the array type */
  562           if (arrayElement != null)
  563           {
  564               /* Configures array type */
  565               XMLUtil.defineXMLProducerApiTypeFromArrayElement(producerComponentImpl, arrayElement, errorMessage);
  566           }
  567           /* Return type is java type */
  568           else
  569           {
  570               /* Configures the java api types and actual type parameters */
  571               XMLInjectionPointModel model = XMLUtil.getInjectionPointModel(typeElement, errorMessage);
  572   
  573               producerComponentImpl.setActualTypeArguments(model.getActualTypeArguments());
  574               producerComponentImpl.addApiType(model.getInjectionClassType());
  575   
  576               if (model.getInjectionClassType().isPrimitive())
  577               {
  578                   producerComponentImpl.setNullable(false);
  579               }
  580           }
  581   
  582           producerComponentImpl.addApiType(Object.class);
  583   
  584           /* Set creator method */
  585           producerComponentImpl.setCreatorMethod(producesMethod);
  586   
  587           /* Configures producer method injected parameters */
  588           for (XMLInjectionPointModel injectionPointModel : injectedParameters)
  589           {
  590               producerComponentImpl.addProducerMethodInjectionPointModel(injectionPointModel);            
  591               producerComponentImpl.addInjectionPoint(getXMLMethodInjectionPoint(producerComponentImpl, injectionPointModel, producesMethod));
  592           }
  593   
  594           return producerComponentImpl;
  595   
  596       }
  597   
  598       /**
  599        * Configures xml defined producer method webbeans type level metadatas.
  600        * 
  601        * @param producerComponentImpl xml webbeans producer component
  602        * @param producesMethod producer method
  603        * @param producerMethodElement producer method xml element
  604        * @param memberLevelMetaData member level annotations
  605        * @param memberLevelElement member level xml elements
  606        * @param component parent component that defines producer method
  607        * @param errorMessage error message
  608        * @return type level metadata configured webbeans
  609        * @see XMLProducerBean
  610        */
  611       private static <T> XMLProducerBean<T> configureProducerTypeLevelMetaData(WebBeansXMLConfigurator configurator, XMLProducerBean<T> producerComponentImpl, Method producesMethod, Element producerMethodElement, List<Class<? extends Annotation>> memberLevelMetaData, List<Element> memberLevelElement, XMLManagedBean<T> component, String errorMessage)
  612       {
  613   
  614           for (Class<? extends Annotation> memberLevelMetaDataClass : memberLevelMetaData)
  615           {
  616               if (!memberLevelMetaDataClass.isAnnotationPresent(DeploymentType.class) && !memberLevelMetaDataClass.isAnnotationPresent(NormalScope.class) && !AnnotationUtil.isStereoTypeAnnotation(memberLevelMetaDataClass) && !memberLevelMetaDataClass.equals(Named.class))
  617               {
  618                   throw new WebBeansConfigurationException(errorMessage + "Defined annotations for producer method name : " + producesMethod.getName() + " in class : " + component.getReturnType().getName() + " is not correct");
  619               }
  620           }
  621   
  622           configurator.configureProducerTypeLevelMetaData(producerComponentImpl, memberLevelMetaData, memberLevelElement, producerMethodElement);
  623   
  624           return producerComponentImpl;
  625       }
  626   
  627       /**
  628        * Configures the disposal method of the webbeans component using the xml
  629        * configuration.
  630        * 
  631        * @param component producer method webbeans component
  632        * @param disposalMethod disposal method defined in the xml
  633        * @param disposalMethodElement disposal method xml element
  634        * @param errorMessage error message used in exceptions
  635        * @throws WebBeansConfigurationException if more than one Disposal element
  636        *             exist for the given disposal method element
  637        * @throws UnsatisfiedResolutionException if no producer method found for
  638        *             given disposal method
  639        */
  640       public static <T> void defineXMLDisposalMethod(XMLManagedBean<T> component, Method disposalMethod, Element disposalMethodElement, String errorMessage)
  641       {
  642           /* Disposal method element childs */
  643           List<Element> disposalChildElements = disposalMethodElement.elements();
  644   
  645           /* Multiple <Disposes> element control parameter */
  646           boolean disposalDefined = false;
  647   
  648           /* Other parameter elements other than @Disposes */
  649           List<Element> otherParameterElements = new ArrayList<Element>();
  650   
  651           XMLProducerBean<?> producerComponent = null;
  652   
  653           for (Element childElement : disposalChildElements)
  654           {
  655               if (XMLUtil.isElementInWebBeansNameSpaceWithName(childElement, WebBeansConstants.WEB_BEANS_XML_DISPOSES_ELEMENT))
  656               {
  657                   if (disposalDefined == false)
  658                   {
  659                       disposalDefined = true;
  660                   }
  661                   else
  662                   {
  663                       throw new WebBeansConfigurationException(errorMessage + "More than one <Disposal> element is defined for defining disposal method : " + disposalMethod.getName());
  664                   }
  665   
  666                   Element typeElement = (Element) childElement.elements().get(0);
  667   
  668                   /* Find disposal method model */
  669                   XMLInjectionPointModel model = XMLUtil.getInjectionPointModel(typeElement, errorMessage);
  670                   
  671                   component.addInjectionPoint(getXMLMethodInjectionPoint(component, model, disposalMethod));
  672   
  673                   /* Binding types for disposal method */
  674                   Set<Annotation> bindingTypes = model.getBindingTypes();
  675                   Annotation[] bindingAnns = new Annotation[bindingTypes.size()];
  676                   bindingAnns = bindingTypes.toArray(bindingAnns);
  677   
  678                   Set<Bean<?>> set = InjectionResolver.getInstance().implResolveByType(model.getInjectionGenericType(), bindingAnns);
  679                   producerComponent = (XMLProducerBean<?>) set.iterator().next();
  680   
  681                   if (producerComponent == null)
  682                   {
  683                       throw new UnsatisfiedResolutionException(errorMessage + "Producer method component of the disposal method : " + disposalMethod.getName() + "is not found");
  684                   }
  685   
  686                   producerComponent.setDisposalMethod(disposalMethod);
  687   
  688               }
  689               /* Disposal method parameter other than @Disposes */
  690               else
  691               {
  692                   otherParameterElements.add(childElement);
  693               }
  694           }// end of for childs
  695   
  696           /* Add other params injection point models */
  697           for (Element otherElement : otherParameterElements)
  698           {
  699               XMLInjectionPointModel injectionPointParamModel = XMLUtil.getInjectionPointModel(otherElement, errorMessage);
  700               producerComponent.addDisposalMethodInjectionPointModel(injectionPointParamModel);
  701           }
  702       }
  703   
  704       public static <T, K> void defineXMLObservesMethod(XMLManagedBean<T> component, Method observesMethod, Element observesMethodElement, String errorMessage)
  705       {
  706           component.addObservableMethod(observesMethod);
  707   
  708           /* Observes method element childs */
  709           List<Element> observesChildElements = observesMethodElement.elements();
  710   
  711           /* Other parameter elements other than @Observes */
  712           List<Element> otherParameterElements = new ArrayList<Element>();
  713   
  714           BeanObserverXMLImpl<K> beanObserver = new BeanObserverXMLImpl<K>(component, observesMethod, false, TransactionalObserverType.NONE);
  715   
  716           Class<K> eventType = null;
  717   
  718           for (Element childElement : observesChildElements)
  719           {
  720               if (XMLUtil.isElementInWebBeansNameSpaceWithName(childElement, WebBeansConstants.WEB_BEANS_XML_OBSERVES_ELEMENT))
  721               {
  722                   Element typeElement = (Element) childElement.elements().get(0);
  723   
  724                   eventType = (Class<K>) XMLUtil.getElementJavaType(typeElement);
  725   
  726                   /* Find observes method model */
  727                   XMLInjectionPointModel model = XMLUtil.getInjectionPointModel(typeElement, errorMessage);
  728                   
  729                   component.addInjectionPoint(getXMLMethodInjectionPoint(component, model, observesMethod));
  730   
  731                   /* Binding types for disposal method */
  732                   Set<Annotation> bindingTypes = model.getBindingTypes();
  733                   Annotation[] bindingAnns = new Annotation[bindingTypes.size()];
  734                   bindingAnns = bindingTypes.toArray(bindingAnns);
  735   
  736                   beanObserver.addXMLInjectionObservesParameter(model);
  737   
  738                   NotificationManager.getInstance().addObserver(beanObserver, eventType, bindingAnns);
  739   
  740               }
  741               /* Disposal method parameter other than @Disposes */
  742               else
  743               {
  744                   otherParameterElements.add(childElement);
  745               }
  746           }// end of for childs
  747   
  748           /* Add other params injection point models */
  749           for (Element otherElement : otherParameterElements)
  750           {
  751               XMLInjectionPointModel injectionPointParamModel = XMLUtil.getInjectionPointModel(otherElement, errorMessage);
  752               beanObserver.addXMLInjectionObservesParameter(injectionPointParamModel);
  753           }
  754       }
  755       
  756       public static InjectionPoint getXMLMethodInjectionPoint(AbstractBean<?> component, XMLInjectionPointModel model, Method method)
  757       {
  758           Asserts.assertNotNull(model,"model parameter can not be null");
  759           Asserts.assertNotNull(method,"method parameter can not be null");
  760           
  761           Annotation[] annots = method.getAnnotations();
  762           for(Annotation annotation : annots)
  763           {
  764               model.addAnnotation(annotation);
  765           }
  766           
  767           model.setInjectionMember(method);
  768           model.setType(XMLInjectionModelType.METHOD);
  769           
  770           return InjectionPointFactory.getXMLInjectionPointData(component, model);
  771           
  772       }
  773   }

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