Package org.jboss.xb.spi

Examples of org.jboss.xb.spi.BeanAdapterFactory


      if (factoryMethod != null && factoryMethod.length() > 0)
         factory = Config.findMethodInfo(factoryClassInfo, factoryMethod, null, true, true);

      // Create the handler
      BeanInfo beanInfo = JBossXBBuilder.configuration.getBeanInfo(typeInfo);
      BeanAdapterFactory beanAdapterFactory = createAdapterFactory(beanAdapterBuilderClass, beanInfo, factory);
      BeanHandler handler = new BeanHandler(beanInfo.getName(), beanAdapterFactory);
      typeBinding.setHandler(handler);
      if (trace)
         log.trace("Created BeanHandler for type=" + beanInfo.getName() + " factory=" + factory);

      // Look through the properties
      JBossXmlNoElements jbossXmlNoElements = typeInfo.getUnderlyingAnnotation(JBossXmlNoElements.class);
      boolean noElements = jbossXmlNoElements != null;
      PropertyInfo valueProperty = null;
      PropertyInfo wildcardProperty = null;
      boolean allBinding = propertyOrder.length == 0;
      boolean determinePropertyOrder = allBinding || (propertyOrder.length == 1 && propertyOrder[0].length() == 0);
      ArrayList<String> propertyNames = new ArrayList<String>();
      Set<PropertyInfo> properties = beanInfo.getProperties();
      if (properties != null && properties.isEmpty() == false)
      {
         boolean seenXmlAnyElement = false;
         for (PropertyInfo property : properties)
         {
            push(typeInfo, property.getName());

            if (trace)
               log.trace("Checking property " + property.getName() + " for " + beanInfo.getName() + " type=" + property.getType().getName());

            // Is this the value property?
            XmlValue xmlValue = property.getUnderlyingAnnotation(XmlValue.class);
            if (xmlValue != null)
            {
               if (trace)
                  log.trace("Seen @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
               if (valueProperty != null)
                  throw new RuntimeException("@XmlValue seen on two properties: " + property.getName() + " and " + valueProperty.getName());
               valueProperty = property;
            }

            // Is this the wildcard property?
            boolean ignoreXmlAnyElement = false;
            XmlAnyElement xmlAnyElement = property.getUnderlyingAnnotation(XmlAnyElement.class);
            if (xmlAnyElement != null)
            {
               if (trace)
                  log.trace("Seen @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
               if (wildcardProperty != null && seenXmlAnyElement)
                  throw new RuntimeException("@XmlAnyElement seen on two properties: " + property.getName() + " and " + wildcardProperty.getName());
               wildcardProperty = property;
               seenXmlAnyElement = true;
              
               // should we ignore it
               if(property.getUnderlyingAnnotation(XmlElements.class) == null &&
                  property.getUnderlyingAnnotation(XmlElementRefs.class) == null)
                  ignoreXmlAnyElement = true;
            }
            else if (!seenXmlAnyElement && wildcardProperty == null && property.getType().getName().equals(org.w3c.dom.Element.class.getName()))
            {
               if (trace)
                  log.trace("Using type=" + beanInfo.getName() + " property=" + property.getName() + " as the base wildcard");
               if (wildcardProperty != null)
                  throw new RuntimeException("@XmlAnyElement seen on two properties: " + property.getName() + " and " + wildcardProperty.getName());
               wildcardProperty = property;
            }

            // Is this an attribute
            XmlAttribute xmlAttribute = property.getUnderlyingAnnotation(XmlAttribute.class);
            if (xmlAttribute != null)
            {
               JBossXmlAttribute jbossXmlAttribute = property.getUnderlyingAnnotation(JBossXmlAttribute.class);
               // Determine the name
               QName qName = generateXmlName(property.getName(), attributeForm, xmlAttribute.namespace(), xmlAttribute.name());
               // Resolve the type
               TypeInfo attributeTypeInfo = property.getType();
               if (jbossXmlAttribute != null && jbossXmlAttribute.type() != Object.class)
                  attributeTypeInfo = attributeTypeInfo.getTypeInfoFactory().getTypeInfo(jbossXmlAttribute.type());
               TypeBinding attributeType = resolveTypeBinding(attributeTypeInfo);
               // Create the attribute handler
               AttributeHandler attributeHandler = new PropertyHandler(property, attributeTypeInfo);
               // Create the attributre and bind it to the type
               AttributeBinding attribute = new AttributeBinding(schemaBinding, qName, attributeType, attributeHandler);
               attribute.setRequired(xmlAttribute.required());
               typeBinding.addAttribute(attribute);
               if (trace)
                  log.trace("Bound attribute " + qName + " type=" + beanInfo.getName() + " property=" + property.getName() + " propertyType=" + attributeTypeInfo);
            }

            // Are we determining the property order?
            if (determinePropertyOrder)
            {
               // Value property
               if (xmlValue != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Wildcard property
               if (ignoreXmlAnyElement)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore xml attribute
               if (xmlAttribute != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlAttribute for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore xml tranient
               XmlTransient xmlTransient = property.getUnderlyingAnnotation(XmlTransient.class);
               if (xmlTransient != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlTransient for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore the class property
               String name = property.getName();
               if ("class".equals(name))
               {
                  pop();
                  continue;
               }

               if (noElements)
               {
                  pop();
                  continue;
               }

               if (trace)
                  log.trace("Element for type=" + beanInfo.getName() + " property=" + property.getName());
               propertyNames.add(property.getName());
            }

            pop();
         }
         // Apply any access order
         if (determinePropertyOrder)
         {
            if (accessOrder == XmlAccessOrder.ALPHABETICAL)
               Collections.sort(propertyNames);
            propertyOrder = propertyNames.toArray(new String[propertyNames.size()]);
         }
      }

      // No value property, see if we have a default one
      //if (valueProperty == null)
      //{
      //   try
      //   {
      //      valueProperty = beanInfo.getProperty("value");
      //   }
      //   catch (Exception ignored)
      //   {
            // Nope.
      //   }
      //}

      // Bind the value
      if (valueProperty != null)
      {
         CharactersHandler charactersHandler = new ValueHandler(valueProperty);
         typeBinding.setSimpleType(charactersHandler);
      }
      else if (trace)
         log.trace("No value for type=" + beanInfo.getName());

      if (trace)
         log.trace("PropertyOrder " + Arrays.asList(propertyOrder) + " for type=" + beanInfo.getName());

      // Determine the model
      // TODO simple types/content when no properties other than @XmlValue and @XmlAttribute
      typeBinding.setSimple(false);
      ModelGroupBinding model = null;
      if (allBinding)
      {
         if (trace)
            log.trace("AllBinding for type=" + beanInfo.getName());
         model = new AllBinding(schemaBinding);
      }
      else
      {
         if (trace)
            log.trace("SequenceBinding for type=" + beanInfo.getName());
         model = new SequenceBinding(schemaBinding);
      }
      model.setHandler(BuilderParticleHandler.INSTANCE);
      ParticleBinding typeParticle = new ParticleBinding(model);
      typeParticle.setMinOccurs(1);
      typeParticle.setMaxOccurs(1);
      typeBinding.setParticle(typeParticle);

      if (typeInfo.isCollection())
      {
         TypeInfo memberBaseType = ((ClassInfo)typeInfo).getComponentType();
         JBossXmlModelGroup xmlModelGroup = ((ClassInfo) memberBaseType)
               .getUnderlyingAnnotation(JBossXmlModelGroup.class);
         if (xmlModelGroup != null && xmlModelGroup.particles().length > 0)
         {
            if (trace)
               log.trace("Item base type for " + typeInfo.getName() + " is " + memberBaseType.getName()
                     + " and bound to repeatable choice");

            // it's choice by default based on the idea that the
            // type parameter is a base class for items
            ModelGroupBinding choiceGroup = null;
            QName choiceName = null;
            if(!JBossXmlConstants.DEFAULT.equals(xmlModelGroup.name()))
            {
               choiceName = new QName(defaultNamespace, xmlModelGroup.name());
               choiceGroup = schemaBinding.getGroup(choiceName);
            }
           
            if(choiceGroup == null)
            {
               choiceGroup = new ChoiceBinding(schemaBinding);
               choiceGroup.setHandler(BuilderParticleHandler.INSTANCE);
               if (choiceName != null)
               {
                  choiceGroup.setQName(choiceName);
                  schemaBinding.addGroup(choiceGroup.getQName(), choiceGroup);
               }

               ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
               model.addParticle(choiceParticle);

               for (JBossXmlModelGroup.Particle member : xmlModelGroup.particles())
               {
                  XmlElement element = member.element();
                  QName memberQName = generateXmlName(element.name(), XmlNsForm.QUALIFIED, element.namespace(), null);
                  TypeInfo memberTypeInfo = typeInfo.getTypeInfoFactory().getTypeInfo(member.type());

                  boolean isCol = false;
                  if (memberTypeInfo.isCollection())
                  {
                     memberTypeInfo = ((ClassInfo) memberTypeInfo).getComponentType();
                     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.pushInterceptor(memberQName, ChildCollectionInterceptor.SINGLETON);
               }
            }
            else
            {
               ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
               model.addParticle(choiceParticle);
            }
           
            if (trace)
               log.trace("choices for " + typeBinding.getQName() + ": " + choiceGroup.getParticles());
         }
      }

      // Determine the wildcard handler
      AbstractPropertyHandler wildcardHandler = null;
      if (wildcardProperty != null)
      {
         TypeInfo wildcardType = wildcardProperty.getType();
         if (wildcardType.isCollection())
            wildcardHandler = new CollectionPropertyWildcardHandler(wildcardProperty, wildcardType);
         else
            wildcardHandler = new PropertyWildcardHandler(wildcardProperty, wildcardType);
      }

      // Look through the properties
      for (String name : propertyOrder)
      {
         // Setup the error stack
         push(typeInfo, name);
         // Get the property
         PropertyInfo property = beanInfo.getProperty(name);
         bindProperty(property, typeBinding, model, beanAdapterFactory, propertyOrder);
         pop();
      }

      // Bind the children
      JBossXmlChild[] children = null;
      JBossXmlChildren jbossXmlChildren = typeInfo.getUnderlyingAnnotation(JBossXmlChildren.class);
      if (jbossXmlChildren != null)
         children = jbossXmlChildren.value();
      else
      {
         JBossXmlChild jbossXmlChild = typeInfo.getUnderlyingAnnotation(JBossXmlChild.class);
         if (jbossXmlChild != null)
            children = new JBossXmlChild[] { jbossXmlChild };
      }

      if (children != null && children.length > 0)
      {
         for (JBossXmlChild child : children)
         {
            QName qName = generateXmlName(child.name(), elementForm, child.namespace(), child.name());
            TypeInfo childType = JBossXBBuilder.configuration.getTypeInfo(child.type());

            TypeBinding elementTypeBinding = resolveTypeBinding(childType);
            ElementBinding elementBinding = createElementBinding(childType, elementTypeBinding, qName, false);

            // Bind it to the model
            ParticleBinding particle = new ParticleBinding(elementBinding, child.minOccurs(), child.maxOccurs(), child.unbounded());
            model.addParticle(particle);

            if(childType.isMap())
               bindMapProperty(null, (ClassInfo) childType, elementTypeBinding.getQName(), (ModelGroupBinding) elementTypeBinding.getParticle().getTerm());
           
            DefaultElementInterceptor interceptor = null;
            if (typeInfo.isCollection())
               interceptor = ChildCollectionInterceptor.SINGLETON;
            else
            {
               // Expect a type with a value property to accept the child value
               PropertyInfo property = beanInfo.getProperty("value");
               if (property == null)
                  throw new UnsupportedOperationException("Expected a value property for non-collection type with JBossXmlChildren");
               TypeInfo propertyType = property.getType();
               interceptor = new PropertyInterceptor(property, propertyType);
            }
            typeBinding.pushInterceptor(qName, interceptor);
            if (trace)
               log.trace("Added interceptor " + qName + " for type=" + childType + " interceptor=" + interceptor);
         }
      }

      // Bind the wildcard
      if (wildcardProperty != null)
      {
         if (trace)
            log.trace("Processing WildcardProperty for type=" + beanInfo.getName() + " property=" + wildcardProperty.getName());
         ModelGroupBinding localModel = model;
         TypeInfo wildcardType = wildcardProperty.getType();
         TypeInfo type = wildcardType;

         // Setup any new model and determine the wildcard type
         if (wildcardType.isArray())
         {
            localModel = createArray(localModel);
            type = ((ArrayInfo) wildcardType).getComponentType();
            if (trace)
               log.trace("Wildcard " + wildcardProperty.getName() + " is an array of type " + type.getName());
         }
         else if (wildcardType.isCollection())
         {
            localModel = createCollection(localModel);
            type = ((ClassInfo)wildcardProperty.getType()).getComponentType();
            if (trace)
               log.trace("Wildcard " + wildcardProperty.getName() + " is a collection of type " + type.getName());
         }

         XmlAnyElement xmlAnyElement = wildcardProperty.getUnderlyingAnnotation(XmlAnyElement.class);
         boolean isLax = xmlAnyElement == null ? true : xmlAnyElement.lax();
         WildcardBinding wildcard = new WildcardBinding(schemaBinding);
         if (isLax)
            wildcard.setProcessContents((short) 3); // Lax
         else
            wildcard.setProcessContents((short) 1); // Strict

         // Dom element?
         if (Element.class.getName().equals(type.getName()))
         {
            wildcard.setUnresolvedElementHandler(DOMHandler.INSTANCE);
            wildcard.setUnresolvedCharactersHandler(DOMHandler.INSTANCE);
         }

         // Bind the particle to the model
         ParticleBinding particleBinding = new ParticleBinding(wildcard);
         particleBinding.setMinOccurs(0);
         particleBinding.setMaxOccurs(1);
         localModel.addParticle(particleBinding);
         typeBinding.getWildcard().setWildcardHandler((ParticleHandler) wildcardHandler);
         beanAdapterFactory.setWildcardHandler(wildcardHandler);
      }

      JBossXmlChildWildcard childWildcard = typeInfo.getUnderlyingAnnotation(JBossXmlChildWildcard.class);
      if (childWildcard != null)
      {
         if (beanAdapterFactory.getWildcardHandler() != null)
            throw new RuntimeException("Cannot have both @JBossXmlChildWildcard and @XmlAnyElement");

         ParticleHandler childWildcardHandler = null;
         if (typeInfo.isCollection())
         {
View Full Code Here


               propertyGroup.setSkip(Boolean.FALSE);

               // handler for the model group members
               BeanInfo propBeanInfo = JBossXBBuilder.configuration.getBeanInfo(propClassInfo);
               BeanAdapterFactory propBeanAdapterFactory = createAdapterFactory(DefaultBeanAdapterBuilder.class, propBeanInfo, null);
               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 = ((ClassInfo) memberTypeInfo).getComponentType();
                     }
                  }
                  // if it is bound with XmlElement.type to a collection
                  else if (memberTypeInfo.isCollection())
                  {
                     memberPropertyHandler = new CollectionPropertyHandler(memberProp, memberTypeInfo);
                     isCol = true;
                     memberTypeInfo = ((ClassInfo) memberTypeInfo).getComponentType();
                  }
                  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();
         QName wrapperQName = generateXmlName(property.getName(), elementForm, wrapperNamespace, wrapperName);
         localModel = bindXmlElementWrapper(propertyType, localModel, xmlWrapper.nillable(), wrapperQName);
         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 propertyQName = 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, propertyQName, 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.setSimpleType(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);

                  if(childType.isMap())
                     bindMapProperty(property, (ClassInfo) childType, childName, (ModelGroupBinding) childTypeBinding.getParticle().getTerm());
                                   
                  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 + " " + childType.getName());

                  beanAdapterFactory.addProperty(propertyQName, 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;
            boolean isMap = 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);
               // here we get the comp type based on the non-overriden property type...
               // which feels like a weak point
               TypeInfo typeArg = ((ClassInfo)property.getType()).getComponentType();

               if (typeArg != null && ((ClassInfo)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)
            {
               if (valueAdapter != null)
               {
                  propertyHandler = new PropertyHandler(property, localPropertyType);
               }
               else
               {
                  propertyHandler = new CollectionPropertyHandler(property, localPropertyType);
               }
               isCol = true;
               localPropertyType = ((ClassInfo)localPropertyType).getComponentType();
            }
            else if (localPropertyType.isMap())
            {
               TypeBinding wrapperType = null;
               if(elements.length > 1)
               {
                  wrapperType = resolveTypeBinding(localPropertyType);
                  ElementBinding elementBinding = createElementBinding(localPropertyType, wrapperType, propertyQName, false);
                  elementBinding.setNillable(nillable);
                  elementBinding.setValueAdapter(valueAdapter);

                  // Bind it to the model
                  ParticleBinding particle = new ParticleBinding(elementBinding, 0, 1, isCol);
                  if (required == false)
                     particle.setMinOccurs(0);

                  targetGroup.addParticle(particle);
                  targetGroup = (ModelGroupBinding) wrapperType.getParticle().getTerm();
               }
              
               QName boundQName = bindMapProperty(property, (ClassInfo) localPropertyType, propertyQName, targetGroup);
               if(boundQName != null)
               {
                  if(wrapperType != null)
                  {
                     BeanAdapterFactory wrapperBeanFactory = ((BeanHandler)wrapperType.getHandler()).getBeanAdapterFactory();
                     Map<QName, AbstractPropertyHandler> properties = wrapperBeanFactory.getProperties();
                     if(!properties.containsKey(boundQName))
                     {
                        propertyHandler = new MapPropertyHandler(JBossXBBuilder.configuration, property, localPropertyType, true);
                        wrapperBeanFactory.addProperty(boundQName, propertyHandler);
                     }
                     propertyHandler = new PropertyHandler(property, localPropertyType);
                  }
                  else
                  {
View Full Code Here

         TypeInfo keyType = propType.getKeyType();
         TypeInfo valueType = propType.getValueType();

         // entry handler
         BeanAdapterFactory entryAdapterFactory = null;
         BeanInfo entryInfo = JBossXBBuilder.configuration.getBeanInfo(DefaultMapEntry.class);
         entryAdapterFactory = createAdapterFactory(DefaultBeanAdapterBuilder.class, entryInfo, null);
         BeanHandler entryHandler = new BeanHandler(entryInfo.getName(), entryAdapterFactory);

         TypeBinding entryType = null;
         TypeInfo entryTypeInfo = null;

         // bind the entry element if present
         if(entryElement != null && !JBossXmlConstants.DEFAULT.equals(entryElement.name()))
         {
            String ns = entryElement.namespace();
            if(JBossXmlConstants.DEFAULT.equals(ns))
               ns = defaultNamespace;                 
            QName entryName = new QName(ns, entryElement.name());

            entryType = new TypeBinding();
            entryType.setSchemaBinding(schemaBinding);
            entryType.setHandler(entryHandler);

            entryTypeInfo = JBossXBBuilder.configuration.getTypeInfo(DefaultMapEntry.class);                    
            ElementBinding entryElementBinding = createElementBinding(entryTypeInfo, entryType, entryName, false);
            ParticleBinding entryParticle = new ParticleBinding(entryElementBinding, 0, -1, true);
            targetGroup.addParticle(entryParticle);
              
            propertyQName = entryName;
              
            if(keyAttribute != null)
            {
               TypeBinding attributeType = resolveTypeBinding(keyType);
               AttributeHandler attributeHandler = new PropertyHandler(entryInfo.getProperty("key"), keyType);
               String attrNs = keyAttribute.namespace();
               if(JBossXmlConstants.DEFAULT.equals(attrNs))
                  attrNs = defaultNamespace;
               AttributeBinding keyBinding = new AttributeBinding(schemaBinding, new QName(attrNs, keyAttribute.name()), attributeType, attributeHandler);
               keyBinding.setRequired(true);
               entryType.addAttribute(keyBinding);
            }

            if(valueAttribute != null)
            {
               TypeBinding attributeType = resolveTypeBinding(valueType);
               AttributeHandler attributeHandler = new PropertyHandler(entryInfo.getProperty("value"), valueType);
               String valueNs = valueAttribute.namespace();
               if(JBossXmlConstants.DEFAULT.equals(valueNs))
                  valueNs = defaultNamespace;
               AttributeBinding valueBinding = new AttributeBinding(schemaBinding, new QName(valueNs, valueAttribute.name()), attributeType, attributeHandler);
               valueBinding.setRequired(true);
               entryType.addAttribute(valueBinding);
            }
            else if(valueElement == null)
            {
               CharactersHandler charactersHandler = new ValueHandler(entryInfo.getProperty("value"), valueType);
               entryType.setSimpleType(charactersHandler);
            }
         }
        
         SequenceBinding keyValueSequence = null;
         if(keyElement != null)
         {
            keyValueSequence = new SequenceBinding(schemaBinding);                    
            if(entryType == null)
            {
               keyValueSequence.setSkip(Boolean.FALSE);
               keyValueSequence.setQName(propertyQName);
               schemaBinding.addGroup(keyValueSequence.getQName(), keyValueSequence);
               ParticleBinding keyValueParticle = new ParticleBinding(keyValueSequence, 0, -1, true);
               targetGroup.addParticle(keyValueParticle);
               keyValueSequence.setHandler(entryHandler);
            }
            else
            {
               ParticleBinding keyValueParticle = new ParticleBinding(keyValueSequence, 1, 1, false);
               entryType.setParticle(keyValueParticle);
            }
           
            // key element
            TypeBinding keyTypeBinding = resolveTypeBinding(keyType);                 
            String keyNs = keyElement.namespace();
            if(JBossXmlConstants.DEFAULT.equals(keyNs))
               keyNs = defaultNamespace;                 
            ElementBinding keyElementBinding = createElementBinding(keyType, keyTypeBinding, new QName(keyNs, keyElement.name()), false);
            ParticleBinding particle = new ParticleBinding(keyElementBinding, 1, 1, false);
            keyValueSequence.addParticle(particle);
            PropertyHandler keyHandler = new PropertyHandler(entryInfo.getProperty("key"), keyType);
            entryAdapterFactory.addProperty(keyElementBinding.getQName(), keyHandler);
         }
        
         if(valueElement != null)
         {
            TypeBinding valueTypeBinding = resolveTypeBinding(valueType);                 
            String valueNs = valueElement.namespace();
            if(JBossXmlConstants.DEFAULT.equals(valueNs))
               valueNs = defaultNamespace;                 
            ElementBinding valueElementBinding = createElementBinding(valueType, valueTypeBinding, new QName(valueNs, valueElement.name()), false);
            ParticleBinding particle = new ParticleBinding(valueElementBinding, 1, 1, false);
            keyValueSequence.addParticle(particle);
            PropertyHandler valueHandler = new PropertyHandler(entryInfo.getProperty("value"), valueType);
            entryAdapterFactory.addProperty(valueElementBinding.getQName(), valueHandler);
         }

         // TODO: need to verify correct binding before proceeding
         boundQName = propertyQName;
      }
View Full Code Here

      if (factoryMethod != null && factoryMethod.length() > 0)
         factory = Config.findMethodInfo(factoryClassInfo, factoryMethod, null, true, true);

      // Create the handler
      BeanInfo beanInfo = JBossXBBuilder.configuration.getBeanInfo(typeInfo);
      BeanAdapterFactory beanAdapterFactory = createAdapterFactory(beanAdapterBuilderClass, beanInfo, factory);
      BeanHandler handler = new BeanHandler(beanInfo.getName(), beanAdapterFactory);
      typeBinding.setHandler(handler);
      if (trace)
         log.trace("Created BeanHandler for type=" + beanInfo.getName() + " factory=" + factory);

      // Look through the properties
      JBossXmlNoElements jbossXmlNoElements = typeInfo.getUnderlyingAnnotation(JBossXmlNoElements.class);
      boolean noElements = jbossXmlNoElements != null;
      PropertyInfo valueProperty = null;
      PropertyInfo wildcardProperty = null;
      boolean allBinding = propertyOrder.length == 0;
      boolean determinePropertyOrder = allBinding || (propertyOrder.length == 1 && propertyOrder[0].length() == 0);
      ArrayList<String> propertyNames = new ArrayList<String>();
      Set<PropertyInfo> properties = beanInfo.getProperties();
      if (properties != null && properties.isEmpty() == false)
      {
         boolean seenXmlAnyElement = false;
         for (PropertyInfo property : properties)
         {
            push(typeInfo, property.getName());

            if (trace)
               log.trace("Checking property " + property.getName() + " for " + beanInfo.getName() + " type=" + property.getType().getName());

            // Is this the value property?
            XmlValue xmlValue = property.getUnderlyingAnnotation(XmlValue.class);
            if (xmlValue != null)
            {
               if (trace)
                  log.trace("Seen @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
               if (valueProperty != null)
                  throw new RuntimeException("@XmlValue seen on two properties: " + property.getName() + " and " + valueProperty.getName());
               valueProperty = property;
            }

            // Is this the wildcard property?
            boolean ignoreXmlAnyElement = false;
            XmlAnyElement xmlAnyElement = property.getUnderlyingAnnotation(XmlAnyElement.class);
            if (xmlAnyElement != null)
            {
               if (trace)
                  log.trace("Seen @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
               if (wildcardProperty != null && seenXmlAnyElement)
                  throw new RuntimeException("@XmlAnyElement seen on two properties: " + property.getName() + " and " + wildcardProperty.getName());
               wildcardProperty = property;
               seenXmlAnyElement = true;
              
               // should we ignore it
               if(property.getUnderlyingAnnotation(XmlElements.class) == null &&
                  property.getUnderlyingAnnotation(XmlElementRefs.class) == null)
                  ignoreXmlAnyElement = true;
            }
            else if (!seenXmlAnyElement && wildcardProperty == null && property.getType().getName().equals(org.w3c.dom.Element.class.getName()))
            {
               if (trace)
                  log.trace("Using type=" + beanInfo.getName() + " property=" + property.getName() + " as the base wildcard");
               if (wildcardProperty != null)
                  throw new RuntimeException("@XmlAnyElement seen on two properties: " + property.getName() + " and " + wildcardProperty.getName());
               wildcardProperty = property;
            }

            // Is this an attribute
            XmlAttribute xmlAttribute = property.getUnderlyingAnnotation(XmlAttribute.class);
            if (xmlAttribute != null)
            {
               JBossXmlAttribute jbossXmlAttribute = property.getUnderlyingAnnotation(JBossXmlAttribute.class);
               // Determine the name
               QName qName = generateXmlName(property.getName(), attributeForm, xmlAttribute.namespace(), xmlAttribute.name());
               // Resolve the type
               TypeInfo attributeTypeInfo = property.getType();
               if (jbossXmlAttribute != null && jbossXmlAttribute.type() != Object.class)
                  attributeTypeInfo = attributeTypeInfo.getTypeInfoFactory().getTypeInfo(jbossXmlAttribute.type());
               TypeBinding attributeType = resolveTypeBinding(attributeTypeInfo);
               // Create the attribute handler
               AttributeHandler attributeHandler = new PropertyHandler(property, attributeTypeInfo);
               // Create the attributre and bind it to the type
               AttributeBinding attribute = new AttributeBinding(schemaBinding, qName, attributeType, attributeHandler);
               attribute.setRequired(xmlAttribute.required());
               typeBinding.addAttribute(attribute);
               if (trace)
                  log.trace("Bound attribute " + qName + " type=" + beanInfo.getName() + " property=" + property.getName() + " propertyType=" + attributeTypeInfo);
            }

            // Are we determining the property order?
            if (determinePropertyOrder)
            {
               // Value property
               if (xmlValue != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Wildcard property
               if (ignoreXmlAnyElement)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore xml attribute
               if (xmlAttribute != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlAttribute for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore xml tranient
               XmlTransient xmlTransient = property.getUnderlyingAnnotation(XmlTransient.class);
               if (xmlTransient != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlTransient for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore the class property
               String name = property.getName();
               if ("class".equals(name))
               {
                  pop();
                  continue;
               }

               if (noElements)
               {
                  pop();
                  continue;
               }

               if (trace)
                  log.trace("Element for type=" + beanInfo.getName() + " property=" + property.getName());
               propertyNames.add(property.getName());
            }

            pop();
         }
         // Apply any access order
         if (determinePropertyOrder)
         {
            if (accessOrder == XmlAccessOrder.ALPHABETICAL)
               Collections.sort(propertyNames);
            propertyOrder = propertyNames.toArray(new String[propertyNames.size()]);
         }
      }

      // No value property, see if we have a default one
      //if (valueProperty == null)
      //{
      //   try
      //   {
      //      valueProperty = beanInfo.getProperty("value");
      //   }
      //   catch (Exception ignored)
      //   {
            // Nope.
      //   }
      //}

      // Bind the value
      if (valueProperty != null)
      {
         CharactersHandler charactersHandler = new ValueHandler(valueProperty);
         typeBinding.setSimpleType(charactersHandler);
      }
      else if (trace)
         log.trace("No value for type=" + beanInfo.getName());

      if (trace)
         log.trace("PropertyOrder " + Arrays.asList(propertyOrder) + " for type=" + beanInfo.getName());

      // Determine the model
      // TODO simple types/content when no properties other than @XmlValue and @XmlAttribute
      typeBinding.setSimple(false);
      ModelGroupBinding model = null;
      if (allBinding)
      {
         if (trace)
            log.trace("AllBinding for type=" + beanInfo.getName());
         model = new AllBinding(schemaBinding);
      }
      else
      {
         if (trace)
            log.trace("SequenceBinding for type=" + beanInfo.getName());
         model = new SequenceBinding(schemaBinding);
      }
      model.setHandler(BuilderParticleHandler.INSTANCE);
      ParticleBinding typeParticle = new ParticleBinding(model);
      typeParticle.setMinOccurs(1);
      typeParticle.setMaxOccurs(1);
      typeBinding.setParticle(typeParticle);

      if (typeInfo.isCollection())
      {
         typeParticle.setMinOccurs(0);
         typeParticle.setMaxOccursUnbounded(true);
         TypeInfo memberBaseType = typeInfo.getComponentType();
         JBossXmlModelGroup xmlModelGroup = ((ClassInfo) memberBaseType)
               .getUnderlyingAnnotation(JBossXmlModelGroup.class);
         if (xmlModelGroup != null && xmlModelGroup.particles().length > 0)
         {
            if (trace)
               log.trace("Item base type for " + typeInfo.getName() + " is " + memberBaseType.getName()
                     + " and bound to repeatable choice");

            // it's choice by default based on the idea that the
            // type parameter is a base class for items
            ModelGroupBinding choiceGroup = null;
            QName choiceName = null;
            if(!JBossXmlConstants.DEFAULT.equals(xmlModelGroup.name()))
            {
               choiceName = new QName(defaultNamespace, xmlModelGroup.name());
               choiceGroup = schemaBinding.getGroup(choiceName);
            }
           
            if(choiceGroup == null)
            {
               choiceGroup = new ChoiceBinding(schemaBinding);
               choiceGroup.setHandler(BuilderParticleHandler.INSTANCE);
               if (choiceName != null)
               {
                  choiceGroup.setQName(choiceName);
                  schemaBinding.addGroup(choiceGroup.getQName(), choiceGroup);
               }

               ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
               model.addParticle(choiceParticle);

               for (JBossXmlModelGroup.Particle member : xmlModelGroup.particles())
               {
                  XmlElement element = member.element();
                  QName memberQName = generateXmlName(element.name(), XmlNsForm.QUALIFIED, element.namespace(), null);
                  TypeInfo memberTypeInfo = typeInfo.getTypeInfoFactory().getTypeInfo(member.type());

                  boolean isCol = false;
                  if (memberTypeInfo.isCollection())
                  {
                     memberTypeInfo = ((ClassInfo) memberTypeInfo).getComponentType();
                     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.pushInterceptor(memberQName, ChildCollectionInterceptor.SINGLETON);
               }
            }
            else
            {
               ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
               model.addParticle(choiceParticle);
            }
           
            if (trace)
               log.trace("choices for " + typeBinding.getQName() + ": " + choiceGroup.getParticles());
         }
      }

      // Determine the wildcard handler
      AbstractPropertyHandler wildcardHandler = null;
      if (wildcardProperty != null)
      {
         TypeInfo wildcardType = wildcardProperty.getType();
         if (wildcardType.isCollection())
            wildcardHandler = new CollectionPropertyWildcardHandler(wildcardProperty, wildcardType);
         else
            wildcardHandler = new PropertyWildcardHandler(wildcardProperty, wildcardType);
      }

      // Look through the properties
      for (String name : propertyOrder)
      {
         // Setup the error stack
         push(typeInfo, name);
         // Get the property
         PropertyInfo property = beanInfo.getProperty(name);
         bindProperty(property, typeBinding, model, beanAdapterFactory, propertyOrder);
         pop();
      }

      // Bind the children
      JBossXmlChild[] children = null;
      JBossXmlChildren jbossXmlChildren = typeInfo.getUnderlyingAnnotation(JBossXmlChildren.class);
      if (jbossXmlChildren != null)
         children = jbossXmlChildren.value();
      else
      {
         JBossXmlChild jbossXmlChild = typeInfo.getUnderlyingAnnotation(JBossXmlChild.class);
         if (jbossXmlChild != null)
            children = new JBossXmlChild[] { jbossXmlChild };
      }

      if (children != null && children.length > 0)
      {
         for (JBossXmlChild child : children)
         {
            QName qName = generateXmlName(child.name(), elementForm, child.namespace(), child.name());
            TypeInfo childType = JBossXBBuilder.configuration.getTypeInfo(child.type());

            TypeBinding elementTypeBinding = resolveTypeBinding(childType);
            ElementBinding elementBinding = createElementBinding(childType, elementTypeBinding, qName, false);

            // Bind it to the model
            ParticleBinding particle = new ParticleBinding(elementBinding, child.minOccurs(), child.maxOccurs(), child.unbounded());
            model.addParticle(particle);

            if(childType.isMap())
               bindMapProperty(null, (ClassInfo) childType, elementTypeBinding.getQName(), (ModelGroupBinding) elementTypeBinding.getParticle().getTerm());
           
            DefaultElementInterceptor interceptor = null;
            if (typeInfo.isCollection())
               interceptor = ChildCollectionInterceptor.SINGLETON;
            else
            {
               // Expect a type with a value property to accept the child value
               PropertyInfo property = beanInfo.getProperty("value");
               if (property == null)
                  throw new UnsupportedOperationException("Expected a value property for non-collection type with JBossXmlChildren");
               TypeInfo propertyType = property.getType();
               interceptor = new PropertyInterceptor(property, propertyType);
            }
            typeBinding.pushInterceptor(qName, interceptor);
            if (trace)
               log.trace("Added interceptor " + qName + " for type=" + childType + " interceptor=" + interceptor);
         }
      }

      // Bind the wildcard
      if (wildcardProperty != null)
      {
         if (trace)
            log.trace("Processing WildcardProperty for type=" + beanInfo.getName() + " property=" + wildcardProperty.getName());
         ModelGroupBinding localModel = model;
         TypeInfo wildcardType = wildcardProperty.getType();
         TypeInfo type = wildcardType;

         // Setup any new model and determine the wildcard type
         if (wildcardType.isArray())
         {
            localModel = createArray(localModel);
            type = ((ArrayInfo) wildcardType).getComponentType();
            if (trace)
               log.trace("Wildcard " + wildcardProperty.getName() + " is an array of type " + type.getName());
         }
         else if (wildcardType.isCollection())
         {
            localModel = createCollection(localModel);
            type = ((ClassInfo)wildcardProperty.getType()).getComponentType();
            if (trace)
               log.trace("Wildcard " + wildcardProperty.getName() + " is a collection of type " + type.getName());
         }

         XmlAnyElement xmlAnyElement = wildcardProperty.getUnderlyingAnnotation(XmlAnyElement.class);
         boolean isLax = xmlAnyElement == null ? true : xmlAnyElement.lax();
         WildcardBinding wildcard = new WildcardBinding(schemaBinding);
         if (isLax)
            wildcard.setProcessContents((short) 3); // Lax
         else
            wildcard.setProcessContents((short) 1); // Strict

         // Dom element?
         if (Element.class.getName().equals(type.getName()))
         {
            wildcard.setUnresolvedElementHandler(DOMHandler.INSTANCE);
            wildcard.setUnresolvedCharactersHandler(DOMHandler.INSTANCE);
         }

         // Bind the particle to the model
         ParticleBinding particleBinding = new ParticleBinding(wildcard);
         particleBinding.setMinOccurs(0);
         particleBinding.setMaxOccurs(1);
         localModel.addParticle(particleBinding);
         typeBinding.getWildcard().setWildcardHandler((ParticleHandler) wildcardHandler);
         beanAdapterFactory.setWildcardHandler(wildcardHandler);
      }

      JBossXmlChildWildcard childWildcard = typeInfo.getUnderlyingAnnotation(JBossXmlChildWildcard.class);
      if (childWildcard != null)
      {
         if (beanAdapterFactory.getWildcardHandler() != null)
            throw new RuntimeException("Cannot have both @JBossXmlChildWildcard and @XmlAnyElement");

         ParticleHandler childWildcardHandler = null;
         if (typeInfo.isCollection())
         {
View Full Code Here

               propertyGroup.setSkip(Boolean.FALSE);

               // handler for the model group members
               BeanInfo propBeanInfo = JBossXBBuilder.configuration.getBeanInfo(propClassInfo);
               BeanAdapterFactory propBeanAdapterFactory = createAdapterFactory(DefaultBeanAdapterBuilder.class, propBeanInfo, null);
               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 = ((ClassInfo) memberTypeInfo).getComponentType();
                     }
                  }
                  // if it is bound with XmlElement.type to a collection
                  else if (memberTypeInfo.isCollection())
                  {
                     memberPropertyHandler = new CollectionPropertyHandler(memberProp, memberTypeInfo);
                     isCol = true;
                     memberTypeInfo = ((ClassInfo) memberTypeInfo).getComponentType();
                  }
                  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();
         QName wrapperQName = generateXmlName(property.getName(), elementForm, wrapperNamespace, wrapperName);
         localModel = bindXmlElementWrapper(propertyType, localModel, xmlWrapper.nillable(), wrapperQName);
         beanAdapterFactory.addProperty(wrapperQName, new PropertyHandler(property, propertyType));
         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 propertyQName = 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();
               JBossXmlGroupText groupText = ((ClassInfo) propertyType).getUnderlyingAnnotation(JBossXmlGroupText.class);
               if (groupText != null && groupText.wrapper() != Object.class)
               {
                  BeanInfo wrapperInfo = JBossXBBuilder.configuration.getBeanInfo(groupText.wrapper());
                  TypeBinding wrapperTypeBinding = resolveTypeBinding(wrapperInfo.getClassInfo());
                  // Steal the attributes
                  Collection<AttributeBinding> otherAttributes = wrapperTypeBinding.getAttributes();
                  if (otherAttributes != null)
                  {
                     for (AttributeBinding other : otherAttributes)
                        elementTypeBinding.addAttribute(other);
                  }
                  ParticleHandler particleHandler = wrapperTypeBinding.getHandler();
                  if (particleHandler instanceof BeanHandler == false)
                     throw new IllegalStateException("Cannot wrap " + wrapperInfo.getName() + " not a bean type " + particleHandler);
                  BeanHandler beanHandler = (BeanHandler) particleHandler;
                  WrapperBeanAdapterFactory wrapperFactory = new WrapperBeanAdapterFactory(beanHandler.getBeanAdapterFactory(), propertyType.getType());
                  elementTypeBinding.setHandler(new BeanHandler(wrapperInfo.getName(), wrapperFactory));
                  elementTypeBinding.setSimpleType(wrapperTypeBinding.getSimpleType());
               }
               else
               {
                  elementTypeBinding.setHandler(BuilderParticleHandler.INSTANCE);
               }
               elementTypeBinding.setSchemaBinding(schemaBinding);
               ElementBinding elementBinding = createElementBinding(localPropertyType, elementTypeBinding, propertyQName, false);

               // Bind it to the model
               ParticleBinding particle = new ParticleBinding(elementBinding, 1, 1, false);
               if (required == false)
                  particle.setMinOccurs(0);
               localModel.addParticle(particle);

               // 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);

                  if(childType.isMap())
                     bindMapProperty(property, (ClassInfo) childType, childName, (ModelGroupBinding) childTypeBinding.getParticle().getTerm());
                                   
                  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 + " " + childType.getName());

                  beanAdapterFactory.addProperty(propertyQName, new PropertyHandler(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;
            boolean isMap = 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);
               // here we get the comp type based on the non-overriden property type...
               // which feels like a weak point
               TypeInfo typeArg = ((ClassInfo)property.getType()).getComponentType();

               if (typeArg != null && ((ClassInfo)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)
            {
               if (valueAdapter != null)
               {
                  propertyHandler = new PropertyHandler(property, localPropertyType);
               }
               else
               {
                  propertyHandler = new CollectionPropertyHandler(property, localPropertyType);
               }
               isCol = true;
               localPropertyType = ((ClassInfo)localPropertyType).getComponentType();
            }
            else if (localPropertyType.isMap())
            {
               TypeBinding wrapperType = null;
               if(elements.length > 1)
               {
                  wrapperType = resolveTypeBinding(localPropertyType);
                  ElementBinding elementBinding = createElementBinding(localPropertyType, wrapperType, propertyQName, false);
                  elementBinding.setNillable(nillable);
                  elementBinding.setValueAdapter(valueAdapter);

                  // Bind it to the model
                  ParticleBinding particle = new ParticleBinding(elementBinding, 0, 1, isCol);
                  if (required == false)
                     particle.setMinOccurs(0);

                  targetGroup.addParticle(particle);
                  targetGroup = (ModelGroupBinding) wrapperType.getParticle().getTerm();
               }
              
               QName boundQName = bindMapProperty(property, (ClassInfo) localPropertyType, propertyQName, targetGroup);
               if(boundQName != null)
               {
                  if(wrapperType != null)
                  {
                     BeanAdapterFactory wrapperBeanFactory = ((BeanHandler)wrapperType.getHandler()).getBeanAdapterFactory();
                     Map<QName, AbstractPropertyHandler> properties = wrapperBeanFactory.getProperties();
                     if(!properties.containsKey(boundQName))
                     {
                        propertyHandler = new MapPropertyHandler(JBossXBBuilder.configuration, property, localPropertyType, true);
                        wrapperBeanFactory.addProperty(boundQName, propertyHandler);
                     }
                     propertyHandler = new PropertyHandler(property, localPropertyType);
                  }
                  else
                  {
View Full Code Here

         TypeInfo keyType = propType.getKeyType();
         TypeInfo valueType = propType.getValueType();

         // entry handler
         BeanAdapterFactory entryAdapterFactory = null;
         BeanInfo entryInfo = JBossXBBuilder.configuration.getBeanInfo(DefaultMapEntry.class);
         entryAdapterFactory = createAdapterFactory(DefaultBeanAdapterBuilder.class, entryInfo, null);
         BeanHandler entryHandler = new BeanHandler(entryInfo.getName(), entryAdapterFactory);

         TypeBinding entryType = null;
         TypeInfo entryTypeInfo = null;

         // bind the entry element if present
         if(entryElement != null && !JBossXmlConstants.DEFAULT.equals(entryElement.name()))
         {
            String ns = entryElement.namespace();
            if(JBossXmlConstants.DEFAULT.equals(ns))
               ns = defaultNamespace;                 
            QName entryName = new QName(ns, entryElement.name());

            entryType = new TypeBinding();
            entryType.setSchemaBinding(schemaBinding);
            entryType.setHandler(entryHandler);

            entryTypeInfo = JBossXBBuilder.configuration.getTypeInfo(DefaultMapEntry.class);                    
            ElementBinding entryElementBinding = createElementBinding(entryTypeInfo, entryType, entryName, false);
            ParticleBinding entryParticle = new ParticleBinding(entryElementBinding, 0, -1, true);
            targetGroup.addParticle(entryParticle);
              
            propertyQName = entryName;
              
            if(keyAttribute != null)
            {
               TypeBinding attributeType = resolveTypeBinding(keyType);
               AttributeHandler attributeHandler = new PropertyHandler(entryInfo.getProperty("key"), keyType);
               QName attrQName = generateXmlName(keyType, attributeForm, keyAttribute.namespace(), keyAttribute.name());
               AttributeBinding keyBinding = new AttributeBinding(schemaBinding, attrQName, attributeType, attributeHandler);
               keyBinding.setRequired(true);
               entryType.addAttribute(keyBinding);
            }

            if(valueAttribute != null)
            {
               TypeBinding attributeType = resolveTypeBinding(valueType);
               AttributeHandler attributeHandler = new PropertyHandler(entryInfo.getProperty("value"), valueType);
               QName attrQName = generateXmlName(valueType, attributeForm, valueAttribute.namespace(), valueAttribute.name());
               AttributeBinding valueBinding = new AttributeBinding(schemaBinding, attrQName, attributeType, attributeHandler);
               valueBinding.setRequired(true);
               entryType.addAttribute(valueBinding);
            }
            else if(valueElement == null)
            {
               CharactersHandler charactersHandler = new ValueHandler(entryInfo.getProperty("value"), valueType);
               entryType.setSimpleType(charactersHandler);
            }
         }
        
         SequenceBinding keyValueSequence = null;
         if(keyElement != null)
         {
            keyValueSequence = new SequenceBinding(schemaBinding);                    
            if(entryType == null)
            {
               keyValueSequence.setSkip(Boolean.FALSE);
               keyValueSequence.setQName(propertyQName);
               schemaBinding.addGroup(keyValueSequence.getQName(), keyValueSequence);
               ParticleBinding keyValueParticle = new ParticleBinding(keyValueSequence, 0, -1, true);
               targetGroup.addParticle(keyValueParticle);
               keyValueSequence.setHandler(entryHandler);
            }
            else
            {
               ParticleBinding keyValueParticle = new ParticleBinding(keyValueSequence, 1, 1, false);
               entryType.setParticle(keyValueParticle);
            }
           
            // key element
            TypeBinding keyTypeBinding = resolveTypeBinding(keyType);                 
            String keyNs = keyElement.namespace();
            if(JBossXmlConstants.DEFAULT.equals(keyNs))
               keyNs = defaultNamespace;                 
            ElementBinding keyElementBinding = createElementBinding(keyType, keyTypeBinding, new QName(keyNs, keyElement.name()), false);
            ParticleBinding particle = new ParticleBinding(keyElementBinding, 1, 1, false);
            keyValueSequence.addParticle(particle);
            PropertyHandler keyHandler = new PropertyHandler(entryInfo.getProperty("key"), keyType);
            entryAdapterFactory.addProperty(keyElementBinding.getQName(), keyHandler);
         }
        
         if(valueElement != null)
         {
            TypeBinding valueTypeBinding = resolveTypeBinding(valueType);                 
            String valueNs = valueElement.namespace();
            if(JBossXmlConstants.DEFAULT.equals(valueNs))
               valueNs = defaultNamespace;                 
            ElementBinding valueElementBinding = createElementBinding(valueType, valueTypeBinding, new QName(valueNs, valueElement.name()), false);
            ParticleBinding particle = new ParticleBinding(valueElementBinding, 1, 1, false);
            keyValueSequence.addParticle(particle);
            PropertyHandler valueHandler = new PropertyHandler(entryInfo.getProperty("value"), valueType);
            entryAdapterFactory.addProperty(valueElementBinding.getQName(), valueHandler);
         }

         // TODO: need to verify correct binding before proceeding
         boundQName = propertyQName;
      }
View Full Code Here

      if (factoryMethod != null && factoryMethod.length() > 0)
         factory = Config.findMethodInfo(factoryClassInfo, factoryMethod, null, true, true);

      // Create the handler
      BeanInfo beanInfo = JBossXBBuilder.configuration.getBeanInfo(typeInfo);
      BeanAdapterFactory beanAdapterFactory = createAdapterFactory(beanAdapterBuilderClass, beanInfo, factory);
      BeanHandler handler = new BeanHandler(beanInfo.getName(), beanAdapterFactory);
      typeBinding.setHandler(handler);
      if (trace)
         log.trace("Created BeanHandler for type=" + beanInfo.getName() + " factory=" + factory);

      // Look through the properties
      JBossXmlNoElements jbossXmlNoElements = typeInfo.getUnderlyingAnnotation(JBossXmlNoElements.class);
      boolean noElements = jbossXmlNoElements != null;
      PropertyInfo valueProperty = null;
      PropertyInfo wildcardProperty = null;
      boolean allBinding = propertyOrder.length == 0;
      boolean determinePropertyOrder = allBinding || (propertyOrder.length == 1 && propertyOrder[0].length() == 0);
      ArrayList<String> propertyNames = new ArrayList<String>();
      Set<PropertyInfo> properties = beanInfo.getProperties();
      if (properties != null && properties.isEmpty() == false)
      {
         boolean seenXmlAnyElement = false;
         for (PropertyInfo property : properties)
         {
            push(typeInfo, property.getName());

            if (trace)
               log.trace("Checking property " + property.getName() + " for " + beanInfo.getName() + " type=" + property.getType().getName());

            // Is this the value property?
            XmlValue xmlValue = property.getUnderlyingAnnotation(XmlValue.class);
            if (xmlValue != null)
            {
               if (trace)
                  log.trace("Seen @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
               if (valueProperty != null)
                  throw new RuntimeException("@XmlValue seen on two properties: " + property.getName() + " and " + valueProperty.getName());
               valueProperty = property;
            }

            // Is this the wildcard property?
            boolean ignoreXmlAnyElement = false;
            XmlAnyElement xmlAnyElement = property.getUnderlyingAnnotation(XmlAnyElement.class);
            if (xmlAnyElement != null)
            {
               if (trace)
                  log.trace("Seen @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
               if (wildcardProperty != null && seenXmlAnyElement)
                  throw new RuntimeException("@XmlAnyElement seen on two properties: " + property.getName() + " and " + wildcardProperty.getName());
               wildcardProperty = property;
               seenXmlAnyElement = true;
              
               // should we ignore it
               if(property.getUnderlyingAnnotation(XmlElements.class) == null &&
                  property.getUnderlyingAnnotation(XmlElementRefs.class) == null)
                  ignoreXmlAnyElement = true;
            }
            else if (!seenXmlAnyElement && wildcardProperty == null && property.getType().getName().equals(org.w3c.dom.Element.class.getName()))
            {
               if (trace)
                  log.trace("Using type=" + beanInfo.getName() + " property=" + property.getName() + " as the base wildcard");
               if (wildcardProperty != null)
                  throw new RuntimeException("@XmlAnyElement seen on two properties: " + property.getName() + " and " + wildcardProperty.getName());
               wildcardProperty = property;
            }

            // Is this an attribute
            XmlAttribute xmlAttribute = property.getUnderlyingAnnotation(XmlAttribute.class);
            if (xmlAttribute != null)
            {
               JBossXmlAttribute jbossXmlAttribute = property.getUnderlyingAnnotation(JBossXmlAttribute.class);
               // Determine the name
               QName qName = generateXmlName(property.getName(), attributeForm, xmlAttribute.namespace(), xmlAttribute.name());
               // Resolve the type
               TypeInfo attributeTypeInfo = property.getType();
               if (jbossXmlAttribute != null && jbossXmlAttribute.type() != Object.class)
                  attributeTypeInfo = attributeTypeInfo.getTypeInfoFactory().getTypeInfo(jbossXmlAttribute.type());
               TypeBinding attributeType = resolveTypeBinding(attributeTypeInfo);
               // Create the attribute handler
               AttributeHandler attributeHandler = new PropertyHandler(property, attributeTypeInfo);
               // Create the attributre and bind it to the type
               AttributeBinding attribute = new AttributeBinding(schemaBinding, qName, attributeType, attributeHandler);
               attribute.setRequired(xmlAttribute.required());
               typeBinding.addAttribute(attribute);
               if (trace)
                  log.trace("Bound attribute " + qName + " type=" + beanInfo.getName() + " property=" + property.getName() + " propertyType=" + attributeTypeInfo);
            }

            // Are we determining the property order?
            if (determinePropertyOrder)
            {
               // Value property
               if (xmlValue != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Wildcard property
               if (ignoreXmlAnyElement)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore xml attribute
               if (xmlAttribute != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlAttribute for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore xml tranient
               XmlTransient xmlTransient = property.getUnderlyingAnnotation(XmlTransient.class);
               if (xmlTransient != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlTransient for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore the class property
               String name = property.getName();
               if ("class".equals(name))
               {
                  pop();
                  continue;
               }

               if (noElements)
               {
                  pop();
                  continue;
               }

               if (trace)
                  log.trace("Element for type=" + beanInfo.getName() + " property=" + property.getName());
               propertyNames.add(property.getName());
            }

            pop();
         }
         // Apply any access order
         if (determinePropertyOrder)
         {
            if (accessOrder == XmlAccessOrder.ALPHABETICAL)
               Collections.sort(propertyNames);
            propertyOrder = propertyNames.toArray(new String[propertyNames.size()]);
         }
      }

      // No value property, see if we have a default one
      //if (valueProperty == null)
      //{
      //   try
      //   {
      //      valueProperty = beanInfo.getProperty("value");
      //   }
      //   catch (Exception ignored)
      //   {
            // Nope.
      //   }
      //}

      // Bind the value
      if (valueProperty != null)
      {
         CharactersHandler charactersHandler = new ValueHandler(valueProperty);
         typeBinding.setSimpleType(charactersHandler);
      }
      else if (trace)
         log.trace("No value for type=" + beanInfo.getName());

      if (trace)
         log.trace("PropertyOrder " + Arrays.asList(propertyOrder) + " for type=" + beanInfo.getName());

      // Determine the model
      // TODO simple types/content when no properties other than @XmlValue and @XmlAttribute
      typeBinding.setSimple(false);
      ModelGroupBinding model = null;
      if (allBinding)
      {
         if (trace)
            log.trace("AllBinding for type=" + beanInfo.getName());
         model = new AllBinding(schemaBinding);
      }
      else
      {
         if (trace)
            log.trace("SequenceBinding for type=" + beanInfo.getName());
         model = new SequenceBinding(schemaBinding);
      }
      model.setHandler(BuilderParticleHandler.INSTANCE);
      ParticleBinding typeParticle = new ParticleBinding(model);
      typeParticle.setMinOccurs(1);
      typeParticle.setMaxOccurs(1);
      typeBinding.setParticle(typeParticle);

      if (typeInfo.isCollection())
      {
         typeParticle.setMinOccurs(0);
         typeParticle.setMaxOccursUnbounded(true);
         TypeInfo memberBaseType = typeInfo.getComponentType();
         JBossXmlModelGroup xmlModelGroup = ((ClassInfo) memberBaseType)
               .getUnderlyingAnnotation(JBossXmlModelGroup.class);
         if (xmlModelGroup != null && xmlModelGroup.particles().length > 0)
         {
            if (trace)
               log.trace("Item base type for " + typeInfo.getName() + " is " + memberBaseType.getName()
                     + " and bound to repeatable choice");

            // it's choice by default based on the idea that the
            // type parameter is a base class for items
            ModelGroupBinding choiceGroup = null;
            QName choiceName = null;
            if(!JBossXmlConstants.DEFAULT.equals(xmlModelGroup.name()))
            {
               choiceName = new QName(defaultNamespace, xmlModelGroup.name());
               choiceGroup = schemaBinding.getGroup(choiceName);
            }
           
            if(choiceGroup == null)
            {
               choiceGroup = new ChoiceBinding(schemaBinding);
               choiceGroup.setHandler(BuilderParticleHandler.INSTANCE);
               if (choiceName != null)
               {
                  choiceGroup.setQName(choiceName);
                  schemaBinding.addGroup(choiceGroup.getQName(), choiceGroup);
               }

               ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
               model.addParticle(choiceParticle);

               for (JBossXmlModelGroup.Particle member : xmlModelGroup.particles())
               {
                  XmlElement element = member.element();
                  QName memberQName = generateXmlName(element.name(), XmlNsForm.QUALIFIED, element.namespace(), null);
                  TypeInfo memberTypeInfo = typeInfo.getTypeInfoFactory().getTypeInfo(member.type());

                  boolean isCol = false;
                  if (memberTypeInfo.isCollection())
                  {
                     memberTypeInfo = ((ClassInfo) memberTypeInfo).getComponentType();
                     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.pushInterceptor(memberQName, ChildCollectionInterceptor.SINGLETON);
               }
            }
            else
            {
               ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
               model.addParticle(choiceParticle);
            }
           
            if (trace)
               log.trace("choices for " + typeBinding.getQName() + ": " + choiceGroup.getParticles());
         }
      }

      // Determine the wildcard handler
      AbstractPropertyHandler wildcardHandler = null;
      if (wildcardProperty != null)
      {
         TypeInfo wildcardType = wildcardProperty.getType();
         if (wildcardType.isCollection())
            wildcardHandler = new CollectionPropertyWildcardHandler(wildcardProperty, wildcardType);
         else
            wildcardHandler = new PropertyWildcardHandler(wildcardProperty, wildcardType);
      }

      // Look through the properties
      for (String name : propertyOrder)
      {
         // Setup the error stack
         push(typeInfo, name);
         // Get the property
         PropertyInfo property = beanInfo.getProperty(name);
         bindProperty(property, typeBinding, model, beanAdapterFactory, propertyOrder);
         pop();
      }

      // Bind the children
      JBossXmlChild[] children = null;
      JBossXmlChildren jbossXmlChildren = typeInfo.getUnderlyingAnnotation(JBossXmlChildren.class);
      if (jbossXmlChildren != null)
         children = jbossXmlChildren.value();
      else
      {
         JBossXmlChild jbossXmlChild = typeInfo.getUnderlyingAnnotation(JBossXmlChild.class);
         if (jbossXmlChild != null)
            children = new JBossXmlChild[] { jbossXmlChild };
      }

      if (children != null && children.length > 0)
      {
         for (JBossXmlChild child : children)
         {
            QName qName = generateXmlName(child.name(), elementForm, child.namespace(), child.name());
            TypeInfo childType = JBossXBBuilder.configuration.getTypeInfo(child.type());

            TypeBinding elementTypeBinding = resolveTypeBinding(childType);
            ElementBinding elementBinding = createElementBinding(childType, elementTypeBinding, qName, false);

            // Bind it to the model
            ParticleBinding particle = new ParticleBinding(elementBinding, child.minOccurs(), child.maxOccurs(), child.unbounded());
            model.addParticle(particle);

            if(childType.isMap())
               bindMapProperty(null, (ClassInfo) childType, elementTypeBinding.getQName(), (ModelGroupBinding) elementTypeBinding.getParticle().getTerm());
           
            DefaultElementInterceptor interceptor = null;
            if (typeInfo.isCollection())
               interceptor = ChildCollectionInterceptor.SINGLETON;
            else
            {
               // Expect a type with a value property to accept the child value
               PropertyInfo property = beanInfo.getProperty("value");
               if (property == null)
                  throw new UnsupportedOperationException("Expected a value property for non-collection type with JBossXmlChildren");
               TypeInfo propertyType = property.getType();
               interceptor = new PropertyInterceptor(property, propertyType);
            }
            typeBinding.pushInterceptor(qName, interceptor);
            if (trace)
               log.trace("Added interceptor " + qName + " for type=" + childType + " interceptor=" + interceptor);
         }
      }

      // Bind the wildcard
      if (wildcardProperty != null)
      {
         if (trace)
            log.trace("Processing WildcardProperty for type=" + beanInfo.getName() + " property=" + wildcardProperty.getName());
         ModelGroupBinding localModel = model;
         TypeInfo wildcardType = wildcardProperty.getType();
         TypeInfo type = wildcardType;

         // Setup any new model and determine the wildcard type
         if (wildcardType.isArray())
         {
            localModel = createArray(localModel);
            type = ((ArrayInfo) wildcardType).getComponentType();
            if (trace)
               log.trace("Wildcard " + wildcardProperty.getName() + " is an array of type " + type.getName());
         }
         else if (wildcardType.isCollection())
         {
            localModel = createCollection(localModel);
            type = ((ClassInfo)wildcardProperty.getType()).getComponentType();
            if (trace)
               log.trace("Wildcard " + wildcardProperty.getName() + " is a collection of type " + type.getName());
         }

         XmlAnyElement xmlAnyElement = wildcardProperty.getUnderlyingAnnotation(XmlAnyElement.class);
         boolean isLax = xmlAnyElement == null ? true : xmlAnyElement.lax();
         WildcardBinding wildcard = new WildcardBinding(schemaBinding);
         if (isLax)
            wildcard.setProcessContents((short) 3); // Lax
         else
            wildcard.setProcessContents((short) 1); // Strict

         // Dom element?
         if (Element.class.getName().equals(type.getName()))
         {
            wildcard.setUnresolvedElementHandler(DOMHandler.INSTANCE);
            wildcard.setUnresolvedCharactersHandler(DOMHandler.INSTANCE);
         }

         // Bind the particle to the model
         ParticleBinding particleBinding = new ParticleBinding(wildcard);
         particleBinding.setMinOccurs(0);
         particleBinding.setMaxOccurs(1);
         localModel.addParticle(particleBinding);
         typeBinding.getWildcard().setWildcardHandler((ParticleHandler) wildcardHandler);
         beanAdapterFactory.setWildcardHandler(wildcardHandler);
      }

      JBossXmlChildWildcard childWildcard = typeInfo.getUnderlyingAnnotation(JBossXmlChildWildcard.class);
      if (childWildcard != null)
      {
         if (beanAdapterFactory.getWildcardHandler() != null)
            throw new RuntimeException("Cannot have both @JBossXmlChildWildcard and @XmlAnyElement");

         ParticleHandler childWildcardHandler = null;
         if (typeInfo.isCollection())
         {
View Full Code Here

               propertyGroup.setSkip(Boolean.FALSE);

               // handler for the model group members
               BeanInfo propBeanInfo = JBossXBBuilder.configuration.getBeanInfo(propClassInfo);
               BeanAdapterFactory propBeanAdapterFactory = createAdapterFactory(DefaultBeanAdapterBuilder.class, propBeanInfo, null);
               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 = ((ClassInfo) memberTypeInfo).getComponentType();
                     }
                  }
                  // if it is bound with XmlElement.type to a collection
                  else if (memberTypeInfo.isCollection())
                  {
                     memberPropertyHandler = new CollectionPropertyHandler(memberProp, memberTypeInfo);
                     isCol = true;
                     memberTypeInfo = ((ClassInfo) memberTypeInfo).getComponentType();
                  }
                  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();
         QName wrapperQName = generateXmlName(property.getName(), elementForm, wrapperNamespace, wrapperName);
         localModel = bindXmlElementWrapper(propertyType, localModel, xmlWrapper.nillable(), wrapperQName);
         beanAdapterFactory.addProperty(wrapperQName, new PropertyHandler(property, propertyType));
         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 propertyQName = 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();
               JBossXmlGroupText groupText = ((ClassInfo) propertyType).getUnderlyingAnnotation(JBossXmlGroupText.class);
               if (groupText != null && groupText.wrapper() != Object.class)
               {
                  BeanInfo wrapperInfo = JBossXBBuilder.configuration.getBeanInfo(groupText.wrapper());
                  TypeBinding wrapperTypeBinding = resolveTypeBinding(wrapperInfo.getClassInfo());
                  // Steal the attributes
                  Collection<AttributeBinding> otherAttributes = wrapperTypeBinding.getAttributes();
                  if (otherAttributes != null)
                  {
                     for (AttributeBinding other : otherAttributes)
                        elementTypeBinding.addAttribute(other);
                  }
                  ParticleHandler particleHandler = wrapperTypeBinding.getHandler();
                  if (particleHandler instanceof BeanHandler == false)
                     throw new IllegalStateException("Cannot wrap " + wrapperInfo.getName() + " not a bean type " + particleHandler);
                  BeanHandler beanHandler = (BeanHandler) particleHandler;
                  WrapperBeanAdapterFactory wrapperFactory = new WrapperBeanAdapterFactory(beanHandler.getBeanAdapterFactory(), propertyType.getType());
                  elementTypeBinding.setHandler(new BeanHandler(wrapperInfo.getName(), wrapperFactory));
                  elementTypeBinding.setSimpleType(wrapperTypeBinding.getSimpleType());
               }
               else
               {
                  elementTypeBinding.setHandler(BuilderParticleHandler.INSTANCE);
               }
               elementTypeBinding.setSchemaBinding(schemaBinding);
               ElementBinding elementBinding = createElementBinding(localPropertyType, elementTypeBinding, propertyQName, false);

               // Bind it to the model
               ParticleBinding particle = new ParticleBinding(elementBinding, 1, 1, false);
               if (required == false)
                  particle.setMinOccurs(0);
               localModel.addParticle(particle);

               // 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);

                  if(childType.isMap())
                     bindMapProperty(property, (ClassInfo) childType, childName, (ModelGroupBinding) childTypeBinding.getParticle().getTerm());
                                   
                  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 + " " + childType.getName());

                  beanAdapterFactory.addProperty(propertyQName, new PropertyHandler(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;
            boolean isMap = 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);
               // here we get the comp type based on the non-overriden property type...
               // which feels like a weak point
               TypeInfo typeArg = ((ClassInfo)property.getType()).getComponentType();

               if (typeArg != null && ((ClassInfo)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)
            {
               if (valueAdapter != null)
               {
                  propertyHandler = new PropertyHandler(property, localPropertyType);
               }
               else
               {
                  propertyHandler = new CollectionPropertyHandler(property, localPropertyType);
               }
               isCol = true;
               localPropertyType = ((ClassInfo)localPropertyType).getComponentType();
            }
            else if (localPropertyType.isMap())
            {
               TypeBinding wrapperType = null;
               if(elements.length > 1)
               {
                  wrapperType = resolveTypeBinding(localPropertyType);
                  ElementBinding elementBinding = createElementBinding(localPropertyType, wrapperType, propertyQName, false);
                  elementBinding.setNillable(nillable);
                  elementBinding.setValueAdapter(valueAdapter);

                  // Bind it to the model
                  ParticleBinding particle = new ParticleBinding(elementBinding, 0, 1, isCol);
                  if (required == false)
                     particle.setMinOccurs(0);

                  targetGroup.addParticle(particle);
                  targetGroup = (ModelGroupBinding) wrapperType.getParticle().getTerm();
               }
              
               QName boundQName = bindMapProperty(property, (ClassInfo) localPropertyType, propertyQName, targetGroup);
               if(boundQName != null)
               {
                  if(wrapperType != null)
                  {
                     BeanAdapterFactory wrapperBeanFactory = ((BeanHandler)wrapperType.getHandler()).getBeanAdapterFactory();
                     Map<QName, AbstractPropertyHandler> properties = wrapperBeanFactory.getProperties();
                     if(!properties.containsKey(boundQName))
                     {
                        propertyHandler = new MapPropertyHandler(JBossXBBuilder.configuration, property, localPropertyType, true);
                        wrapperBeanFactory.addProperty(boundQName, propertyHandler);
                     }
                     propertyHandler = new PropertyHandler(property, localPropertyType);
                  }
                  else
                  {
View Full Code Here

         TypeInfo keyType = propType.getKeyType();
         TypeInfo valueType = propType.getValueType();

         // entry handler
         BeanAdapterFactory entryAdapterFactory = null;
         BeanInfo entryInfo = JBossXBBuilder.configuration.getBeanInfo(DefaultMapEntry.class);
         entryAdapterFactory = createAdapterFactory(DefaultBeanAdapterBuilder.class, entryInfo, null);
         BeanHandler entryHandler = new BeanHandler(entryInfo.getName(), entryAdapterFactory);

         TypeBinding entryType = null;
         TypeInfo entryTypeInfo = null;

         // bind the entry element if present
         if(entryElement != null && !JBossXmlConstants.DEFAULT.equals(entryElement.name()))
         {
            String ns = entryElement.namespace();
            if(JBossXmlConstants.DEFAULT.equals(ns))
               ns = defaultNamespace;                 
            QName entryName = new QName(ns, entryElement.name());

            entryType = new TypeBinding();
            entryType.setSchemaBinding(schemaBinding);
            entryType.setHandler(entryHandler);

            entryTypeInfo = JBossXBBuilder.configuration.getTypeInfo(DefaultMapEntry.class);                    
            ElementBinding entryElementBinding = createElementBinding(entryTypeInfo, entryType, entryName, false);
            ParticleBinding entryParticle = new ParticleBinding(entryElementBinding, 0, -1, true);
            targetGroup.addParticle(entryParticle);
              
            propertyQName = entryName;
              
            if(keyAttribute != null)
            {
               TypeBinding attributeType = resolveTypeBinding(keyType);
               AttributeHandler attributeHandler = new PropertyHandler(entryInfo.getProperty("key"), keyType);
               String attrNs = keyAttribute.namespace();
               if(JBossXmlConstants.DEFAULT.equals(attrNs))
                  attrNs = defaultNamespace;
               AttributeBinding keyBinding = new AttributeBinding(schemaBinding, new QName(attrNs, keyAttribute.name()), attributeType, attributeHandler);
               keyBinding.setRequired(true);
               entryType.addAttribute(keyBinding);
            }

            if(valueAttribute != null)
            {
               TypeBinding attributeType = resolveTypeBinding(valueType);
               AttributeHandler attributeHandler = new PropertyHandler(entryInfo.getProperty("value"), valueType);
               String valueNs = valueAttribute.namespace();
               if(JBossXmlConstants.DEFAULT.equals(valueNs))
                  valueNs = defaultNamespace;
               AttributeBinding valueBinding = new AttributeBinding(schemaBinding, new QName(valueNs, valueAttribute.name()), attributeType, attributeHandler);
               valueBinding.setRequired(true);
               entryType.addAttribute(valueBinding);
            }
            else if(valueElement == null)
            {
               CharactersHandler charactersHandler = new ValueHandler(entryInfo.getProperty("value"), valueType);
               entryType.setSimpleType(charactersHandler);
            }
         }
        
         SequenceBinding keyValueSequence = null;
         if(keyElement != null)
         {
            keyValueSequence = new SequenceBinding(schemaBinding);                    
            if(entryType == null)
            {
               keyValueSequence.setSkip(Boolean.FALSE);
               keyValueSequence.setQName(propertyQName);
               schemaBinding.addGroup(keyValueSequence.getQName(), keyValueSequence);
               ParticleBinding keyValueParticle = new ParticleBinding(keyValueSequence, 0, -1, true);
               targetGroup.addParticle(keyValueParticle);
               keyValueSequence.setHandler(entryHandler);
            }
            else
            {
               ParticleBinding keyValueParticle = new ParticleBinding(keyValueSequence, 1, 1, false);
               entryType.setParticle(keyValueParticle);
            }
           
            // key element
            TypeBinding keyTypeBinding = resolveTypeBinding(keyType);                 
            String keyNs = keyElement.namespace();
            if(JBossXmlConstants.DEFAULT.equals(keyNs))
               keyNs = defaultNamespace;                 
            ElementBinding keyElementBinding = createElementBinding(keyType, keyTypeBinding, new QName(keyNs, keyElement.name()), false);
            ParticleBinding particle = new ParticleBinding(keyElementBinding, 1, 1, false);
            keyValueSequence.addParticle(particle);
            PropertyHandler keyHandler = new PropertyHandler(entryInfo.getProperty("key"), keyType);
            entryAdapterFactory.addProperty(keyElementBinding.getQName(), keyHandler);
         }
        
         if(valueElement != null)
         {
            TypeBinding valueTypeBinding = resolveTypeBinding(valueType);                 
            String valueNs = valueElement.namespace();
            if(JBossXmlConstants.DEFAULT.equals(valueNs))
               valueNs = defaultNamespace;                 
            ElementBinding valueElementBinding = createElementBinding(valueType, valueTypeBinding, new QName(valueNs, valueElement.name()), false);
            ParticleBinding particle = new ParticleBinding(valueElementBinding, 1, 1, false);
            keyValueSequence.addParticle(particle);
            PropertyHandler valueHandler = new PropertyHandler(entryInfo.getProperty("value"), valueType);
            entryAdapterFactory.addProperty(valueElementBinding.getQName(), valueHandler);
         }

         // TODO: need to verify correct binding before proceeding
         boundQName = propertyQName;
      }
View Full Code Here

      if (factoryMethod != null && factoryMethod.length() > 0)
         factory = Config.findMethodInfo(factoryClassInfo, factoryMethod, null, true, true);

      // Create the handler
      BeanInfo beanInfo = JBossXBBuilder.configuration.getBeanInfo(typeInfo);
      BeanAdapterFactory beanAdapterFactory = createAdapterFactory(beanAdapterBuilderClass, beanInfo, factory);
      BeanHandler handler = new BeanHandler(beanInfo.getName(), beanAdapterFactory);
      typeBinding.setHandler(handler);
      if (trace)
         log.trace("Created BeanHandler for type=" + beanInfo.getName() + " factory=" + factory);

      // Look through the properties
      JBossXmlNoElements jbossXmlNoElements = typeInfo.getUnderlyingAnnotation(JBossXmlNoElements.class);
      boolean noElements = jbossXmlNoElements != null;
      PropertyInfo valueProperty = null;
      PropertyInfo wildcardProperty = null;
      boolean allBinding = propertyOrder.length == 0;
      boolean determinePropertyOrder = allBinding || (propertyOrder.length == 1 && propertyOrder[0].length() == 0);
      ArrayList<String> propertyNames = new ArrayList<String>();
      Set<PropertyInfo> properties = beanInfo.getProperties();
      if (properties != null && properties.isEmpty() == false)
      {
         boolean seenXmlAnyElement = false;
         PropertyInfo seenXmlAnyAttribute = null;
         for (PropertyInfo property : properties)
         {
            push(typeInfo, property.getName());

            if (trace)
               log.trace("Checking property " + property.getName() + " for " + beanInfo.getName() + " type=" + property.getType().getName());

            // Is this the value property?
            XmlValue xmlValue = property.getUnderlyingAnnotation(XmlValue.class);
            if (xmlValue != null)
            {
               if (trace)
                  log.trace("Seen @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
               if (valueProperty != null)
                  throw new RuntimeException("@XmlValue seen on two properties: " + property.getName() + " and " + valueProperty.getName());
               valueProperty = property;
            }

            // Is this the wildcard property?
            boolean ignoreXmlAnyElement = false;
            XmlAnyElement xmlAnyElement = property.getUnderlyingAnnotation(XmlAnyElement.class);
            if (xmlAnyElement != null)
            {
               if (trace)
                  log.trace("Seen @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
               if (wildcardProperty != null && seenXmlAnyElement)
                  throw new RuntimeException("@XmlAnyElement seen on two properties: " + property.getName() + " and " + wildcardProperty.getName());
               wildcardProperty = property;
               seenXmlAnyElement = true;
              
               // should we ignore it
               if(property.getUnderlyingAnnotation(XmlElements.class) == null &&
                  property.getUnderlyingAnnotation(XmlElementRefs.class) == null)
                  ignoreXmlAnyElement = true;
            }
            else if (!seenXmlAnyElement && wildcardProperty == null && property.getType().getName().equals(org.w3c.dom.Element.class.getName()))
            {
               if (trace)
                  log.trace("Using type=" + beanInfo.getName() + " property=" + property.getName() + " as the base wildcard");
               if (wildcardProperty != null)
                  throw new RuntimeException("@XmlAnyElement seen on two properties: " + property.getName() + " and " + wildcardProperty.getName());
               wildcardProperty = property;
            }

            // Is this an attribute
            XmlAttribute xmlAttribute = property.getUnderlyingAnnotation(XmlAttribute.class);
            if (xmlAttribute != null)
            {
               JBossXmlAttribute jbossXmlAttribute = property.getUnderlyingAnnotation(JBossXmlAttribute.class);
               // Determine the name
               QName qName = generateXmlName(property.getName(), attributeForm, xmlAttribute.namespace(), xmlAttribute.name());
               // Resolve the type
               TypeInfo attributeTypeInfo = property.getType();
               if (jbossXmlAttribute != null && jbossXmlAttribute.type() != Object.class)
                  attributeTypeInfo = attributeTypeInfo.getTypeInfoFactory().getTypeInfo(jbossXmlAttribute.type());
               TypeBinding attributeType = resolveTypeBinding(attributeTypeInfo);
               // Create the attribute handler
               AttributeHandler attributeHandler = new PropertyHandler(property, attributeTypeInfo);
               // Create the attributre and bind it to the type
               AttributeBinding attribute = new AttributeBinding(schemaBinding, qName, attributeType, attributeHandler);
               attribute.setRequired(xmlAttribute.required());
               typeBinding.addAttribute(attribute);
               JBossXmlPreserveWhitespace preserveSpace = property.getUnderlyingAnnotation(JBossXmlPreserveWhitespace.class);
               if(preserveSpace != null)
                  attribute.setNormalizeSpace(preserveSpace.preserve() ? false : true);
               if (trace)
                  log.trace("Bound attribute " + qName + " type=" + beanInfo.getName() + " property=" + property.getName() + " propertyType=" + attributeTypeInfo + ", normalizeSpace=" + attribute.isNormalizeSpace());
            }

            // Is this any attribute
            XmlAnyAttribute xmlAnyAttribute = property.getUnderlyingAnnotation(XmlAnyAttribute.class);
            if (xmlAnyAttribute != null)
            {
               if (seenXmlAnyAttribute != null)
                  throw new RuntimeException("@XmlAnyAttribute seen on two properties: " + property.getName() + " and " + seenXmlAnyAttribute.getName());
               seenXmlAnyAttribute = property;
              
               AnyAttributePropertyHandler anyHandler = new AnyAttributePropertyHandler(property, property.getType());
               AnyAttributeBinding anyAttribute = new AnyAttributeBinding(schemaBinding, anyHandler);
               typeBinding.setAnyAttribute(anyAttribute);

               JBossXmlPreserveWhitespace preserveSpace = property.getUnderlyingAnnotation(JBossXmlPreserveWhitespace.class);
               if(preserveSpace != null)
                  anyAttribute.setNormalizeSpace(preserveSpace.preserve() ? false : true);
               if (trace)
                  log.trace("Bound any attribute type=" + beanInfo.getName() + " property=" + property.getName() + ", normalizeSpace=" + anyAttribute.isNormalizeSpace());
            }
           
            // Are we determining the property order?
            if (determinePropertyOrder)
            {
               // Value property
               if (xmlValue != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Wildcard property
               if (ignoreXmlAnyElement)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore xml attribute
               if (xmlAttribute != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlAttribute for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore xml tranient
               XmlTransient xmlTransient = property.getUnderlyingAnnotation(XmlTransient.class);
               if (xmlTransient != null)
               {
                  if (trace)
                     log.trace("Ignore not element @XmlTransient for type=" + beanInfo.getName() + " property=" + property.getName());
                  pop();
                  continue;
               }
               // Ignore the class property
               String name = property.getName();
               if ("class".equals(name))
               {
                  pop();
                  continue;
               }

               if (noElements)
               {
                  pop();
                  continue;
               }

               if (trace)
                  log.trace("Element for type=" + beanInfo.getName() + " property=" + property.getName());
               propertyNames.add(property.getName());
            }

            pop();
         }
         // Apply any access order
         if (determinePropertyOrder)
         {
            if (accessOrder == XmlAccessOrder.ALPHABETICAL)
               Collections.sort(propertyNames);
            propertyOrder = propertyNames.toArray(new String[propertyNames.size()]);
         }
      }

      // No value property, see if we have a default one
      //if (valueProperty == null)
      //{
      //   try
      //   {
      //      valueProperty = beanInfo.getProperty("value");
      //   }
      //   catch (Exception ignored)
      //   {
            // Nope.
      //   }
      //}

      // Bind the value
      if (valueProperty != null)
      {
         CharactersHandler charactersHandler = new ValueHandler(valueProperty);
         typeBinding.setSimpleType(charactersHandler);
        
         JBossXmlValue jbossXmlValue = typeInfo.getUnderlyingAnnotation(JBossXmlValue.class);
         if(jbossXmlValue != null)
         {
            if(trace)
               log.trace("Type " + typeInfo.getName() + " is annotated with @JBossXmlValue.ignoreEmptyString=" + jbossXmlValue.ignoreEmptyString());
            typeBinding.setIgnoreEmptyString(jbossXmlValue.ignoreEmptyString());
         }
      }
      else if (trace)
         log.trace("No value for type=" + beanInfo.getName());

      if (trace)
         log.trace("PropertyOrder " + Arrays.asList(propertyOrder) + " for type=" + beanInfo.getName());

      // Determine the model
      // TODO simple types/content when no properties other than @XmlValue and @XmlAttribute
      typeBinding.setSimple(false);
      ModelGroupBinding model = null;
      if (allBinding)
      {
         if (trace)
            log.trace("AllBinding for type=" + beanInfo.getName());
         model = new AllBinding(schemaBinding);
      }
      else
      {
         if (trace)
            log.trace("SequenceBinding for type=" + beanInfo.getName());
         model = new SequenceBinding(schemaBinding);
      }
      model.setHandler(BuilderParticleHandler.INSTANCE);
      ParticleBinding typeParticle = new ParticleBinding(model);
      typeParticle.setMinOccurs(1);
      typeParticle.setMaxOccurs(1);
      typeBinding.setParticle(typeParticle);

      if (typeInfo.isCollection())
      {
         typeParticle.setMinOccurs(0);
         typeParticle.setMaxOccursUnbounded(true);
         TypeInfo memberBaseType = typeInfo.getComponentType();
         JBossXmlModelGroup xmlModelGroup = ((ClassInfo) memberBaseType)
               .getUnderlyingAnnotation(JBossXmlModelGroup.class);
         if (xmlModelGroup != null && xmlModelGroup.particles().length > 0)
         {
            if (trace)
               log.trace("Item base type for " + typeInfo.getName() + " is " + memberBaseType.getName()
                     + " and bound to repeatable choice");

            // it's choice by default based on the idea that the
            // type parameter is a base class for items
            ModelGroupBinding choiceGroup = null;
            QName choiceName = null;
            if(!JBossXmlConstants.DEFAULT.equals(xmlModelGroup.name()))
            {
               choiceName = new QName(defaultNamespace, xmlModelGroup.name());
               choiceGroup = schemaBinding.getGroup(choiceName);
            }
           
            if(choiceGroup == null)
            {
               choiceGroup = new ChoiceBinding(schemaBinding);
               choiceGroup.setHandler(BuilderParticleHandler.INSTANCE);
               if (choiceName != null)
               {
                  choiceGroup.setQName(choiceName);
                  schemaBinding.addGroup(choiceGroup.getQName(), choiceGroup);
               }

               ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
               model.addParticle(choiceParticle);

               for (JBossXmlModelGroup.Particle member : xmlModelGroup.particles())
               {
                  XmlElement element = member.element();
                  QName memberQName = generateXmlName(element.name(), XmlNsForm.QUALIFIED, element.namespace(), null);
                  TypeInfo memberTypeInfo = typeInfo.getTypeInfoFactory().getTypeInfo(member.type());

                  boolean isCol = false;
                  if (memberTypeInfo.isCollection())
                  {
                     memberTypeInfo = ((ClassInfo) memberTypeInfo).getComponentType();
                     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.pushInterceptor(memberQName, ChildCollectionInterceptor.SINGLETON);
               }
            }
            else
            {
               ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
               model.addParticle(choiceParticle);
            }
           
            if (trace)
               log.trace("choices for " + typeBinding.getQName() + ": " + choiceGroup.getParticles());
         }
      }

      // Determine the wildcard handler
      AbstractPropertyHandler wildcardHandler = null;
      if (wildcardProperty != null)
      {
         TypeInfo wildcardType = wildcardProperty.getType();
         if (wildcardType.isCollection())
            wildcardHandler = new CollectionPropertyWildcardHandler(wildcardProperty, wildcardType);
         else
            wildcardHandler = new PropertyWildcardHandler(wildcardProperty, wildcardType);
      }

      // Look through the properties
      for (String name : propertyOrder)
      {
         // Setup the error stack
         push(typeInfo, name);
         // Get the property
         PropertyInfo property = beanInfo.getProperty(name);
         bindProperty(property, typeBinding, model, beanAdapterFactory, propertyOrder);
         pop();
      }

      // Bind the children
      JBossXmlChild[] children = null;
      JBossXmlChildren jbossXmlChildren = typeInfo.getUnderlyingAnnotation(JBossXmlChildren.class);
      if (jbossXmlChildren != null)
         children = jbossXmlChildren.value();
      else
      {
         JBossXmlChild jbossXmlChild = typeInfo.getUnderlyingAnnotation(JBossXmlChild.class);
         if (jbossXmlChild != null)
            children = new JBossXmlChild[] { jbossXmlChild };
      }

      if (children != null && children.length > 0)
      {
         for (JBossXmlChild child : children)
         {
            QName qName = generateXmlName(child.name(), elementForm, child.namespace(), child.name());
            TypeInfo childType = JBossXBBuilder.configuration.getTypeInfo(child.type());

            TypeBinding elementTypeBinding = resolveTypeBinding(childType);
            ElementBinding elementBinding = createElementBinding(childType, elementTypeBinding, qName, false);

            // Bind it to the model
            ParticleBinding particle = new ParticleBinding(elementBinding, child.minOccurs(), child.maxOccurs(), child.unbounded());
            model.addParticle(particle);

            if(childType.isMap())
               bindMapProperty(null, (ClassInfo) childType, elementTypeBinding.getQName(), (ModelGroupBinding) elementTypeBinding.getParticle().getTerm());
           
            DefaultElementInterceptor interceptor = null;
            if (typeInfo.isCollection())
               interceptor = ChildCollectionInterceptor.SINGLETON;
            else
            {
               // Expect a type with a value property to accept the child value
               PropertyInfo property = beanInfo.getProperty("value");
               if (property == null)
                  throw new UnsupportedOperationException("Expected a value property for non-collection type with JBossXmlChildren");
               TypeInfo propertyType = property.getType();
               interceptor = new PropertyInterceptor(property, propertyType);
            }
            typeBinding.pushInterceptor(qName, interceptor);
            if (trace)
               log.trace("Added interceptor " + qName + " for type=" + childType + " interceptor=" + interceptor);
         }
      }

      // Bind the wildcard
      if (wildcardProperty != null)
      {
         if (trace)
            log.trace("Processing WildcardProperty for type=" + beanInfo.getName() + " property=" + wildcardProperty.getName());
         ModelGroupBinding localModel = model;
         TypeInfo wildcardType = wildcardProperty.getType();
         TypeInfo type = wildcardType;

         // Setup any new model and determine the wildcard type
         if (wildcardType.isArray())
         {
            localModel = createArray(localModel);
            type = ((ArrayInfo) wildcardType).getComponentType();
            if (trace)
               log.trace("Wildcard " + wildcardProperty.getName() + " is an array of type " + type.getName());
         }
         else if (wildcardType.isCollection())
         {
            localModel = createCollection(localModel);
            type = ((ClassInfo)wildcardProperty.getType()).getComponentType();
            if (trace)
               log.trace("Wildcard " + wildcardProperty.getName() + " is a collection of type " + type.getName());
         }

         XmlAnyElement xmlAnyElement = wildcardProperty.getUnderlyingAnnotation(XmlAnyElement.class);
         boolean isLax = xmlAnyElement == null ? true : xmlAnyElement.lax();
         WildcardBinding wildcard = new WildcardBinding(schemaBinding);
         if (isLax)
            wildcard.setProcessContents((short) 3); // Lax
         else
            wildcard.setProcessContents((short) 1); // Strict

         // Dom element?
         if (Element.class.getName().equals(type.getName()))
         {
            wildcard.setUnresolvedElementHandler(DOMHandler.INSTANCE);
            wildcard.setUnresolvedCharactersHandler(DOMHandler.INSTANCE);
         }

         // Bind the particle to the model
         ParticleBinding particleBinding = new ParticleBinding(wildcard);
         particleBinding.setMinOccurs(0);
         particleBinding.setMaxOccurs(1);
         localModel.addParticle(particleBinding);
         typeBinding.getWildcard().setWildcardHandler((ParticleHandler) wildcardHandler);
         beanAdapterFactory.setWildcardHandler(wildcardHandler);
      }

      JBossXmlChildWildcard childWildcard = typeInfo.getUnderlyingAnnotation(JBossXmlChildWildcard.class);
      if (childWildcard != null)
      {
         if (beanAdapterFactory.getWildcardHandler() != null)
            throw new RuntimeException("Cannot have both @JBossXmlChildWildcard and @XmlAnyElement");

         ParticleHandler childWildcardHandler = null;
         if (typeInfo.isCollection())
         {
View Full Code Here

TOP

Related Classes of org.jboss.xb.spi.BeanAdapterFactory

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.