[seam-commits] Seam SVN: r12105 - in modules/xml/trunk/src: main/java/org/jboss/seam/xml/parser/namespace and 5 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Fri Mar 5 16:33:43 EST 2010


Author: swd847
Date: 2010-03-05 16:33:42 -0500 (Fri, 05 Mar 2010)
New Revision: 12105

Added:
   modules/xml/trunk/src/main/java/org/jboss/seam/xml/util/ReflectionUtils.java
   modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/
   modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ConstructedBean.java
   modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ConstructorTest.java
   modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ValueProvider.java
   modules/xml/trunk/src/test/resources/org/jboss/seam/xml/test/constructor/
   modules/xml/trunk/src/test/resources/org/jboss/seam/xml/test/constructor/constructor-beans.xml
Removed:
   modules/xml/trunk/src/main/java/org/jboss/seam/xml/parser/namespace/NamespaceUtils.java
   modules/xml/trunk/src/test/resources/org/jboss/seam/xml/test/dependency/
Modified:
   modules/xml/trunk/src/main/java/org/jboss/seam/xml/model/ModelBuilder.java
   modules/xml/trunk/src/main/java/org/jboss/seam/xml/model/XmlItem.java
   modules/xml/trunk/src/main/java/org/jboss/seam/xml/parser/namespace/PackageNamespaceElementResolver.java
Log:
Added the ability to configure a bean constructor via XML



Modified: modules/xml/trunk/src/main/java/org/jboss/seam/xml/model/ModelBuilder.java
===================================================================
--- modules/xml/trunk/src/main/java/org/jboss/seam/xml/model/ModelBuilder.java	2010-03-05 20:48:08 UTC (rev 12104)
+++ modules/xml/trunk/src/main/java/org/jboss/seam/xml/model/ModelBuilder.java	2010-03-05 21:33:42 UTC (rev 12105)
@@ -5,6 +5,7 @@
 package org.jboss.seam.xml.model;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -14,6 +15,8 @@
 import java.util.Map.Entry;
 
 import javax.enterprise.inject.Stereotype;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Inject;
 import javax.inject.Qualifier;
 import javax.interceptor.InterceptorBinding;
 
@@ -24,6 +27,7 @@
 import org.jboss.seam.xml.parser.namespace.CompositeNamespaceElementResolver;
 import org.jboss.seam.xml.parser.namespace.NamespaceElementResolver;
 import org.jboss.seam.xml.parser.namespace.RootNamespaceElementResolver;
+import org.jboss.seam.xml.util.ReflectionUtils;
 import org.jboss.seam.xml.util.XmlConfigurationException;
 import org.jboss.seam.xml.util.XmlObjectConverter;
 import org.jboss.weld.extensions.util.AnnotationInstanceProvider;
@@ -94,7 +98,7 @@
          ResultType type = getItemType(rb);
          if (type == ResultType.BEAN)
          {
-            BeanResult<?> tp = buildAnnotatedType(rb);
+            BeanResult<?> tp = buildAnnotatedType((ClassXmlItem) rb);
             if (tp.isExtend())
             {
                ret.getExtendBeans().add(tp);
@@ -123,11 +127,11 @@
          }
          else if (type == ResultType.QUALIFIER)
          {
-            ret.getQualifiers().add(rb.getJavaClass());
+            ret.getQualifiers().add((Class) rb.getJavaClass());
          }
          else if (type == ResultType.INTERCEPTOR_BINDING)
          {
-            ret.getInterceptorBindings().add(rb.getJavaClass());
+            ret.getInterceptorBindings().add((Class) rb.getJavaClass());
          }
          else if (type == ResultType.STEREOTYPE)
          {
@@ -231,12 +235,12 @@
    }
 
    @SuppressWarnings("unchecked")
-   <T> BeanResult<T> buildAnnotatedType(XmlItem rb)
+   BeanResult<?> buildAnnotatedType(ClassXmlItem rb)
    {
-      BeanResult<T> result = new BeanResult<T>(rb.getJavaClass());
-      NewAnnotatedTypeBuilder<T> type = result.getBuilder();
+      BeanResult<?> result = new BeanResult(rb.getJavaClass());
+      NewAnnotatedTypeBuilder<?> type = result.getBuilder();
       // list of constructor arguments
-      List<XmlItem> constList = new ArrayList<XmlItem>();
+      List<ParameterXmlItem> constList = new ArrayList<ParameterXmlItem>();
 
       boolean override = !rb.getChildrenOfType(OverrideXmlItem.class).isEmpty();
       boolean extend = !rb.getChildrenOfType(ExtendsXmlItem.class).isEmpty();
@@ -252,11 +256,18 @@
          Annotation a = createAnnotation(item);
          type.addToClass(a);
       }
-
-      for (ParameterXmlItem item : rb.getChildrenOfType(ParameterXmlItem.class))
+      List<ParametersXmlItem> constructorParameters = rb.getChildrenOfType(ParametersXmlItem.class);
+      if (constructorParameters.size() > 1)
       {
-         constList.add(item);
+         throw new XmlConfigurationException("A method may only have a single <parameters> element", rb.getDocument(), rb.getLineno());
       }
+      else if (!constructorParameters.isEmpty())
+      {
+         for (ParameterXmlItem item : constructorParameters.get(0).getChildrenOfType(ParameterXmlItem.class))
+         {
+            constList.add(item);
+         }
+      }
       for (FieldXmlItem item : rb.getChildrenOfType(FieldXmlItem.class))
       {
          for (AnnotationXmlItem fi : item.getChildrenOfType(AnnotationXmlItem.class))
@@ -296,11 +307,40 @@
 
       if (!constList.isEmpty())
       {
-         // the bean defined constructor arguments
+         int paramCount = 0;
+         Constructor<?> c = resolveConstructor(rb, constList);
+         // we automatically add inject to the constructor
+         type.addToConstructor((Constructor) c, new AnnotationLiteral<Inject>()
+         {
+         });
+         for (ParameterXmlItem fi : constList)
+         {
+            int param = paramCount++;
+            for (AnnotationXmlItem pan : fi.getChildrenOfType(AnnotationXmlItem.class))
+            {
+               Annotation a = createAnnotation(pan);
+               type.addToConstructorParameter((Constructor) c, param, a);
+            }
+         }
       }
       return result;
    }
 
+   protected static Constructor<?> resolveConstructor(ClassXmlItem bean, List<ParameterXmlItem> constList)
+   {
+      Class<?>[] params = new Class[constList.size()];
+      for (int i = 0; i < constList.size(); ++i)
+      {
+         params[i] = constList.get(i).getJavaClass();
+      }
+      Constructor<?> ret = ReflectionUtils.getConstructor(bean.getJavaClass(), params);
+      if (ret == null)
+      {
+         throw new XmlConfigurationException("Could not resolve constructor for " + bean.getJavaClass() + " with arguments " + params, bean.getDocument(), bean.getLineno());
+      }
+      return ret;
+   }
+
    @SuppressWarnings("unchecked")
    void addStereotypeToResult(XmlResult ret, XmlItem rb)
    {
@@ -320,7 +360,7 @@
          }
          count++;
       }
-      ret.getStereotypes().put(rb.getJavaClass(), values);
+      ret.getStereotypes().put((Class) rb.getJavaClass(), values);
 
    }
 

Modified: modules/xml/trunk/src/main/java/org/jboss/seam/xml/model/XmlItem.java
===================================================================
--- modules/xml/trunk/src/main/java/org/jboss/seam/xml/model/XmlItem.java	2010-03-05 20:48:08 UTC (rev 12104)
+++ modules/xml/trunk/src/main/java/org/jboss/seam/xml/model/XmlItem.java	2010-03-05 21:33:42 UTC (rev 12105)
@@ -20,7 +20,7 @@
 
    public XmlItemType getType();
 
-   public Class getJavaClass();
+   public Class<?> getJavaClass();
 
    /**
     * attempts to resolve any information that is not available at parse time

Deleted: modules/xml/trunk/src/main/java/org/jboss/seam/xml/parser/namespace/NamespaceUtils.java
===================================================================
--- modules/xml/trunk/src/main/java/org/jboss/seam/xml/parser/namespace/NamespaceUtils.java	2010-03-05 20:48:08 UTC (rev 12104)
+++ modules/xml/trunk/src/main/java/org/jboss/seam/xml/parser/namespace/NamespaceUtils.java	2010-03-05 21:33:42 UTC (rev 12105)
@@ -1,66 +0,0 @@
-/*
- * Distributed under the LGPL License
- * 
- */
-package org.jboss.seam.xml.parser.namespace;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-import org.jboss.seam.xml.model.FieldXmlItem;
-import org.jboss.seam.xml.model.MethodXmlItem;
-import org.jboss.seam.xml.model.XmlItem;
-import org.jboss.seam.xml.util.XmlConfigurationException;
-
-class NamespaceUtils
-{
-   static XmlItem resolveMethodOrField(String name, XmlItem parent, String innerText, String document, int lineno)
-   {
-      Class<?> p = parent.getJavaClass();
-      Field f = null;
-      boolean methodFound = false;
-      f = getField(p, name);
-      for (Method m : parent.getJavaClass().getMethods())
-      {
-         if (m.getName().equals(name))
-         {
-            methodFound = true;
-            break;
-         }
-      }
-      if (methodFound && f != null)
-      {
-         throw new XmlConfigurationException(parent.getJavaClass().getName() + " has both a method and a field named " + name + " and so cannot be configured via XML", document, lineno);
-      }
-      if (methodFound)
-      {
-         return new MethodXmlItem(parent, name, document, lineno);
-      }
-      else if (f != null)
-      {
-         return new FieldXmlItem(parent, f, innerText, document, lineno);
-      }
-      return null;
-   }
-
-   /**
-    * we need access to private fields so we cannot just use getField
-    */
-   public static Field getField(Class<?> parent, String name)
-   {
-      Class<?> p = parent;
-      while (p != Object.class)
-      {
-         try
-         {
-            return p.getDeclaredField(name);
-         }
-         catch (Exception e1)
-         {
-
-         }
-         p = p.getSuperclass();
-      }
-      return null;
-   }
-}

Modified: modules/xml/trunk/src/main/java/org/jboss/seam/xml/parser/namespace/PackageNamespaceElementResolver.java
===================================================================
--- modules/xml/trunk/src/main/java/org/jboss/seam/xml/parser/namespace/PackageNamespaceElementResolver.java	2010-03-05 20:48:08 UTC (rev 12104)
+++ modules/xml/trunk/src/main/java/org/jboss/seam/xml/parser/namespace/PackageNamespaceElementResolver.java	2010-03-05 21:33:42 UTC (rev 12105)
@@ -15,6 +15,7 @@
 import org.jboss.seam.xml.model.XmlItem;
 import org.jboss.seam.xml.model.XmlItemType;
 import org.jboss.seam.xml.parser.SaxNode;
+import org.jboss.seam.xml.util.ReflectionUtils;
 
 public class PackageNamespaceElementResolver implements NamespaceElementResolver
 {
@@ -79,7 +80,7 @@
          // if the item can be a method of a FIELD
          if (parent.getAllowedItem().contains(XmlItemType.METHOD) || parent.getAllowedItem().contains(XmlItemType.FIELD))
          {
-            return NamespaceUtils.resolveMethodOrField(name, parent, node.getInnerText(), node.getDocument(), node.getLineNo());
+            return ReflectionUtils.resolveMethodOrField(name, parent, node.getInnerText(), node.getDocument(), node.getLineNo());
          }
          else
          {

Copied: modules/xml/trunk/src/main/java/org/jboss/seam/xml/util/ReflectionUtils.java (from rev 12102, modules/xml/trunk/src/main/java/org/jboss/seam/xml/parser/namespace/NamespaceUtils.java)
===================================================================
--- modules/xml/trunk/src/main/java/org/jboss/seam/xml/util/ReflectionUtils.java	                        (rev 0)
+++ modules/xml/trunk/src/main/java/org/jboss/seam/xml/util/ReflectionUtils.java	2010-03-05 21:33:42 UTC (rev 12105)
@@ -0,0 +1,112 @@
+/*
+ * Distributed under the LGPL License
+ * 
+ */
+package org.jboss.seam.xml.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.jboss.seam.xml.model.FieldXmlItem;
+import org.jboss.seam.xml.model.MethodXmlItem;
+import org.jboss.seam.xml.model.XmlItem;
+
+public class ReflectionUtils
+{
+   public static XmlItem resolveMethodOrField(String name, XmlItem parent, String innerText, String document, int lineno)
+   {
+      Class<?> p = parent.getJavaClass();
+      Field f = null;
+      boolean methodFound = methodExists(p, name);
+      f = getField(p, name);
+
+      if (methodFound && f != null)
+      {
+         throw new XmlConfigurationException(parent.getJavaClass().getName() + " has both a method and a field named " + name + " and so cannot be configured via XML", document, lineno);
+      }
+      if (methodFound)
+      {
+         return new MethodXmlItem(parent, name, document, lineno);
+      }
+      else if (f != null)
+      {
+         return new FieldXmlItem(parent, f, innerText, document, lineno);
+      }
+      return null;
+   }
+
+   /**
+    * we need access to private fields so we cannot just use getField
+    */
+   public static Field getField(Class<?> parent, String name)
+   {
+      Class<?> p = parent;
+      while (p != Object.class)
+      {
+         try
+         {
+            return p.getDeclaredField(name);
+         }
+         catch (Exception e1)
+         {
+
+         }
+         p = p.getSuperclass();
+      }
+      return null;
+   }
+
+   public static boolean methodExists(Class<?> parent, String name)
+   {
+      Class<?> p = parent;
+      while (p != Object.class)
+      {
+         for (Method m : p.getDeclaredMethods())
+         {
+            if (m.getName().equals(name))
+            {
+               return true;
+            }
+         }
+         p = p.getSuperclass();
+      }
+      return false;
+   }
+
+   public static Method getMethod(Class<?> parent, String name, Class<?>... args)
+   {
+      Class<?> p = parent;
+      while (p != Object.class)
+      {
+         try
+         {
+            return p.getDeclaredMethod(name, args);
+         }
+         catch (Exception e1)
+         {
+
+         }
+         p = p.getSuperclass();
+      }
+      return null;
+   }
+
+   public static Constructor<?> getConstructor(Class<?> parent, Class<?>... args)
+   {
+      Class<?> p = parent;
+      while (p != Object.class)
+      {
+         try
+         {
+            return p.getDeclaredConstructor(args);
+         }
+         catch (Exception e1)
+         {
+
+         }
+         p = p.getSuperclass();
+      }
+      return null;
+   }
+}

Added: modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ConstructedBean.java
===================================================================
--- modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ConstructedBean.java	                        (rev 0)
+++ modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ConstructedBean.java	2010-03-05 21:33:42 UTC (rev 12105)
@@ -0,0 +1,22 @@
+package org.jboss.seam.xml.test.constructor;
+
+public class ConstructedBean
+{
+   public ConstructedBean(int val)
+   {
+      this.value = val;
+   }
+
+   public ConstructedBean()
+   {
+
+   }
+
+   int value;
+
+   public int getValue()
+   {
+      return value;
+   }
+
+}

Added: modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ConstructorTest.java
===================================================================
--- modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ConstructorTest.java	                        (rev 0)
+++ modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ConstructorTest.java	2010-03-05 21:33:42 UTC (rev 12105)
@@ -0,0 +1,21 @@
+package org.jboss.seam.xml.test.constructor;
+
+import org.jboss.seam.xml.test.AbstractXMLTest;
+import org.testng.annotations.Test;
+
+public class ConstructorTest extends AbstractXMLTest
+{
+   @Override
+   protected String getXmlFileName()
+   {
+      return "constructor-beans.xml";
+   }
+
+   @Test
+   public void testBeanConstructorAnnotations()
+   {
+      ConstructedBean bean = getReference(ConstructedBean.class);
+      assert bean.getValue() == 10;
+
+   }
+}

Added: modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ValueProvider.java
===================================================================
--- modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ValueProvider.java	                        (rev 0)
+++ modules/xml/trunk/src/test/java/org/jboss/seam/xml/test/constructor/ValueProvider.java	2010-03-05 21:33:42 UTC (rev 12105)
@@ -0,0 +1,7 @@
+package org.jboss.seam.xml.test.constructor;
+
+
+public class ValueProvider
+{
+   public int value;
+}

Added: modules/xml/trunk/src/test/resources/org/jboss/seam/xml/test/constructor/constructor-beans.xml
===================================================================
--- modules/xml/trunk/src/test/resources/org/jboss/seam/xml/test/constructor/constructor-beans.xml	                        (rev 0)
+++ modules/xml/trunk/src/test/resources/org/jboss/seam/xml/test/constructor/constructor-beans.xml	2010-03-05 21:33:42 UTC (rev 12105)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Beans xmlns="urn:seam:core"
+          xmlns:test="urn:java:org.jboss.seam.xml.test.constructor">
+
+	<test:ValueProvider>
+		<test:value>
+			<Produces/>
+			<value>10</value>
+		</test:value>
+	</test:ValueProvider>
+   
+   	<test:ConstructedBean>
+   		<override/>
+   		<parameters><int/></parameters>
+   	</test:ConstructedBean>
+   
+</Beans>
\ No newline at end of file



More information about the seam-commits mailing list