Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * JBoss, Home of Professional Open Source
    * Copyright 2006, JBoss Inc., and individual contributors as indicated
    * by the @authors tag. See the copyright.txt in the distribution for a
    * full listing of individual contributors.
    *
    * This is free software; you can redistribute it and/or modify it
    * under the terms of the GNU Lesser General Public License as
    * published by the Free Software Foundation; either version 2.1 of
   * the License, or (at your option) any later version.
   *
   * This software is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this software; if not, write to the Free
   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   */
  package org.jboss.xb.builder;
  
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.Stack;
  
  
  import  org.jboss.logging.Logger;
JBossXBNoSchemaBuilder.

Author(s):
Adrian Brock
Version:
$Revision: 1.1 $
 
 public class JBossXBNoSchemaBuilder
 {
   
The log
 
    private static final Logger log = Logger.getLogger(JBossXBBuilder.class);

   
Whether trace is enabled
 
    private boolean trace = .isTraceEnabled();

   
The schema binding
 
    private SchemaBinding schemaBinding;

   
The root type
 
    private ClassInfo root;

   
The namespace
 
    private String defaultNamespace;

   
The attribute form
 
    private XmlNsForm attributeForm = .;

   
The element form
 
    private XmlNsForm elementForm = .;

   
A cache of types
 
    private Map<TypeInfoTypeBindingtypeCache = new HashMap<TypeInfoTypeBinding>();

   
A root elements we have processed
 
    private Map<TypeInfoElementBindingrootCache = new HashMap<TypeInfoElementBinding>();

   
The current location
 
    private Stack<Locationlocations = new Stack<Location>();

   
Create a new JBossXBNoSchemaBuilder.

Parameters:
root the root class info
Throws:
IllegalArgumentException for a null root class info
 
    public JBossXBNoSchemaBuilder(ClassInfo root)
    {
       if (root == null)
          throw new IllegalArgumentException("Null root");
 
       this. = root;
    }

   
Build the schema

Returns:
the schema
 
    public SchemaBinding build()
    {
       initSchema();
       createRootElements();
       return ;
    }

   
Initialise the schema
 
    protected void initSchema()
    {
       // Initialize the schema
        = new SchemaBinding();
       JBossXBBuilder.initSchema();
       if ()
          .trace("Building schema for " + .getName() + " schemaBinding=" + );
 
       // Remember the default namespace
       if ( == null)
       {
       }
 
       JBossXmlSchema jbossXmlSchema = .getUnderlyingAnnotation(JBossXmlSchema.class);
       if (jbossXmlSchema != null)
       {
           = jbossXmlSchema.attributeFormDefault();
           = jbossXmlSchema.elementFormDefault();
       }
 
       // Look for an annotation
       PackageInfo packageInfo = .getPackage();
       if (packageInfo != null)
       {
          jbossXmlSchema = .getUnderlyingAnnotation(JBossXmlSchema.class);
          if (jbossXmlSchema != null)
          {
             if ( == .)
                 = jbossXmlSchema.attributeFormDefault();
             if ( == .)
                 = jbossXmlSchema.elementFormDefault();
          }
 
          XmlSchema xmlSchema = packageInfo.getUnderlyingAnnotation(XmlSchema.class);
          if (xmlSchema != null)
          {
             String namespace = xmlSchema.namespace();
             if (..equals(xmlSchema) == false && ..equals())
             {
                 = namespace;
                addNamespace(true);
             }
 
             if ( == .)
                 = xmlSchema.attributeFormDefault();
             if ( == .)
                 = xmlSchema.elementFormDefault();
          }
 
          // Check for adapted types
          JBossXmlAdaptedTypes adaptedTypes = packageInfo.getUnderlyingAnnotation(JBossXmlAdaptedTypes.class);
          if (adaptedTypes != null)
          {
             for (JBossXmlAdaptedType adaptedType : adaptedTypes.value())
                generateAdaptedType(adaptedType);
          }
          JBossXmlAdaptedType adaptedType = packageInfo.getUnderlyingAnnotation(JBossXmlAdaptedType.class);
          if (adaptedType != null)
             generateAdaptedType(adaptedType);
       }
    }

   
Create the root elements
 
    protected void createRootElements()
    {
       // Create the root element
    }

   
Create a root element binding

Parameters:
typeInfo the type info
 
    protected void createRootElementBinding(TypeInfo typeInfo)
    {
       // Already done/doing this
       if (.containsKey(typeInfo))
          return;
       // Put a skeleton marker in the cache so we know not to redo it
       .put(typeInfonull);
 
       // We force the element to be a root element
       push(typeInfo);
       try
       {
          createElementBinding(typeInfotypeInfo.getSimpleName(), true);
          pop();
       }
       catch (Exception e)
       {
          throw rethrowWithLocation(e);
       }
    }

   
Create an element binding

Parameters:
typeInfo the type info
name the java element name
root pass true to force a root element
Returns:
the element binding
 
    private ElementBinding createElementBinding(TypeInfo typeInfoString nameboolean root)
    {
       // Resolve the type
       TypeBinding typeBinding = resolveTypeBinding(typeInfo);
 
       // Create the element
       return createElementBinding(typeInfotypeBindingnameroot);
    }

   
Create an element binding

Parameters:
typeInfo the type info
typeBinding the type binding
name the java element name
root pass true to force a root element
Returns:
the element binding
 
    private ElementBinding createElementBinding(TypeInfo typeInfoTypeBinding typeBindingString nameboolean root)
    {
       // Determine the parameters
       String overrideNamespace = null;
       String overrideName = null;
       if (typeInfo instanceof ClassInfo)
       {
          ClassInfo classInfo = (ClassInfotypeInfo;
          XmlRootElement xmlRootElement = classInfo.getUnderlyingAnnotation(XmlRootElement.class);
          if (xmlRootElement != null)
          {
             overrideNamespace = xmlRootElement.namespace();
             overrideName = xmlRootElement.name();
          }
       }
 
       // Create the binding
       XmlNsForm form = ;
       if (root)
          form = .;
       QName qName = generateXmlName(nameformoverrideNamespaceoverrideName);
       return createElementBinding(typeInfotypeBindingqNameroot);
    }

   
Create an element binding

Parameters:
typeInfo the type info
typeBinding the type binding
qName the qualified name
root pass true to force a root element
Returns:
the element binding
 
    private ElementBinding createElementBinding(TypeInfo typeInfoTypeBinding typeBindingQName qNameboolean root)
    {
       if ()
          .trace("creating element " + qName + " with type " + typeInfo.getName());
 
       if (typeInfo instanceof ClassInfo)
       {
          ClassInfo classInfo = (ClassInfotypeInfo;
          XmlRootElement xmlRootElement = classInfo.getUnderlyingAnnotation(XmlRootElement.class);
          if (xmlRootElement != null)
             root = true;
       }
 
       ElementBinding elementBinding = new ElementBinding(qNametypeBinding);
       if ()
          .trace("created  element " + qName + " element=" + elementBinding + " rootElement=" + root);
 
       // If we are a root element bind it
       if (root)
       {
          .addElement(elementBinding);
          ParticleBinding particleBinding = .getElementParticle(qName);
          particleBinding.setMinOccurs(1);
          particleBinding.setMaxOccurs(1);
          .put(typeInfoelementBinding);
       }
 
       return elementBinding;
    }

   
Process a type

Parameters:
typeInfo the type info
 
    protected void process(TypeInfo typeInfo)
    {
       if (typeInfo.isPrimitive() == false && typeInfo.isEnum() && typeInfo.isAnnotation() && Object.class.getName().equals(typeInfo.getName()) == false)
       {
          ClassInfo classInfo = (ClassInfotypeInfo;
 
          // Create the type
          resolveTypeBinding(typeInfo);
 
          // Check wether we need to add it as a root element
          if (.containsKey(typeInfo) == false)
          {
             XmlRootElement xmlRootElement = classInfo.getUnderlyingAnnotation(XmlRootElement.class);
             if (xmlRootElement != null)
                createRootElementBinding(typeInfo);
          }
       }
    }

   
Resolve a type binding

Parameters:
typeInfo the type info
Returns:
the type binding
 
    @SuppressWarnings("unchecked")
    protected TypeBinding resolveTypeBinding(TypeInfo typeInfo)
    {
       if ()
          .trace("resolving type " + typeInfo.getName());
 
       // Look for a cached value
       TypeBinding result = .get(typeInfo);
 
       // No cached value
       if (result == null)
       {
          // Generate it
          result = generateTypeBinding(typeInfo);
 
          // Cache it
          .put(typeInforesult);
       }
       if ()
          .trace("resolved  type " + typeInfo.getName() + " binding=" + result);
 
       // Return the result 
       return result;
    }

   
Generate a type binding

Parameters:
typeInfo the type info
Returns:
the type binding
 
    protected TypeBinding generateTypeBinding(TypeInfo typeInfo)
    {
       try
       {
          if (typeInfo.isEnum())
             return generateEnum((EnumInfotypeInfo);
 
          if (typeInfo.isAnnotation())
             return generateAnnotation((ClassInfotypeInfo);
 
          if (typeInfo.isArray())
             return generateArray((ArrayInfotypeInfo);
 
          if (typeInfo.isCollection())
             return generateCollection((ClassInfotypeInfo);
 
          if (typeInfo.isMap())
             return generateMap((ClassInfotypeInfo);
 
          TypeBinding typeBinding = isSimpleType(typeInfo);
          if (typeBinding != null)
             return typeBinding;
 
          return generateBean((ClassInfotypeInfo);
       }
       finally
       {
          // Not a primitive type
          if (typeInfo.isPrimitive() == false)
          {
             ClassInfo classInfo = (ClassInfotypeInfo;
 
             // Process our type args
             TypeInfo[] typeArgs = classInfo.getActualTypeArguments();
             if (typeArgs != null)
             {
                for (int i = 0; i < typeArgs.length; ++i)
                   process(typeArgs[i]);
             }
 
             // Process the super class
             ClassInfo superClass = classInfo.getGenericSuperclass();
             if (superClass != null)
                process(superClass);
          }
       }
    }

   
Generate an enum type binding

Parameters:
typeInfo the type info
Returns:
the type binding
 
    public TypeBinding generateEnum(EnumInfo typeInfo)
    {
       // Determine the parameters
       String overrideNamespace = null;
       String overrideName = null;
       boolean root = false;
       XmlType xmlType = typeInfo.getUnderlyingAnnotation(XmlType.class);
       if (xmlType != null)
       {
          root = true;
          overrideNamespace = xmlType.namespace();
          overrideName = xmlType.name();
       }
 
       // Determine the enum type 
       Class<?> xmlEnumValue = String.class;
       XmlEnum xmlEnum = typeInfo.getUnderlyingAnnotation(XmlEnum.class);
       if (xmlEnum != null)
          xmlEnumValue = xmlEnum.value();
       TypeInfo enumType = typeInfo.getTypeInfoFactory().getTypeInfo(xmlEnumValue);
 
       // Resolve the enum type as the parent (must be simple)
       TypeBinding parent = getSimpleType(enumType);
 
       // Create the enum type
       QName qName = null;
       TypeBinding typeBinding = null;
       if (root)
       {
          qName = generateXmlName(typeInfo.overrideNamespaceoverrideName);
          typeBinding = new TypeBinding(qNameparent);
       }
       else
       {
          typeBinding = new TypeBinding(nullparent);
       }
 
       typeBinding.setValueAdapter(new EnumValueAdapter(qNametypeInfoenumType));
 
       if ()
          .trace("Created enum=" + typeInfo.getName() + " type=" + typeBinding + " rootType=" + root);
 
       // Bind it as a global type
       if (root)
          .addType(typeBinding);
       else
          typeBinding.setSchemaBinding();
 
       return typeBinding;
    }

   
Generate an adapted type

Parameters:
adaptedType the information about the adaption
Returns:
the type binding
 
    {
       // Determine the parameters
       String overrideNamespace = adaptedType.namespace();
       String overrideName = adaptedType.name();
       Class<?> type = adaptedType.type();
       Class<? extends ValueAdapteradapter = adaptedType.valueAdapter();
       try
       {
 
          TypeInfo typeInfo = ..getTypeInfo(type);
          BeanInfo adapterInfo = ..getBeanInfo(adapter);
 
          ValueAdapter valueAdapter = (ValueAdapteradapterInfo.newInstance();
 
          QName qName = generateXmlName(typeInfo.overrideNamespaceoverrideName);
 
          TypeInfo parentType = typeInfo.getTypeInfoFactory().getTypeInfo(String.class);
          TypeBinding parent = getSimpleType(parentType);
 
          TypeBinding typeBinding = new TypeBinding(qNameparent);
          typeBinding.setValueAdapter(valueAdapter);
          if ()
             .trace("Created adapted type=" + typeInfo.getName() + " typeBinding=" + typeBinding + " adapter=" + adapter.getName());
 
          .put(typeInfotypeBinding);
          .addType(typeBinding);
 
          return typeBinding;
       }
       catch (Throwable t)
       {
          throw new RuntimeException("Unable to adapt type " + type.getName() + " with " + adapter.getName(), t);
       }
    }

   
Generate an annotation type binding

Parameters:
typeInfo the type info
Returns:
the type binding
 
    public TypeBinding generateAnnotation(ClassInfo typeInfo)
    {
       // TODO generateAnnotation
       throw new UnsupportedOperationException("generateAnnotation");
    }

   
Generate an array type binding

Parameters:
typeInfo the type info
Returns:
the type binding
 
    public TypeBinding generateArray(ArrayInfo typeInfo)
    {
       return resolveTypeBinding(typeInfo.getComponentType());
    }

   
Generate a collection type binding

Parameters:
typeInfo the type info
Returns:
the type binding
 
    public TypeBinding generateCollection(ClassInfo typeInfo)
    {
       if (typeInfo instanceof ParameterizedClassInfo)
       {
          ParameterizedClassInfo parameterizedClassInfo = (ParameterizedClassInfotypeInfo;
          TypeInfo[] actualTypes = parameterizedClassInfo.getActualTypeArguments();
          TypeInfo elementType = actualTypes[0];
          return resolveTypeBinding(elementType);
       }
       else
       {
          return generateBean(typeInfo);
       }
    }

   
Generate a map type binding

Parameters:
typeInfo the type info
Returns:
the type binding
 
    public TypeBinding generateMap(ClassInfo typeInfo)
    {
       // the map is bound in bindProperty method currently
       return generateBean(typeInfo);
    }

   
Check whether this is a simple type

Parameters:
typeInfo the type info
Returns:
the type binding if it is simple
 
    public TypeBinding isSimpleType(TypeInfo typeInfo)
    {
       QName qName = SimpleTypeBindings.typeQName(typeInfo.getType());
       if (qName == null)
          return null;
       TypeBinding result = .getType(qName);
       if (result == null)
          throw new IllegalStateException("SimpleType is not bound in the schema: " + qName + " for " + typeInfo.getName());
       return result;
    }

   
Get the simple type

Parameters:
typeInfo the type info
Returns:
the type binding if it is simple
Throws:
IllegalStateException if the type is not bound
 
    public TypeBinding getSimpleType(TypeInfo typeInfo)
    {
       TypeBinding result = isSimpleType(typeInfo);
       if (result == null)
          throw new IllegalStateException(typeInfo.getName() + " does not map to a simple type.");
       return result;
    }

   
Generate a bean type binding

Parameters:
typeInfo the type info
Returns:
the type binding
 
    public TypeBinding generateBean(ClassInfo typeInfo)
    {
       return generateBean(typeInfofalse);
    }

   
Generate a bean type binding

Parameters:
typeInfo the type info
root whether to force a root type
Returns:
the type binding
 
    public TypeBinding generateBean(ClassInfo typeInfoboolean root)
    {
       return generateType(typeInforoot);
    }

   
Generate a bean type binding

Parameters:
typeInfo the type info
root whether to force a root type
Returns:
the type binding
 
    public TypeBinding generateType(ClassInfo typeInfoboolean root)
    {
       // Determine the paremeters
       String overrideNamespace = null;
       String overrideName = null;
       ClassInfo factoryClassInfo = typeInfo;
       String factoryMethod = null;
       String[] propertyOrder = {""};
       XmlAccessOrder accessOrder = .;
       Class<? extends BeanAdapterBuilderbeanAdapterBuilderClass = DefaultBeanAdapterBuilder.class;
       XmlType xmlType = typeInfo.getUnderlyingAnnotation(XmlType.class);
       if (xmlType != null)
       {
          root = true;
          overrideNamespace = xmlType.namespace();
          overrideName = xmlType.name();
          if (overrideName.length() == 0)
             root = false;
 
          Class<?> factoryClass = xmlType.factoryClass();
          if (factoryClass != XmlType.DEFAULT.class)
             factoryClassInfo = (ClassInfotypeInfo.getTypeInfoFactory().getTypeInfo(factoryClass);
          factoryMethod = xmlType.factoryMethod();
          propertyOrder = xmlType.propOrder();
       }
       JBossXmlType jbossXmlType = typeInfo.getUnderlyingAnnotation(JBossXmlType.class);
       if (jbossXmlType != null)
       {
          beanAdapterBuilderClass = jbossXmlType.beanAdapterBuilder();
       }
       // Determine the property access order
       XmlAccessorOrder accessorOrder = typeInfo.getUnderlyingAnnotation(XmlAccessorOrder.class);
       if (accessorOrder == null)
       {
          PackageInfo pkg = typeInfo.getPackage();
          if (pkg != null)
             accessorOrder = pkg.getUnderlyingAnnotation(XmlAccessorOrder.class);
       }
       if (accessorOrder != null)
          accessOrder = accessorOrder.value();
 
       // Create the binding
       TypeBinding typeBinding = null;
       if (root)
       {
          QName qName = generateXmlName(typeInfo.overrideNamespaceoverrideName);
          typeBinding = new TypeBinding(qName);
       }
       else
       {
          typeBinding = new TypeBinding();
       }
 
       // Push into the cache early to avoid recursion
       .put(typeInfotypeBinding);
 
       // Determine any factory method
       MethodInfo factory = null;
       if (factoryMethod != null && factoryMethod.length() > 0)
          factory = Config.findMethodInfo(factoryClassInfofactoryMethodnulltruetrue);
 
       // Create the handler
       BeanInfo beanInfo = ..getBeanInfo(typeInfo);
       BeanAdapterFactory beanAdapterFactory = createAdapterFactory(beanAdapterBuilderClassbeanInfofactory);
       BeanHandler handler = new BeanHandler(beanInfo.getName(), beanAdapterFactory);
       typeBinding.setHandler(handler);
       if ()
          .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<StringpropertyNames = new ArrayList<String>();
       Set<PropertyInfoproperties = beanInfo.getProperties();
       if (properties != null && properties.isEmpty() == false)
       {
          boolean seenXmlAnyElement = false;
          for (PropertyInfo property : properties)
          {
             push(typeInfoproperty.getName());
 
             if ()
                .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("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("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("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(), 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(propertyattributeTypeInfo);
                // Create the attributre and bind it to the type
                AttributeBinding attribute = new AttributeBinding(qNameattributeTypeattributeHandler);
                attribute.setRequired(xmlAttribute.required());
                typeBinding.addAttribute(attribute);
                if ()
                   .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("Ignore not element @XmlValue for type=" + beanInfo.getName() + " property=" + property.getName());
                   pop();
                   continue;
                }
                // Wildcard property
                if (ignoreXmlAnyElement)
                {
                   if ()
                      .trace("Ignore not element @XmlAnyElement for type=" + beanInfo.getName() + " property=" + property.getName());
                   pop();
                   continue;
                }
                // Ignore xml attribute
                if (xmlAttribute != null)
                {
                   if ()
                      .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("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("Element for type=" + beanInfo.getName() + " property=" + property.getName());
                propertyNames.add(property.getName());
             }
 
             pop();
          }
          // Apply any access order
          if (determinePropertyOrder)
          {
             if (accessOrder == .)
                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("No value for type=" + beanInfo.getName());
 
       if ()
          .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("AllBinding for type=" + beanInfo.getName());
          model = new AllBinding();
       }
       else
       {
          if ()
             .trace("SequenceBinding for type=" + beanInfo.getName());
          model = new SequenceBinding();
       }
       ParticleBinding typeParticle = new ParticleBinding(model);
       typeParticle.setMinOccurs(1);
       typeParticle.setMaxOccurs(1);
       typeBinding.setParticle(typeParticle);
 
       if (typeInfo.isCollection())
       {
          TypeInfo memberBaseType = ((ClassInfo)typeInfo).getComponentType();
          JBossXmlModelGroup xmlModelGroup = ((ClassInfomemberBaseType)
                .getUnderlyingAnnotation(JBossXmlModelGroup.class);
          if (xmlModelGroup != null && xmlModelGroup.particles().length > 0)
          {
             if ()
                .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(!..equals(xmlModelGroup.name()))
             {
                choiceName = new QName(xmlModelGroup.name());
                choiceGroup = .getGroup(choiceName);
             }
             
             if(choiceGroup == null)
             {
                choiceGroup = new ChoiceBinding();
                choiceGroup.setHandler(.);
                if (choiceName != null)
                {
                   choiceGroup.setQName(choiceName);
                   .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(), .element.namespace(), null);
                  TypeInfo memberTypeInfo = typeInfo.getTypeInfoFactory().getTypeInfo(member.type());
                  boolean isCol = false;
                  if (memberTypeInfo.isCollection())
                  {
                     memberTypeInfo = ((ClassInfomemberTypeInfo).getComponentType();
                     isCol = true;
                  }
                  TypeBinding memberTypeBinding = resolveTypeBinding(memberTypeInfo);
                  ElementBinding memberElement = createElementBinding(memberTypeInfomemberTypeBindingmemberQNamefalse);
                  memberElement.setNillable(true);
                  ParticleBinding memberParticle = new ParticleBinding(memberElement, 0, 1, isCol);
                  choiceGroup.addParticle(memberParticle);
                  typeBinding.pushInterceptor(memberQName.);
               }
            }
            else
            {
               ParticleBinding choiceParticle = new ParticleBinding(choiceGroup, 0, 1, true);
               model.addParticle(choiceParticle);
            }
            
            if ()
               .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(wildcardPropertywildcardType);
         else
            wildcardHandler = new PropertyWildcardHandler(wildcardPropertywildcardType);
      }
      // Look through the properties
      for (String name : propertyOrder)
      {
         // Setup the error stack
         push(typeInfoname);
         // Get the property
         PropertyInfo property = beanInfo.getProperty(name);
         bindProperty(propertytypeBindingmodelbeanAdapterFactorypropertyOrder);
         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(), child.namespace(), child.name());
            TypeInfo childType = ..getTypeInfo(child.type());
            TypeBinding elementTypeBinding = resolveTypeBinding(childType);
            ElementBinding elementBinding = createElementBinding(childTypeelementTypeBindingqNamefalse);
            // Bind it to the model
            ParticleBinding particle = new ParticleBinding(elementBindingchild.minOccurs(), child.maxOccurs(), child.unbounded());
            model.addParticle(particle);
            if(childType.isMap())
               bindMapProperty(null, (ClassInfochildTypeelementTypeBinding.getQName(), (ModelGroupBindingelementTypeBinding.getParticle().getTerm());
            
            DefaultElementInterceptor interceptor = null;
            if (typeInfo.isCollection())
               interceptor = .;
            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(propertypropertyType);
            }
            typeBinding.pushInterceptor(qNameinterceptor);
            if ()
               .trace("Added interceptor " + qName + " for type=" + childType + " interceptor=" + interceptor);
         }
      }
      // Bind the wildcard
      if (wildcardProperty != null)
      {
         if ()
            .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 = ((ArrayInfowildcardType).getComponentType();
            if ()
               .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("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();
         if (isLax)
            wildcard.setProcessContents((short) 3); // Lax
         else
            wildcard.setProcessContents((short) 1); // Strict
         // Dom element?
         if (Element.class.getName().equals(type.getName()))
         {
            wildcard.setUnresolvedElementHandler(.);
            wildcard.setUnresolvedCharactersHandler(.);
         }
         // Bind the particle to the model
         ParticleBinding particleBinding = new ParticleBinding(wildcard);
         particleBinding.setMinOccurs(0);
         particleBinding.setMaxOccurs(1);
         localModel.addParticle(particleBinding);
         typeBinding.getWildcard().setWildcardHandler((ParticleHandlerwildcardHandler);
         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())
         {
            if (childWildcard.wrapper() != Object.class</