Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
     * JBoss, Home of Professional Open Source
     * Copyright 2005, 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.binding.sunday.unmarshalling;
  
  import java.io.Reader;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.List;
  import java.util.Set;
  
  
  import  org.apache.xerces.xs.StringList;
  import  org.apache.xerces.xs.XSAnnotation;
  import  org.apache.xerces.xs.XSAttributeDeclaration;
  import  org.apache.xerces.xs.XSAttributeUse;
  import  org.apache.xerces.xs.XSComplexTypeDefinition;
  import  org.apache.xerces.xs.XSConstants;
  import  org.apache.xerces.xs.XSElementDeclaration;
  import  org.apache.xerces.xs.XSModel;
  import  org.apache.xerces.xs.XSModelGroup;
  import  org.apache.xerces.xs.XSModelGroupDefinition;
  import  org.apache.xerces.xs.XSNamedMap;
  import  org.apache.xerces.xs.XSObjectList;
  import  org.apache.xerces.xs.XSParticle;
  import  org.apache.xerces.xs.XSSimpleTypeDefinition;
  import  org.apache.xerces.xs.XSTerm;
  import  org.apache.xerces.xs.XSTypeDefinition;
  import  org.apache.xerces.xs.XSWildcard;

Author(s):
Alexey Loubyansky
Version:
$Revision: 3021 $
  
  public class XsdBinder
  {
     static final Logger log = Logger.getLogger(XsdBinder.class);

   
Creates a new instance of the binder the user can use to tune configuration before parsing the XSD.

Returns:
a new instance of the XsdBinder
  
     public static XsdBinder newInstance()
     {
       return new XsdBinder();
     }
   
   
Create a SchemaBinding from and xsd url/uri.

Parameters:
xsdUrl
Returns:
SchemaBinding mapping
  
     public static SchemaBinding bind(String xsdUrl)
     {
        MultiClassSchemaResolver resolver = new MultiClassSchemaResolver();
       resolver.setBaseURI(xsdUrl);
       return bind(xsdUrlresolver);
    }

   
Create a SchemaBinding from and xsd url/uri.

Parameters:
xsdUrl
resolver the resolver will be used to resolve imported schemas in the schema being loaded and also will be set on the returned instance of SchemaBinding
Returns:
SchemaBinding mapping
 
    public static SchemaBinding bind(String xsdUrlSchemaBindingResolver resolver)
    {
       XSModel model = Util.loadSchema(xsdUrlresolver);
       return bind(modelresolver);
    }
 
    public static SchemaBinding bind(InputStream xsdStreamString encoding)
    {
       return bind(xsdStreamencodingnew MultiClassSchemaResolver());
    }

   
Create a SchemaBinding from and xsd stream.

Parameters:
xsdStream - the xsd InputStream
encoding - optional stream encoding
Returns:
SchemaBinding mapping
 
    public static SchemaBinding bind(InputStream xsdStreamString encodingString baseURI)
    {
       return bind(xsdStreamencodingbaseURItrue);
    }

   
Create a SchemaBinding from and xsd stream.

Parameters:
xsdStream - the xsd InputStream
encoding - optional stream encoding
processAnnotations - process annotations
Returns:
SchemaBinding mapping
 
    public static SchemaBinding bind(InputStream xsdStreamString encodingString baseURIboolean processAnnotations)
    {
       MultiClassSchemaResolver resolver = new MultiClassSchemaResolver();
       resolver.setBaseURI(baseURI);
       return bind(xsdStreamencodingresolverprocessAnnotations);
    }

   
Create a SchemaBinding from and xsd stream.

Parameters:
xsdStream - the xsd InputStream
encoding - optional stream encoding
resolver the resolver will be used to resolve imported schemas in the schema being loaded and also will be set on the returned instance of SchemaBinding
Returns:
SchemaBinding mapping
 
    public static SchemaBinding bind(InputStream xsdStreamString encodingSchemaBindingResolver resolver)
    {
       return bind(xsdStreamencodingresolvertrue);
    }

   
Create a SchemaBinding from and xsd stream.

Parameters:
xsdStream - the xsd InputStream
encoding - optional stream encoding
resolver the resolver will be used to resolve imported schemas in the schema being loaded and also will be set on the returned instance of SchemaBinding
processAnnotations whether to process annotations
Returns:
SchemaBinding mapping
 
    public static SchemaBinding bind(InputStream xsdStreamString encodingSchemaBindingResolver resolverboolean processAnnotations)
    {
       XSModel model = Util.loadSchema(xsdStreamencodingresolver);
       return bind(modelresolverprocessAnnotations);
    }
 
    public static SchemaBinding bind(Reader xsdReaderString encoding)
    {
       return bind(xsdReaderencodingnew MultiClassSchemaResolver());
    }

   
Create a SchemaBinding from and xsd reader.

Parameters:
xsdReader - xsd reader
encoding - optional reader encoding
Returns:
SchemaBinding mapping
 
    public static SchemaBinding bind(Reader xsdReaderString encodingString baseURI)
    {
       MultiClassSchemaResolver resolver = new MultiClassSchemaResolver();
       resolver.setBaseURI(baseURI);
       return bind(xsdReaderencodingresolver);
    }

   
Create a SchemaBinding from and xsd reader.

Parameters:
xsdReader - xsd reader
encoding - optional reader encoding
resolver the resolver will be used to resolve imported schemas in the schema being loaded and also will be set on the returned instance of SchemaBinding
Returns:
SchemaBinding mapping
 
    public static SchemaBinding bind(Reader xsdReaderString encodingSchemaBindingResolver resolver)
    {
       XSModel model = Util.loadSchema(xsdReaderencodingresolver);
       return bind(modelresolver);
    }

   
Create a SchemaBinding from and xsd string.

Parameters:
xsd - xsd string
encoding - optional string encoding
Returns:
SchemaBinding mapping
 
    public static SchemaBinding bind(String xsdString encoding)
    {
       return bind(xsdencodingnew MultiClassSchemaResolver());
    }

   
Create a SchemaBinding from and xsd string.

Parameters:
xsd - xsd string
encoding - optional string encoding
resolver the resolver will be used to resolve imported schemas in the schema being loaded and also will be set on the returned instance of SchemaBinding
Returns:
SchemaBinding mapping
 
    public static SchemaBinding bind(String xsdString encodingSchemaBindingResolver resolver)
    {
       XSModel model = Util.loadSchema(xsdencoding);
       return bind(modelresolver);
    }
 
    public static SchemaBinding bind(XSModel modelSchemaBindingResolver resolver)
    {
       return bind(model,resolvertrue);
    }
 
    public static SchemaBinding bind(XSModel modelSchemaBindingResolver resolverboolean processAnnotations)
    {
       XsdBinder binder = new XsdBinder();
       binder.setProcessAnnotations(processAnnotations);
       binder.setSchemaResolver(resolver);
       return binder.parse(model);
    }

   

Deprecated:
This method is added temporary to get anonymous type binding working in JBossWS. It will be removed when anonymous type binding in JBossWS is implemented properly. No one else should use this method.

This method binds a type definition and adds it as a global type to the passed in schema binding.

Parameters:
schema schema binding the type should be added to
type type definition to be bound
 
    public static void bindType(SchemaBinding schema, XSTypeDefinition type)
    {
       XsdBinder binder = new XsdBinder(schema);
       TypeBinding typeBinding = binder.bindType(type);
       schema.addType(typeBinding);
    }

   

Deprecated:
This method is added temporary to get anonymous type binding working in JBossWS. It will be removed when anonymous type binding in JBossWS is implemented properly. No one else should use this method.

This method binds an element declaration and adds it as a global element to the passed in schema binding.

Parameters:
schema schema binding the type should be added to
element element declaration to be bound
minOccurs
maxOccurs
maxOccursUnbounded
 
    public static void bindElement(SchemaBinding schema,
                                   XSElementDeclaration element,
                                   int minOccurs,
                                   int maxOccurs,
                                   boolean maxOccursUnbounded)
    {
       XsdBinder binder = new XsdBinder(schema);
       ParticleBinding particle = binder.bindElement(element,
          minOccurs,
          maxOccurs,
          maxOccursUnbounded
       );
       schema.addElementParticle(particle);
    }
 
    // Exposed attributes
    
    private boolean processAnnotations = true;
    private boolean simpleContentWithIdAsSimpleType = true;
    private boolean unresolvedContentBoundToDOM = true;
    
    // Internal attributes
    
    private boolean trace = .isTraceEnabled();
    private final SchemaBinding schema;
    private SharedElements sharedElements = new SharedElements();
    private final List<ObjecttypeGroupStack = new ArrayList<Object>();
 
    // Ctors
    
    private XsdBinder()
    {
       this(new SchemaBinding());
    }
 
    private XsdBinder(SchemaBinding schema)
    {
       this. = schema;
    }
 
    // Public
    
    public void setProcessAnnotations(boolean processAnnotations)
    {
       this. = processAnnotations;
    }
 
    public boolean isProcessAnnotations()
    {
       return ;
    }
 
    public void setSchemaResolver(SchemaBindingResolver resolver)
    {
       this. = resolver;
    }
 
    {
       return ;
    }
 
    public void setSimpleContentWithIdAsSimpleType(boolean simpleContentWithIdAsSimpleType)
    {
       this. = simpleContentWithIdAsSimpleType;
    }
 
    public boolean isSimpleContentWithIdAsSimpleType()
    {
       return ;
    }
 
    public void setUnresolvedContentBoundToDOM(boolean toDOM)
    {
       this. = toDOM;      
    }
    
    public boolean isUnresolvedContentBoundToDOM()
    {
       return this.;
    }
    
    public SchemaBinding parse(String xsdUrl)
    {
       if( == null)
       {
           = new MultiClassSchemaResolver();
       }
 
       XSModel model = Util.loadSchema(xsdUrl);
       return parse(model);
    }
    
    public SchemaBinding parse(InputStream xsdStreamString encoding)
    {
       if( == null)
       {
           = new MultiClassSchemaResolver();
       }
 
       XSModel model = Util.loadSchema(xsdStreamencoding);
       return parse(model);
    }
    
    public SchemaBinding parse(Reader xsdReaderString encoding)
    {
       if( == null)
       {
           = new MultiClassSchemaResolver();
       }
   
       XSModel model = Util.loadSchema(xsdReaderencoding);
       return parse(model);
    }
 
    
    // Private
 
    private SchemaBinding parse(XSModel model)
    {      
 
       // read annotations. for now just log the ones that are going to be used
       if ()
       {
          XSObjectList annotations = model.getAnnotations();
          if ()
          {
             .trace("started binding schema " + );
             .trace("Schema annotations: " + annotations.getLength());
          }
 
          for(int i = 0; i < annotations.getLength(); ++i)
          {
             XSAnnotation annotation = (XSAnnotation)annotations.item(i);
             XsdAnnotation an = XsdAnnotation.unmarshal(annotation.getAnnotationString());
             XsdAppInfo appinfo = an.getAppInfo();
             if(appinfo != null)
             {
                SchemaMetaData schemaBindings = appinfo.getSchemaMetaData();
                if(schemaBindings != null)
                {
                   // Get the ignoreUnresolvedFieldOrClass
                   .setIgnoreUnresolvedFieldOrClass(schemaBindings.isIgnoreUnresolvedFieldOrClass());
                   // Get the ignoreUnresolvedFieldOrClass
                   .setReplacePropertyRefs(schemaBindings.isReplacePropertyRefs());
                   // Get the default package
                   PackageMetaData packageMetaData = schemaBindings.getPackage();
                   if(packageMetaData != null)
                   {
                      if ()
                         .trace("schema default package: " + packageMetaData.getName());
                      .setPackageMetaData(packageMetaData);
                   }
                }
             }
          }
       }
 
       StringList namespaceList = model.getNamespaces();
       Set<Stringnamespaces = new LinkedHashSet<String>(namespaceList.getLength());
       for (int i = 0; i < namespaceList.getLength(); ++i)
          namespaces.add(namespaceList.item(i));
       .setNamespaces(namespaces);
       
       XSNamedMap groups = model.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
       if ()
          .trace("Model groups: " + groups.getLength());
       // First make sure we bind all the groups
       for(int i = 0; i < groups.getLength(); ++i)
       {
          XSModelGroupDefinition groupDef = (XSModelGroupDefinition)groups.item(i);
          bindGlobalGroup(groupDef);
       }
       // Now bind the particles which may have references to the other groups
       for(int i = 0; i < groups.getLength(); ++i)
       {
          XSModelGroupDefinition groupDef = (XSModelGroupDefinition)groups.item(i);
          bindGlobalGroupParticles(groupDef.getModelGroup());
       }
 
       XSNamedMap types = model.getComponents(XSConstants.TYPE_DEFINITION);
       if ()
          .trace("Model types: " + types.getLength());
       for(int i = 0; i < types.getLength(); ++i)
       {
          XSTypeDefinition type = (XSTypeDefinition)types.item(i);
          if(!..equals(type.getNamespace()))
          {
             bindType(type);
          }
       }
 
       XSNamedMap elements = model.getComponents(XSConstants.ELEMENT_DECLARATION);
       if ()
          .trace("Model elements: " + types.getLength());
       for(int i = 0; i < elements.getLength(); ++i)
       {
          XSElementDeclaration element = (XSElementDeclaration)elements.item(i);
          bindElement(element, 1, 0, false);
       }
 
       {
       }
       
       if ()
       {
          .trace("finished binding schema " + );
       }
 
       return ;
    }
 
    // Private
    
    private TypeBinding bindType(XSTypeDefinition type)
    {
       TypeBinding binding;
       switch(type.getTypeCategory())
       {
          case XSTypeDefinition.SIMPLE_TYPE:
             binding = bindSimpleType((XSSimpleTypeDefinition)type);
             break;
          case XSTypeDefinition.COMPLEX_TYPE:
             binding = bindComplexType((XSComplexTypeDefinition)type);
             break;
          default:
             throw new JBossXBRuntimeException("Unexpected type category: " + type.getTypeCategory());
       }
       return binding;
    }
 
    private TypeBinding bindSimpleType(XSSimpleTypeDefinition type)
    {
       QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
       TypeBinding binding = typeName == null ? null : .getType(typeName);
       if(binding != null)
       {
          return binding;
       }
 
       if()
       {
          .trace("binding simple type " + typeName);
       }
 
       XSTypeDefinition baseTypeDef = type.getBaseType();
       TypeBinding baseType = baseTypeDef == null ? null : bindType(baseTypeDef);
 
       binding = baseType == null ? new TypeBinding(typeName) : new TypeBinding(typeNamebaseType);
 
       StringList strList = type.getLexicalPattern();
       if(strList != null && strList.getLength() > 0)
       {
          for(int i = 0; i < strList.getLength(); ++i)
          {
             binding.addLexicalPattern(strList.item(i));
          }
       }
 
       strList = type.getLexicalEnumeration();
       if(strList != null && strList.getLength() > 0)
       {
          for(int i = 0; i < strList.getLength(); ++i)
          {
             binding.addEnumValue(strList.item(i));
          }
       }
 
       if(type.getItemType() != null)
       {
          TypeBinding itemType = bindSimpleType(type.getItemType());
          binding.setItemType(itemType);
       }
 
       if(typeName != null)
       {
          .addType(binding);
       }
 
       if()
       {
          String msg = typeName == null ? "bound simple anonymous type" : "bound simple type " + typeName;
          if(baseType != null)
          {
             msg += " inherited binding metadata from " + baseType.getQName();
          }
          .trace(msg);
       }
 
       // customize binding with annotations
       if()
       {
          XSObjectList annotations = type.getAnnotations();
          if(annotations != null)
          {
             if()
             {
                .trace(typeName + " annotations " + annotations.getLength());
             }
             for(int i = 0; i < annotations.getLength(); ++i)
             {
                XSAnnotation an = (XSAnnotation)annotations.item(i);
                XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
                XsdAppInfo appInfo = xsdAn.getAppInfo();
                if(appInfo != null)
                {
                   ClassMetaData classMetaData = appInfo.getClassMetaData();
                   if(classMetaData != null)
                   {
                      if()
                      {
                         .trace("simple type " +
                            type.getName() +
                            ": impl=" +
                            classMetaData.getImpl());
                      }
                      binding.setClassMetaData(classMetaData);
                   }
 
                   ValueMetaData valueMetaData = appInfo.getValueMetaData();
                   if(valueMetaData != null)
                   {
                      if()
                      {
                         .trace("simple type " +
                            type.getName() +
                            ": unmarshalMethod=" +
                            valueMetaData.getUnmarshalMethod() +
                            ", marshalMethod=" +
                            valueMetaData.getMarshalMethod());
                      }
                      binding.setValueMetaData(valueMetaData);
                   }
                }
             }
          }
       }
 
       binding.setSchemaBinding();
 
       return binding;
    }
 
    private TypeBinding bindComplexType(XSComplexTypeDefinition type)
    {
       QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
       TypeBinding binding = typeName == null ? null : .getType(typeName);
       if(binding != null)
       {
          return binding;
       }
 
       XSTypeDefinition baseTypeDef = type.getBaseType();
       // anyType is the parent of all the types, even the parent of itself according to xerces :)
       TypeBinding baseType = null;
       if(baseTypeDef != null && !..equals(typeName))
       {
          baseType = bindType(baseTypeDef);
          // sometimes binding the base type can lead to another request
          // to bind the type being bound here
          if(typeName != null)
          {
             binding = .getType(typeName);
             if(binding != null)
             {
                return binding;
             }
          }
       }
 
       if ()
          .trace("binding complex " + (typeName == null ? "anonymous type" : "type " + typeName));
 
       binding = new TypeBinding(typeName);
       binding.setBaseType(baseType);
       binding.setSimple(false);
 
       if(type.getSimpleType() != null)
       {
          TypeBinding simpleType = bindSimpleType(type.getSimpleType());
          binding.setSimpleType(simpleType);
       }
       else if(type.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_MIXED)
       {
          TypeBinding stringType = .getType(.);
          if(stringType == null)
          {
             throw new JBossXBRuntimeException("xsd:string has not been bound yet!");
          }
          binding.setSimpleType(stringType);
       }
 
       if(typeName != null)
       {
          .addType(binding);
       }
 
       binding.setSchemaBinding();
 
       XSObjectList attrs = type.getAttributeUses();
       if ()
          .trace(typeName + " attributes " + attrs.getLength());
 
       AttributeBinding attrBinding = null;
       boolean hasOnlyIdAttrs = true;
       for(int i = 0; i < attrs.getLength(); ++i)
       {
          XSAttributeUse attr = (XSAttributeUse)attrs.item(i);
          attrBinding = bindAttribute(attr);
          binding.addAttribute(attrBinding);
          if(hasOnlyIdAttrs && !..equals(attrBinding.getType().getQName()))
          {
             hasOnlyIdAttrs = false;
          }
       }
       
       // customize binding with xsd annotations
       if ()
       {
          XSObjectList annotations = type.getAnnotations();
          if(annotations != null)
          {
             if ()
                .trace(typeName + " annotations " + annotations.getLength());
             for(int i = 0; i < annotations.getLength(); ++i)
             {
                XSAnnotation an = (XSAnnotation)annotations.item(i);
                XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
                XsdAppInfo appInfo = xsdAn.getAppInfo();
                if(appInfo != null)
                {
                   ClassMetaData classMetaData = appInfo.getClassMetaData();
                   if(classMetaData != null)
                   {
                      if ()
                      {
                         .trace("complex type " +
                            type.getName() +
                            ": impl=" +
                            classMetaData.getImpl()
                         );
                      }
                      binding.setClassMetaData(classMetaData);
                   }
 
                   CharactersMetaData charactersMetaData = appInfo.getCharactersMetaData();
                   if(charactersMetaData != null)
                   {
                      if ()
                      {
                         PropertyMetaData propertyMetaData = charactersMetaData.getProperty();
                         if(propertyMetaData != null)
                         {
                            .trace("complex type " +
                               type.getName() +
                               ": characters bound to " + propertyMetaData.getName()
                            );
                         }
 
                         ValueMetaData valueMetaData = charactersMetaData.getValue();
                         if(valueMetaData != null)
                         {
                            .trace("complex type " +
                               type.getName() +
                               ": characters unmarshalMethod=" +
                               valueMetaData.getUnmarshalMethod() +
                               ", marshalMethod=" + valueMetaData.getMarshalMethod()
                            );
                         }
 
                         boolean mapEntryKey = appInfo.isMapEntryKey();
                         if(mapEntryKey)
                         {
                            .trace("complex type " +
                               type.getName() +
                               ": characters are bound as a key in a map entry"
                            );
                         }
 
                         boolean mapEntryValue = appInfo.isMapEntryValue();
                         if(mapEntryValue)
                         {
                            .trace("complex type " +
                               type.getName() +
                               ": characters are bound as a value in a map entry"
                            );
                         }
                      }
                      binding.setCharactersMetaData(charactersMetaData);
                   }
 
                   MapEntryMetaData mapEntryMetaData = appInfo.getMapEntryMetaData();
                   if(mapEntryMetaData != null)
                   {
                      if ()
                      {
                         .trace("complex type " +
                            type.getName() +
                            " is bound to a map entry: impl=" +
                            mapEntryMetaData.getImpl() +
                            ", getKeyMethod=" +
                            mapEntryMetaData.getGetKeyMethod() +
                            ", setKeyMethod=" +
                            mapEntryMetaData.getSetKeyMethod() +
                            ", getValueMethod=" +
                            mapEntryMetaData.getGetValueMethod() +
                            ", setValueMethod=" +
                            mapEntryMetaData.getSetValueMethod() +
                            ", valueType=" +
                            mapEntryMetaData.getValueType() +
                            ", nonNullValue=" + mapEntryMetaData.isNonNullValue()
                         );
                      }
 
                      if(classMetaData != null)
                      {
                         throw new JBossXBRuntimeException("Illegal binding: both jbxb:class and jbxb:mapEntry are specified for complex type " +
                            type.getName()
                         );
                      }
                      binding.setMapEntryMetaData(mapEntryMetaData);
                   }
 
                   boolean skip = appInfo.isSkip();
                   if(skip)
                   {
                      if ()
                      {
                         .trace("complex type " +
                            type.getName() +
                            ": elements of this type will be skipped; their attrs, character content " +
                            "and elements will be set the parent."
                         );
                      }
                      binding.setSkip(skip);
                   }
 
                   PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
                   if(propertyMetaData != null)
                   {
                      if ()
                      {
                         .trace("complex type " +
                            type.getName() +
                            ": the content of elements of this type is bound to property " + propertyMetaData.getName()
                         );
                      }
                      binding.setPropertyMetaData(propertyMetaData);
                   }
 
                   AddMethodMetaData addMethodMetaData = appInfo.getAddMethodMetaData();
                   if(addMethodMetaData != null)
                   {
                      if ()
                      {
                         .trace("complex type " +
                            type.getName() +
                            ": elements of this type will be added to parent objects with addMethod=" +
                            addMethodMetaData.getMethodName() + ", valueType=" + addMethodMetaData.getValueType()
                         );
                      }
                      binding.setAddMethodMetaData(addMethodMetaData);
                   }
                }
             }
          }
       }
 
       XSParticle particle = type.getParticle();
       if(particle != null)
       {
          pushType(binding);
          bindParticle(particle);
          popType();
       }
 
       if(binding.getClassMetaData() == null &&
              &&
             particle == null && hasOnlyIdAttrs)
       {
          binding.setStartElementCreatesObject(false);
       }
       else
       {
          binding.setStartElementCreatesObject(true);
       }
       
       if(binding.hasOnlyXmlMimeAttributes())
       {
          addXOPInclude(binding);
       }
 
       if()
       {
          .trace(typeName == null ? "bound complex anonymous type" : "bound complex type " + typeName);
       }
 
       return binding;
    }
 
    private AttributeBinding bindAttribute(XSAttributeUse attrUse)
    {
       XSAttributeDeclaration attr = attrUse.getAttrDeclaration();
       QName attrName = new QName(attr.getNamespace(), attr.getName());
 
       XSSimpleTypeDefinition attrType = attr.getTypeDefinition();
       TypeBinding typeBinding = bindSimpleType(attrType);
 
       if ()
       {
          .trace("binding attribute " + attrName + ", required=" + attrUse.getRequired());
       }
 
       AttributeBinding binding = new AttributeBinding(attrNametypeBinding.);
       binding.setRequired(attrUse.getRequired());
       if(attrUse.getConstraintType() == XSConstants.VC_DEFAULT)
       {
          // Associate the default value with the binding
          binding.setDefaultConstraint(attrUse.getConstraintValue());
       }
 
       if ()
       {
          XSAnnotation an = attr.getAnnotation();
          if(an != null)
          {
             if ()
             {
                .trace(attrName + " attribute annotation");
             }
 
             XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
             XsdAppInfo appInfo = xsdAn.getAppInfo();
             if(appInfo != null)
             {
                PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
                if(propertyMetaData != null)
                {
                   binding.setPropertyMetaData(propertyMetaData);
                }
 
                boolean mapEntryKey = appInfo.isMapEntryKey();
                if(mapEntryKey)
                {
                   binding.setMapEntryKey(mapEntryKey);
                }
 
                boolean mapEntryValue = appInfo.isMapEntryValue();
                if(mapEntryValue)
                {
                   binding.setMapEntryValue(mapEntryValue);
                }
             }
          }
       }
 
 
       if ()
       {
          String msg = "bound attribute " + attrName;
 
          if(binding.getPropertyMetaData() != null)
          {
             msg += " property=" +
                binding.getPropertyMetaData().getName() +
                ", collectionType=" + binding.getPropertyMetaData().getCollectionType();
          }
          else if(binding.isMapEntryKey())
          {
             msg += "bound as a key in a map entry";
          }
          else if(binding.isMapEntryValue())
          {
             msg += "bound as a value in a map entry";
          }
          else
          {
             msg += " type=" + attrType.getName();
          }
 
          if(binding.getDefaultConstraint() != null)
          {
             msg += ", default=" + binding.getDefaultConstraint();
          }
 
          .trace(msg);
       }
       
       return binding;
    }
 
    private void bindParticle(XSParticle particle)
    {
       XSTerm term = particle.getTerm();
       switch(term.getType())
       {
          case XSConstants.MODEL_GROUP:
             XSModelGroup modelGroup = (XSModelGroup)term;
             // todo: investigate this
             if(modelGroup.getParticles().getLength() > 0)
             {
                ModelGroupBinding groupBinding = bindModelGroup(modelGroup);
 
                ParticleBinding particleBinding = new ParticleBinding(groupBinding);
                particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
                particleBinding.setMinOccurs(particle.getMinOccurs());
                particleBinding.setMaxOccurs(particle.getMaxOccurs());
 
                Object o = peekTypeOrGroup();
                if(o instanceof ModelGroupBinding)
                {
                   ModelGroupBinding parentGroup = (ModelGroupBinding)o;
                   parentGroup.addParticle(particleBinding);
                   if ()
                  {
                     .trace("added " + groupBinding + " to " + parentGroup);
                  }
               }
               else if(o instanceof TypeBinding)
               {
                  TypeBinding typeBinding = (TypeBinding)o;
                  typeBinding.setParticle(particleBinding);
                  if ()
                  {
                     .trace("added " + groupBinding + " to type " + typeBinding.getQName());
                  }
               }
               if (groupBinding.getParticles().isEmpty())
               {
                  pushModelGroup(groupBinding);
                  bindModelGroupParticles(modelGroup);
                  popModelGroup();
               }
            }
            break;
         case XSConstants.WILDCARD:
            bindWildcard(particle);
            break;
         case XSConstants.ELEMENT_DECLARATION:
            bindElement(
               (XSElementDeclaration)term,
               particle.getMinOccurs(),
               particle.getMaxOccurs(),
               particle.getMaxOccursUnbounded()
            );
            break;
         default:
            throw new IllegalStateException("Unexpected term type: " + term.getType());
      }
   }
   private ModelGroupBinding bindModelGroup(XSModelGroup modelGroup)
   {
      // Is this a global group?
      ModelGroupBinding groupBinding = .getGlobalGroup(modelGroup);
      if (groupBinding != null)
         return groupBinding;
      
      switch(modelGroup.getCompositor())
      {
         case XSModelGroup.COMPOSITOR_ALL:
            groupBinding = new AllBinding();
            break;
         case XSModelGroup.COMPOSITOR_CHOICE:
            groupBinding = new ChoiceBinding();
            break;
         case XSModelGroup.COMPOSITOR_SEQUENCE:
            groupBinding = new SequenceBinding();
            break;
         default:
            throw new JBossXBRuntimeException("Unexpected model group: " + modelGroup.getCompositor());
      }
      if ()
         .trace("created model group " + groupBinding);
      if ()
      {
         XSAnnotation annotation = modelGroup.getAnnotation();
         if (annotation != null)
            customizeTerm(annotationgroupBinding);
      }
      return groupBinding;
   }
   private void bindWildcard(XSParticle particle)
   {
      WildcardBinding binding = new WildcardBinding();
      ParticleBinding particleBinding = new ParticleBinding(binding);
      particleBinding.setMaxOccurs(particle.getMaxOccurs());
      particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
      particleBinding.setMinOccurs(particle.getMinOccurs());
      group.addParticle(particleBinding);
      XSWildcard wildcard = (XSWildcard)particle.getTerm();
      if(wildcard.getName() != null)
      {
         binding.setQName(new QName(wildcard.getNamespace(), wildcard.getName()));
      }
      binding.setProcessContents(wildcard.getProcessContents());
      if ()
      {
         XSAnnotation annotation = wildcard.getAnnotation();
         if(annotation != null)
         {
            customizeTerm(annotationbinding);
         }
      }
   }
   private ParticleBinding bindElement(XSElementDeclaration elementDec,
                                       int minOccurs,
                                       int maxOccurs,
                                       boolean maxOccursUnbounded)
   {
      QName qName = new QName(elementDec.getNamespace(), elementDec.getName());
      boolean global = elementDec.getScope() == XSConstants.SCOPE_GLOBAL;
      ElementBinding element = .getElement(qName);
      ParticleBinding particle;
      if(global && element != null)
      {
         particle = new ParticleBinding(element);
         if(parentGroup != null)
         {
            parentGroup.addParticle(particle);
         }
         particle.setMinOccurs(minOccurs);
         if(maxOccursUnbounded)
         {
            particle.setMaxOccursUnbounded(maxOccursUnbounded);
         }
         else
         {
            particle.setMaxOccurs(maxOccurs);
         }
         return particle;
      }
      TypeBinding type = null;
      boolean shared = .isShared(elementDec);
      if(shared)
      {
         type = .getTypeBinding(elementDec);
      }
      if(type == null)
      {
         type = bindType(elementDec.getTypeDefinition());
         if(shared)
         {
            .setTypeBinding(elementDectype);
         }
      }
      element = new ElementBinding(qNametype);
      element.setNillable(elementDec.getNillable());
      particle = new ParticleBinding(element);
      particle.setMinOccurs(minOccurs);
      particle.setMaxOccurs(maxOccurs);
      particle.setMaxOccursUnbounded(maxOccursUnbounded);
      if(global)
      {
         .addElementParticle(particle);
      }
      if(parentGroup != null)
      {
         parentGroup.addParticle(particle);
         if ()
         {
            .trace("Element " + element.getQName() + " added to " + parentGroup);
         }
      }
      if ()
      {
         TypeBinding parentType = peekType();
         QName parentQName = null;
         if (parentType != null)
            parentQName = parentType.getQName();
         .trace("element: name=" +
            qName +
            ", type=" +
            type.getQName() +
            ", repeatable=" +
            particle.isRepeatable() +
            ", nillable=" +
            element.isNillable() +
            ", minOccurs=" + minOccurs +
            ", maxOccurs=" + (maxOccursUnbounded ? "unbounded" : "" + maxOccurs) +
            ", " + (global ? "global scope" : " owner type=" + parentQName)
         );
      }
      // customize element with annotations
      if ()
      {
         XSAnnotation an = elementDec.getAnnotation();
         if(an != null)
         {
            customizeTerm(anelement