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.io.InputStream;
   17   import java.lang.annotation.Annotation;
   18   import java.lang.reflect.Array;
   19   import java.lang.reflect.Method;
   20   import java.lang.reflect.Type;
   21   import java.lang.reflect.TypeVariable;
   22   import java.util.ArrayList;
   23   import java.util.HashSet;
   24   import java.util.Iterator;
   25   import java.util.List;
   26   import java.util.Set;
   27   
   28   
   29   import org.apache.log4j.LogManager;
   30   import org.apache.log4j.Logger;
   31   import org.apache.webbeans.WebBeansConstants;
   32   import org.apache.webbeans.annotation.CurrentLiteral;
   33   import org.apache.webbeans.annotation.WebBeansAnnotation;
   34   import org.apache.webbeans.component.xml.XMLProducerBean;
   35   import org.apache.webbeans.exception.WebBeansConfigurationException;
   36   import org.apache.webbeans.exception.WebBeansException;
   37   import org.apache.webbeans.exception.definition.NonexistentTypeException;
   38   import org.apache.webbeans.exception.inject.DefinitionException;
   39   import org.apache.webbeans.inject.xml.XMLInjectionPointModel;
   40   import org.apache.webbeans.proxy.JavassistProxyFactory;
   41   import org.apache.webbeans.util.AnnotationUtil;
   42   import org.apache.webbeans.util.Asserts;
   43   import org.apache.webbeans.util.ClassUtil;
   44   import org.dom4j.Attribute;
   45   import org.dom4j.Document;
   46   import org.dom4j.DocumentException;
   47   import org.dom4j.Element;
   48   import org.dom4j.ElementHandler;
   49   import org.dom4j.ElementPath;
   50   import org.dom4j.Namespace;
   51   import org.dom4j.io.SAXReader;
   52   
   53   /**
   54    * Used for getting information contained in the file web-beans.xml.
   55    * 
   56    * @author <a href="mailto:gurkanerdogdu@yahoo.com">Gurkan Erdogdu</a>
   57    * @since 1.0
   58    */
   59   @SuppressWarnings("unchecked")
   60   public final class XMLUtil
   61   {
   62   
   63       private XMLUtil()
   64       {
   65       }
   66   
   67       private static final Logger log = LogManager.getLogger(XMLUtil.class);
   68   
   69       /**
   70        * Gets new {@link SAXReader} instance.
   71        * 
   72        * @return sax reader instance
   73        */
   74       public static SAXReader getSaxReader()
   75       {
   76           return new SAXReader();
   77       }
   78   
   79       /**
   80        * Gets the root element of the parsed document.
   81        * 
   82        * @param stream parsed document
   83        * @return root element of the document
   84        * @throws WebBeansException if any runtime exception occurs
   85        */
   86       public static Element getRootElement(InputStream stream) throws WebBeansException
   87       {
   88           try
   89           {  
   90               SAXReader saxReader = getSaxReader();
   91               saxReader.setMergeAdjacentText(true);
   92               saxReader.setStripWhitespaceText(true);
   93               saxReader.setErrorHandler(new WebBeansErrorHandler());
   94               saxReader.setEntityResolver(new WebBeansResolver());
   95               saxReader.setValidation(false);
   96               saxReader.setDefaultHandler(new ElementHandler()
   97               {
   98                   public void onEnd(ElementPath path)
   99                   {
  100   
  101                   }
  102   
  103                   public void onStart(ElementPath path)
  104                   {
  105                       Element element = path.getCurrent();
  106                       if (element.getNamespaceURI() == null || element.getNamespaceURI().equals(""))
  107                       {
  108                           throw new WebBeansConfigurationException("All elements in the beans.xml file have to declare name space.");
  109                       }
  110                       else
  111                       {
  112                           if (element.isRootElement())
  113                           {
  114                               WebBeansNameSpaceContainer.getInstance().addNewPackageNameSpace(element.getNamespace().getURI());
  115   
  116                               List allNs = element.declaredNamespaces();
  117                               Iterator itNs = allNs.iterator();
  118   
  119                               while (itNs.hasNext())
  120                               {
  121                                   Namespace namespace = (Namespace)itNs.next();
  122                                   WebBeansNameSpaceContainer.getInstance().addNewPackageNameSpace(namespace.getURI());
  123                               }
  124                           }
  125                       }
  126                   }
  127   
  128               });
  129   
  130               Document document = saxReader.read(stream);
  131   
  132               return document.getRootElement();
  133   
  134           }
  135           catch (DocumentException e)
  136           {
  137               log.fatal("Unable to read root element of the given input stream", e);
  138               throw new WebBeansException("Unable to read root element of the given input stream", e);
  139           }
  140       }
  141       
  142       /**
  143        * Gets the root element of the parsed document.
  144        * 
  145        * @param stream parsed document
  146        * @return root element of the document
  147        * @throws WebBeansException if any runtime exception occurs
  148        */
  149       public static Element getSpecStrictRootElement(InputStream stream) throws WebBeansException
  150       {
  151           try
  152           {  
  153               SAXReader saxReader = getSaxReader();
  154               saxReader.setMergeAdjacentText(true);
  155               saxReader.setStripWhitespaceText(true);
  156               saxReader.setErrorHandler(new WebBeansErrorHandler());
  157               saxReader.setEntityResolver(new WebBeansResolver());
  158               saxReader.setValidation(false);
  159               Document document = saxReader.read(stream);
  160   
  161               return document.getRootElement();
  162   
  163           }
  164           catch (DocumentException e)
  165           {
  166               log.fatal("Unable to read root element of the given input stream", e);
  167               throw new WebBeansException("Unable to read root element of the given input stream", e);
  168           }
  169       }
  170       
  171   
  172       public static boolean isElementInNamespace(Element element, String namespace)
  173       {
  174           Asserts.assertNotNull(element, "element parameter can not be null");
  175           Asserts.assertNotNull(namespace, "namespace parameter can not be null");
  176   
  177           Namespace ns = element.getNamespace();
  178           if (!Namespace.NO_NAMESPACE.equals(ns))
  179           {
  180               if (ns.getURI().equals(namespace))
  181               {
  182                   return true;
  183               }
  184           }
  185   
  186           return false;
  187       }
  188   
  189       public static boolean isElementInWebBeansNameSpace(Element element)
  190       {
  191           nullCheckForElement(element);
  192           String ns = getElementNameSpace(element);
  193   
  194           if (ns != null && ns.equals(WebBeansConstants.WEB_BEANS_NAMESPACE))
  195           {
  196               return true;
  197           }
  198   
  199           return false;
  200       }
  201   
  202       public static boolean isElementInWebBeansNameSpaceWithName(Element element, String name)
  203       {
  204           nullCheckForElement(element);
  205   
  206           if (isElementInWebBeansNameSpace(element))
  207           {
  208               String txtName = element.getName();
  209   
  210               if (name.equals(txtName))
  211               {
  212                   return true;
  213               }
  214           }
  215   
  216           return false;
  217       }
  218   
  219       public static String getElementNameSpace(Element element)
  220       {
  221           nullCheckForElement(element);
  222   
  223           Namespace ns = element.getNamespace();
  224           if (!Namespace.NO_NAMESPACE.equals(ns))
  225           {
  226               return ns.getURI();
  227           }
  228   
  229           return null;
  230       }
  231   
  232       public static boolean isElementWebBeanDeclaration(Element element)
  233       {
  234           nullCheckForElement(element);
  235   
  236           if (!isElementInWebBeansNameSpaceWithName(element, WebBeansConstants.WEB_BEANS_XML_DEPLOY_ELEMENT) && 
  237                   !isElementInWebBeansNameSpaceWithName(element, WebBeansConstants.WEB_BEANS_XML_INTERCEPTORS_ELEMENT) && 
  238                   !isElementInWebBeansNameSpaceWithName(element, WebBeansConstants.WEB_BEANS_XML_DECORATORS_ELEMENT) && 
  239                   !isElementChildExist(element, WebBeansConstants.WEB_BEANS_XML_BINDING_TYPE) && 
  240                   !isElementChildExist(element, WebBeansConstants.WEB_BEANS_XML_INTERCEPTOR_BINDING_TYPE) && 
  241                   !isElementChildExist(element, WebBeansConstants.WEB_BEANS_XML_STEREOTYPE))
  242           {
  243               return true;
  244           }
  245   
  246           return false;
  247   
  248       }
  249   
  250       /**
  251        * Returns true if element has a bindingtype child element in webbeans
  252        * namespace false otherwise.
  253        * 
  254        * @param element parent element
  255        * @return true if element has a bindingtype child element in webbeans
  256        *         namespace
  257        */
  258       public static boolean isElementBindingTypeDecleration(Element element)
  259       {
  260           nullCheckForElement(element);
  261   
  262           if (isElementChildExistWithWebBeansNameSpace(element, WebBeansConstants.WEB_BEANS_XML_BINDING_TYPE))
  263           {
  264               return true;
  265           }
  266   
  267           return false;
  268       }
  269   
  270       /**
  271        * Returns true if element has a interceptor bindingtype child element in
  272        * webbeans namespace false otherwise.
  273        * 
  274        * @param element parent element
  275        * @return true if element has a interceptor bindingtype child element in
  276        *         webbeans namespace
  277        */
  278       public static boolean isElementInterceptorBindingTypeDecleration(Element element)
  279       {
  280           nullCheckForElement(element);
  281   
  282           if (isElementChildExistWithWebBeansNameSpace(element, WebBeansConstants.WEB_BEANS_XML_INTERCEPTOR_BINDING_TYPE))
  283           {
  284               return true;
  285           }
  286   
  287           return false;
  288       }
  289   
  290       /**
  291        * Returns true if element has a stereotype child element in webbeans
  292        * namespace false otherwise.
  293        * 
  294        * @param element parent element
  295        * @return true if element has a stereotype child element in webbeans
  296        *         namespace
  297        */
  298       public static boolean isElementStereoTypeDecleration(Element element)
  299       {
  300           nullCheckForElement(element);
  301   
  302           if (isElementChildExistWithWebBeansNameSpace(element, WebBeansConstants.WEB_BEANS_XML_STEREOTYPE))
  303           {
  304               return true;
  305           }
  306   
  307           return false;
  308       }
  309   
  310       public static boolean isElementDeployDeclaration(Element element)
  311       {
  312           nullCheckForElement(element);
  313   
  314           if (isElementInWebBeansNameSpaceWithName(element, WebBeansConstants.WEB_BEANS_XML_DEPLOY_ELEMENT))
  315           {
  316               return true;
  317           }
  318   
  319           return false;
  320   
  321       }
  322   
  323       public static boolean isElementInterceptorsDeclaration(Element element)
  324       {
  325           nullCheckForElement(element);
  326   
  327           if (isElementInWebBeansNameSpaceWithName(element, WebBeansConstants.WEB_BEANS_XML_INTERCEPTORS_ELEMENT))
  328           {
  329               return true;
  330           }
  331   
  332           return false;
  333   
  334       }
  335   
  336       public static boolean isElementDecoratosDeclaration(Element element)
  337       {
  338           nullCheckForElement(element);
  339   
  340           if (isElementInWebBeansNameSpaceWithName(element, WebBeansConstants.WEB_BEANS_XML_DECORATORS_ELEMENT))
  341           {
  342               return true;
  343           }
  344   
  345           return false;
  346   
  347       }
  348   
  349       /**
  350        * Returns true if this element defines JMS webbeans, false otherwise.
  351        * 
  352        * @param element webbeans element decleration
  353        * @return true if this element defines JMS webbeans, false otherwise
  354        */
  355       public static boolean isElementJMSDeclaration(Element element)
  356       {
  357           nullCheckForElement(element);
  358   
  359           if (isElementWebBeanDeclaration(element))
  360           {
  361               if (isElementInWebBeansNameSpaceWithName(element, WebBeansConstants.WEB_BEANS_XML_QUEUE_ELEMENT) 
  362                       || isElementInWebBeansNameSpaceWithName(element, WebBeansConstants.WEB_BEANS_XML_TOPIC_ELEMENT))
  363               {
  364                   return true;
  365               }
  366           }
  367   
  368           return false;
  369       }
  370   
  371       public static boolean isElementHasDecoratesChild(Element element)
  372       {
  373           nullCheckForElement(element);
  374           if (isElementChildExistWithWebBeansNameSpace(element, WebBeansConstants.WEB_BEANS_XML_DECORATES_ELEMENT))
  375           {
  376               return true;
  377           }
  378   
  379           return false;
  380       }
  381   
  382       /**
  383        * Returns true if this element defines field, false otherwise.
  384        * 
  385        * @param element webbeans decleration child element
  386        * @return true if this element defines field, false otherwise
  387        */
  388       public static boolean isElementField(Element element)
  389       {
  390           nullCheckForElement(element);
  391   
  392           List<Element> childs = element.elements();
  393   
  394           for (Element child : childs)
  395           {
  396               if (!isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_INITIALIZER_ELEMENT) && !isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_DESTRUCTOR_ELEMENT) && !isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_PRODUCES_ELEMENT) && !isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_DISPOSES_ELEMENT) && !isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_OBSERVES_ELEMENT) && !isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_DECORATES_ELEMENT))
  397               {
  398   
  399                   Class<?> clazz = getElementJavaType(child);
  400                   if (clazz != null)
  401                   {
  402                       if (clazz.isAnnotation())
  403                       {
  404                           if (AnnotationUtil.isInterceptorBindingAnnotation((Class<? extends Annotation>) clazz))
  405                           {
  406                               return false;
  407                           }
  408                       }
  409   
  410                   }
  411   
  412               }
  413               else
  414               {
  415                   return false;
  416               }
  417   
  418           }
  419   
  420           return true;
  421   
  422       }
  423   
  424       /**
  425        * Checks that given element is a webbeans method or not.
  426        * 
  427        * @param element dom element represents method decleration
  428        * @return true if the given element is a true element decleration false
  429        *         otherwise
  430        */
  431       public static boolean isElementMethod(Element element)
  432       {
  433           Asserts.nullCheckForDomElement(element);
  434   
  435           List<Element> childs = element.elements();
  436   
  437           for (Element child : childs)
  438           {
  439               if (isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_INITIALIZER_ELEMENT) || isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_DESTRUCTOR_ELEMENT) || isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_PRODUCES_ELEMENT) || isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_DISPOSES_ELEMENT) || isElementInWebBeansNameSpaceWithName(child, WebBeansConstants.WEB_BEANS_XML_OBSERVES_ELEMENT))
  440               {
  441                   return true;
  442   
  443               }
  444               else
  445               {
  446                   Class<?> clazz = getElementJavaType(child);
  447                   if (clazz != null)
  448                   {
  449                       if (clazz.isAnnotation())
  450                       {
  451                           if (AnnotationUtil.isInterceptorBindingAnnotation((Class<? extends Annotation>) clazz))
  452                           {
  453                               return true;
  454                           }
  455                       }
  456   
  457                   }
  458               }
  459   
  460           }
  461   
  462           return false;
  463   
  464       }
  465   
  466       public static String getName(Element element)
  467       {
  468           nullCheckForElement(element);
  469   
  470           return element.getName();
  471       }
  472   
  473       public static Class<?> getElementJavaType(Element element)
  474       {
  475           String ns = getElementNameSpace(element);
  476           List<String> packageNames = WebBeansNameSpaceContainer.getInstance().getPackageNameFromNameSpace(ns);
  477           
  478           Class<?> clazz = null; 
  479           Class<?> foundClazz = null;
  480           if(packageNames != null)
  481           {
  482               boolean found = false;
  483   
  484               for(String packageName : packageNames)
  485               {
  486                   String className = packageName + XMLUtil.getName(element);
  487                   clazz = ClassUtil.getClassFromName(className);
  488                   
  489                   if(clazz != null)
  490                   {
  491                      if(found)
  492                      {
  493                          throw new DefinitionException("Multiple class with name : " + clazz.getName());
  494                      }
  495                      else
  496                      {
  497                          foundClazz = clazz;
  498                          found = true;
  499                      }
  500                   }
  501               }
  502               
  503           }
  504           
  505           return foundClazz;
  506       }
  507   
  508       public static String getElementJavaClassName(Element element)
  509       {
  510           Class<?> clazz = getElementJavaType(element);
  511           
  512           if(clazz != null)
  513           {
  514               return clazz.getName();
  515           }
  516           
  517           return getName(element);
  518       }
  519   
  520       private static void nullCheckForElement(Element element)
  521       {
  522           Asserts.nullCheckForDomElement(element);
  523       }
  524   
  525       public static boolean isElementChildExist(Element parent, String childName)
  526       {
  527           Asserts.assertNotNull(parent, "parent parameter can not be null");
  528           Asserts.assertNotNull(childName, "childName parameter can not be null");
  529   
  530           return parent.element(childName) != null ? true : false;
  531       }
  532   
  533       /**
  534        * Return child element within webbeans namespace with given child name.
  535        * 
  536        * @param parent parent element
  537        * @param childName child element name
  538        * @return if child element exist within webbeans namespace with given child
  539        *         name
  540        */
  541       public static boolean isElementChildExistWithWebBeansNameSpace(Element parent, String childName)
  542       {
  543           Asserts.assertNotNull(parent, "parent parameter can not be null");
  544           Asserts.assertNotNull(childName, "childName parameter can not be null");
  545   
  546           Element child = parent.element(childName);
  547           if (child == null)
  548           {
  549               return false;
  550           }
  551           else
  552           {
  553               return isElementInWebBeansNameSpace(child);
  554           }
  555   
  556       }
  557   
  558       /**
  559        * Creates new xml injection point model.
  560        * 
  561        * @param typeElement injection point API type
  562        * @param errorMessage error message
  563        * @return new injection point model object
  564        */
  565       public static XMLInjectionPointModel getInjectionPointModel(Element typeElement, String errorMessage)
  566       {
  567           Asserts.assertNotNull(typeElement, "typeElement parameter can not be null");
  568   
  569           /* Element <Array> */
  570           if (typeElement.getName().equals(WebBeansConstants.WEB_BEANS_XML_ARRAY_ELEMENT))
  571           {
  572               return getArrayInjectionPointModel(typeElement, errorMessage);
  573           }
  574           /* Java class or interface */
  575           else
  576           {
  577               return getTypeInjectionPointModel(typeElement, errorMessage);
  578           }
  579   
  580       }
  581   
  582       /**
  583        * Injection point with Java type.
  584        * 
  585        * @param typeElement injection point API type
  586        * @param errorMessage error message
  587        * @return new injection point model
  588        */
  589       private static XMLInjectionPointModel getTypeInjectionPointModel(Element typeElement, String errorMessage)
  590       {
  591           XMLInjectionPointModel model = null;
  592   
  593           Class<?> clazz = getElementJavaType(typeElement);
  594           if (clazz == null)
  595           {
  596               throw new NonexistentTypeException(errorMessage + "Java type with name : " + getElementJavaClassName(typeElement) + " is not found in the deployment");
  597           }
  598   
  599           else if (clazz.isAnnotation() || clazz.isArray() || clazz.isEnum())
  600           {
  601               throw new WebBeansConfigurationException(errorMessage + "Java type with name : " + getElementJavaClassName(typeElement) + " must be class or interface type");
  602           }
  603   
  604           else
  605           {
  606               TypeVariable[] typeVariables = clazz.getTypeParameters();
  607               int actualTypeArgument = typeVariables.length;
  608               List<Element> childElements = typeElement.elements();
  609               List<Type> typeArguments = new ArrayList<Type>();
  610               List<Annotation> bindingAnnots = new ArrayList<Annotation>();
  611   
  612               Class<? extends Annotation> definedBindingType = null;
  613               for (Element childElement : childElements)
  614               {
  615                   Type actualType = getElementJavaType(childElement);
  616                   if (actualType == null)
  617                   {
  618                       throw new NonexistentTypeException(errorMessage + "Java type with name : " + getElementJavaClassName(typeElement) + " is not found in the deployment");
  619                   }
  620                   else if (((Class) actualType).isArray() || ((Class) actualType).isEnum())
  621                   {
  622                       throw new WebBeansConfigurationException(errorMessage + "Java type with name : " + getElementJavaClassName(typeElement) + " must be class or interface type");
  623                   }
  624                   else if (((Class) actualType).isAnnotation())
  625                   {
  626                       Class<? extends Annotation> annotClazz = (Class<? extends Annotation>) actualType;
  627                       if (!AnnotationUtil.isQualifierAnnotation(annotClazz))
  628                       {
  629                           throw new WebBeansConfigurationException(errorMessage + "Java type with name : " + getElementJavaClassName(typeElement) + " is not a @Qualifier");
  630                       }
  631   
  632                       if (definedBindingType == null)
  633                       {
  634                           definedBindingType = annotClazz;
  635                       }
  636                       else
  637                       {
  638                           if (definedBindingType.equals(annotClazz))
  639                           {
  640                               throw new IllegalArgumentException(errorMessage + "Java type with name : " + getElementJavaClassName(typeElement) + " is duplicated");
  641                           }
  642                       }
  643   
  644                       bindingAnnots.add(getXMLDefinedAnnotationMember(childElement, annotClazz, errorMessage));
  645                   }
  646                   else
  647                   {
  648                       typeArguments.add(actualType);
  649                   }
  650               }
  651   
  652               if (actualTypeArgument != typeArguments.size())
  653               {
  654                   throw new WebBeansConfigurationException(errorMessage + "Java type with name : " + getElementJavaClassName(typeElement) + " actual type parameters size are not equals defined in the xml");
  655               }
  656   
  657               int i = 0;
  658               for (Type type : typeArguments)
  659               {
  660                   TypeVariable typeVariable = typeVariables[i];
  661                   Type[] bounds = typeVariable.getBounds();
  662   
  663                   Class<?> clazzBound = (Class<?>) bounds[0];
  664   
  665                   if (!clazzBound.isAssignableFrom((Class<?>) type))
  666                   {
  667                       throw new WebBeansConfigurationException(errorMessage + "Java type with name : " + getElementJavaClassName(typeElement) + " actual type parameter bounded exception");
  668                   }
  669   
  670               }
  671   
  672               Type[] typeArray = new Type[typeArguments.size()];
  673               typeArray = typeArguments.toArray(typeArray);
  674               model = new XMLInjectionPointModel(clazz, typeArray);
  675   
  676               if (bindingAnnots.isEmpty())
  677               {
  678                   model.addBindingType(new CurrentLiteral());
  679               }
  680   
  681               for (Annotation annot : bindingAnnots)
  682               {
  683                   model.addBindingType(annot);
  684               }
  685           }
  686   
  687           return model;
  688       }
  689   
  690       /**
  691        * Creates new annotation with configured members values.
  692        * 
  693        * @param annotationElement annotation element
  694        * @param annotClazz annotation class
  695        * @param errorMessage error message
  696        * @return new annotation with members configures
  697        */
  698       public static Annotation getXMLDefinedAnnotationMember(Element annotationElement, Class<? extends Annotation> annotClazz, String errorMessage)
  699       {
  700           String value = annotationElement.getTextTrim();
  701           List<Attribute> attrs = annotationElement.attributes();
  702           List<String> attrsNames = new ArrayList<String>();
  703   
  704           for (Attribute attr : attrs)
  705           {
  706               attrsNames.add(attr.getName());
  707           }
  708   
  709           /* Default value check */
  710           if (value != null && !value.equals(""))
  711           {
  712               if (attrsNames.contains("value"))
  713               {
  714                   throw new WebBeansConfigurationException(errorMessage + "Annotation with type : " + annotClazz.getName() + " can not have both element 'value' attribute and body text");
  715               }
  716           }
  717           /* Check for attribute "value" */
  718           else
  719           {
  720               if (attrsNames.contains("value"))
  721               {
  722                   try
  723                   {
  724                       /* Contains value member method */
  725                       annotClazz.getDeclaredMethod("value", new Class[] {});
  726   
  727                   }
  728                   catch (SecurityException e)
  729                   {
  730                       throw new WebBeansException(e);
  731   
  732                   }
  733                   catch (NoSuchMethodException e)
  734                   {
  735                       throw new WebBeansConfigurationException(errorMessage + "Annotation with type : " + annotClazz.getName() + " must have 'value' method");
  736                   }
  737               }
  738           }
  739   
  740           /* Check annotation members with name attrs */
  741           for (String attrName : attrsNames)
  742           {
  743               try
  744               {
  745                   annotClazz.getDeclaredMethod(attrName, new Class[] {});
  746   
  747               }
  748               catch (SecurityException e)
  749               {
  750                   throw new WebBeansException(e);
  751   
  752               }
  753               catch (NoSuchMethodException e)
  754               {
  755                   throw new WebBeansConfigurationException(errorMessage + "Annotation with type : " + annotClazz.getName() + " does not have member with name : " + attrName);
  756               }
  757           }
  758   
  759           /* Non-default members must defined in the xml */
  760           Method[] members = annotClazz.getDeclaredMethods();
  761           for (Method member : members)
  762           {
  763               if (member.getDefaultValue() == null && value == null)
  764               {
  765                   if (!attrsNames.contains(member.getName()))
  766                   {
  767                       throw new WebBeansConfigurationException(errorMessage + "Annotation with type : " + annotClazz.getName() + " with non-default member method with name : " + member.getName() + " has to defined in the xml element attribute.");
  768                   }
  769               }
  770           }
  771   
  772           return createInjectionPointAnnotation(attrs, annotClazz, value, errorMessage);
  773       }
  774   
  775       /**
  776        * Creates new annotation with its member values.
  777        * 
  778        * @param attrs list of annotation element attributes
  779        * @param annotClazz annotation class
  780        * @param errorMessage error message
  781        * @return new annotation
  782        */
  783       private static WebBeansAnnotation createInjectionPointAnnotation(List<Attribute> attrs, Class<? extends Annotation> annotClazz, String valueText, String errorMessage)
  784       {
  785           WebBeansAnnotation annotation = JavassistProxyFactory.createNewAnnotationProxy(annotClazz);
  786           boolean isValueAttrDefined = false;
  787           for (Attribute attr : attrs)
  788           {
  789               String attrName = attr.getName();
  790               String attrValue = attr.getValue();
  791   
  792               if (!isValueAttrDefined)
  793               {
  794                   if (attrName.equals("value"))
  795                   {
  796                       isValueAttrDefined = true;
  797                   }
  798               }
  799   
  800               Class returnType = null;
  801               try
  802               {
  803                   returnType = annotClazz.getDeclaredMethod(attrName, new Class[] {}).getReturnType();
  804                   Object value = null;
  805                   if (returnType.isPrimitive())
  806                   {
  807                       value = ClassUtil.isValueOkForPrimitiveOrWrapper(returnType, attrValue);
  808                   }
  809                   else if (returnType.equals(String.class))
  810                   {
  811                       value = attrValue;
  812                   }
  813                   else if (returnType.equals(Class.class))
  814                   {
  815                       value = ClassUtil.getClassFromName(attrValue);
  816   
  817                   }
  818                   else if (returnType.isEnum())
  819                   {
  820                       value = ClassUtil.isValueOkForEnum(returnType, attrValue);
  821                   }
  822                   else
  823                   {
  824                       throw new WebBeansConfigurationException(errorMessage + "Annotation with type : " + annotClazz.getName() + " with member : " + attrName + " does not have sutiable member return type");
  825                   }
  826   
  827                   if (value == null)
  828                   {
  829                       throw new WebBeansConfigurationException(errorMessage + "Annotation with type : " + annotClazz.getName() + " with member : " + attrName + " value does not defined correctly");
  830                   }
  831   
  832                   annotation.setMemberValue(attrName, value);
  833   
  834               }
  835               catch (SecurityException e)
  836               {
  837                   throw new WebBeansException(e);
  838   
  839               }
  840               catch (NoSuchMethodException e)
  841               {
  842                   throw new WebBeansConfigurationException(errorMessage + "Annotation with type : " + annotClazz.getName() + " does not have member with name : " + attrName);
  843               }
  844           }
  845   
  846           if (!isValueAttrDefined)
  847           {
  848               if (valueText != null && !valueText.equals(""))
  849               {
  850                   annotation.setMemberValue("value", valueText);
  851               }
  852           }
  853   
  854           return annotation;
  855       }
  856   
  857       /**
  858        * Injection point with array type.
  859        * 
  860        * @param typeElement array element
  861        * @param errorMessage error message
  862        * @return new injection point model
  863        */
  864       public static XMLInjectionPointModel getArrayInjectionPointModel(Element typeElement, String errorMessage)
  865       {
  866           XMLInjectionPointModel model = null;
  867   
  868           List<Element> childElements = typeElement.elements();
  869           boolean isElementTypeDefined = false;
  870   
  871           Set<Annotation> anns = new HashSet<Annotation>();
  872           for (Element childElement : childElements)
  873           {
  874               Class<?> clazz = XMLUtil.getElementJavaType(childElement);
  875   
  876               if (clazz == null)
  877               {
  878                   throw new NonexistentTypeException(errorMessage + "Class with name : " + XMLUtil.getElementJavaClassName(childElement) + " is not found for Array element type");
  879               }
  880   
  881               if (clazz.isAnnotation())
  882               {
  883                   anns.add(getXMLDefinedAnnotationMember(childElement, (Class<? extends Annotation>) clazz, errorMessage));
  884               }
  885               else if (clazz.isArray() || clazz.isEnum())
  886               {
  887                   throw new WebBeansConfigurationException(errorMessage + "<Array> element child with Java type : " + getElementJavaClassName(typeElement) + " must be class or interface type");
  888               }
  889               else
  890               {
  891                   if (isElementTypeDefined)
  892                   {
  893                       throw new WebBeansConfigurationException(errorMessage + "<Array> element can not have more than one child element. It has one child element that declares its type");
  894                   }
  895                   else
  896                   {
  897                       model = new XMLInjectionPointModel(clazz);
  898                       isElementTypeDefined = true;
  899                   }
  900               }
  901           }
  902   
  903           if (anns.size() == 0)
  904           {
  905               model.addBindingType(new CurrentLiteral());
  906           }
  907   
  908           for (Annotation ann : anns)
  909           {
  910               model.addBindingType(ann);
  911           }
  912   
  913           return model;
  914       }
  915   
  916       public static <T> void defineXMLProducerApiTypeFromArrayElement(XMLProducerBean<T> component, Element typeElement, String errorMessage)
  917       {
  918           List<Element> childElements = typeElement.elements();
  919           boolean isElementTypeDefined = false;
  920   
  921           Set<Annotation> anns = new HashSet<Annotation>();
  922           for (Element childElement : childElements)
  923           {
  924               Class<?> clazz = XMLUtil.getElementJavaType(childElement);
  925   
  926               if (clazz == null)
  927               {
  928                   throw new NonexistentTypeException(errorMessage + "Class with name : " + XMLUtil.getElementJavaClassName(childElement) + " is not found for Array element type");
  929               }
  930   
  931               if (clazz.isAnnotation())
  932               {
  933                   anns.add(getXMLDefinedAnnotationMember(childElement, (Class<? extends Annotation>) clazz, errorMessage));
  934               }
  935               else if (clazz.isArray() || clazz.isEnum())
  936               {
  937                   throw new WebBeansConfigurationException(errorMessage + "<Array> element child with Java type : " + getElementJavaClassName(typeElement) + " must be class or interface type");
  938               }
  939               else
  940               {
  941                   if (isElementTypeDefined)
  942                   {
  943                       throw new WebBeansConfigurationException(errorMessage + "<Array> element can not have more than one child element. It has one child element that declares its type");
  944                   }
  945                   else
  946                   {
  947                       isElementTypeDefined = true;
  948                       component.addApiType(Array.newInstance(clazz, 0).getClass());
  949                   }
  950               }
  951           }
  952   
  953           if (anns.size() == 0)
  954           {
  955               component.addQualifier(new CurrentLiteral());
  956           }
  957   
  958           for (Annotation ann : anns)
  959           {
  960               component.addQualifier(ann);
  961           }
  962   
  963       }
  964   
  965   }

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