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