[jboss-svn-commits] JBoss Common SVN: r3358 - in jbossxb/trunk/src: main/java/org/jboss/xb/util and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Jul 9 07:10:50 EDT 2009


Author: alesj
Date: 2009-07-09 07:10:50 -0400 (Thu, 09 Jul 2009)
New Revision: 3358

Added:
   jbossxb/trunk/src/main/java/org/jboss/xb/util/DefaultSchemaBindingValidator.java
Modified:
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/resolver/AbstractMutableSchemaResolver.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/resolver/MutableSchemaResolver.java
   jbossxb/trunk/src/main/java/org/jboss/xb/util/SchemaBindingValidator.java
   jbossxb/trunk/src/test/java/org/jboss/test/xb/validator/test/BasicBindingValidatorUnitTestCase.java
   jbossxb/trunk/src/test/java/org/jboss/test/xb/validator/test/ValidatingResolverUnitTestCase.java
Log:
[JBXB-213]; introduce SBV as interface.
Fix "choice" test depending on JVM order.

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/resolver/AbstractMutableSchemaResolver.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/resolver/AbstractMutableSchemaResolver.java	2009-07-09 05:44:28 UTC (rev 3357)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/resolver/AbstractMutableSchemaResolver.java	2009-07-09 11:10:50 UTC (rev 3358)
@@ -37,6 +37,7 @@
 import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingInitializer;
 import org.jboss.xb.binding.sunday.unmarshalling.XsdBinder;
 import org.jboss.xb.builder.JBossXBBuilder;
+import org.jboss.xb.util.DefaultSchemaBindingValidator;
 import org.jboss.xb.util.SchemaBindingValidator;
 import org.w3c.dom.ls.LSInput;
 import org.xml.sax.InputSource;
@@ -91,7 +92,7 @@
     * Enables/disables validation of SchemaBinding instances built from JAXB/JBossXB annotations
     * against the corresponding XSD schemas.
     * 
-    * @param validateBinding
+    * @param validateBinding validate binding flag
     */
    public void setValidateBinding(boolean validateBinding)
    {
@@ -113,10 +114,10 @@
    /**
     * Sets the validator which should be used to validate SchemaBinding instances built from JAXB/JBossXB annotations
     * if validation is enabled.
-    * By default validator is not initialized. And if validation is enabled a new instance of SchemaBindingValidator
+    * By default validator is not initialized. And if validation is enabled a new instance of DefaultSchemaBindingValidator
     * will be created and used for validation for every new SchemaBinding.
     * 
-    * @param validator
+    * @param validator the schema binding validator
     */
    public void setBindingValidator(SchemaBindingValidator validator)
    {
@@ -133,12 +134,13 @@
     * schemas (which is the default) with namespace URI being the identifier of a schema.
     * False will flush the cache and make the schema resolver to resolve schemas
     * on each request.
-    * @param cacheResolvedSchemas
+    *
+    * @param cacheResolvedSchemas do we cache resolved schemas
     */
    public void setCacheResolvedSchemas(boolean cacheResolvedSchemas)
    {
       this.cacheResolvedSchemas = cacheResolvedSchemas;
-      if(!cacheResolvedSchemas)
+      if(cacheResolvedSchemas == false)
       {
          schemasByUri = Collections.emptyMap();
       }
@@ -319,7 +321,8 @@
             {
                SchemaBindingValidator validator = this.validator;
                if(validator == null)
-                  validator = new SchemaBindingValidator(this);
+                  validator = new DefaultSchemaBindingValidator(this);
+
                validator.validate(is, schema);
             }
             else
@@ -345,7 +348,7 @@
                baseURI = this.baseURI;
    
             Boolean processAnnotationsBoolean = schemaParseAnnotationsByUri.get(nsURI);
-            boolean processAnnotations = (processAnnotationsBoolean == null) ? true : processAnnotationsBoolean.booleanValue();
+            boolean processAnnotations = (processAnnotationsBoolean == null) || processAnnotationsBoolean;
             try
             {
                schema = XsdBinder.bind(is.getByteStream(), null, baseURI, processAnnotations);

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/resolver/MutableSchemaResolver.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/resolver/MutableSchemaResolver.java	2009-07-09 05:44:28 UTC (rev 3357)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/resolver/MutableSchemaResolver.java	2009-07-09 11:10:50 UTC (rev 3358)
@@ -42,7 +42,8 @@
     * passing in true will enable caching.
     * False will (possibly) flush the cache and make the schema resolver resolve schemas
     * on each request.
-    * @param cacheResolvedSchemas
+    *
+    * @param cacheResolvedSchemas cache resolved schemas flag
     */
    void setCacheResolvedSchemas(boolean cacheResolvedSchemas);
    

Copied: jbossxb/trunk/src/main/java/org/jboss/xb/util/DefaultSchemaBindingValidator.java (from rev 3357, jbossxb/trunk/src/main/java/org/jboss/xb/util/SchemaBindingValidator.java)
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/util/DefaultSchemaBindingValidator.java	                        (rev 0)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/util/DefaultSchemaBindingValidator.java	2009-07-09 11:10:50 UTC (rev 3358)
@@ -0,0 +1,805 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+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.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;
+import org.jboss.logging.Logger;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.Util;
+import org.jboss.xb.binding.resolver.MultiClassSchemaResolver;
+import org.jboss.xb.binding.sunday.unmarshalling.AllBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.AttributeBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ChoiceBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingResolver;
+import org.jboss.xb.binding.sunday.unmarshalling.SequenceBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.UnorderedSequenceBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.WildcardBinding;
+import org.xml.sax.InputSource;
+
+/**
+ * This class is used to check consistency between SchemaBinding instances and their corresponding XSD schemas.
+ * It can be configured to exclude (or include) validation of certain namespaces
+ * (i.e. types, elements and model groups from certain namespaces).
+ * By default, namespace "http://www.w3.org/2001/XMLSchema" is excluded.
+ *
+ * Also specific types identified by their QName can be excluded or included from validation.
+ * Simple XSD types are validated only if present in SchemaBinding. The reason for that is
+ * many simple types are bound/represented in Java model by java.lang.String
+ * which when building SchemaBinding is bound to xsd:string.
+ *
+ * Current implementation does not ensures complete consistency but only the basics such as
+ * existence of type definitions, element declarations, element ordering in groups and
+ * possible occurences of particles.
+ *
+ * When an inconsistency is found handleError(String msg) is called. The default implementation
+ * of which throws IllegalStateException. Subclasses can override this method to report errors
+ * differently.
+ *
+ * Sometimes the error itself may not be informative enough to e.g. identify the location
+ * of the inconsistency in the schema. In this case logging should be enabled.
+ * Default logger is an instance of org.jboss.logging.Logger with category org.jboss.xb.util.SchemaBindingValidator.
+ * All the messages are logged from method log(String msg) which subclasses can override.
+ *
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @version $Revision: 1.1 $
+ */
+public class DefaultSchemaBindingValidator implements SchemaBindingValidator
+{
+   private static final Logger log = Logger.getLogger(DefaultSchemaBindingValidator.class);
+
+   private static final QName WILDCARD = new QName("wildcard", "wildcard");
+
+   private Set<String> excludedNs = new HashSet<String>();
+   private Set<QName> excludedTypes = new HashSet<QName>();
+
+   private Set<QName> validatedTypes = new HashSet<QName>();
+   private Set<QName> validatedElements = new HashSet<QName>();
+
+   private SchemaBindingResolver resolver;
+
+   private boolean loggingEnabled;
+
+   public DefaultSchemaBindingValidator()
+   {
+      reset();
+      excludeNs(Constants.NS_XML_SCHEMA);
+   }
+
+   /**
+    * @param resolver  default schema resolver
+    */
+   public DefaultSchemaBindingValidator(SchemaBindingResolver resolver)
+   {
+      this();
+      this.resolver = resolver;
+   }
+
+   /**
+    * Resets instance variables (such as a set of validated types, elements and also loggingEnabled property).
+    * This method is required to invoked before another validation.
+    * It is called internally at the end of validate(XSModel xsSchema, SchemaBinding schemaBinding).
+    * NOTE: this method doesn't clear excluded namespaces and types.
+    */
+   public void reset()
+   {
+      loggingEnabled = log.isTraceEnabled();
+      validatedTypes.clear();
+      validatedElements.clear();
+   }
+
+   public boolean isLoggingEnabled()
+   {
+      return loggingEnabled;
+   }
+
+   public void enableLogging(boolean value)
+   {
+      loggingEnabled = value;
+   }
+
+   /**
+    * Types and elements from the namespace passed into this method will be excluded from validation.
+    *
+    * @param ns  namespace to exclude
+    */
+   public void excludeNs(String ns)
+   {
+      excludedNs.add(ns);
+   }
+
+   /**
+    * Checks if the specified namespace is excluded from validation.
+    *
+    * @param ns  the namespace to check
+    * @return  true if the namespace is excluded
+    */
+   public boolean isNsExcluded(String ns)
+   {
+      return excludedNs.contains(ns);
+   }
+
+   /**
+    * Removes the namespace from the excluded set. If the namespace has not been excluded, the method does nothing.
+    *
+    * @param ns  the namespace to remove from the excluded set.
+    */
+   public void includeNs(String ns)
+   {
+      excludedNs.remove(ns);
+   }
+
+   /**
+    * Excludes the specified type from validation.
+    *
+    * @param qName  the QName of the type to exclude from validation
+    */
+   public void excludeType(QName qName)
+   {
+      excludedTypes.add(qName);
+   }
+
+   /**
+    * Checks if the type is excluded from validation.
+    *
+    * @param qName  the QName of the type to check
+    * @return  true if the type is excluded from validation
+    */
+   public boolean isTypeExcluded(QName qName)
+   {
+      return excludedTypes.contains(qName);
+   }
+
+   /**
+    * Removes the specified type from the excluded set. If the type has not been excluded, the method does nothing.
+    *
+    * @param qName  the QName of type to remove from the excluded set.
+    */
+   public void includeType(QName qName)
+   {
+      excludedTypes.remove(qName);
+   }
+
+   /**
+    * @return The default resolver used to resolve schemas
+    */
+   public SchemaBindingResolver getSchemaResolver()
+   {
+      return resolver;
+   }
+
+   /**
+    * @param resolver  The default resolver used to resolve schemas
+    */
+   public void setSchemaResolver(SchemaBindingResolver resolver)
+   {
+      this.resolver = resolver;
+   }
+
+   /**
+    * This method will check that the XSD represented with InputSource and SchemaBinding are consistent.
+    * The consistency is checked to certain degree and is far from 100%. Currently it checks just for basic things
+    * such as the existence of type definitions, attribute and element declarations and element ordering.
+    *
+    * @param is  InputSource of the XSD
+    * @param binding  SchemaBinding
+    */
+   public void validate(InputSource is, SchemaBinding binding)
+   {
+      SchemaBindingResolver resolver = binding.getSchemaResolver();
+      if(resolver == null)
+      {
+         resolver = this.resolver;
+         if(resolver == null)
+            log("Schema resolver was not provided");
+      }
+      XSModel xsModel = Util.loadSchema(is, resolver);
+      validate(xsModel, binding);
+   }
+
+   public void validate(String xsdName, Class<?>... cls)
+   {
+      log("validate: " + xsdName + ", " + Arrays.asList(cls));
+
+      URL xsdUrl = Thread.currentThread().getContextClassLoader().getResource("schema/" + xsdName);
+      if(xsdUrl == null)
+         handleError("Failed to load schema from the classpath: schema/" + xsdName);
+
+      MultiClassSchemaResolver multiClassResolver = new MultiClassSchemaResolver();
+      multiClassResolver.mapLocationToClasses(xsdName, cls);
+      SchemaBinding binding = resolver.resolve("", null, xsdName);
+
+      SchemaBindingResolver resolver = this.resolver;
+      if(resolver == null)
+         resolver = multiClassResolver;
+
+      XSModel xsModel;
+      try
+      {
+         xsModel = Util.loadSchema(xsdUrl.openStream(), null, resolver);
+      }
+      catch (IOException e)
+      {
+         throw new IllegalStateException("Failed to read schema " + xsdName, e);
+      }
+
+      validate(xsModel, binding);
+   }
+
+   public void validate(XSModel xsSchema, SchemaBinding schemaBinding)
+   {
+      try
+      {
+         /* TODO groups are not properly bound
+         XSNamedMap groups = xsSchema.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
+         for(int i = 0; i < groups.getLength(); ++i)
+         {
+            XSModelGroupDefinition xsGroupDef = (XSModelGroupDefinition)groups.item(i);
+            System.out.println(xsGroupDef.getName());
+            QName groupQName = new QName(xsGroupDef.getNamespace(), xsGroupDef.getName());
+            ModelGroupBinding groupBinding = schemaBinding.getGroup(groupQName);
+            assertNotNull("Group " + groupQName + " exists in the schema binding.", groupBinding);
+         }
+         */
+
+         XSNamedMap types = xsSchema.getComponents(XSConstants.TYPE_DEFINITION);
+         for (int i = 0; i < types.getLength(); ++i)
+         {
+            XSTypeDefinition xsType = (XSTypeDefinition) types.item(i);
+            if (excludedNs.contains(xsType.getNamespace()))
+               continue;
+
+            QName typeQName = new QName(xsType.getNamespace(), xsType.getName());
+            if (excludedTypes.contains(typeQName))
+               continue;
+
+            TypeBinding typeBinding = schemaBinding.getType(typeQName);
+            if (typeBinding == null)
+            {
+               boolean ignoreIfNotFound = false;
+               if (xsType.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE)
+               {
+                  ignoreIfNotFound = true;
+               }
+               else
+               {
+                  XSComplexTypeDefinition xsComplexType = (XSComplexTypeDefinition) xsType;
+                  if (xsComplexType.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_SIMPLE)
+                  {
+                     XSObjectList attributeUses = xsComplexType.getAttributeUses();
+                     if (attributeUses.getLength() == 0)
+                     {
+                        ignoreIfNotFound = true;
+                     }
+                     else if (attributeUses.getLength() == 1)
+                     {
+                        XSAttributeUse xsAttrUse = (XSAttributeUse) attributeUses.item(0);
+                        XSAttributeDeclaration xsAttr = xsAttrUse.getAttrDeclaration();
+                        if (xsAttr.getNamespace() == null && "id".equals(xsAttr.getName()))
+                           ignoreIfNotFound = true;
+                     }
+                  }
+               }
+
+               if (!ignoreIfNotFound)
+               {
+                  if (isLoggingEnabled())
+                  {
+                     log("SchemaBinding global types: ");
+                     for (Iterator<TypeBinding> iter = schemaBinding.getTypes(); iter.hasNext();)
+                     {
+                        TypeBinding type = iter.next();
+                        if (!excludedNs.contains(type.getQName().getNamespaceURI()))
+                           log("- " + type.getQName());
+                     }
+                  }
+
+                  handleError("TypeBinding " + typeQName + " is not found in the SchemaBinding.");
+               }
+            }
+            else
+            {
+               validate(xsType, typeBinding);
+            }
+         }
+
+         XSNamedMap elements = xsSchema.getComponents(XSConstants.ELEMENT_DECLARATION);
+         for (int i = 0; i < elements.getLength(); ++i)
+         {
+            XSElementDeclaration xsElement = (XSElementDeclaration) elements.item(i);
+            if (excludedNs.contains(xsElement.getNamespace()))
+               continue;
+            QName elementQName = new QName(xsElement.getNamespace(), xsElement.getName());
+            ElementBinding elementBinding = schemaBinding.getElement(elementQName);
+            if (elementBinding == null)
+               handleError("ElementBinding " + elementQName + " is not found in the SchemaBinding.");
+            validate(xsElement.getTypeDefinition(), elementBinding.getType());
+         }
+      }
+      finally
+      {
+         reset();
+      }
+   }
+
+   public void validate(XSElementDeclaration xsElement, ElementBinding elementBinding)
+   {
+      QName xsQName = new QName(xsElement.getNamespace(), xsElement.getName());
+      if(xsQName.equals(elementBinding.getQName()))
+         handleError("Compared elements have difference names: XSD QName is " + xsQName + ", ElementBinding QName is " + elementBinding.getQName());
+
+      log("element " + xsQName);
+
+      if(validatedElements.contains(xsQName))
+         return;
+      validatedElements.add(xsQName);
+
+      validate(xsElement.getTypeDefinition(), elementBinding.getType());
+   }
+
+   public void validate(XSTypeDefinition xsType, TypeBinding typeBinding)
+   {
+      if(xsType.getName() == null)
+      {
+         if(typeBinding.getQName() != null)
+            handleError("XSD type is anonymous but TypeBinding has QName " + typeBinding.getQName());
+      }
+      else
+      {
+         if(excludedNs.contains(xsType.getNamespace()))
+            return;
+
+         QName xsQName = new QName(xsType.getNamespace(), xsType.getName());
+         if(!xsQName.equals(typeBinding.getQName()))
+            handleError("Compared types have different names: XSD QName is " + xsQName + ", TypeBinding QName is " + typeBinding.getQName());
+
+         if(validatedTypes.contains(xsQName) || excludedTypes.contains(xsQName))
+            return;
+         validatedTypes.add(xsQName);
+      }
+
+      if(xsType.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE)
+         validate((XSSimpleTypeDefinition)xsType, typeBinding);
+      else
+         validate((XSComplexTypeDefinition)xsType, typeBinding);
+   }
+
+   public void validate(XSSimpleTypeDefinition xsType, TypeBinding typeBinding)
+   {
+      // TODO there could xsd types that are mapped to String which is bound by default to xsd:string
+      //QName xsQName = xsType.getName() == null ? null : new QName(xsType.getNamespace(), xsType.getName());
+      //assertEquals("Simple type expected to be " + (xsType == null ? "anonymous" : "named '" + xsQName + "'"), xsQName, typeBinding.getQName());
+
+      if(!typeBinding.isSimple())
+         handleError("XSD type " + typeBinding.getQName() + " is simple but TypeBinding is not.");
+      // TODO the rest of the simple type stuff?
+   }
+
+   public void validate(XSComplexTypeDefinition xsType, TypeBinding typeBinding)
+   {
+      QName xsQName = xsType.getName() == null ? null : new QName(xsType.getNamespace(), xsType.getName());
+
+      log("complex type " + xsQName);
+
+      if(xsQName == null && typeBinding.getQName() != null ||
+            xsQName != null && !xsQName.equals(typeBinding.getQName()))
+         handleError("Compared complex types have different names: XSD QName is " + xsQName + ", TypeBindign QName is " + typeBinding.getQName());
+
+      XSObjectList xsAttrUses = xsType.getAttributeUses();
+      if(xsAttrUses.getLength() == 0)
+      {
+         // TODO missing id attributes in the schema
+         //assertTrue("Type " + typeBinding.getQName() + " has no attributes in the schema", typeBinding.getAttributes().isEmpty());
+      }
+      else
+      {
+         for(int i = 0; i < xsAttrUses.getLength(); ++i)
+         {
+            XSAttributeDeclaration xsAttr = ((XSAttributeUse)xsAttrUses.item(i)).getAttrDeclaration();
+            QName xsAttrQName = new QName(xsAttr.getNamespace(), xsAttr.getName());
+            AttributeBinding attrBinding = typeBinding.getAttribute(xsAttrQName);
+            if(attrBinding == null)
+               handleError("Attribute " + xsAttrQName + " is not found in TypeBinding " + typeBinding.getQName());
+            validate(xsAttr.getTypeDefinition(), attrBinding.getType());
+         }
+      }
+
+      XSWildcard xsAttrWildcard = xsType.getAttributeWildcard();
+      if(xsAttrWildcard != null && typeBinding.getAnyAttribute() == null)
+         handleError("TypeBinding " + typeBinding.getQName() + " doesn't have AnyAttributeBinding");
+
+      XSSimpleTypeDefinition xsSimpleType = xsType.getSimpleType();
+      if(xsSimpleType != null)
+      {
+         TypeBinding simpleTypeBinding = typeBinding.getSimpleType();
+         if(simpleTypeBinding == null)
+            handleError("XSD type " + typeBinding.getQName() + " allows text content but its corresponding TypeBinding doesn't.");
+         validate(xsSimpleType, simpleTypeBinding);
+      }
+
+      XSParticle xsParticle = xsType.getParticle();
+      if(xsParticle != null)
+      {
+         ParticleBinding particleBinding = typeBinding.getParticle();
+         if(particleBinding == null)
+            handleError("TypeBinding " + xsQName + " doesn't contain a ParticleBinding.");
+         validate(xsParticle, particleBinding);
+      }
+   }
+
+   public void validate(XSParticle xsParticle, ParticleBinding particleBinding)
+   {
+      XSTerm xsTerm = xsParticle.getTerm();
+      TermBinding termBinding = particleBinding.getTerm();
+      if(termBinding == null)
+         handleError("ParticleBinding doesn't contain a TermBinding.");
+      short xsTermType = xsTerm.getType();
+      String termStr = null;
+      if(xsTermType == XSConstants.MODEL_GROUP)
+      {
+         termStr = "sequence";
+         XSModelGroup xsModelGroup = (XSModelGroup)xsTerm;
+         short xsModelGroupCompositor = (xsModelGroup).getCompositor();
+         if(XSModelGroup.COMPOSITOR_CHOICE == xsModelGroupCompositor)
+            termStr = "choice";
+         else if(XSModelGroup.COMPOSITOR_ALL == xsModelGroupCompositor)
+            termStr = "all";
+
+         if(!termBinding.isModelGroup())
+         {
+            // TODO review this
+            // let's see whether it's wrapped
+            if(xsModelGroup.getParticles().getLength() == 1)
+            {
+               XSParticle xsWrappedParticle = (XSParticle) xsModelGroup.getParticles().item(0);
+               validate(xsWrappedParticle, particleBinding);
+            }
+            else
+               handleError("TermBinding expected to be a " + termStr + " but was " + termBinding);
+         }
+         else
+            validate(xsModelGroup, (ModelGroupBinding) termBinding);
+      }
+      else if(xsTermType == XSConstants.ELEMENT_DECLARATION)
+      {
+         XSElementDeclaration xsElement = (XSElementDeclaration) xsTerm;
+         QName xsElementName = new QName(xsElement.getNamespace(), xsElement.getName());
+         termStr = xsElementName.toString();
+
+         if(!termBinding.isElement())
+         {
+            // TODO sometimes XB wraps (maybe unnecessarily) repeatable elements into a sequence.
+            // the same xml structure can be described differently in xsd
+            if (/*(xsParticle.getMaxOccursUnbounded() || xsParticle.getMaxOccurs() > 1) &&*/
+                  termBinding instanceof SequenceBinding)
+            {
+               SequenceBinding seq = (SequenceBinding) termBinding;
+               Collection<ParticleBinding> particles = seq.getParticles();
+               if(particles.size() == 1)
+               {
+                  ParticleBinding particle = particles.iterator().next();
+                  if(particle.getTerm().isElement())
+                  {
+                     particleBinding = particle;
+                     termBinding = particle.getTerm();
+                  }
+               }
+            }
+
+            if(!termBinding.isElement())
+               handleError("TermBinding expected to be element " + termStr + " but was " + termBinding);
+         }
+
+         if(!xsElementName.equals(((ElementBinding)termBinding).getQName()))
+            handleError("Compared elements have different names: XSD QName is " + xsElementName + ", ElementBinding QName is " + ((ElementBinding)termBinding).getQName());
+      }
+      else if(xsTermType == XSConstants.WILDCARD)
+      {
+         if(!termBinding.isWildcard())
+            handleError("TermBinding expected to be a wildcard but was " + termBinding);
+         XSWildcard xsWildcard = (XSWildcard) xsTerm;
+         WildcardBinding wildcardBinding = (WildcardBinding) termBinding;
+         if(xsWildcard.getProcessContents() != wildcardBinding.getProcessContents())
+            throw new IllegalStateException("Wildcard processContents doesn't match: XSD processContents is " + xsWildcard.getProcessContents() +
+                  ", WildcardBinding processContents is " + wildcardBinding.getProcessContents());
+         termStr = "wildcard";
+      }
+      else
+         handleError("Unexpected XSTerm type: " + xsTermType);
+
+      // TODO minOccurs is not trivial for flattened choices
+      //assertEquals("ParticleBinding<" + termStr + "> min occurs.", xsParticle.getMinOccurs(), particleBinding.getMinOccurs());
+
+      if(xsParticle.getMaxOccursUnbounded())
+      {
+         if(!particleBinding.getMaxOccursUnbounded())
+            handleError("XSD particle has maxOccurs unbounded but ParticleBinding of " + particleBinding.getTerm() + " does not.");
+      }
+      else if(xsParticle.getMaxOccurs() != particleBinding.getMaxOccurs())
+         handleError("maxOccurs for particle of " + particleBinding.getTerm() + " don't match: XSD maxOccurs=" + xsParticle.getMaxOccurs() +
+               ", ParticleBinding maxOccurs=" + particleBinding.getMaxOccurs());
+   }
+
+   public void validate(XSModelGroup xsModelGroup, ModelGroupBinding modelGroupBinding)
+   {
+      short xsCompositor = xsModelGroup.getCompositor();
+      boolean all = false;
+      if(xsCompositor == XSModelGroup.COMPOSITOR_SEQUENCE)
+      {
+         log("sequence");
+         if(!(modelGroupBinding instanceof SequenceBinding))
+         {
+            // another chance...
+            if(modelGroupBinding instanceof AllBinding || modelGroupBinding instanceof UnorderedSequenceBinding)
+               all = true;
+            else
+               handleError("ModelGroupBinding expected to be a sequence but was " + modelGroupBinding);
+         }
+      }
+      else if(xsCompositor == XSModelGroup.COMPOSITOR_CHOICE)
+      {
+         log("choice");
+         if(modelGroupBinding instanceof SequenceBinding)
+         {
+            // another chance...
+            Collection<ParticleBinding> particles = modelGroupBinding.getParticles();
+            if(particles.size() == 1)
+            {
+               ParticleBinding particleBinding = particles.iterator().next();
+               if(particleBinding.getTerm() instanceof ChoiceBinding)
+                  modelGroupBinding = (ModelGroupBinding) particleBinding.getTerm();
+            }
+         }
+
+         if(!(modelGroupBinding instanceof ChoiceBinding))
+            handleError("XSD model group is choice but ModelGroupBinding is " + modelGroupBinding);
+      }
+      else if(xsCompositor == XSModelGroup.COMPOSITOR_ALL)
+      {
+         log("all");
+         if(!(modelGroupBinding instanceof AllBinding))
+            handleError("XSD model group is all but ModelGroupBinding is " + modelGroupBinding);
+         all = true;
+      }
+      else
+         handleError("Unexpected compositor type for model group " + xsCompositor);
+
+
+      XSObjectList xsParticles = xsModelGroup.getParticles();
+      Collection<ParticleBinding> particleBindings = modelGroupBinding.getParticles();
+      Map<QName, XSParticle> xsElementParticles = null;
+      Map<QName, ParticleBinding> elementParticles = null;
+      if(xsParticles.getLength() > 0)
+      {
+         if(particleBindings == null)
+            handleError("XSD model group has " + xsParticles.getLength() + " particles but ModelGroupBinding doesn't have any.");
+         if(xsParticles.getLength() != particleBindings.size() || all)
+         {
+            // let's try making it flat... to the elements
+            xsElementParticles = new HashMap<QName, XSParticle>();
+            flatten(xsModelGroup, xsElementParticles);
+            elementParticles = new HashMap<QName, ParticleBinding>();
+            flatten(modelGroupBinding, elementParticles);
+
+            if(xsElementParticles.size() != elementParticles.size())
+            {
+               if (isLoggingEnabled())
+               {
+                  String msg = "expected particles:\n";
+                  for (int i = 0; i < xsParticles.getLength(); ++i)
+                  {
+                     XSTerm xsTerm = ((XSParticle) xsParticles.item(i)).getTerm();
+                     short type = xsTerm.getType();
+                     if (type == XSConstants.MODEL_GROUP)
+                     {
+                        short compositor = ((XSModelGroup) xsTerm).getCompositor();
+                        if (compositor == XSModelGroup.COMPOSITOR_SEQUENCE)
+                           msg += "- sequence\n";
+                        else if (compositor == XSModelGroup.COMPOSITOR_CHOICE)
+                           msg += "- choice\n";
+                        else if (compositor == XSModelGroup.COMPOSITOR_ALL)
+                           msg += "- all\n";
+                     }
+                     else if (type == XSConstants.ELEMENT_DECLARATION)
+                     {
+                        XSElementDeclaration element = (XSElementDeclaration) xsTerm;
+                        msg += "- " + new QName(element.getNamespace(), element.getName()) + "\n";
+                     }
+                     else
+                     {
+                        msg += "- wildcard\n";
+                     }
+                  }
+
+                  msg += "actual particles:\n";
+                  Iterator<ParticleBinding> iter = particleBindings.iterator();
+                  while (iter.hasNext())
+                  {
+                     TermBinding term = iter.next().getTerm();
+                     if (term.isModelGroup())
+                     {
+                        if (term instanceof SequenceBinding)
+                           msg += "- sequence\n";
+                        else if (term instanceof ChoiceBinding)
+                           msg += "- choice\n";
+                        else
+                           msg += "- wildcard\n";
+                     }
+                     else if (term.isElement())
+                        msg += "- " + ((ElementBinding) term).getQName() + "\n";
+                     else
+                        msg += "- wildcard";
+                  }
+                  log(msg);
+
+                  List<QName> missing = new ArrayList<QName>(xsElementParticles.keySet());
+                  missing.removeAll(elementParticles.keySet());
+                  log("flattened ModelGroupBinding is missing: ");
+                  for (Iterator<QName> missingNames = missing.iterator(); missingNames.hasNext();)
+                     log("- " + missingNames.next());
+
+                  missing = new ArrayList<QName>(elementParticles.keySet());
+                  missing.removeAll(xsElementParticles.keySet());
+                  log("flattened XSModelGroup is missing: ");
+                  for (Iterator<QName> missingNames = missing.iterator(); missingNames.hasNext();)
+                     log("- " + missingNames.next());
+               }
+               handleError("ModelGroupBinding expected to have " + xsParticles.getLength() + " particle(s) but has "
+                     + particleBindings.size());
+            }
+         }
+      }
+
+      if(xsElementParticles != null)
+      {
+         Iterator<ParticleBinding> iter = elementParticles.values().iterator();
+         while(iter.hasNext())
+         {
+            ParticleBinding particleBinding = iter.next();
+            QName particleQName;
+            TermBinding termBinding = particleBinding.getTerm();
+            if(termBinding.isWildcard())
+               particleQName = WILDCARD;
+            else
+               particleQName = ((ElementBinding)termBinding).getQName();
+            XSParticle xsParticle = xsElementParticles.get(particleQName);
+            if(xsParticle == null)
+            {
+               if(particleQName == WILDCARD)
+                  handleError("WildcardBinding is missing");
+               else
+                  handleError("ElementBinding " + particleQName + " is missing: " + xsElementParticles.keySet());
+            }
+            validate(xsParticle, particleBinding);
+         }
+      }
+      else
+      {
+         Iterator<ParticleBinding> iter = particleBindings.iterator();
+         for (int i = 0; i < xsParticles.getLength(); ++i)
+         {
+            XSParticle xsParticle = (XSParticle) xsParticles.item(i);
+            validate(xsParticle, iter.next());
+         }
+      }
+   }
+
+   private void flatten(XSModelGroup xsModelGroup, Map<QName, XSParticle> elementParticles)
+   {
+      XSObjectList xsParticles = xsModelGroup.getParticles();
+      for(int i = 0; i < xsParticles.getLength(); ++i)
+      {
+         XSParticle particle = (XSParticle)xsParticles.item(i);
+         XSTerm term = particle.getTerm();
+         short termType = term.getType();
+         if(termType == XSConstants.ELEMENT_DECLARATION)
+         {
+            XSElementDeclaration element = (XSElementDeclaration) term;
+            QName qName = new QName(element.getNamespace(), element.getName());
+            elementParticles.put(qName, particle);
+         }
+         else if(termType == XSConstants.WILDCARD)
+            elementParticles.put(WILDCARD, particle);
+         else
+         {
+            XSModelGroup modelGroup = (XSModelGroup) term;
+            flatten(modelGroup, elementParticles);
+         }
+      }
+   }
+
+   private void flatten(ModelGroupBinding group, Map<QName, ParticleBinding> elementParticles)
+   {
+      Iterator<ParticleBinding> i = group.getParticles().iterator();
+      while(i.hasNext())
+      {
+         ParticleBinding particle = i.next();
+         TermBinding term = particle.getTerm();
+         if(term.isElement())
+         {
+            ElementBinding element = (ElementBinding) term;
+            elementParticles.put(element.getQName(), particle);
+         }
+         else if(term.isWildcard())
+            elementParticles.put(WILDCARD, particle);
+         else
+         {
+            ModelGroupBinding modelGroup = (ModelGroupBinding) term;
+            flatten(modelGroup, elementParticles);
+         }
+      }
+   }
+
+   /**
+    * This an error handler method. Default implementation throws IllegalStateException with the message passed in as the argument.
+    *
+    * @param msg  the error message
+    */
+   protected void handleError(String msg)
+   {
+      throw new IllegalStateException(msg);
+   }
+
+   /**
+    * This method is supposed to log a message. Default implementation uses trace logging.
+    *
+    * @param msg  the message to log.
+    */
+   protected void log(String msg)
+   {
+      if(loggingEnabled)
+         log.trace(msg);
+   }
+}
\ No newline at end of file

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/util/SchemaBindingValidator.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/util/SchemaBindingValidator.java	2009-07-09 05:44:28 UTC (rev 3357)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/util/SchemaBindingValidator.java	2009-07-09 11:10:50 UTC (rev 3358)
@@ -21,784 +21,31 @@
  */
 package org.jboss.xb.util;
 
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import javax.xml.namespace.QName;
 
-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.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;
-import org.jboss.logging.Logger;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.Util;
-import org.jboss.xb.binding.resolver.MultiClassSchemaResolver;
-import org.jboss.xb.binding.sunday.unmarshalling.AllBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.AttributeBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ChoiceBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
 import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingResolver;
-import org.jboss.xb.binding.sunday.unmarshalling.SequenceBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.UnorderedSequenceBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.WildcardBinding;
 import org.xml.sax.InputSource;
 
 /**
- * This class is used to check consistency between SchemaBinding instances and their corresponding XSD schemas.
- * It can be configured to exclude (or include) validation of certain namespaces
- * (i.e. types, elements and model groups from certain namespaces).
- * By default, namespace "http://www.w3.org/2001/XMLSchema" is excluded.
- * 
- * Also specific types identified by their QName can be excluded or included from validation.
- * Simple XSD types are validated only if present in SchemaBinding. The reason for that is
- * many simple types are bound/represented in Java model by java.lang.String
- * which when building SchemaBinding is bound to xsd:string.
- * 
- * Current implementation does not ensures complete consistency but only the basics such as
- * existence of type definitions, element declarations, element ordering in groups and
- * possible occurences of particles.
- * 
- * When an inconsistency is found handleError(String msg) is called. The default implementation
- * of which throws IllegalStateException. Subclasses can override this method to report errors
- * differently.
- * 
- * Sometimes the error itself may not be informative enough to e.g. identify the location
- * of the inconsistency in the schema. In this case logging should be enabled.
- * Default logger is an instance of org.jboss.logging.Logger with category org.jboss.xb.util.SchemaBindingValidator.
- * All the messages are logged from method log(String msg) which subclasses can override.
- * 
+ * Simple schema binding interface.
+ *
  * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
- * @version $Revision: 1.1 $
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
  */
-public class SchemaBindingValidator
+public interface SchemaBindingValidator
 {
-   private static final Logger log = Logger.getLogger(SchemaBindingValidator.class);
-   
-   private static final QName WILDCARD = new QName("wildcard", "wildcard"); 
-
-   private Set<String> excludedNs = new HashSet<String>();
-   private Set<QName> excludedTypes = new HashSet<QName>();
-
-   private Set<QName> validatedTypes = new HashSet<QName>();
-   private Set<QName> validatedElements = new HashSet<QName>();
-
-   private SchemaBindingResolver resolver;
-   
-   private boolean loggingEnabled;
-
-   public SchemaBindingValidator()
-   {
-      reset();
-      excludeNs(Constants.NS_XML_SCHEMA);
-   }
-   
    /**
-    * @param resolver  default schema resolver
+    * Validate schema binding.
+    *
+    * @param is the input source
+    * @param binding the schema binding
     */
-   public SchemaBindingValidator(SchemaBindingResolver resolver)
-   {
-      this();
-      this.resolver = resolver;
-   }
-   
-   /**
-    * Resets instance variables (such as a set of validated types, elements and also loggingEnabled property).
-    * This method is required to invoked before another validation.
-    * It is called internally at the end of validate(XSModel xsSchema, SchemaBinding schemaBinding).
-    * NOTE: this method doesn't clear excluded namespaces and types.
-    */
-   public void reset()
-   {
-      loggingEnabled = log.isTraceEnabled();
-      validatedTypes.clear();
-      validatedElements.clear();
-   }
+   void validate(InputSource is, SchemaBinding binding);
 
-   public boolean isLoggingEnabled()
-   {
-      return loggingEnabled;
-   }
-   
-   public void enableLogging(boolean value)
-   {
-      loggingEnabled = value;
-   }
-
    /**
-    * Types and elements from the namespace passed into this method will be excluded from validation.
-    * 
-    * @param ns  namespace to exclude
+    * Exclude QName.
+    *
+    * @param qName the qname to exclude
     */
-   public void excludeNs(String ns)
-   {
-      excludedNs.add(ns);
-   }
-   
-   /**
-    * Checks if the specified namespace is excluded from validation.
-    * 
-    * @param ns  the namespace to check
-    * @return  true if the namespace is excluded
-    */
-   public boolean isNsExcluded(String ns)
-   {
-      return excludedNs.contains(ns);
-   }
-   
-   /**
-    * Removes the namespace from the excluded set. If the namespace has not been excluded, the method does nothing.
-    * 
-    * @param ns  the namespace to remove from the excluded set.
-    */
-   public void includeNs(String ns)
-   {
-      excludedNs.remove(ns);
-   }
-   
-   /**
-    * Excludes the specified type from validation.
-    * 
-    * @param qName  the QName of the type to exclude from validation
-    */
-   public void excludeType(QName qName)
-   {
-      excludedTypes.add(qName);
-   }
-   
-   /**
-    * Checks if the type is excluded from validation.
-    * 
-    * @param qName  the QName of the type to check
-    * @return  true if the type is excluded from validation
-    */
-   public boolean isTypeExcluded(QName qName)
-   {
-      return excludedTypes.contains(qName);
-   }
-   
-   /**
-    * Removes the specified type from the excluded set. If the type has not been excluded, the method does nothing.
-    * 
-    * @param qName  the QName of type to remove from the excluded set.
-    */
-   public void includeType(QName qName)
-   {
-      excludedTypes.remove(qName);
-   }
-   
-   /**
-    * @return The default resolver used to resolve schemas
-    */
-   public SchemaBindingResolver getSchemaResolver()
-   {
-      return resolver;
-   }
-   
-   /**
-    * @param resolver  The default resolver used to resolve schemas
-    */
-   public void setSchemaResolver(SchemaBindingResolver resolver)
-   {
-      this.resolver = resolver;
-   }
-   
-   /**
-    * This method will check that the XSD represented with InputSource and SchemaBinding are consistent.
-    * The consistency is checked to certain degree and is far from 100%. Currently it checks just for basic things
-    * such as the existence of type definitions, attribute and element declarations and element ordering.
-    * 
-    * @param is  InputSource of the XSD
-    * @param binding  SchemaBinding
-    */
-   public void validate(InputSource is, SchemaBinding binding)
-   {
-      SchemaBindingResolver resolver = binding.getSchemaResolver();
-      if(resolver == null)
-      {
-         resolver = this.resolver;
-         if(resolver == null)
-            log("Schema resolver was not provided");
-      }
-      XSModel xsModel = Util.loadSchema(is, resolver);
-      validate(xsModel, binding);
-   }
-   
-   public void validate(String xsdName, Class<?>... cls)
-   {
-      log("validate: " + xsdName + ", " + Arrays.asList(cls));
-      
-      URL xsdUrl = Thread.currentThread().getContextClassLoader().getResource("schema/" + xsdName);
-      if(xsdUrl == null)
-         handleError("Failed to load schema from the classpath: schema/" + xsdName);
-
-      MultiClassSchemaResolver multiClassResolver = new MultiClassSchemaResolver();
-      multiClassResolver.mapLocationToClasses(xsdName, cls);
-      SchemaBinding binding = resolver.resolve("", null, xsdName);
-
-      SchemaBindingResolver resolver = this.resolver;
-      if(resolver == null)
-         resolver = multiClassResolver;
-      
-      XSModel xsModel;
-      try
-      {
-         xsModel = Util.loadSchema(xsdUrl.openStream(), null, resolver);
-      }
-      catch (IOException e)
-      {
-         throw new IllegalStateException("Failed to read schema " + xsdName, e);
-      }
-
-      validate(xsModel, binding);
-   }
-
-   public void validate(XSModel xsSchema, SchemaBinding schemaBinding)
-   {
-      try
-      {
-         /* TODO groups are not properly bound
-         XSNamedMap groups = xsSchema.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
-         for(int i = 0; i < groups.getLength(); ++i)
-         {
-            XSModelGroupDefinition xsGroupDef = (XSModelGroupDefinition)groups.item(i);
-            System.out.println(xsGroupDef.getName());
-            QName groupQName = new QName(xsGroupDef.getNamespace(), xsGroupDef.getName());
-            ModelGroupBinding groupBinding = schemaBinding.getGroup(groupQName);
-            assertNotNull("Group " + groupQName + " exists in the schema binding.", groupBinding);
-         }
-         */
-
-         XSNamedMap types = xsSchema.getComponents(XSConstants.TYPE_DEFINITION);
-         for (int i = 0; i < types.getLength(); ++i)
-         {
-            XSTypeDefinition xsType = (XSTypeDefinition) types.item(i);
-            if (excludedNs.contains(xsType.getNamespace()))
-               continue;
-
-            QName typeQName = new QName(xsType.getNamespace(), xsType.getName());
-            if (excludedTypes.contains(typeQName))
-               continue;
-
-            TypeBinding typeBinding = schemaBinding.getType(typeQName);
-            if (typeBinding == null)
-            {
-               boolean ignoreIfNotFound = false;
-               if (xsType.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE)
-               {
-                  ignoreIfNotFound = true;
-               }
-               else
-               {
-                  XSComplexTypeDefinition xsComplexType = (XSComplexTypeDefinition) xsType;
-                  if (xsComplexType.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_SIMPLE)
-                  {
-                     XSObjectList attributeUses = xsComplexType.getAttributeUses();
-                     if (attributeUses.getLength() == 0)
-                     {
-                        ignoreIfNotFound = true;
-                     }
-                     else if (attributeUses.getLength() == 1)
-                     {
-                        XSAttributeUse xsAttrUse = (XSAttributeUse) attributeUses.item(0);
-                        XSAttributeDeclaration xsAttr = xsAttrUse.getAttrDeclaration();
-                        if (xsAttr.getNamespace() == null && "id".equals(xsAttr.getName()))
-                           ignoreIfNotFound = true;
-                     }
-                  }
-               }
-
-               if (!ignoreIfNotFound)
-               {
-                  if (isLoggingEnabled())
-                  {
-                     log("SchemaBinding global types: ");
-                     for (Iterator<TypeBinding> iter = schemaBinding.getTypes(); iter.hasNext();)
-                     {
-                        TypeBinding type = iter.next();
-                        if (!excludedNs.contains(type.getQName().getNamespaceURI()))
-                           log("- " + type.getQName());
-                     }
-                  }
-
-                  handleError("TypeBinding " + typeQName + " is not found in the SchemaBinding.");
-               }
-            }
-            else
-            {
-               validate(xsType, typeBinding);
-            }
-         }
-
-         XSNamedMap elements = xsSchema.getComponents(XSConstants.ELEMENT_DECLARATION);
-         for (int i = 0; i < elements.getLength(); ++i)
-         {
-            XSElementDeclaration xsElement = (XSElementDeclaration) elements.item(i);
-            if (excludedNs.contains(xsElement.getNamespace()))
-               continue;
-            QName elementQName = new QName(xsElement.getNamespace(), xsElement.getName());
-            ElementBinding elementBinding = schemaBinding.getElement(elementQName);
-            if (elementBinding == null)
-               handleError("ElementBinding " + elementQName + " is not found in the SchemaBinding.");
-            validate(xsElement.getTypeDefinition(), elementBinding.getType());
-         }
-      }
-      finally
-      {
-         reset();
-      }
-   }
-   
-   public void validate(XSElementDeclaration xsElement, ElementBinding elementBinding)
-   {      
-      QName xsQName = new QName(xsElement.getNamespace(), xsElement.getName());
-      if(xsQName.equals(elementBinding.getQName()))
-         handleError("Compared elements have difference names: XSD QName is " + xsQName + ", ElementBinding QName is " + elementBinding.getQName());
-      
-      log("element " + xsQName);
-      
-      if(validatedElements.contains(xsQName))
-         return;
-      validatedElements.add(xsQName);
-
-      validate(xsElement.getTypeDefinition(), elementBinding.getType());
-   }
-
-   public void validate(XSTypeDefinition xsType, TypeBinding typeBinding)
-   {
-      if(xsType.getName() == null)
-      {
-         if(typeBinding.getQName() != null)
-            handleError("XSD type is anonymous but TypeBinding has QName " + typeBinding.getQName());
-      }
-      else
-      {
-         if(excludedNs.contains(xsType.getNamespace()))
-            return;
-         
-         QName xsQName = new QName(xsType.getNamespace(), xsType.getName());
-         if(!xsQName.equals(typeBinding.getQName()))
-            handleError("Compared types have different names: XSD QName is " + xsQName + ", TypeBinding QName is " + typeBinding.getQName());
-         
-         if(validatedTypes.contains(xsQName) || excludedTypes.contains(xsQName))
-            return;
-         validatedTypes.add(xsQName);
-      }
-      
-      if(xsType.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE)
-         validate((XSSimpleTypeDefinition)xsType, typeBinding);
-      else
-         validate((XSComplexTypeDefinition)xsType, typeBinding);         
-   }
-
-   public void validate(XSSimpleTypeDefinition xsType, TypeBinding typeBinding)
-   {
-      // TODO there could xsd types that are mapped to String which is bound by default to xsd:string
-      //QName xsQName = xsType.getName() == null ? null : new QName(xsType.getNamespace(), xsType.getName());
-      //assertEquals("Simple type expected to be " + (xsType == null ? "anonymous" : "named '" + xsQName + "'"), xsQName, typeBinding.getQName());
-      
-      if(!typeBinding.isSimple())
-         handleError("XSD type " + typeBinding.getQName() + " is simple but TypeBinding is not.");
-      // TODO the rest of the simple type stuff?
-   }
-
-   public void validate(XSComplexTypeDefinition xsType, TypeBinding typeBinding)
-   {
-      QName xsQName = xsType.getName() == null ? null : new QName(xsType.getNamespace(), xsType.getName());
-      
-      log("complex type " + xsQName);
-      
-      if(xsQName == null && typeBinding.getQName() != null ||
-            xsQName != null && !xsQName.equals(typeBinding.getQName()))
-         handleError("Compared complex types have different names: XSD QName is " + xsQName + ", TypeBindign QName is " + typeBinding.getQName());
-
-      XSObjectList xsAttrUses = xsType.getAttributeUses();
-      if(xsAttrUses.getLength() == 0)
-      {
-         // TODO missing id attributes in the schema
-         //assertTrue("Type " + typeBinding.getQName() + " has no attributes in the schema", typeBinding.getAttributes().isEmpty());
-      }
-      else
-      {
-         for(int i = 0; i < xsAttrUses.getLength(); ++i)
-         {
-            XSAttributeDeclaration xsAttr = ((XSAttributeUse)xsAttrUses.item(i)).getAttrDeclaration();
-            QName xsAttrQName = new QName(xsAttr.getNamespace(), xsAttr.getName());
-            AttributeBinding attrBinding = typeBinding.getAttribute(xsAttrQName);
-            if(attrBinding == null)
-               handleError("Attribute " + xsAttrQName + " is not found in TypeBinding " + typeBinding.getQName());
-            validate(xsAttr.getTypeDefinition(), attrBinding.getType());
-         }
-      }
-      
-      XSWildcard xsAttrWildcard = xsType.getAttributeWildcard();
-      if(xsAttrWildcard != null && typeBinding.getAnyAttribute() == null)
-         handleError("TypeBinding " + typeBinding.getQName() + " doesn't have AnyAttributeBinding");
-      
-      XSSimpleTypeDefinition xsSimpleType = xsType.getSimpleType();
-      if(xsSimpleType != null)
-      {
-         TypeBinding simpleTypeBinding = typeBinding.getSimpleType();
-         if(simpleTypeBinding == null)
-            handleError("XSD type " + typeBinding.getQName() + " allows text content but its corresponding TypeBinding doesn't.");
-         validate(xsSimpleType, simpleTypeBinding);
-      }
-      
-      XSParticle xsParticle = xsType.getParticle();
-      if(xsParticle != null)
-      {
-         ParticleBinding particleBinding = typeBinding.getParticle();
-         if(particleBinding == null)
-            handleError("TypeBinding " + xsQName + " doesn't contain a ParticleBinding.");
-         validate(xsParticle, particleBinding);
-      }
-   }
-   
-   public void validate(XSParticle xsParticle, ParticleBinding particleBinding)
-   {
-      XSTerm xsTerm = xsParticle.getTerm();
-      TermBinding termBinding = particleBinding.getTerm();
-      if(termBinding == null)
-         handleError("ParticleBinding doesn't contain a TermBinding.");
-      short xsTermType = xsTerm.getType();
-      String termStr = null;
-      if(xsTermType == XSConstants.MODEL_GROUP)
-      {
-         termStr = "sequence";
-         XSModelGroup xsModelGroup = (XSModelGroup)xsTerm;
-         short xsModelGroupCompositor = (xsModelGroup).getCompositor();
-         if(XSModelGroup.COMPOSITOR_CHOICE == xsModelGroupCompositor)
-            termStr = "choice";
-         else if(XSModelGroup.COMPOSITOR_ALL == xsModelGroupCompositor)
-            termStr = "all";
-
-         if(!termBinding.isModelGroup())
-         {
-            // TODO review this
-            // let's see whether it's wrapped
-            if(xsModelGroup.getParticles().getLength() == 1)
-            {
-               XSParticle xsWrappedParticle = (XSParticle) xsModelGroup.getParticles().item(0);
-               validate(xsWrappedParticle, particleBinding);
-            }
-            else
-               handleError("TermBinding expected to be a " + termStr + " but was " + termBinding);
-         }
-         else
-            validate(xsModelGroup, (ModelGroupBinding) termBinding);
-      }
-      else if(xsTermType == XSConstants.ELEMENT_DECLARATION)
-      {
-         XSElementDeclaration xsElement = (XSElementDeclaration) xsTerm;
-         QName xsElementName = new QName(xsElement.getNamespace(), xsElement.getName());
-         termStr = xsElementName.toString();
-
-         if(!termBinding.isElement())
-         {
-            // TODO sometimes XB wraps (maybe unnecessarily) repeatable elements into a sequence.
-            // the same xml structure can be described differently in xsd
-            if (/*(xsParticle.getMaxOccursUnbounded() || xsParticle.getMaxOccurs() > 1) &&*/
-                  termBinding instanceof SequenceBinding)
-            {
-               SequenceBinding seq = (SequenceBinding) termBinding;
-               Collection<ParticleBinding> particles = seq.getParticles();
-               if(particles.size() == 1)
-               {
-                  ParticleBinding particle = particles.iterator().next();
-                  if(particle.getTerm().isElement())
-                  {
-                     particleBinding = particle;
-                     termBinding = particle.getTerm();
-                  }
-               }
-            }
-            
-            if(!termBinding.isElement())
-               handleError("TermBinding expected to be element " + termStr + " but was " + termBinding);
-         }
-         
-         if(!xsElementName.equals(((ElementBinding)termBinding).getQName()))
-            handleError("Compared elements have different names: XSD QName is " + xsElementName + ", ElementBinding QName is " + ((ElementBinding)termBinding).getQName());
-      }
-      else if(xsTermType == XSConstants.WILDCARD)
-      {
-         if(!termBinding.isWildcard())
-            handleError("TermBinding expected to be a wildcard but was " + termBinding);
-         XSWildcard xsWildcard = (XSWildcard) xsTerm;
-         WildcardBinding wildcardBinding = (WildcardBinding) termBinding;
-         if(xsWildcard.getProcessContents() != wildcardBinding.getProcessContents())
-            throw new IllegalStateException("Wildcard processContents doesn't match: XSD processContents is " + xsWildcard.getProcessContents() +
-                  ", WildcardBinding processContents is " + wildcardBinding.getProcessContents());
-         termStr = "wildcard";
-      }
-      else
-         handleError("Unexpected XSTerm type: " + xsTermType);
-      
-      // TODO minOccurs is not trivial for flattened choices
-      //assertEquals("ParticleBinding<" + termStr + "> min occurs.", xsParticle.getMinOccurs(), particleBinding.getMinOccurs());
-      
-      if(xsParticle.getMaxOccursUnbounded())
-      {
-         if(!particleBinding.getMaxOccursUnbounded())
-            handleError("XSD particle has maxOccurs unbounded but ParticleBinding of " + particleBinding.getTerm() + " does not.");
-      }
-      else if(xsParticle.getMaxOccurs() != particleBinding.getMaxOccurs())
-         handleError("maxOccurs for particle of " + particleBinding.getTerm() + " don't match: XSD maxOccurs=" + xsParticle.getMaxOccurs() +
-               ", ParticleBinding maxOccurs=" + particleBinding.getMaxOccurs());
-   }
-   
-   public void validate(XSModelGroup xsModelGroup, ModelGroupBinding modelGroupBinding)
-   {
-      short xsCompositor = xsModelGroup.getCompositor();
-      boolean all = false;
-      if(xsCompositor == XSModelGroup.COMPOSITOR_SEQUENCE)
-      {
-         log("sequence");
-         if(!(modelGroupBinding instanceof SequenceBinding))
-         {
-            // another chance...
-            if(modelGroupBinding instanceof AllBinding || modelGroupBinding instanceof UnorderedSequenceBinding)
-               all = true;
-            else
-               handleError("ModelGroupBinding expected to be a sequence but was " + modelGroupBinding);
-         }
-      }
-      else if(xsCompositor == XSModelGroup.COMPOSITOR_CHOICE)
-      {
-         log("choice");
-         if(modelGroupBinding instanceof SequenceBinding)
-         {
-            // another chance...
-            Collection<ParticleBinding> particles = modelGroupBinding.getParticles();
-            if(particles.size() == 1)
-            {
-               ParticleBinding particleBinding = particles.iterator().next();
-               if(particleBinding.getTerm() instanceof ChoiceBinding)
-                  modelGroupBinding = (ModelGroupBinding) particleBinding.getTerm();
-            }
-         }
-
-         if(!(modelGroupBinding instanceof ChoiceBinding))
-            handleError("XSD model group is choice but ModelGroupBinding is " + modelGroupBinding);
-      }
-      else if(xsCompositor == XSModelGroup.COMPOSITOR_ALL)
-      {
-         log("all");
-         if(!(modelGroupBinding instanceof AllBinding))
-            handleError("XSD model group is all but ModelGroupBinding is " + modelGroupBinding);
-         all = true;
-      }
-      else
-         handleError("Unexpected compositor type for model group " + xsCompositor);
-      
-      
-      XSObjectList xsParticles = xsModelGroup.getParticles();
-      Collection<ParticleBinding> particleBindings = modelGroupBinding.getParticles();
-      Map<QName, XSParticle> xsElementParticles = null;
-      Map<QName, ParticleBinding> elementParticles = null;
-      if(xsParticles.getLength() > 0)
-      {
-         if(particleBindings == null)
-            handleError("XSD model group has " + xsParticles.getLength() + " particles but ModelGroupBinding doesn't have any.");
-         if(xsParticles.getLength() != particleBindings.size() || all)
-         {
-            // let's try making it flat... to the elements
-            xsElementParticles = new HashMap<QName, XSParticle>();
-            flatten(xsModelGroup, xsElementParticles);
-            elementParticles = new HashMap<QName, ParticleBinding>();
-            flatten(modelGroupBinding, elementParticles);
-            
-            if(xsElementParticles.size() != elementParticles.size())
-            {
-               if (isLoggingEnabled())
-               {
-                  String msg = "expected particles:\n";
-                  for (int i = 0; i < xsParticles.getLength(); ++i)
-                  {
-                     XSTerm xsTerm = ((XSParticle) xsParticles.item(i)).getTerm();
-                     short type = xsTerm.getType();
-                     if (type == XSConstants.MODEL_GROUP)
-                     {
-                        short compositor = ((XSModelGroup) xsTerm).getCompositor();
-                        if (compositor == XSModelGroup.COMPOSITOR_SEQUENCE)
-                           msg += "- sequence\n";
-                        else if (compositor == XSModelGroup.COMPOSITOR_CHOICE)
-                           msg += "- choice\n";
-                        else if (compositor == XSModelGroup.COMPOSITOR_ALL)
-                           msg += "- all\n";
-                     }
-                     else if (type == XSConstants.ELEMENT_DECLARATION)
-                     {
-                        XSElementDeclaration element = (XSElementDeclaration) xsTerm;
-                        msg += "- " + new QName(element.getNamespace(), element.getName()) + "\n";
-                     }
-                     else
-                     {
-                        msg += "- wildcard\n";
-                     }
-                  }
-
-                  msg += "actual particles:\n";
-                  Iterator<ParticleBinding> iter = particleBindings.iterator();
-                  while (iter.hasNext())
-                  {
-                     TermBinding term = iter.next().getTerm();
-                     if (term.isModelGroup())
-                     {
-                        if (term instanceof SequenceBinding)
-                           msg += "- sequence\n";
-                        else if (term instanceof ChoiceBinding)
-                           msg += "- choice\n";
-                        else
-                           msg += "- wildcard\n";
-                     }
-                     else if (term.isElement())
-                        msg += "- " + ((ElementBinding) term).getQName() + "\n";
-                     else
-                        msg += "- wildcard";
-                  }
-                  log(msg);
-                  
-                  List<QName> missing = new ArrayList<QName>(xsElementParticles.keySet());
-                  missing.removeAll(elementParticles.keySet());
-                  log("flattened ModelGroupBinding is missing: ");
-                  for (Iterator<QName> missingNames = missing.iterator(); missingNames.hasNext();)
-                     log("- " + missingNames.next());
-
-                  missing = new ArrayList<QName>(elementParticles.keySet());
-                  missing.removeAll(xsElementParticles.keySet());
-                  log("flattened XSModelGroup is missing: ");
-                  for (Iterator<QName> missingNames = missing.iterator(); missingNames.hasNext();)
-                     log("- " + missingNames.next());
-               }
-               handleError("ModelGroupBinding expected to have " + xsParticles.getLength() + " particle(s) but has "
-                     + particleBindings.size());
-            }
-         }
-      }
-
-      if(xsElementParticles != null)
-      {
-         Iterator<ParticleBinding> iter = elementParticles.values().iterator();
-         while(iter.hasNext())
-         {
-            ParticleBinding particleBinding = iter.next();
-            QName particleQName;
-            TermBinding termBinding = particleBinding.getTerm();
-            if(termBinding.isWildcard())
-               particleQName = WILDCARD;
-            else
-               particleQName = ((ElementBinding)termBinding).getQName();
-            XSParticle xsParticle = xsElementParticles.get(particleQName);
-            if(xsParticle == null)
-            {
-               if(particleQName == WILDCARD)
-                  handleError("WildcardBinding is missing");
-               else
-                  handleError("ElementBinding " + particleQName + " is missing: " + xsElementParticles.keySet());
-            }
-            validate(xsParticle, particleBinding);            
-         }
-      }
-      else
-      {
-         Iterator<ParticleBinding> iter = particleBindings.iterator();
-         for (int i = 0; i < xsParticles.getLength(); ++i)
-         {
-            XSParticle xsParticle = (XSParticle) xsParticles.item(i);
-            validate(xsParticle, iter.next());
-         }
-      }
-   }
-
-   private void flatten(XSModelGroup xsModelGroup, Map<QName, XSParticle> elementParticles)
-   {
-      XSObjectList xsParticles = xsModelGroup.getParticles();
-      for(int i = 0; i < xsParticles.getLength(); ++i)
-      {
-         XSParticle particle = (XSParticle)xsParticles.item(i);
-         XSTerm term = particle.getTerm();
-         short termType = term.getType();
-         if(termType == XSConstants.ELEMENT_DECLARATION)
-         {
-            XSElementDeclaration element = (XSElementDeclaration) term;
-            QName qName = new QName(element.getNamespace(), element.getName());
-            elementParticles.put(qName, particle);
-         }
-         else if(termType == XSConstants.WILDCARD)
-            elementParticles.put(WILDCARD, particle);
-         else
-         {
-            XSModelGroup modelGroup = (XSModelGroup) term;
-            flatten(modelGroup, elementParticles);
-         }
-      }
-   }
-
-   private void flatten(ModelGroupBinding group, Map<QName, ParticleBinding> elementParticles)
-   {
-      Iterator<ParticleBinding> i = group.getParticles().iterator();
-      while(i.hasNext())
-      {
-         ParticleBinding particle = i.next();
-         TermBinding term = particle.getTerm();
-         if(term.isElement())
-         {
-            ElementBinding element = (ElementBinding) term;
-            elementParticles.put(element.getQName(), particle);
-         }
-         else if(term.isWildcard())
-            elementParticles.put(WILDCARD, particle);
-         else
-         {
-            ModelGroupBinding modelGroup = (ModelGroupBinding) term;
-            flatten(modelGroup, elementParticles);
-         }
-      }
-   }
-   
-   /**
-    * This an error handler method. Default implementation throws IllegalStateException with the message passed in as the argument.
-    * 
-    * @param msg  the error message
-    */
-   protected void handleError(String msg)
-   {
-      throw new IllegalStateException(msg);
-   }
-   
-   /**
-    * This method is supposed to log a message. Default implementation uses trace logging.
-    * 
-    * @param msg  the message to log.
-    */
-   protected void log(String msg)
-   {
-      if(loggingEnabled)
-         log.trace(msg);
-   }   
+   void excludeType(QName qName);
 }

Modified: jbossxb/trunk/src/test/java/org/jboss/test/xb/validator/test/BasicBindingValidatorUnitTestCase.java
===================================================================
--- jbossxb/trunk/src/test/java/org/jboss/test/xb/validator/test/BasicBindingValidatorUnitTestCase.java	2009-07-09 05:44:28 UTC (rev 3357)
+++ jbossxb/trunk/src/test/java/org/jboss/test/xb/validator/test/BasicBindingValidatorUnitTestCase.java	2009-07-09 11:10:50 UTC (rev 3358)
@@ -24,7 +24,6 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-
 import javax.xml.namespace.QName;
 
 import org.jboss.test.xb.builder.AbstractBuilderTest;
@@ -40,6 +39,7 @@
 import org.jboss.xb.binding.sunday.unmarshalling.SequenceBinding;
 import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
 import org.jboss.xb.binding.sunday.unmarshalling.WildcardBinding;
+import org.jboss.xb.util.DefaultSchemaBindingValidator;
 import org.jboss.xb.util.SchemaBindingValidator;
 import org.xml.sax.InputSource;
 
@@ -60,7 +60,7 @@
    private SchemaBinding schema;
    private Map<String, ErrorHandler> handlerByMsg;
 
-   SchemaBindingValidator validator = new SchemaBindingValidator()
+   SchemaBindingValidator validator = new DefaultSchemaBindingValidator()
    {
 /*      protected void log(String msg)
       {
@@ -81,7 +81,6 @@
 
       new AbstractErrorHandler("TypeBinding {urn:jboss:xb:test}excludedType is not found in the SchemaBinding.")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             validator.excludeType(new QName("urn:jboss:xb:test", "excludedType"));
@@ -90,7 +89,6 @@
 
       new AbstractErrorHandler("TypeBinding {urn:jboss:xb:test}attributesType is not found in the SchemaBinding.")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = new TypeBinding(new QName("urn:jboss:xb:test", "attributesType"));
@@ -100,7 +98,6 @@
 
       new AbstractErrorHandler("Attribute attr1 is not found in TypeBinding {urn:jboss:xb:test}attributesType")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "attributesType"));
@@ -111,7 +108,6 @@
 
       new AbstractErrorHandler("TypeBinding {urn:jboss:xb:test}choiceType is not found in the SchemaBinding.")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = new TypeBinding(new QName("urn:jboss:xb:test", "choiceType"));
@@ -123,7 +119,6 @@
 
       new AbstractErrorHandler("ModelGroupBinding expected to have 3 particle(s) but has 0")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "choiceType"));
@@ -144,7 +139,6 @@
 
       new AbstractErrorHandler("Compared elements have different names: XSD QName is {urn:jboss:xb:test}choice3_1, ElementBinding QName is {urn:jboss:xb:test}choice3")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "choiceType"));
@@ -171,7 +165,6 @@
 
       new AbstractErrorHandler("TypeBinding {urn:jboss:xb:test}aComplexType is not found in the SchemaBinding.")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = new TypeBinding(new QName("urn:jboss:xb:test", "aComplexType"));
@@ -181,7 +174,6 @@
 
       new AbstractErrorHandler("TypeBinding {urn:jboss:xb:test}aComplexType doesn't have AnyAttributeBinding")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "aComplexType"));
@@ -191,7 +183,6 @@
 
       new AbstractErrorHandler("TypeBinding {urn:jboss:xb:test}aComplexType doesn't contain a ParticleBinding.")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "aComplexType"));
@@ -202,7 +193,6 @@
 
       new AbstractErrorHandler("ModelGroupBinding expected to be a sequence but was choice:")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "aComplexType"));
@@ -213,7 +203,6 @@
 
       new AbstractErrorHandler("ModelGroupBinding expected to have 1 particle(s) but has 0")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "aComplexType"));
@@ -225,7 +214,6 @@
 
       new AbstractErrorHandler("TermBinding expected to be a wildcard but was all:")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "aComplexType"));
@@ -241,7 +229,6 @@
 
       new AbstractErrorHandler("Wildcard processContents doesn't match: XSD processContents is 3, WildcardBinding processContents is 1")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "aComplexType"));
@@ -255,7 +242,6 @@
 
       new AbstractErrorHandler("XSD particle has maxOccurs unbounded but ParticleBinding of wildcard processContents=lax does not.")
       {
-         @Override
          public void handle(SchemaBindingValidator validator, SchemaBinding schema)
          {
             TypeBinding type = schema.getType(new QName("urn:jboss:xb:test", "aComplexType"));

Modified: jbossxb/trunk/src/test/java/org/jboss/test/xb/validator/test/ValidatingResolverUnitTestCase.java
===================================================================
--- jbossxb/trunk/src/test/java/org/jboss/test/xb/validator/test/ValidatingResolverUnitTestCase.java	2009-07-09 05:44:28 UTC (rev 3357)
+++ jbossxb/trunk/src/test/java/org/jboss/test/xb/validator/test/ValidatingResolverUnitTestCase.java	2009-07-09 11:10:50 UTC (rev 3358)
@@ -57,12 +57,18 @@
       }
       catch(JBossXBException e)
       {
-         String msg;
+         String msg = e.getCause().getMessage();
          if(JBossXBBuilder.isUseUnorderedSequence())
-            msg = "ElementBinding {urn:jboss:xb:test}e is missing: [{urn:jboss:xb:test}e2, {urn:jboss:xb:test}e1]";
+         {
+            // ordering hack
+            boolean check = "ElementBinding {urn:jboss:xb:test}e is missing: [{urn:jboss:xb:test}e2, {urn:jboss:xb:test}e1]".equals(msg);
+            check |=        "ElementBinding {urn:jboss:xb:test}e is missing: [{urn:jboss:xb:test}e1, {urn:jboss:xb:test}e2]".equals(msg);
+            assertTrue(check);
+         }
          else
-            msg = "Compared elements have different names: XSD QName is {urn:jboss:xb:test}e1, ElementBinding QName is {urn:jboss:xb:test}e";
-         assertEquals(msg, e.getCause().getMessage());
+         {
+            assertEquals("Compared elements have different names: XSD QName is {urn:jboss:xb:test}e1, ElementBinding QName is {urn:jboss:xb:test}e", msg);
+         }
       }
    }
 




More information about the jboss-svn-commits mailing list