[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