[jboss-svn-commits] JBoss Common SVN: r2674 - jbossxb/trunk/src/main/java/org/jboss/xb/builder.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Nov 12 11:11:21 EST 2007


Author: alex.loubyansky at jboss.com
Date: 2007-11-12 11:11:21 -0500 (Mon, 12 Nov 2007)
New Revision: 2674

Modified:
   jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java
Log:
refactoring huge and messy generateType(): extracted property binding part into a separate method

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java	2007-11-12 16:02:17 UTC (rev 2673)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java	2007-11-12 16:11:21 UTC (rev 2674)
@@ -1049,535 +1049,9 @@
       {
          // Setup the error stack
          push(typeInfo, name);
-
          // Get the property
          PropertyInfo property = beanInfo.getProperty(name);
-         TypeInfo propertyType = property.getType();
-         if (trace)
-            log.trace("Processing type=" + beanInfo.getName() + " property=" + property.getName());
-
-         // This is illegal
-         XmlTransient xmlTransient = property.getUnderlyingAnnotation(XmlTransient.class);
-         if (xmlTransient != null)
-            throw new RuntimeException("Property " + name + " in property order " + Arrays.asList(propertyOrder) + " is marked @XmlTransient");
-
-         // The current model
-         ModelGroupBinding localModel = model;
-
-         // Setup any new model
-         if (propertyType.isArray())
-         {
-            if (trace)
-               log.trace("Property " + property.getName() + " is an array");
-            localModel = createArray(localModel);
-         }
-         else if (propertyType.isCollection())
-         {
-            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())
-         {
-            ClassInfo propClassInfo = (ClassInfo) property.getType();
-
-            // TODO XmlElement on this property?..
-            XmlElement propXmlElement = property.getUnderlyingAnnotation(XmlElement.class);
-            if (propXmlElement != null)
-            {
-               propClassInfo = (ClassInfo) propClassInfo.getTypeInfoFactory().getTypeInfo(propXmlElement.type());
-            }
-
-            JBossXmlModelGroup xmlModelGroup = propClassInfo.getUnderlyingAnnotation(JBossXmlModelGroup.class);
-            if (xmlModelGroup != null && xmlModelGroup.particles().length == 0)
-            {
-               if (trace)
-                  log.trace("Property " + property.getName() + " is bound to " + xmlModelGroup.kind());
-               
-               ModelGroupBinding propertyGroup = null;
-               QName groupName = null;
-               if (!JBossXmlConstants.DEFAULT.equals(xmlModelGroup.name()))
-                  groupName = new QName(xmlModelGroup.name());
-               
-               if(groupName != null)
-                  propertyGroup = schemaBinding.getGroup(groupName);
-               
-               if (propertyGroup == null)
-               {
-                  if (xmlModelGroup.kind().equals(JBossXmlConstants.MODEL_GROUP_SEQUENCE))
-                  {
-                     propertyGroup = new SequenceBinding(schemaBinding);
-                  }
-                  else if (xmlModelGroup.kind().equals(JBossXmlConstants.MODEL_GROUP_CHOICE))
-                  {
-                     propertyGroup = new ChoiceBinding(schemaBinding);
-                  }
-                  else if (xmlModelGroup.kind().equals(JBossXmlConstants.MODEL_GROUP_ALL))
-                  {
-                     propertyGroup = new AllBinding(schemaBinding);
-                  }
-                  else
-                  {
-                     throw new IllegalStateException("Unexpected JBossXmlModelGroup.kind=" + xmlModelGroup.kind());
-                  }
-
-                  if (groupName != null)
-                  {
-                     // TODO what if it doesn't have a name? should an artificial one be created?
-                     propertyGroup.setQName(groupName);
-                     schemaBinding.addGroup(propertyGroup.getQName(), propertyGroup);
-                  }
-
-                  propertyGroup.setSkip(Boolean.FALSE);
-
-                  // handler for the model group members
-                  BeanInfo propBeanInfo = JBossXBBuilder.configuration.getBeanInfo(propClassInfo);
-                  BeanAdapterFactory propBeanAdapterFactory = null;
-                  try
-                  {
-                     // TODO this has to use its own adapter class and the factory method
-                     BeanInfo propBeanAdapterBuilderInfo = JBossXBBuilder.configuration.getBeanInfo(DefaultBeanAdapterBuilder.class);
-                     BeanAdapterBuilder propBeanAdapterBuilder = (BeanAdapterBuilder) propBeanAdapterBuilderInfo.newInstance();
-                     propBeanAdapterFactory = propBeanAdapterBuilder.newFactory(propBeanInfo, null);
-                  }
-                  catch (Throwable t)
-                  {
-                     throw new RuntimeException("Error creating BeanAdapterFactory for "
-                           + beanAdapterBuilderClass.getName(), t);
-                  }
-                  BeanHandler propHandler = new BeanHandler(propBeanInfo.getName(), propBeanAdapterFactory);
-                  propertyGroup.setHandler(propHandler);
-
-                  String[] memberOrder = xmlModelGroup.propOrder();
-                  if (memberOrder.length == 0 || memberOrder[0].length() == 0)
-                  {
-                     List<String> propNames = new ArrayList<String>();
-                     for (PropertyInfo prop : propBeanInfo.getProperties())
-                     {
-                        propNames.add(prop.getName());
-                     }
-                     memberOrder = propNames.toArray(new String[propNames.size()]);
-                  }
-
-                  if (trace)
-                     log.trace("Property order for " + xmlModelGroup.kind() + " property " + property.getName() + ": "
-                           + Arrays.asList(memberOrder));
-
-                  // bind model group members
-                  for (String memberPropName : memberOrder)
-                  {
-                     if ("class".equals(memberPropName))
-                     {
-                        continue;
-                     }
-
-                     PropertyInfo memberProp = propBeanInfo.getProperty(memberPropName);
-                     TypeInfo memberTypeInfo = memberProp.getType();
-                     String memberNamespace = null;
-
-                     JBossXmlNsPrefix nsPrefix = memberProp.getUnderlyingAnnotation(JBossXmlNsPrefix.class);
-                     if (nsPrefix != null)
-                     {
-                        memberNamespace = schemaBinding.getNamespace(nsPrefix.prefix());
-                        if (memberNamespace == null && nsPrefix.schemaTargetIfNotMapped())
-                        {
-                           throw new IllegalStateException("Prefix '" + nsPrefix.prefix()
-                                 + "' is not mapped to any namespace!");
-                        }
-                     }
-
-                     String memberName = null;
-                     XmlElement memberXmlElement = memberProp.getUnderlyingAnnotation(XmlElement.class);
-                     if (memberXmlElement != null)
-                     {
-                        if (!XmlElement.DEFAULT.class.equals(memberXmlElement.type()))
-                        {
-                           memberTypeInfo = memberTypeInfo.getTypeInfoFactory().getTypeInfo(memberXmlElement.type());
-                        }
-
-                        if (memberNamespace == null)
-                           memberNamespace = memberXmlElement.namespace();
-                        memberName = memberXmlElement.name();
-                     }
-
-                     if (memberNamespace == null)
-                     {
-                        memberNamespace = defaultNamespace;
-                     }
-
-                     boolean isCol = false;
-                     AbstractPropertyHandler memberPropertyHandler = null;
-                     if (memberProp.getType().isCollection())
-                     {
-                        memberPropertyHandler = new CollectionPropertyHandler(memberProp, memberProp.getType());
-                        isCol = true;
-                        // if memberXmlElement is present then the collection item type is set explicitly
-                        if (memberXmlElement == null || XmlElement.DEFAULT.class.equals(memberXmlElement.type()))
-                        {
-                           JBossXmlCollection jbossXmlCollection = memberProp
-                                 .getUnderlyingAnnotation(JBossXmlCollection.class);
-                           if (jbossXmlCollection != null)
-                           {
-                              memberTypeInfo = memberTypeInfo.getTypeInfoFactory().getTypeInfo(
-                                    jbossXmlCollection.type());
-                           }
-                           memberTypeInfo = findComponentType((ClassInfo) memberTypeInfo);
-                        }
-                     }
-                     // if it is bound with XmlElement.type to a collection
-                     else if (memberTypeInfo.isCollection())
-                     {
-                        memberPropertyHandler = new CollectionPropertyHandler(memberProp, memberTypeInfo);
-                        isCol = true;
-                        memberTypeInfo = findComponentType((ClassInfo) memberTypeInfo);
-                     }
-                     else
-                     {
-                        memberPropertyHandler = new PropertyHandler(memberProp, memberTypeInfo);
-                     }
-
-                     QName memberQName = generateXmlName(memberProp.getName(), elementForm, memberNamespace, memberName);
-                     propBeanAdapterFactory.addProperty(memberQName, memberPropertyHandler);
-
-                     XBValueAdapter valueAdapter = null;
-                     XmlJavaTypeAdapter xmlTypeAdapter = memberProp.getUnderlyingAnnotation(XmlJavaTypeAdapter.class);
-                     if (xmlTypeAdapter != null)
-                     {
-                        valueAdapter = new XBValueAdapter(xmlTypeAdapter.value(), memberTypeInfo.getTypeInfoFactory());
-                        memberTypeInfo = valueAdapter.getAdaptedTypeInfo();
-                     }
-
-                     TypeBinding memberTypeBinding = resolveTypeBinding(memberTypeInfo);
-                     ElementBinding memberElement = createElementBinding(memberTypeInfo, memberTypeBinding,
-                           memberQName, false);
-                     memberElement.setNillable(true);
-                     memberElement.setValueAdapter(valueAdapter);
-                     ParticleBinding memberParticle = new ParticleBinding(memberElement, 0, 1, isCol);
-                     propertyGroup.addParticle(memberParticle);
-
-                     if (trace)
-                        log.trace("added " + memberParticle + " to " + xmlModelGroup.kind() + ", property " + property.getName());
-                  }
-               }
-               
-               model.addParticle(new ParticleBinding(propertyGroup));
-
-               // model group value handler based on the model group name
-               // TODO what if it doesn't have a name?
-               AbstractPropertyHandler propertyHandler = null;
-               if (propertyType.isCollection())
-                  propertyHandler = new CollectionPropertyHandler(property, propClassInfo);
-               else
-               {
-                  propertyHandler = new PropertyHandler(property, propClassInfo);
-               }
-               beanAdapterFactory.addProperty(propertyGroup.getQName(), propertyHandler);
-
-               pop();
-               continue;
-            }
-         }
-
-         // So this is element(s)
-         XmlElement[] elements = null;
-         XmlElement xmlElement = property.getUnderlyingAnnotation(XmlElement.class);
-         if (xmlElement != null)
-         {
-            // A single element annotated
-            elements = new XmlElement[] { xmlElement };
-         }
-         else
-         {
-            // Mutlple elements
-            XmlElements xmlElements = property.getUnderlyingAnnotation(XmlElements.class);
-            if (xmlElements != null)
-               elements = xmlElements.value();
-         }
-
-         // A single element not annotated
-         if (elements == null || elements.length == 0)
-            elements = new XmlElement[1];
-
-         // for now support just one JBossXmlNsPrefix
-         JBossXmlNsPrefix xmlNsPrefix = property.getUnderlyingAnnotation(JBossXmlNsPrefix.class);
-
-         // support for @XmlElementWrapper
-         // the wrapping element is ignored in this case
-         XmlElementWrapper xmlWrapper = property.getUnderlyingAnnotation(XmlElementWrapper.class);
-         if(xmlWrapper != null)
-         {
-            String wrapperNamespace = xmlWrapper.namespace();
-            String wrapperName = xmlWrapper.name();
-            boolean wrapperNillable = xmlWrapper.nillable();
-
-            QName wrapperQName = generateXmlName(property.getName(), elementForm, wrapperNamespace, wrapperName);
-
-            TypeBinding wrapperType = new TypeBinding();
-            SequenceBinding seq = new SequenceBinding(schemaBinding);
-            seq.setHandler(BuilderParticleHandler.INSTANCE);
-            ParticleBinding particle = new ParticleBinding(seq);
-            wrapperType.setParticle(particle);
-            wrapperType.setHandler(new DefaultElementHandler());
-
-            ElementBinding wrapperElement = createElementBinding(propertyType, wrapperType, wrapperQName, false);
-            wrapperElement.setNillable(wrapperNillable);
-            wrapperElement.setSkip(Boolean.TRUE);
-            particle = new ParticleBinding(wrapperElement, 1, 1, false);
-            localModel.addParticle(particle);
-
-            localModel = seq;
-            
-            if (trace)
-               log.trace("Added property " + wrapperQName + " for type=" + beanInfo.getName() + " property="
-                     + property.getName() + " as a wrapper element");
-         }
-         
-         // Setup a choice
-         if (elements.length > 1)
-         {
-            ChoiceBinding choice = new ChoiceBinding(schemaBinding);
-            choice.setHandler(BuilderParticleHandler.INSTANCE);
-            ParticleBinding particleBinding = new ParticleBinding(choice);
-            particleBinding.setMinOccurs(0);
-            particleBinding.setMaxOccurs(1);
-            localModel.addParticle(particleBinding);
-            localModel = choice;
-            if (trace)
-               log.trace("XmlElements seen adding choice for type=" + beanInfo.getName() + " property=" + property.getName());
-         }
-
-         for (int i = 0; i < elements.length; ++i)
-         {
-            XmlElement element = elements[i];
-            if (trace)
-               log.trace("Processing " + element + " for type=" + beanInfo.getName() + " property=" + property.getName());
-
-            // Determine the parameters
-            overrideNamespace = null;
-            overrideName = null;
-            boolean nillable = false;
-            boolean required = false;
-
-            TypeInfo localPropertyType = propertyType;
-
-            if (element != null)
-            {
-               overrideNamespace = element.namespace();
-               overrideName = element.name();
-               nillable = element.nillable();
-               required = element.required();
-               Class<?> elementType = element.type();
-               if (elementType != XmlElement.DEFAULT.class)
-                  localPropertyType = propertyType.getTypeInfoFactory().getTypeInfo(elementType);
-            }
-
-            if (xmlNsPrefix != null)
-            {
-               overrideNamespace = schemaBinding.getNamespace(xmlNsPrefix.prefix());
-               if (overrideNamespace == null)
-               {
-                  if (xmlNsPrefix.schemaTargetIfNotMapped())
-                  {
-                     overrideNamespace = defaultNamespace;
-                  }
-                  else
-                  {
-                     throw new IllegalStateException("Prefix '" + xmlNsPrefix.prefix() + "' is not mapped to any namespace!");
-                  }
-               }
-            }
-
-            // Determine the name
-            QName qName = generateXmlName(property.getName(), elementForm, overrideNamespace, overrideName);
-
-            // Create the element
-            JBossXmlGroup jbossXmlGroup = null;
-            if (!propertyType.isPrimitive())
-               jbossXmlGroup = ((ClassInfo) propertyType).getUnderlyingAnnotation(JBossXmlGroup.class);
-            if (element == null && jbossXmlGroup != null)
-            {
-               if (trace)
-                  log.trace("Processing group for property " + property.getName() + " in " + typeInfo.getName() + " " + jbossXmlGroup);
-               JBossXmlChild[] children = jbossXmlGroup.value();
-               if (children != null && children.length > 0)
-               {
-                  TypeBinding elementTypeBinding = new TypeBinding();
-                  elementTypeBinding.setSchemaBinding(schemaBinding);
-                  elementTypeBinding.setHandler(BuilderParticleHandler.INSTANCE);
-                  ElementBinding elementBinding = createElementBinding(localPropertyType, elementTypeBinding, qName, false);
-
-                  // Bind it to the model
-                  ParticleBinding particle = new ParticleBinding(elementBinding, 1, 1, false);
-                  if (required == false)
-                     particle.setMinOccurs(0);
-                  localModel.addParticle(particle);
-
-                  // Can it take text?
-                  JBossXmlGroupText groupText = ((ClassInfo) propertyType).getUnderlyingAnnotation(JBossXmlGroupText.class);
-                  if (groupText != null)
-                  {
-                     CharactersHandler textHandler;
-                     if (groupText.wrapper() != Object.class)
-                     {
-                        BeanInfo wrapperInfo = JBossXBBuilder.configuration.getBeanInfo(groupText.wrapper());
-                        textHandler = new ValueHandler(property, wrapperInfo, groupText.property());
-                     }
-                     else
-                        textHandler = new ValueHandler(property);
-                     elementTypeBinding.setCharactersHandler(textHandler);
-                  }
-
-                  // Setup the child model
-                  ChoiceBinding childModel = new ChoiceBinding(schemaBinding);
-                  childModel.setHandler(BuilderParticleHandler.INSTANCE);
-                  ParticleBinding particleBinding = new ParticleBinding(childModel);
-                  particleBinding.setMinOccurs(0);
-                  particleBinding.setMaxOccurs(1);
-                  elementTypeBinding.setParticle(particleBinding);
-
-                  for (JBossXmlChild child : children)
-                  {
-                     QName childName = generateXmlName(child.name(), elementForm, child.namespace(), child.name());
-                     TypeInfo childType = JBossXBBuilder.configuration.getTypeInfo(child.type());
-
-                     TypeBinding childTypeBinding = resolveTypeBinding(childType);
-                     ElementBinding childBinding = createElementBinding(childType, childTypeBinding, childName, false);
-                     childBinding.setNillable(nillable);
-
-                     // Bind it to the model
-                     particle = new ParticleBinding(childBinding, child.minOccurs(), child.maxOccurs(), child.unbounded());
-                     particle.setMinOccurs(0);
-                     childModel.addParticle(particle);
-
-                     DefaultElementInterceptor interceptor = new PropertyInterceptor(property, propertyType);
-                     elementTypeBinding.pushInterceptor(childName, interceptor);
-                     if (trace)
-                        log.trace("Added interceptor " + childName + " for type=" + beanInfo.getName() + " property=" + property.getName() + " interceptor=" + interceptor);
-
-                     beanAdapterFactory.addProperty(qName, new NoopPropertyHandler(property, propertyType));
-
-                     JBossXmlGroupWildcard groupWildcard = ((ClassInfo) propertyType).getUnderlyingAnnotation(JBossXmlGroupWildcard.class);
-
-                     if (groupWildcard != null)
-                     {
-                        ChildWildcardHandler groupWildcardHandler;
-                        if (groupWildcard.wrapper() != Object.class)
-                        {
-                           BeanInfo wrapperInfo = JBossXBBuilder.configuration.getBeanInfo(groupWildcard.wrapper());
-                           groupWildcardHandler = new ChildWildcardHandler(property, wrapperInfo, groupWildcard.property());
-                        }
-                        else
-                           groupWildcardHandler = new ChildWildcardHandler(property);
-
-                        WildcardBinding wildcard = new WildcardBinding(schemaBinding);
-                        if (groupWildcard.lax())
-                           wildcard.setProcessContents((short) 3); // Lax
-                        else
-                           wildcard.setProcessContents((short) 1); // Strict
-
-                        particleBinding = new ParticleBinding(wildcard);
-                        particleBinding.setMinOccurs(0);
-                        particleBinding.setMaxOccurs(1);
-                        childModel.addParticle(particleBinding);
-
-                        elementTypeBinding.getWildcard().setWildcardHandler(groupWildcardHandler);
-                     }
-                  }
-               }
-            }
-            else
-            {
-               XBValueAdapter valueAdapter = null;
-               XmlJavaTypeAdapter xmlTypeAdapter = property.getUnderlyingAnnotation(XmlJavaTypeAdapter.class);
-               if (xmlTypeAdapter != null)
-               {
-                  valueAdapter = new XBValueAdapter(xmlTypeAdapter.value(), propertyType.getTypeInfoFactory());
-                  localPropertyType = valueAdapter.getAdaptedTypeInfo();
-               }
-
-               ModelGroupBinding targetGroup = localModel;
-               boolean isCol = false;
-               AbstractPropertyHandler propertyHandler = null;
-               // handled by wildcard
-               if (wildcardProperty == property)
-               {
-                  propertyHandler = wildcardHandler;
-               }
-               // 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) propertyType).getUnderlyingAnnotation(XmlType.class) == null)
-               {
-                  isCol = true;
-                  propertyHandler = new CollectionPropertyHandler(property, propertyType);
-                  ClassInfo typeArg = (ClassInfo) findComponentType(property);
-
-                  //if (((ClassInfo) typeArg).getUnderlyingAnnotation(XmlType.class) != null)
-                  if (typeArg != null && typeArg.getUnderlyingAnnotation(JBossXmlModelGroup.class) == null)
-                  {// it may be a model group in which case we don't want to change the type
-
-                     // TODO yes, this is another hack with collections
-                     JBossXmlChild xmlChild = ((ClassInfo) propertyType).getUnderlyingAnnotation(JBossXmlChild.class);
-                     if (xmlChild == null && localPropertyType.equals(propertyType))
-                     { // the localPropertyType was not overriden previously so use the collection parameter type
-                        localPropertyType = typeArg;
-                     }
-                  }
-               }
-               // TODO this shouldn't be here (because localPropertyType should specify an item?)
-               // this is to support the Descriptions.class -> DescriptionsImpl.class
-               else if (localPropertyType.isCollection() && ((ClassInfo) localPropertyType).getUnderlyingAnnotation(XmlType.class) == null)
-               {
-                  Type parameterizedType;
-                  if(valueAdapter != null)
-                  {
-                     propertyHandler = new PropertyHandler(property, localPropertyType);
-                     parameterizedType = valueAdapter.getAdaptedType();
-                  }
-                  else
-                  {
-                     propertyHandler = new CollectionPropertyHandler(property, localPropertyType);
-                     parameterizedType = localPropertyType.getType();
-                  }
-                  isCol = true;                  
-                  localPropertyType = findActualType((ClassInfo) localPropertyType, parameterizedType, java.util.Collection.class, 0);
-               }
-               else
-               {
-                  propertyHandler = new PropertyHandler(property, localPropertyType);
-               }
-
-               ParticleBinding particle;
-               // DOM elements are going to be treated as unresolved
-               // however having the property registered
-               if (!Element.class.getName().equals(propertyType.getName()))
-               {
-                  TypeBinding elementTypeBinding = resolveTypeBinding(localPropertyType);
-                  ElementBinding elementBinding = createElementBinding(localPropertyType, elementTypeBinding, qName, false);
-                  elementBinding.setNillable(nillable);
-                  elementBinding.setValueAdapter(valueAdapter);
-
-                  // Bind it to the model
-                  particle = new ParticleBinding(elementBinding, 1, 1, isCol);
-                  if (required == false)
-                     particle.setMinOccurs(0);
-
-                  targetGroup.addParticle(particle);
-               }
-
-               beanAdapterFactory.addProperty(qName, propertyHandler);
-               if (trace)
-                  log.trace("Added property " + qName + " for type=" + beanInfo.getName() + " property="
-                        + property.getName() + " handler=" + propertyHandler);
-            }
-         }
+         bindProperty(property, typeBinding, model, beanAdapterFactory, propertyOrder);
          pop();
       }
 
@@ -1677,7 +1151,7 @@
       JBossXmlChildWildcard childWildcard = typeInfo.getUnderlyingAnnotation(JBossXmlChildWildcard.class);
       if (childWildcard != null)
       {
-         if (wildcardProperty != null)
+         if (beanAdapterFactory.getWildcardHandler() != null)
             throw new RuntimeException("Cannot have both @JBossXmlChildWildcard and @XmlAnyElement");
 
          ParticleHandler childWildcardHandler = null;
@@ -1720,6 +1194,545 @@
       return typeBinding;
    }
 
+   private void bindProperty(PropertyInfo property, TypeBinding typeBinding, ModelGroupBinding model,
+         BeanAdapterFactory beanAdapterFactory, String[] propertyOrder)
+   {
+      TypeInfo propertyType = property.getType();
+      if (trace)
+         log.trace("Processing type=" + property.getBeanInfo().getName() + " property=" + property.getName());
+
+      // This is illegal
+      XmlTransient xmlTransient = property.getUnderlyingAnnotation(XmlTransient.class);
+      if (xmlTransient != null && propertyOrder != null)
+         throw new RuntimeException("Property " + property.getName() + " in property order "
+               + Arrays.asList(propertyOrder) + " is marked @XmlTransient");
+
+      // The current model
+      ModelGroupBinding localModel = model;
+
+      // Setup any new model
+      if (propertyType.isArray())
+      {
+         if (trace)
+            log.trace("Property " + property.getName() + " is an array");
+         localModel = createArray(localModel);
+      }
+      else if (propertyType.isCollection())
+      {
+         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())
+      {
+         ClassInfo propClassInfo = (ClassInfo) property.getType();
+
+         // TODO XmlElement on this property?..
+         XmlElement propXmlElement = property.getUnderlyingAnnotation(XmlElement.class);
+         if (propXmlElement != null)
+         {
+            propClassInfo = (ClassInfo) propClassInfo.getTypeInfoFactory().getTypeInfo(propXmlElement.type());
+         }
+
+         JBossXmlModelGroup xmlModelGroup = propClassInfo.getUnderlyingAnnotation(JBossXmlModelGroup.class);
+         if (xmlModelGroup != null && xmlModelGroup.particles().length == 0)
+         {
+            if (trace)
+               log.trace("Property " + property.getName() + " is bound to " + xmlModelGroup.kind());
+
+            ModelGroupBinding propertyGroup = null;
+            QName groupName = null;
+            if (!JBossXmlConstants.DEFAULT.equals(xmlModelGroup.name()))
+               groupName = new QName(xmlModelGroup.name());
+
+            if (groupName != null)
+               propertyGroup = schemaBinding.getGroup(groupName);
+
+            if (propertyGroup == null)
+            {
+               if (xmlModelGroup.kind().equals(JBossXmlConstants.MODEL_GROUP_SEQUENCE))
+               {
+                  propertyGroup = new SequenceBinding(schemaBinding);
+               }
+               else if (xmlModelGroup.kind().equals(JBossXmlConstants.MODEL_GROUP_CHOICE))
+               {
+                  propertyGroup = new ChoiceBinding(schemaBinding);
+               }
+               else if (xmlModelGroup.kind().equals(JBossXmlConstants.MODEL_GROUP_ALL))
+               {
+                  propertyGroup = new AllBinding(schemaBinding);
+               }
+               else
+               {
+                  throw new IllegalStateException("Unexpected JBossXmlModelGroup.kind=" + xmlModelGroup.kind());
+               }
+
+               if (groupName != null)
+               {
+                  // TODO what if it doesn't have a name? should an artificial one be created?
+                  propertyGroup.setQName(groupName);
+                  schemaBinding.addGroup(propertyGroup.getQName(), propertyGroup);
+               }
+
+               propertyGroup.setSkip(Boolean.FALSE);
+
+               // handler for the model group members
+               BeanInfo propBeanInfo = JBossXBBuilder.configuration.getBeanInfo(propClassInfo);
+               BeanAdapterFactory propBeanAdapterFactory = null;
+               try
+               {
+                  // TODO this has to use its own adapter class and the factory method
+                  BeanInfo propBeanAdapterBuilderInfo = JBossXBBuilder.configuration
+                        .getBeanInfo(DefaultBeanAdapterBuilder.class);
+                  BeanAdapterBuilder propBeanAdapterBuilder = (BeanAdapterBuilder) propBeanAdapterBuilderInfo
+                        .newInstance();
+                  propBeanAdapterFactory = propBeanAdapterBuilder.newFactory(propBeanInfo, null);
+               }
+               catch (Throwable t)
+               {
+                  throw new RuntimeException("Error creating BeanAdapterFactory for "
+                        + DefaultBeanAdapterBuilder.class.getName(), t);
+               }
+               BeanHandler propHandler = new BeanHandler(propBeanInfo.getName(), propBeanAdapterFactory);
+               propertyGroup.setHandler(propHandler);
+
+               String[] memberOrder = xmlModelGroup.propOrder();
+               if (memberOrder.length == 0 || memberOrder[0].length() == 0)
+               {
+                  List<String> propNames = new ArrayList<String>();
+                  for (PropertyInfo prop : propBeanInfo.getProperties())
+                  {
+                     propNames.add(prop.getName());
+                  }
+                  memberOrder = propNames.toArray(new String[propNames.size()]);
+               }
+
+               if (trace)
+                  log.trace("Property order for " + xmlModelGroup.kind() + " property " + property.getName() + ": "
+                        + Arrays.asList(memberOrder));
+
+               // bind model group members
+               for (String memberPropName : memberOrder)
+               {
+                  if ("class".equals(memberPropName))
+                  {
+                     continue;
+                  }
+
+                  PropertyInfo memberProp = propBeanInfo.getProperty(memberPropName);
+                  TypeInfo memberTypeInfo = memberProp.getType();
+                  String memberNamespace = null;
+
+                  JBossXmlNsPrefix nsPrefix = memberProp.getUnderlyingAnnotation(JBossXmlNsPrefix.class);
+                  if (nsPrefix != null)
+                  {
+                     memberNamespace = schemaBinding.getNamespace(nsPrefix.prefix());
+                     if (memberNamespace == null && nsPrefix.schemaTargetIfNotMapped())
+                     {
+                        throw new IllegalStateException("Prefix '" + nsPrefix.prefix()
+                              + "' is not mapped to any namespace!");
+                     }
+                  }
+
+                  String memberName = null;
+                  XmlElement memberXmlElement = memberProp.getUnderlyingAnnotation(XmlElement.class);
+                  if (memberXmlElement != null)
+                  {
+                     if (!XmlElement.DEFAULT.class.equals(memberXmlElement.type()))
+                     {
+                        memberTypeInfo = memberTypeInfo.getTypeInfoFactory().getTypeInfo(memberXmlElement.type());
+                     }
+
+                     if (memberNamespace == null)
+                        memberNamespace = memberXmlElement.namespace();
+                     memberName = memberXmlElement.name();
+                  }
+
+                  if (memberNamespace == null)
+                  {
+                     memberNamespace = defaultNamespace;
+                  }
+
+                  boolean isCol = false;
+                  AbstractPropertyHandler memberPropertyHandler = null;
+                  if (memberProp.getType().isCollection())
+                  {
+                     memberPropertyHandler = new CollectionPropertyHandler(memberProp, memberProp.getType());
+                     isCol = true;
+                     // if memberXmlElement is present then the collection item type is set explicitly
+                     if (memberXmlElement == null || XmlElement.DEFAULT.class.equals(memberXmlElement.type()))
+                     {
+                        JBossXmlCollection jbossXmlCollection = memberProp
+                              .getUnderlyingAnnotation(JBossXmlCollection.class);
+                        if (jbossXmlCollection != null)
+                        {
+                           memberTypeInfo = memberTypeInfo.getTypeInfoFactory().getTypeInfo(jbossXmlCollection.type());
+                        }
+                        memberTypeInfo = findComponentType((ClassInfo) memberTypeInfo);
+                     }
+                  }
+                  // if it is bound with XmlElement.type to a collection
+                  else if (memberTypeInfo.isCollection())
+                  {
+                     memberPropertyHandler = new CollectionPropertyHandler(memberProp, memberTypeInfo);
+                     isCol = true;
+                     memberTypeInfo = findComponentType((ClassInfo) memberTypeInfo);
+                  }
+                  else
+                  {
+                     memberPropertyHandler = new PropertyHandler(memberProp, memberTypeInfo);
+                  }
+
+                  QName memberQName = generateXmlName(memberProp.getName(), elementForm, memberNamespace, memberName);
+                  propBeanAdapterFactory.addProperty(memberQName, memberPropertyHandler);
+
+                  XBValueAdapter valueAdapter = null;
+                  XmlJavaTypeAdapter xmlTypeAdapter = memberProp.getUnderlyingAnnotation(XmlJavaTypeAdapter.class);
+                  if (xmlTypeAdapter != null)
+                  {
+                     valueAdapter = new XBValueAdapter(xmlTypeAdapter.value(), memberTypeInfo.getTypeInfoFactory());
+                     memberTypeInfo = valueAdapter.getAdaptedTypeInfo();
+                  }
+
+                  TypeBinding memberTypeBinding = resolveTypeBinding(memberTypeInfo);
+                  ElementBinding memberElement = createElementBinding(memberTypeInfo, memberTypeBinding, memberQName,
+                        false);
+                  memberElement.setNillable(true);
+                  memberElement.setValueAdapter(valueAdapter);
+                  ParticleBinding memberParticle = new ParticleBinding(memberElement, 0, 1, isCol);
+                  propertyGroup.addParticle(memberParticle);
+
+                  if (trace)
+                     log.trace("added " + memberParticle + " to " + xmlModelGroup.kind() + ", property "
+                           + property.getName());
+               }
+            }
+
+            model.addParticle(new ParticleBinding(propertyGroup));
+
+            // model group value handler based on the model group name
+            // TODO what if it doesn't have a name?
+            AbstractPropertyHandler propertyHandler = null;
+            if (propertyType.isCollection())
+               propertyHandler = new CollectionPropertyHandler(property, propClassInfo);
+            else
+            {
+               propertyHandler = new PropertyHandler(property, propClassInfo);
+            }
+            beanAdapterFactory.addProperty(propertyGroup.getQName(), propertyHandler);
+            return;
+         }
+      }
+
+      // So this is element(s)
+      XmlElement[] elements = null;
+      XmlElement xmlElement = property.getUnderlyingAnnotation(XmlElement.class);
+      if (xmlElement != null)
+      {
+         // A single element annotated
+         elements = new XmlElement[]
+         {xmlElement};
+      }
+      else
+      {
+         // Mutlple elements
+         XmlElements xmlElements = property.getUnderlyingAnnotation(XmlElements.class);
+         if (xmlElements != null)
+            elements = xmlElements.value();
+      }
+
+      // A single element not annotated
+      if (elements == null || elements.length == 0)
+         elements = new XmlElement[1];
+
+      // for now support just one JBossXmlNsPrefix
+      JBossXmlNsPrefix xmlNsPrefix = property.getUnderlyingAnnotation(JBossXmlNsPrefix.class);
+
+      // support for @XmlElementWrapper
+      // the wrapping element is ignored in this case
+      XmlElementWrapper xmlWrapper = property.getUnderlyingAnnotation(XmlElementWrapper.class);
+      if (xmlWrapper != null)
+      {
+         String wrapperNamespace = xmlWrapper.namespace();
+         String wrapperName = xmlWrapper.name();
+         boolean wrapperNillable = xmlWrapper.nillable();
+
+         QName wrapperQName = generateXmlName(property.getName(), elementForm, wrapperNamespace, wrapperName);
+
+         TypeBinding wrapperType = new TypeBinding();
+         SequenceBinding seq = new SequenceBinding(schemaBinding);
+         seq.setHandler(BuilderParticleHandler.INSTANCE);
+         ParticleBinding particle = new ParticleBinding(seq);
+         wrapperType.setParticle(particle);
+         wrapperType.setHandler(new DefaultElementHandler());
+
+         ElementBinding wrapperElement = createElementBinding(propertyType, wrapperType, wrapperQName, false);
+         wrapperElement.setNillable(wrapperNillable);
+         wrapperElement.setSkip(Boolean.TRUE);
+         particle = new ParticleBinding(wrapperElement, 1, 1, false);
+         localModel.addParticle(particle);
+
+         localModel = seq;
+
+         if (trace)
+            log.trace("Added property " + wrapperQName + " for type=" + property.getBeanInfo().getName() + " property="
+                  + property.getName() + " as a wrapper element");
+      }
+
+      // Setup a choice
+      if (elements.length > 1)
+      {
+         ChoiceBinding choice = new ChoiceBinding(schemaBinding);
+         choice.setHandler(BuilderParticleHandler.INSTANCE);
+         ParticleBinding particleBinding = new ParticleBinding(choice);
+         particleBinding.setMinOccurs(0);
+         particleBinding.setMaxOccurs(1);
+         localModel.addParticle(particleBinding);
+         localModel = choice;
+         if (trace)
+            log.trace("XmlElements seen adding choice for type=" + property.getBeanInfo().getName() + " property="
+                  + property.getName());
+      }
+
+      for (int i = 0; i < elements.length; ++i)
+      {
+         XmlElement element = elements[i];
+         if (trace)
+            log.trace("Processing " + element + " for type=" + property.getBeanInfo().getName() + " property="
+                  + property.getName());
+
+         // Determine the parameters
+         String overrideNamespace = null;
+         String overrideName = null;
+         boolean nillable = false;
+         boolean required = false;
+
+         TypeInfo localPropertyType = propertyType;
+
+         if (element != null)
+         {
+            overrideNamespace = element.namespace();
+            overrideName = element.name();
+            nillable = element.nillable();
+            required = element.required();
+            Class<?> elementType = element.type();
+            if (elementType != XmlElement.DEFAULT.class)
+               localPropertyType = propertyType.getTypeInfoFactory().getTypeInfo(elementType);
+         }
+
+         if (xmlNsPrefix != null)
+         {
+            overrideNamespace = schemaBinding.getNamespace(xmlNsPrefix.prefix());
+            if (overrideNamespace == null)
+            {
+               if (xmlNsPrefix.schemaTargetIfNotMapped())
+               {
+                  overrideNamespace = defaultNamespace;
+               }
+               else
+               {
+                  throw new IllegalStateException("Prefix '" + xmlNsPrefix.prefix()
+                        + "' is not mapped to any namespace!");
+               }
+            }
+         }
+
+         // Determine the name
+         QName qName = generateXmlName(property.getName(), elementForm, overrideNamespace, overrideName);
+
+         // Create the element
+         JBossXmlGroup jbossXmlGroup = null;
+         if (!propertyType.isPrimitive())
+            jbossXmlGroup = ((ClassInfo) propertyType).getUnderlyingAnnotation(JBossXmlGroup.class);
+         if (element == null && jbossXmlGroup != null)
+         {
+            if (trace)
+               log.trace("Processing group for property " + property.getName() + " in "
+                     + property.getBeanInfo().getName() + " " + jbossXmlGroup);
+            JBossXmlChild[] children = jbossXmlGroup.value();
+            if (children != null && children.length > 0)
+            {
+               TypeBinding elementTypeBinding = new TypeBinding();
+               elementTypeBinding.setSchemaBinding(schemaBinding);
+               elementTypeBinding.setHandler(BuilderParticleHandler.INSTANCE);
+               ElementBinding elementBinding = createElementBinding(localPropertyType, elementTypeBinding, qName, false);
+
+               // Bind it to the model
+               ParticleBinding particle = new ParticleBinding(elementBinding, 1, 1, false);
+               if (required == false)
+                  particle.setMinOccurs(0);
+               localModel.addParticle(particle);
+
+               // Can it take text?
+               JBossXmlGroupText groupText = ((ClassInfo) propertyType)
+                     .getUnderlyingAnnotation(JBossXmlGroupText.class);
+               if (groupText != null)
+               {
+                  CharactersHandler textHandler;
+                  if (groupText.wrapper() != Object.class)
+                  {
+                     BeanInfo wrapperInfo = JBossXBBuilder.configuration.getBeanInfo(groupText.wrapper());
+                     textHandler = new ValueHandler(property, wrapperInfo, groupText.property());
+                  }
+                  else
+                     textHandler = new ValueHandler(property);
+                  elementTypeBinding.setCharactersHandler(textHandler);
+               }
+
+               // Setup the child model
+               ChoiceBinding childModel = new ChoiceBinding(schemaBinding);
+               childModel.setHandler(BuilderParticleHandler.INSTANCE);
+               ParticleBinding particleBinding = new ParticleBinding(childModel);
+               particleBinding.setMinOccurs(0);
+               particleBinding.setMaxOccurs(1);
+               elementTypeBinding.setParticle(particleBinding);
+
+               for (JBossXmlChild child : children)
+               {
+                  QName childName = generateXmlName(child.name(), elementForm, child.namespace(), child.name());
+                  TypeInfo childType = JBossXBBuilder.configuration.getTypeInfo(child.type());
+
+                  TypeBinding childTypeBinding = resolveTypeBinding(childType);
+                  ElementBinding childBinding = createElementBinding(childType, childTypeBinding, childName, false);
+                  childBinding.setNillable(nillable);
+
+                  // Bind it to the model
+                  particle = new ParticleBinding(childBinding, child.minOccurs(), child.maxOccurs(), child.unbounded());
+                  particle.setMinOccurs(0);
+                  childModel.addParticle(particle);
+
+                  DefaultElementInterceptor interceptor = new PropertyInterceptor(property, propertyType);
+                  elementTypeBinding.pushInterceptor(childName, interceptor);
+                  if (trace)
+                     log.trace("Added interceptor " + childName + " for type=" + property.getBeanInfo().getName()
+                           + " property=" + property.getName() + " interceptor=" + interceptor);
+
+                  beanAdapterFactory.addProperty(qName, new NoopPropertyHandler(property, propertyType));
+
+                  JBossXmlGroupWildcard groupWildcard = ((ClassInfo) propertyType)
+                        .getUnderlyingAnnotation(JBossXmlGroupWildcard.class);
+
+                  if (groupWildcard != null)
+                  {
+                     ChildWildcardHandler groupWildcardHandler;
+                     if (groupWildcard.wrapper() != Object.class)
+                     {
+                        BeanInfo wrapperInfo = JBossXBBuilder.configuration.getBeanInfo(groupWildcard.wrapper());
+                        groupWildcardHandler = new ChildWildcardHandler(property, wrapperInfo, groupWildcard.property());
+                     }
+                     else
+                        groupWildcardHandler = new ChildWildcardHandler(property);
+
+                     WildcardBinding wildcard = new WildcardBinding(schemaBinding);
+                     if (groupWildcard.lax())
+                        wildcard.setProcessContents((short) 3); // Lax
+                     else
+                        wildcard.setProcessContents((short) 1); // Strict
+
+                     particleBinding = new ParticleBinding(wildcard);
+                     particleBinding.setMinOccurs(0);
+                     particleBinding.setMaxOccurs(1);
+                     childModel.addParticle(particleBinding);
+
+                     elementTypeBinding.getWildcard().setWildcardHandler(groupWildcardHandler);
+                  }
+               }
+            }
+         }
+         else
+         {
+            XBValueAdapter valueAdapter = null;
+            XmlJavaTypeAdapter xmlTypeAdapter = property.getUnderlyingAnnotation(XmlJavaTypeAdapter.class);
+            if (xmlTypeAdapter != null)
+            {
+               valueAdapter = new XBValueAdapter(xmlTypeAdapter.value(), propertyType.getTypeInfoFactory());
+               localPropertyType = valueAdapter.getAdaptedTypeInfo();
+            }
+
+            ModelGroupBinding targetGroup = localModel;
+            boolean isCol = false;
+            AbstractPropertyHandler propertyHandler = null;
+
+            // a collection may be bound as a value of a complex type
+            // and this is checked with the XmlType annotation
+            if (propertyType.isCollection()
+                  && ((ClassInfo) propertyType).getUnderlyingAnnotation(XmlType.class) == null)
+            {
+               isCol = true;
+               propertyHandler = new CollectionPropertyHandler(property, propertyType);
+               ClassInfo typeArg = (ClassInfo) findComponentType(property);
+
+               //if (((ClassInfo) typeArg).getUnderlyingAnnotation(XmlType.class) != null)
+               if (typeArg != null && typeArg.getUnderlyingAnnotation(JBossXmlModelGroup.class) == null)
+               {// it may be a model group in which case we don't want to change the type
+
+                  // TODO yes, this is another hack with collections
+                  JBossXmlChild xmlChild = ((ClassInfo) propertyType).getUnderlyingAnnotation(JBossXmlChild.class);
+                  if (xmlChild == null && localPropertyType.equals(propertyType))
+                  { // the localPropertyType was not overriden previously so use the collection parameter type
+                     localPropertyType = typeArg;
+                  }
+               }
+            }
+            // TODO this shouldn't be here (because localPropertyType should specify an item?)
+            // this is to support the Descriptions.class -> DescriptionsImpl.class
+            else if (localPropertyType.isCollection()
+                  && ((ClassInfo) localPropertyType).getUnderlyingAnnotation(XmlType.class) == null)
+            {
+               Type parameterizedType;
+               if (valueAdapter != null)
+               {
+                  propertyHandler = new PropertyHandler(property, localPropertyType);
+                  parameterizedType = valueAdapter.getAdaptedType();
+               }
+               else
+               {
+                  propertyHandler = new CollectionPropertyHandler(property, localPropertyType);
+                  parameterizedType = localPropertyType.getType();
+               }
+               isCol = true;
+               localPropertyType = findActualType((ClassInfo) localPropertyType, parameterizedType,
+                     java.util.Collection.class, 0);
+            }
+            else
+            {
+               propertyHandler = new PropertyHandler(property, localPropertyType);
+            }
+
+            ParticleBinding particle;
+            // DOM elements are going to be treated as unresolved
+            // however having the property registered
+            if (!Element.class.getName().equals(propertyType.getName()))
+            {
+               TypeBinding elementTypeBinding = resolveTypeBinding(localPropertyType);
+               ElementBinding elementBinding = createElementBinding(localPropertyType, elementTypeBinding, qName, false);
+               elementBinding.setNillable(nillable);
+               elementBinding.setValueAdapter(valueAdapter);
+
+               // Bind it to the model
+               particle = new ParticleBinding(elementBinding, 1, 1, isCol);
+               if (required == false)
+                  particle.setMinOccurs(0);
+
+               targetGroup.addParticle(particle);
+            }
+
+            beanAdapterFactory.addProperty(qName, propertyHandler);
+            if (trace)
+               log.trace("Added property " + qName + " for type=" + property.getBeanInfo().getName() + " property="
+                     + property.getName() + " handler=" + propertyHandler);
+         }
+      }
+   }
+
    /**
     * Create an array
     * 
@@ -1738,6 +1751,7 @@
       arraySequenceBinding.addParticle(particle);
       particle = new ParticleBinding(arraySequenceBinding);
       localModel.addParticle(particle);
+      System.out.println("added " + arraySequenceBinding + " to " + localModel);
       return sequenceBinding;
    }
 




More information about the jboss-svn-commits mailing list