[jboss-svn-commits] JBoss Common SVN: r2646 - in jbossxb/trunk/src/main/java/org/jboss/xb: builder and 1 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Oct 22 10:06:25 EDT 2007
Author: alex.loubyansky at jboss.com
Date: 2007-10-22 10:06:25 -0400 (Mon, 22 Oct 2007)
New Revision: 2646
Added:
jbossxb/trunk/src/main/java/org/jboss/xb/annotations/JBossXmlCollection.java
Modified:
jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java
jbossxb/trunk/src/main/java/org/jboss/xb/builder/runtime/CollectionPropertyHandler.java
Log:
added @JBossXmlCollection annotation to specify the impl class for collection properties
Added: jbossxb/trunk/src/main/java/org/jboss/xb/annotations/JBossXmlCollection.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/annotations/JBossXmlCollection.java (rev 0)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/annotations/JBossXmlCollection.java 2007-10-22 14:06:25 UTC (rev 2646)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.xb.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * A JBossXmlCollection.
+ *
+ * Used to specify the implementation of java.util.Collection
+ * for collection properties.
+ *
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+ at Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
+ at Retention(RetentionPolicy.RUNTIME)
+public @interface JBossXmlCollection
+{
+ Class<? extends java.util.Collection> type() default java.util.ArrayList.class;
+}
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java 2007-10-22 04:19:07 UTC (rev 2645)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java 2007-10-22 14:06:25 UTC (rev 2646)
@@ -72,6 +72,7 @@
import org.jboss.xb.annotations.JBossXmlChild;
import org.jboss.xb.annotations.JBossXmlChildWildcard;
import org.jboss.xb.annotations.JBossXmlChildren;
+import org.jboss.xb.annotations.JBossXmlCollection;
import org.jboss.xb.annotations.JBossXmlConstants;
import org.jboss.xb.annotations.JBossXmlGroup;
import org.jboss.xb.annotations.JBossXmlGroupText;
@@ -968,55 +969,48 @@
if (typeInfo.isCollection())
{
TypeInfo memberBaseType = findComponentType(typeInfo);
- // if the type is a parameterized collection then
- // bind its members as items
- TypeInfo gs = typeInfo.getGenericSuperclass();
- if (gs instanceof ParameterizedClassInfo)
+ JBossXmlModelGroup xmlModelGroup = ((ClassInfo) memberBaseType)
+ .getUnderlyingAnnotation(JBossXmlModelGroup.class);
+ if (xmlModelGroup != null && xmlModelGroup.particles().length > 0)
{
- //ParameterizedClassInfo pti = (ParameterizedClassInfo) gs;
- //TypeInfo memberBaseType = pti.getActualTypeArguments()[0];
+ if (trace)
+ log.trace("Item base type for " + typeInfo.getName() + " is " + memberBaseType.getName()
+ + " and bound to repeatable choice");
- JBossXmlModelGroup xmlModelGroup = ((ClassInfo) memberBaseType)
- .getUnderlyingAnnotation(JBossXmlModelGroup.class);
- if (xmlModelGroup != null && xmlModelGroup.particles().length > 0)
+ // it's choice by default based on the idea that the
+ // type parameter is a base class for items
+ ModelGroupBinding choiceGroup = new ChoiceBinding(schemaBinding);
+ choiceGroup.setHandler(BuilderParticleHandler.INSTANCE);
+ ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
+ model.addParticle(choiceParticle);
+
+ for (JBossXmlModelGroup.Particle member : xmlModelGroup.particles())
{
- if (trace)
- log.trace("Item base type for " + typeInfo.getName() + " is " + memberBaseType.getName() + " and bound to repeatable choice");
+ XmlElement element = member.element();
+ QName memberQName = generateXmlName(element.name(), XmlNsForm.QUALIFIED, element.namespace(), null);
+ TypeInfo memberTypeInfo = typeInfo.getTypeInfoFactory().getTypeInfo(member.type());
- // it's choice by default based on the idea that the
- // type parameter is a base class for items
- ModelGroupBinding choiceGroup = new ChoiceBinding(schemaBinding);
- choiceGroup.setHandler(BuilderParticleHandler.INSTANCE);
- ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
- model.addParticle(choiceParticle);
-
- for (JBossXmlModelGroup.Particle member : xmlModelGroup.particles())
+ boolean isCol = false;
+ if (memberTypeInfo.isCollection())
{
- XmlElement element = member.element();
- QName memberQName = generateXmlName(element.name(), XmlNsForm.QUALIFIED, element.namespace(), null);
- TypeInfo memberTypeInfo = typeInfo.getTypeInfoFactory().getTypeInfo(member.type());
+ // TODO here we should properly identify the type of the item (based on a testcase)
+ //memberTypeInfo = pti.getActualTypeArguments()[0];
+ memberTypeInfo = findComponentType((ClassInfo) memberTypeInfo);
+ isCol = true;
+ }
- boolean isCol = false;
- if (memberTypeInfo.isCollection())
- {
- // TODO here we should properly identify the type of the item (based on a testcase)
- //memberTypeInfo = pti.getActualTypeArguments()[0];
- memberTypeInfo = findComponentType((ClassInfo) memberTypeInfo);
- isCol = true;
- }
+ TypeBinding memberTypeBinding = resolveTypeBinding(memberTypeInfo);
+ ElementBinding memberElement = createElementBinding(memberTypeInfo, memberTypeBinding, memberQName,
+ false);
+ memberElement.setNillable(true);
+ ParticleBinding memberParticle = new ParticleBinding(memberElement, 0, 1, isCol);
+ choiceGroup.addParticle(memberParticle);
- TypeBinding memberTypeBinding = resolveTypeBinding(memberTypeInfo);
- ElementBinding memberElement = createElementBinding(memberTypeInfo, memberTypeBinding, memberQName, false);
- memberElement.setNillable(true);
- ParticleBinding memberParticle = new ParticleBinding(memberElement, 0, 1, isCol);
- choiceGroup.addParticle(memberParticle);
+ typeBinding.pushInterceptor(memberQName, ChildCollectionInterceptor.SINGLETON);
+ }
- typeBinding.pushInterceptor(memberQName, ChildCollectionInterceptor.SINGLETON);
- }
-
- if (trace)
- log.trace("choices for " + typeBinding.getQName() + ": " + choiceGroup.getParticles());
- }
+ if (trace)
+ log.trace("choices for " + typeBinding.getQName() + ": " + choiceGroup.getParticles());
}
}
@@ -1063,6 +1057,13 @@
if (trace)
log.trace("Property " + property.getName() + " is a collection");
localModel = createCollection(localModel);
+
+ JBossXmlCollection xmlCol = property.getUnderlyingAnnotation(JBossXmlCollection.class);
+ if(xmlCol != null)
+ {
+ // this is the type that should be analyzed
+ propertyType = propertyType.getTypeInfoFactory().getTypeInfo(xmlCol.type());
+ }
}
// Is this property bound to a model group
else if (!property.getType().isPrimitive())
@@ -1460,7 +1461,7 @@
}
// a collection may be bound as a value of a complex type
// and this is checked with the XmlType annotation
- else if (propertyType.isCollection() && ((ClassInfo) localPropertyType).getUnderlyingAnnotation(XmlType.class) == null)
+ else if (propertyType.isCollection() && ((ClassInfo) propertyType).getUnderlyingAnnotation(XmlType.class) == null)
{
isCol = true;
propertyHandler = new CollectionPropertyHandler(property, propertyType);
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/builder/runtime/CollectionPropertyHandler.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/builder/runtime/CollectionPropertyHandler.java 2007-10-22 04:19:07 UTC (rev 2645)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/builder/runtime/CollectionPropertyHandler.java 2007-10-22 14:06:25 UTC (rev 2646)
@@ -33,6 +33,7 @@
import org.jboss.reflect.spi.ClassInfo;
import org.jboss.reflect.spi.ConstructorInfo;
import org.jboss.reflect.spi.TypeInfo;
+import org.jboss.xb.annotations.JBossXmlCollection;
import org.jboss.xb.spi.BeanAdapter;
/**
@@ -43,8 +44,7 @@
*/
public class CollectionPropertyHandler extends AbstractPropertyHandler
{
- /** Whether this is a set */
- private boolean isSet = false;
+ private final CollectionFactory colFactory;
/**
* Create a new CollectionPropertyHandler.
@@ -56,10 +56,53 @@
public CollectionPropertyHandler(PropertyInfo propertyInfo, TypeInfo propertyType)
{
super(propertyInfo, propertyType);
-
- TypeInfo set = propertyType.getTypeInfoFactory().getTypeInfo(Set.class);
- if (set.isAssignableFrom(propertyType))
- isSet = true;
+
+ ClassInfo collectionType = null;
+ JBossXmlCollection xmlCol = propertyInfo.getUnderlyingAnnotation(JBossXmlCollection.class);
+ if (xmlCol != null)
+ {
+ collectionType = (ClassInfo) propertyType.getTypeInfoFactory().getTypeInfo(xmlCol.type());
+ }
+ else if (!Modifier.isAbstract(((ClassInfo) propertyType).getModifiers()))
+ {
+ collectionType = (ClassInfo) propertyType;
+ }
+
+ if (collectionType == null)
+ {
+ TypeInfo set = propertyType.getTypeInfoFactory().getTypeInfo(Set.class);
+ if (set.isAssignableFrom(propertyType))
+ {
+ colFactory = new HashSetFactory();
+ }
+ else
+ {
+ colFactory = new ArrayListFactory();
+ }
+ }
+ else
+ {
+ ConstructorInfo constructor = collectionType.getDeclaredConstructor(null);
+ if (constructor == null)
+ {
+ for (ConstructorInfo ctor : collectionType.getDeclaredConstructors())
+ {
+ if (ctor.getParameterTypes().length == 0)
+ {
+ log.warn("ClassInfo.getDeclaredConstructor(null) didn't work for " + collectionType.getName()
+ + ", found the default ctor in ClassInfo.getDeclaredConstructors()");
+ constructor = ctor;
+ break;
+ }
+ }
+
+ if (constructor == null)
+ {
+ throw new RuntimeException("Default constructor not found for " + collectionType.getName());
+ }
+ }
+ colFactory = new CtorCollectionFactory(constructor);
+ }
}
@Override
@@ -82,40 +125,14 @@
// No collection so create one
if (c == null)
{
- ClassInfo collectionType = (ClassInfo) propertyType;
- if (Modifier.isAbstract(collectionType.getModifiers()) == false)
+ try
{
- try
- {
- ConstructorInfo constructor = collectionType.getDeclaredConstructor(null);
- if(constructor == null)
- {
- for(ConstructorInfo ctor : collectionType.getDeclaredConstructors())
- {
- if(ctor.getParameterTypes().length == 0)
- {
- log.warn("ClassInfo.getDeclaredConstructor(null) didn't work for " + collectionType.getName() + ", found the default ctor in ClassInfo.getDeclaredConstructors()");
- constructor = ctor;
- break;
- }
- }
-
- if(constructor == null)
- {
- throw new NoSuchMethodException("Default constructor not found for " + collectionType.getName());
- }
- }
- c = (Collection) constructor.newInstance(null);
- }
- catch (Throwable t)
- {
- throw new RuntimeException("QName " + qName + " error creating collection: " + propertyType.getName(), t);
- }
+ c = colFactory.createCollection();
}
- else if (isSet)
- c = new HashSet<Object>();
- else
- c = new ArrayList<Object>();
+ catch (Throwable t)
+ {
+ throw new RuntimeException("QName " + qName + " error creating collection: " + propertyType.getName(), t);
+ }
try
{
@@ -137,4 +154,43 @@
throw new RuntimeException("QName " + qName + " error adding " + BuilderUtil.toDebugString(child) + " to collection " + BuilderUtil.toDebugString(c), e);
}
}
+
+ private static interface CollectionFactory
+ {
+ Collection<Object> createCollection() throws Throwable;
+ }
+
+ private static class ArrayListFactory implements CollectionFactory
+ {
+ @SuppressWarnings("unchecked")
+ public Collection<Object> createCollection()
+ {
+ return new ArrayList();
+ }
+ }
+
+ private static class HashSetFactory implements CollectionFactory
+ {
+ @SuppressWarnings("unchecked")
+ public Collection<Object> createCollection()
+ {
+ return new HashSet();
+ }
+ }
+
+ private static class CtorCollectionFactory implements CollectionFactory
+ {
+ private final ConstructorInfo ctor;
+
+ CtorCollectionFactory(ConstructorInfo ctor)
+ {
+ this.ctor = ctor;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<Object> createCollection() throws Throwable
+ {
+ return (Collection) ctor.newInstance(null);
+ }
+ }
}
More information about the jboss-svn-commits
mailing list