ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dk...@apache.org
Subject svn commit: r1625632 [8/9] - in /webservices/xmlschema/trunk: ./ xmlschema-walker/ xmlschema-walker/src/ xmlschema-walker/src/main/ xmlschema-walker/src/main/java/ xmlschema-walker/src/main/java/org/ xmlschema-walker/src/main/java/org/apache/ xmlschema...
Date Wed, 17 Sep 2014 15:32:46 GMT
Added: webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java
URL: http://svn.apache.org/viewvc/webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java?rev=1625632&view=auto
==============================================================================
--- webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java (added)
+++ webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java Wed Sep 17 15:32:44 2014
@@ -0,0 +1,542 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.commons.schema.docpath;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.testutils.UtilsForTests;
+import org.apache.ws.commons.schema.walker.XmlSchemaBaseSimpleType;
+import org.apache.ws.commons.schema.walker.XmlSchemaTypeInfo;
+import org.apache.ws.commons.schema.walker.XmlSchemaWalker;
+import org.junit.Test;
+
+public class TestXmlSchemaStateMachineGenerator {
+
+    private static final String TESTSCHEMA_NS = "http://avro.apache.org/AvroTest";
+    private static final String COMPLEX_SCHEMA_NS = "urn:avro:complex_schema";
+
+    @Test
+    public void testSchema() throws IOException {
+        final File schemaFile = UtilsForTests.buildFile("src", "test", "resources", "test_schema.xsd");
+
+        XmlSchemaStateMachineNode stateMachine = buildSchema(schemaFile, new QName(TESTSCHEMA_NS, "root"));
+
+        HashSet<QName> seen = new HashSet<QName>();
+
+        // avro:root
+        ExpectedElement rootElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        ExpectedStateMachineNode rootState = new ExpectedStateMachineNode(
+                                                                          XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                          new QName(TESTSCHEMA_NS, "root"),
+                                                                          rootElem);
+
+        ExpectedStateMachineNode groupSequence = new ExpectedStateMachineNode(
+                                                                              XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                              null, null);
+
+        rootState.addNextState(groupSequence);
+
+        ExpectedStateMachineNode groupChoice = new ExpectedStateMachineNode(
+                                                                            XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                            null, null);
+
+        groupSequence.addNextState(groupChoice);
+
+        // avro:primitive
+        ExpectedElement primitiveElem = new ExpectedElement(
+                                                            new XmlSchemaTypeInfo(
+                                                                                  XmlSchemaBaseSimpleType.STRING));
+
+        QName primitiveQName = new QName(TESTSCHEMA_NS, "primitive");
+
+        ExpectedStateMachineNode primitiveState = new ExpectedStateMachineNode(
+                                                                               XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               primitiveQName, primitiveElem);
+
+        groupChoice.addNextState(primitiveState);
+
+        // avro:nonNullPrimitive
+        ExpectedElement nonNullPrimitiveElem = new ExpectedElement(
+                                                                   new XmlSchemaTypeInfo(
+                                                                                         XmlSchemaBaseSimpleType.STRING));
+
+        QName nonNullPrimitiveQName = new QName(TESTSCHEMA_NS, "nonNullPrimitive");
+
+        ExpectedStateMachineNode nonNullPrimitiveState = new ExpectedStateMachineNode(
+                                                                                      XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                                      nonNullPrimitiveQName,
+                                                                                      nonNullPrimitiveElem);
+
+        groupChoice.addNextState(nonNullPrimitiveState);
+
+        // avro:record
+        ExpectedElement recordElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName recordQName = new QName(TESTSCHEMA_NS, "record");
+
+        ExpectedStateMachineNode recordState = new ExpectedStateMachineNode(
+                                                                            XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                            recordQName, recordElem);
+
+        recordState.addNextState(groupSequence);
+
+        // avro:map
+        ExpectedElement mapElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName mapQName = new QName(TESTSCHEMA_NS, "map");
+
+        ExpectedStateMachineNode mapState = new ExpectedStateMachineNode(
+                                                                         XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                         mapQName, mapElem);
+
+        mapState.addNextState(groupSequence);
+
+        ExpectedStateMachineNode recordSubstGrp = new ExpectedStateMachineNode(
+                                                                               XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP,
+                                                                               null, null);
+
+        recordSubstGrp.addNextState(recordState);
+        recordSubstGrp.addNextState(mapState);
+
+        groupChoice.addNextState(recordSubstGrp);
+
+        // avro:list
+        ExpectedElement listElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName listQName = new QName(TESTSCHEMA_NS, "list");
+
+        ExpectedStateMachineNode listState = new ExpectedStateMachineNode(
+                                                                          XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                          listQName, listElem);
+
+        groupChoice.addNextState(listState);
+
+        ExpectedStateMachineNode listChoice = new ExpectedStateMachineNode(
+                                                                           XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                           null, null);
+
+        listChoice.addNextState(primitiveState);
+        listChoice.addNextState(recordSubstGrp);
+
+        listState.addNextState(listChoice);
+
+        // avro:tuple
+        ExpectedElement tupleElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName tupleQName = new QName(TESTSCHEMA_NS, "tuple");
+
+        ExpectedStateMachineNode tupleState = new ExpectedStateMachineNode(
+                                                                           XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                           tupleQName, tupleElem);
+
+        groupChoice.addNextState(tupleState);
+
+        ExpectedStateMachineNode groupOfAll = new ExpectedStateMachineNode(
+                                                                           XmlSchemaStateMachineNode.Type.ALL,
+                                                                           null, null);
+
+        groupOfAll.addNextState(primitiveState);
+        groupOfAll.addNextState(nonNullPrimitiveState);
+        groupOfAll.addNextState(recordSubstGrp);
+        groupOfAll.addNextState(listState);
+
+        tupleState.addNextState(groupOfAll);
+
+        validate(rootState, stateMachine, seen);
+    }
+
+    @Test
+    public void testComplex() throws IOException {
+        final File schemaFile = UtilsForTests.buildFile("src", "test", "resources", "complex_schema.xsd");
+
+        XmlSchemaStateMachineNode stateMachine = buildSchema(schemaFile, new QName(COMPLEX_SCHEMA_NS, "root"));
+
+        HashSet<QName> seen = new HashSet<QName>();
+
+        ExpectedStateMachineNode rootSubstGrp = new ExpectedStateMachineNode(
+                                                                             XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP,
+                                                                             null, null);
+
+        // realRoot
+        ExpectedElement realRootElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName realRootQName = new QName(COMPLEX_SCHEMA_NS, "realRoot");
+
+        ExpectedStateMachineNode realRootState = new ExpectedStateMachineNode(
+                                                                              XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                              realRootQName, realRootElem);
+
+        ExpectedStateMachineNode realRootSeq = new ExpectedStateMachineNode(
+                                                                            XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                            null, null);
+
+        // backtrack
+        ExpectedElement backtrackElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName backtrackQName = new QName(COMPLEX_SCHEMA_NS, "backtrack");
+
+        ExpectedStateMachineNode backtrackState = new ExpectedStateMachineNode(
+                                                                               XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               backtrackQName, backtrackElem);
+
+        ExpectedStateMachineNode backtrackSeq = new ExpectedStateMachineNode(
+                                                                             XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                             null, null);
+
+        ExpectedStateMachineNode backtrackChoice = new ExpectedStateMachineNode(
+                                                                                XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                                null, null);
+
+        ExpectedStateMachineNode backtrackChoiceChoice = new ExpectedStateMachineNode(
+                                                                                      XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                                      null, null);
+
+        // avro:qName
+        ExpectedElement qNameElem = new ExpectedElement(new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.QNAME));
+
+        QName qNameQName = new QName(COMPLEX_SCHEMA_NS, "qName");
+
+        ExpectedStateMachineNode qNameState = new ExpectedStateMachineNode(
+                                                                           XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                           qNameQName, qNameElem);
+
+        // avro:avroEnum
+        ExpectedElement avroEnumElem = new ExpectedElement(
+                                                           new XmlSchemaTypeInfo(
+                                                                                 XmlSchemaBaseSimpleType.STRING));
+
+        QName avroEnumQName = new QName(COMPLEX_SCHEMA_NS, "avroEnum");
+
+        ExpectedStateMachineNode avroEnumState = new ExpectedStateMachineNode(
+                                                                              XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                              avroEnumQName, avroEnumElem);
+
+        // avro:xmlEnum
+        ExpectedElement xmlEnumElem = new ExpectedElement(
+                                                          new XmlSchemaTypeInfo(
+                                                                                XmlSchemaBaseSimpleType.STRING));
+
+        QName xmlEnumQName = new QName(COMPLEX_SCHEMA_NS, "xmlEnum");
+
+        ExpectedStateMachineNode xmlEnumState = new ExpectedStateMachineNode(
+                                                                             XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                             xmlEnumQName, xmlEnumElem);
+
+        ExpectedStateMachineNode backtrackChoiceSequence = new ExpectedStateMachineNode(
+                                                                                        XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                                        null, null);
+
+        // avro:unsignedLongList
+        ExpectedElement unsignedLongListElem = new ExpectedElement(
+                                                                   new XmlSchemaTypeInfo(
+                                                                                         new XmlSchemaTypeInfo(
+                                                                                                               XmlSchemaBaseSimpleType.DECIMAL)));
+
+        QName unsignedLongListQName = new QName(COMPLEX_SCHEMA_NS, "unsignedLongList");
+
+        ExpectedStateMachineNode unsignedLongListState = new ExpectedStateMachineNode(
+                                                                                      XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                                      unsignedLongListQName,
+                                                                                      unsignedLongListElem);
+
+        ExpectedStateMachineNode backtrackSeqSequence = new ExpectedStateMachineNode(
+                                                                                     XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                                     null, null);
+
+        // listOfUnion
+        ArrayList<XmlSchemaTypeInfo> unionForListOfUnion = new ArrayList<XmlSchemaTypeInfo>();
+        unionForListOfUnion.add(new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.BOOLEAN));
+        unionForListOfUnion.add(new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.STRING));
+        unionForListOfUnion.add(new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+        unionForListOfUnion.add(new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        ExpectedElement listOfUnionElem = new ExpectedElement(
+                                                              new XmlSchemaTypeInfo(
+                                                                                    new XmlSchemaTypeInfo(
+                                                                                                          unionForListOfUnion)));
+
+        QName listOfUnionQName = new QName(COMPLEX_SCHEMA_NS, "listOfUnion");
+
+        ExpectedStateMachineNode listOfUnionState = new ExpectedStateMachineNode(
+                                                                                 XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                                 listOfUnionQName,
+                                                                                 listOfUnionElem);
+
+        // avro:allTheThings
+        ExpectedElement allTheThingsElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName allTheThingsQName = new QName(COMPLEX_SCHEMA_NS, "allTheThings");
+
+        ExpectedStateMachineNode allTheThingsState = new ExpectedStateMachineNode(
+                                                                                  XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                                  allTheThingsQName,
+                                                                                  allTheThingsElem);
+
+        ExpectedStateMachineNode allTheThingsAll = new ExpectedStateMachineNode(
+                                                                                XmlSchemaStateMachineNode.Type.ALL,
+                                                                                null, null);
+
+        // firstMap
+        ExpectedElement firstMapElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName firstMapQName = new QName(COMPLEX_SCHEMA_NS, "firstMap");
+
+        ExpectedStateMachineNode firstMapState = new ExpectedStateMachineNode(
+                                                                              XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                              firstMapQName, firstMapElem);
+
+        ExpectedStateMachineNode firstMapSeq = new ExpectedStateMachineNode(
+                                                                            XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                            null, null);
+
+        // value
+        ExpectedElement valueElem = new ExpectedElement(
+                                                        new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        QName valueQName = new QName(COMPLEX_SCHEMA_NS, "value");
+
+        ExpectedStateMachineNode valueState = new ExpectedStateMachineNode(
+                                                                           XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                           valueQName, valueElem);
+
+        // secondMap
+        ExpectedElement secondMapElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName secondMapQName = new QName(COMPLEX_SCHEMA_NS, "secondMap");
+
+        ExpectedStateMachineNode secondMapState = new ExpectedStateMachineNode(
+                                                                               XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               secondMapQName, secondMapElem);
+
+        // prohibit
+        ExpectedElement prohibitElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName prohibitQName = new QName(COMPLEX_SCHEMA_NS, "prohibit");
+
+        ExpectedStateMachineNode prohibitState = new ExpectedStateMachineNode(
+                                                                              XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                              prohibitQName, prohibitElem);
+
+        ExpectedStateMachineNode prohibitSeq = new ExpectedStateMachineNode(
+                                                                            XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                            null, null);
+
+        // fixed
+        ExpectedElement fixedElem = new ExpectedElement(
+                                                        new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        QName fixedQName = new QName(COMPLEX_SCHEMA_NS, "fixed");
+
+        ExpectedStateMachineNode fixedState = new ExpectedStateMachineNode(
+                                                                           XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                           fixedQName, fixedElem);
+
+        // avro:anyAndFriends
+        ExpectedElement anyAndFriendsElem = new ExpectedElement(new XmlSchemaTypeInfo(true));
+
+        QName anyAndFriendsQName = new QName(COMPLEX_SCHEMA_NS, "anyAndFriends");
+
+        ExpectedStateMachineNode anyAndFriendsState = new ExpectedStateMachineNode(
+                                                                                   XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                                   anyAndFriendsQName,
+                                                                                   anyAndFriendsElem);
+
+        ExpectedStateMachineNode anyAndFriendsSeq = new ExpectedStateMachineNode(
+                                                                                 XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                                 null, null);
+
+        ExpectedStateMachineNode anyState = new ExpectedStateMachineNode(XmlSchemaStateMachineNode.Type.ANY,
+                                                                         null, null);
+
+        // avro:simpleExtension
+        ArrayList<XmlSchemaTypeInfo> baseUnion = new ArrayList<XmlSchemaTypeInfo>();
+        baseUnion.add(new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.BOOLEAN));
+        baseUnion.add(new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        ExpectedElement simpleExtensionElem = new ExpectedElement(new XmlSchemaTypeInfo(baseUnion));
+
+        QName simpleExtensionQName = new QName(COMPLEX_SCHEMA_NS, "simpleExtension");
+
+        ExpectedStateMachineNode simpleExtensionState = new ExpectedStateMachineNode(
+                                                                                     XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                                     simpleExtensionQName,
+                                                                                     simpleExtensionElem);
+
+        // simpleRestriction
+        QName simpleRestrictionQName = new QName(COMPLEX_SCHEMA_NS, "simpleRestriction");
+
+        ExpectedStateMachineNode simpleRestrictionState = new ExpectedStateMachineNode(
+                                                                                       XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                                       simpleRestrictionQName,
+                                                                                       simpleExtensionElem);
+
+        // complexExtension
+        ExpectedElement complexExtensionElem = new ExpectedElement(new XmlSchemaTypeInfo(false));
+
+        QName complexExtensionQName = new QName(COMPLEX_SCHEMA_NS, "complexExtension");
+
+        ExpectedStateMachineNode complexExtensionState = new ExpectedStateMachineNode(
+                                                                                      XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                                      complexExtensionQName,
+                                                                                      complexExtensionElem);
+
+        ExpectedStateMachineNode complexExtensionSeq = new ExpectedStateMachineNode(
+                                                                                    XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                                    null, null);
+
+        ExpectedStateMachineNode complexExtensionSeqChoice = new ExpectedStateMachineNode(
+                                                                                          XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                                          null, null);
+
+        ExpectedStateMachineNode complexExtensionSeqSequence = new ExpectedStateMachineNode(
+                                                                                            XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                                            null, null);
+
+        // avro:mixedType
+        ExpectedElement mixedTypeElem = new ExpectedElement(new XmlSchemaTypeInfo(true));
+
+        QName mixedTypeQName = new QName(COMPLEX_SCHEMA_NS, "mixedType");
+
+        ExpectedStateMachineNode mixedTypeState = new ExpectedStateMachineNode(
+                                                                               XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               mixedTypeQName, mixedTypeElem);
+
+        ExpectedStateMachineNode mixedTypeSeq = new ExpectedStateMachineNode(
+                                                                             XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                             null, null);
+
+        // Indentation follows schema
+        rootSubstGrp.addNextState(realRootState);
+        realRootState.addNextState(realRootSeq);
+        realRootSeq.addNextState(backtrackState);
+        backtrackState.addNextState(backtrackSeq);
+        backtrackSeq.addNextState(backtrackChoice);
+        backtrackChoice.addNextState(backtrackChoiceChoice);
+        backtrackChoiceChoice.addNextState(qNameState);
+        backtrackChoiceChoice.addNextState(avroEnumState);
+        backtrackChoiceChoice.addNextState(xmlEnumState);
+        backtrackChoice.addNextState(backtrackChoiceSequence);
+        backtrackChoiceSequence.addNextState(xmlEnumState);
+        backtrackChoiceSequence.addNextState(unsignedLongListState);
+        backtrackSeq.addNextState(backtrackSeqSequence);
+        backtrackSeqSequence.addNextState(qNameState);
+        backtrackSeqSequence.addNextState(avroEnumState);
+        backtrackSeqSequence.addNextState(xmlEnumState);
+        backtrackSeqSequence.addNextState(unsignedLongListState);
+        backtrackSeqSequence.addNextState(listOfUnionState);
+        realRootSeq.addNextState(allTheThingsState);
+        allTheThingsState.addNextState(allTheThingsAll);
+        allTheThingsAll.addNextState(firstMapState);
+        firstMapState.addNextState(firstMapSeq);
+        firstMapSeq.addNextState(valueState);
+        allTheThingsAll.addNextState(secondMapState);
+        realRootSeq.addNextState(prohibitState);
+        prohibitState.addNextState(prohibitSeq);
+        prohibitSeq.addNextState(fixedState);
+        realRootSeq.addNextState(anyAndFriendsState);
+        anyAndFriendsState.addNextState(anyAndFriendsSeq);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        realRootSeq.addNextState(simpleExtensionState);
+        realRootSeq.addNextState(simpleRestrictionState);
+        realRootSeq.addNextState(complexExtensionState);
+        complexExtensionState.addNextState(complexExtensionSeq);
+        complexExtensionSeq.addNextState(complexExtensionSeqSequence);
+        complexExtensionSeqSequence.addNextState(fixedState);
+        complexExtensionSeq.addNextState(complexExtensionSeqChoice);
+        complexExtensionSeqChoice.addNextState(listOfUnionState);
+        complexExtensionSeqChoice.addNextState(unsignedLongListState);
+        realRootSeq.addNextState(mixedTypeState);
+        mixedTypeState.addNextState(mixedTypeSeq);
+        mixedTypeSeq.addNextState(listOfUnionState);
+        mixedTypeSeq.addNextState(unsignedLongListState);
+
+        validate(rootSubstGrp, stateMachine, seen);
+    }
+
+    private XmlSchemaStateMachineNode buildSchema(File schemaFile, QName root) throws IOException {
+
+        XmlSchemaCollection xmlSchemaCollection = new XmlSchemaCollection();
+
+        FileReader schemaFileReader = null;
+        try {
+            schemaFileReader = new FileReader(schemaFile);
+            xmlSchemaCollection.read(new StreamSource(schemaFileReader));
+        } finally {
+            if (schemaFileReader != null) {
+                schemaFileReader.close();
+            }
+        }
+
+        XmlSchemaStateMachineGenerator stateMachineGen = new XmlSchemaStateMachineGenerator();
+
+        XmlSchemaWalker walker = new XmlSchemaWalker(xmlSchemaCollection, stateMachineGen);
+
+        XmlSchemaElement rootElement = xmlSchemaCollection.getElementByQName(root);
+
+        walker.walk(rootElement);
+
+        return stateMachineGen.getStartNode();
+    }
+
+    private void validate(ExpectedStateMachineNode exp, XmlSchemaStateMachineNode act, HashSet<QName> seen) {
+
+        exp.validate(act);
+
+        if (exp.expNodeType.equals(XmlSchemaStateMachineNode.Type.ELEMENT)) {
+            /*
+             * The state machine may fold back onto itself if an element is a
+             * child of itself. Likewise, we need to keep track of what we've
+             * seen so we do not traverse state machine nodes again.
+             */
+            seen.add(exp.expElemQName);
+        }
+
+        for (int idx = 0; idx < exp.expNextStates.size(); ++idx) {
+            ExpectedStateMachineNode expNext = exp.expNextStates.get(idx);
+            XmlSchemaStateMachineNode actNext = act.getPossibleNextStates().get(idx);
+
+            if (expNext.expNodeType.equals(XmlSchemaStateMachineNode.Type.ELEMENT)
+                && seen.contains(expNext.expElemQName)) {
+
+                // We've seen this one; no need to follow it.
+                expNext.validate(actNext);
+                continue;
+            }
+
+            validate(expNext, actNext, seen);
+        }
+
+    }
+}

Propchange: webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java
URL: http://svn.apache.org/viewvc/webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java?rev=1625632&view=auto
==============================================================================
--- webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java (added)
+++ webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java Wed Sep 17 15:32:44 2014
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ws.commons.schema.testutils;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.custommonkey.xmlunit.DetailedDiff;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.w3c.dom.Document;
+
+public final class UtilsForTests {
+
+    public static void assertEquivalent(Document expected, Document actual) {
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreAttributeOrder(true);
+
+        DetailedDiff diff = new DetailedDiff(XMLUnit.compareXML(expected, actual));
+
+        assertTrue("Differences found: " + diff.toString(), diff.similar());
+    }
+
+    public static File buildFile(String... parts) {
+        File file = null;
+
+        for (String part : parts) {
+            if (file == null) {
+                file = new File(part);
+            } else {
+                file = new File(file, part);
+            }
+        }
+
+        return file;
+    }
+}

Propchange: webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java
URL: http://svn.apache.org/viewvc/webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java?rev=1625632&view=auto
==============================================================================
--- webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java (added)
+++ webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java Wed Sep 17 15:32:44 2014
@@ -0,0 +1,922 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.commons.schema.walker;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.transform.stream.StreamSource;
+
+import org.junit.Assert;
+
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaAll;
+import org.apache.ws.commons.schema.XmlSchemaAny;
+import org.apache.ws.commons.schema.XmlSchemaAnyAttribute;
+import org.apache.ws.commons.schema.XmlSchemaAttribute;
+import org.apache.ws.commons.schema.XmlSchemaChoice;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.XmlSchemaFractionDigitsFacet;
+import org.apache.ws.commons.schema.XmlSchemaMaxInclusiveFacet;
+import org.apache.ws.commons.schema.XmlSchemaMinInclusiveFacet;
+import org.apache.ws.commons.schema.XmlSchemaParticle;
+import org.apache.ws.commons.schema.XmlSchemaPatternFacet;
+import org.apache.ws.commons.schema.XmlSchemaSequence;
+import org.apache.ws.commons.schema.XmlSchemaUse;
+import org.apache.ws.commons.schema.XmlSchemaWhiteSpaceFacet;
+import org.apache.ws.commons.schema.testutils.UtilsForTests;
+import org.apache.ws.commons.schema.walker.XmlSchemaAttrInfo;
+import org.apache.ws.commons.schema.walker.XmlSchemaBaseSimpleType;
+import org.apache.ws.commons.schema.walker.XmlSchemaRestriction;
+import org.apache.ws.commons.schema.walker.XmlSchemaTypeInfo;
+import org.apache.ws.commons.schema.walker.XmlSchemaVisitor;
+import org.apache.ws.commons.schema.walker.XmlSchemaWalker;
+import org.junit.Test;
+
+public class TestSchemaWalker {
+
+    private static enum Type {
+        ELEMENT, SEQUENCE, CHOICE, ALL, SUBSTITUTION_GROUP
+    }
+
+    private static class StackEntry {
+        StackEntry(Type type) {
+            this.type = type;
+            this.name = null;
+            this.typeName = null;
+            this.facets = null;
+            this.baseType = null;
+            this.minOccurs = 1;
+            this.maxOccurs = 1;
+        }
+
+        StackEntry(Type type, long minOccurs, long maxOccurs) {
+            this(type);
+            this.minOccurs = minOccurs;
+            this.maxOccurs = maxOccurs;
+        }
+
+        StackEntry(Type type, String name) {
+            this(type);
+            this.name = name;
+            this.typeName = null;
+        }
+
+        StackEntry(Type type, String name, String typeName) {
+            this(type, name);
+            this.typeName = typeName;
+        }
+
+        StackEntry(Type type, String name, String typeName, XmlSchemaBaseSimpleType baseType) {
+
+            this(type, name, typeName);
+            this.baseType = baseType;
+        }
+
+        StackEntry(Type type, String name, String typeName, long minOccurs, long maxOccurs) {
+
+            this(type, name, typeName);
+            this.minOccurs = minOccurs;
+            this.maxOccurs = maxOccurs;
+        }
+
+        StackEntry(Type type, String name, String typeName, XmlSchemaBaseSimpleType baseType, long minOccurs,
+                   long maxOccurs) {
+
+            this(type, name, typeName, baseType);
+            this.minOccurs = minOccurs;
+            this.maxOccurs = maxOccurs;
+        }
+
+        StackEntry(Type type, String name, String typeName, XmlSchemaBaseSimpleType baseType,
+                   Set<XmlSchemaRestriction> facets) {
+
+            this(type, name, typeName, baseType);
+            this.facets = facets;
+        }
+
+        StackEntry(Type type, String name, String typeName, XmlSchemaBaseSimpleType baseType, long minOccurs,
+                   long maxOccurs, Set<XmlSchemaRestriction> facets) {
+
+            this(type, name, typeName, baseType, minOccurs, maxOccurs);
+            this.facets = facets;
+
+        }
+
+        Type type;
+        String name;
+        String typeName;
+        Set<XmlSchemaRestriction> facets;
+        long minOccurs;
+        long maxOccurs;
+        XmlSchemaBaseSimpleType baseType;
+    }
+
+    private static class Attribute {
+        public Attribute(String name, String typeName, XmlSchemaTypeInfo.Type type,
+                         XmlSchemaBaseSimpleType baseType) {
+
+            this.name = name;
+            this.typeName = typeName;
+            this.isOptional = false;
+            this.type = type;
+            this.baseType = baseType;
+        }
+
+        public Attribute(String name, String typeName, XmlSchemaTypeInfo.Type type,
+                         XmlSchemaBaseSimpleType baseType, boolean isOptional) {
+
+            this(name, typeName, type, baseType);
+            this.isOptional = isOptional;
+        }
+
+        public Attribute(String name, String typeName, XmlSchemaTypeInfo.Type type,
+                         XmlSchemaBaseSimpleType baseType, Set<XmlSchemaRestriction> facets) {
+
+            this(name, typeName, type, baseType);
+            this.facets = facets;
+        }
+
+        public Attribute(String name, String typeName, XmlSchemaTypeInfo.Type type,
+                         XmlSchemaBaseSimpleType baseType, boolean isOptional,
+                         Set<XmlSchemaRestriction> facets) {
+
+            this(name, typeName, type, baseType, isOptional);
+            this.facets = facets;
+        }
+
+        String name;
+        String typeName;
+        boolean isOptional;
+        Set<XmlSchemaRestriction> facets;
+        XmlSchemaBaseSimpleType baseType;
+        XmlSchemaTypeInfo.Type type;
+    }
+
+    private static class Visitor implements XmlSchemaVisitor {
+
+        Visitor(List<StackEntry> stack, HashMap<String, List<Attribute>> attributes) {
+
+            this.stack = stack;
+            this.attributes = attributes;
+        }
+
+        @Override
+        public void onEnterElement(XmlSchemaElement element, XmlSchemaTypeInfo typeInfo,
+                                   boolean previouslyVisited) {
+
+            StackEntry next = pop();
+            if (next.type != Type.ELEMENT) {
+                throw new IllegalStateException("Expected a " + next.type + " named \"" + next.name
+                                                + "\" but received an element named \"" + element.getName()
+                                                + "\".");
+
+            } else if (!next.name.equals(element.getName())) {
+                throw new IllegalStateException("Expected an element named \"" + next.name
+                                                + "\" but received an element named " + element.getName()
+                                                + "\"");
+
+            } else if ((next.typeName == null) && !element.getSchemaType().isAnonymous()) {
+
+                throw new IllegalStateException("Expected the element named \"" + next.name
+                                                + "\" to carry an anonymous type, but the type was "
+                                                + element.getSchemaType().getQName());
+
+            } else if ((next.typeName != null) && element.getSchemaType().isAnonymous()) {
+                throw new IllegalStateException("Expected the element named \"" + next.name
+                                                + "\" to carry a type named \"" + next.typeName
+                                                + "\"; but the type was anonymous instead.");
+            }
+
+            checkMinAndMaxOccurs(next, element);
+
+            if (typeInfo != null) {
+                checkFacets(next.name, typeInfo, next.facets);
+
+                if ((next.baseType == null) && (typeInfo.getBaseType() != null)
+                    && !typeInfo.getBaseType().equals(XmlSchemaBaseSimpleType.ANYTYPE)) {
+
+                    throw new IllegalStateException("Element \"" + next.name
+                                                    + "\" was not expected to have an Avro schema,"
+                                                    + " but has a schema of " + typeInfo.getBaseType());
+
+                } else if ((next.baseType != null) && (typeInfo.getBaseType() == null)) {
+
+                    throw new IllegalStateException("Element \"" + next.name
+                                                    + "\" was expected to have a schema of " + next.baseType
+                                                    + " but instead has no schema.");
+
+                } else if ((next.baseType != null) && !next.baseType.equals(typeInfo.getBaseType())) {
+                    throw new IllegalStateException("Element \"" + next.name
+                                                    + "\" was expected to have a schema of " + next.baseType
+                                                    + " but instead has a schema of "
+                                                    + typeInfo.getBaseType());
+                }
+
+            } else if (next.baseType != null) {
+                throw new IllegalStateException("Expected a schema of " + next.baseType
+                                                + " but received none.");
+            }
+
+            if ((next.facets != null) && !next.facets.isEmpty()) {
+                StringBuilder errMsg = new StringBuilder("Element \"");
+                errMsg.append(next.name);
+                errMsg.append("\" was expected to have the following facets, ");
+                errMsg.append("but did not:");
+
+                for (XmlSchemaRestriction facet : next.facets) {
+                    errMsg.append(" \"").append(facet).append('\"');
+                }
+
+                throw new IllegalStateException(errMsg.toString());
+            }
+        }
+
+        @Override
+        public void onExitElement(XmlSchemaElement element, XmlSchemaTypeInfo typeInfo,
+                                  boolean previouslyVisited) {
+
+            if (!previouslyVisited && attributes.containsKey(element.getName())) {
+                List<Attribute> remainingAttrs = attributes.get(element.getName());
+                if (!remainingAttrs.isEmpty()) {
+                    StringBuilder errMsg = new StringBuilder("Element \"");
+                    errMsg.append(element.getName());
+                    errMsg.append("\" did not have the expected attributes ");
+                    errMsg.append("of the following names:");
+                    for (Attribute attr : remainingAttrs) {
+                        errMsg.append(" \"").append(attr.name).append('\"');
+                    }
+                    throw new IllegalStateException(errMsg.toString());
+                }
+            }
+        }
+
+        @Override
+        public void onVisitAttribute(XmlSchemaElement element, XmlSchemaAttrInfo attrInfo) {
+
+            final XmlSchemaAttribute attribute = attrInfo.getAttribute();
+            final XmlSchemaTypeInfo attributeType = attrInfo.getType();
+
+            if (!attributes.containsKey(element.getName())) {
+                throw new IllegalStateException("No attributes were expected for \"" + element.getName()
+                                                + "\", but \"" + attribute.getQName() + "\" was found.");
+            }
+
+            List<Attribute> attrs = attributes.get(element.getName());
+            boolean found = false;
+            int index = 0;
+
+            for (; index < attrs.size(); ++index) {
+                Attribute attr = attrs.get(index);
+                if (attr.name.equals(attribute.getName())) {
+                    if ((attr.typeName == null) && !attribute.getSchemaType().isAnonymous()) {
+
+                        throw new IllegalStateException("Element \"" + element.getName()
+                                                        + "\" has an attribute named \"" + attr.name
+                                                        + "\" whose type was expected to be anonymous, "
+                                                        + "but actually is named \""
+                                                        + attribute.getSchemaType().getName() + "\"");
+
+                    } else if ((attr.typeName != null) && attribute.getSchemaType().isAnonymous()) {
+
+                        throw new IllegalStateException("Element \"" + element.getName()
+                                                        + "\" has an attribute named \"" + attr.name
+                                                        + "\" whose type was expected to be \""
+                                                        + attr.typeName + "\"; but is anonymous instead.");
+
+                    } else if ((attr.typeName != null)
+                               && !attr.typeName.equals(attribute.getSchemaType().getName())) {
+
+                        throw new IllegalStateException("Element \"" + element.getName()
+                                                        + "\" has an attribute named \"" + attr.name
+                                                        + "\"; its type was expected to be \""
+                                                        + attr.typeName + "\" but instead was \""
+                                                        + attribute.getSchemaType().getName() + "\"");
+
+                    } else if (attr.isOptional && !attribute.getUse().equals(XmlSchemaUse.OPTIONAL)) {
+
+                        throw new IllegalStateException(
+                                                        "Element \""
+                                                            + element.getName()
+                                                            + "\" has an attribute named \""
+                                                            + attr.name
+                                                            + "\" whose usage was expected to be optional, but instead is "
+                                                            + attribute.getUse());
+
+                    } else if (!attr.isOptional && attribute.getUse().equals(XmlSchemaUse.OPTIONAL)) {
+
+                        throw new IllegalStateException("Element \"" + element.getName()
+                                                        + "\" has an attribute named \"" + attr.name
+                                                        + "\" whose usage was expected to be required,"
+                                                        + " but is actually optional.");
+
+                    } else if (!attr.type.equals(attributeType.getType())) {
+                        throw new IllegalStateException("Element \"" + element.getName()
+                                                        + "\" has an attribute named \"" + attr.name
+                                                        + "\" whose type was expected to be " + attr.type
+                                                        + " but actually was " + attributeType.getType());
+
+                    } else if (attr.type.equals(XmlSchemaTypeInfo.Type.ATOMIC)
+                               && !attr.baseType.equals(attributeType.getBaseType())) {
+
+                        throw new IllegalStateException("Element \"" + element.getName()
+                                                        + "\" has an attribute named \"" + attr.name
+                                                        + "\" whose type was expected to be "
+                                                        + attr.baseType.name() + " but actually was "
+                                                        + attributeType.getBaseType());
+
+                    } else if (attr.type.equals(XmlSchemaTypeInfo.Type.LIST)
+                               && !attr.baseType.equals(attributeType.getChildTypes().get(0).getBaseType())) {
+
+                        throw new IllegalStateException("Element \"" + element.getName()
+                                                        + "\" has an attribute named \"" + attr.name
+                                                        + "\" with a type of " + attr.type
+                                                        + " whose base type is expected to be "
+                                                        + attr.baseType + " but actually is "
+                                                        + attributeType.getChildTypes().get(0).getBaseType());
+
+                    } else {
+
+                        checkFacets(attr.name, attributeType, attr.facets);
+
+                        found = true;
+                        break;
+                    }
+                }
+            }
+
+            if (found) {
+                attrs.remove(index);
+            } else {
+                throw new IllegalStateException("Element \"" + element.getName()
+                                                + "\" has unexpected attribute \"" + attribute.getName()
+                                                + "\"");
+            }
+        }
+
+        @Override
+        public void onEndAttributes(XmlSchemaElement element, XmlSchemaTypeInfo elemTypeInfo) {
+
+        }
+
+        @Override
+        public void onEnterSubstitutionGroup(XmlSchemaElement base) {
+            StackEntry next = pop();
+
+            if (next.type != Type.SUBSTITUTION_GROUP) {
+                throw new IllegalStateException("Expected a " + next.type
+                                                + " but instead found a substition group of \""
+                                                + base.getName() + "\"");
+
+            } else if (!next.name.equals(base.getName())) {
+                throw new IllegalStateException("Expected a substitution group for element \"" + next.name
+                                                + "\", but instead received one for \"" + base.getName()
+                                                + "\"");
+
+            } else if (next.minOccurs != base.getMinOccurs()) {
+                throw new IllegalStateException("Expected a substitution group for element \"" + next.name
+                                                + "\" and min occurs of " + next.minOccurs
+                                                + ", but received a min occurs of " + base.getMinOccurs());
+
+            } else if (next.maxOccurs != base.getMaxOccurs()) {
+                throw new IllegalStateException("Expected a substitution group for element \"" + next.name
+                                                + "\" and max occurs of " + next.maxOccurs
+                                                + ", but received a max occurs of " + base.getMaxOccurs());
+            }
+        }
+
+        @Override
+        public void onExitSubstitutionGroup(XmlSchemaElement base) {
+        }
+
+        @Override
+        public void onEnterAllGroup(XmlSchemaAll all) {
+            StackEntry next = pop();
+            if (next.type != Type.ALL) {
+                throw new IllegalStateException("Expected a " + next.type + " but received an All group.");
+            }
+            checkMinAndMaxOccurs(next, all);
+        }
+
+        @Override
+        public void onExitAllGroup(XmlSchemaAll all) {
+        }
+
+        @Override
+        public void onEnterChoiceGroup(XmlSchemaChoice choice) {
+            StackEntry next = pop();
+            if (next.type != Type.CHOICE) {
+                throw new IllegalStateException("Expected a " + next.type + " but received a Choice group.");
+            }
+            checkMinAndMaxOccurs(next, choice);
+        }
+
+        @Override
+        public void onExitChoiceGroup(XmlSchemaChoice choice) {
+        }
+
+        @Override
+        public void onEnterSequenceGroup(XmlSchemaSequence seq) {
+            StackEntry next = pop();
+            if (next.type != Type.SEQUENCE) {
+                throw new IllegalStateException("Expected a " + next.type + " but received a Sequence group.");
+            }
+            checkMinAndMaxOccurs(next, seq);
+        }
+
+        @Override
+        public void onExitSequenceGroup(XmlSchemaSequence seq) {
+        }
+
+        @Override
+        public void onVisitAny(XmlSchemaAny any) {
+            throw new IllegalStateException("No Any types were expected in the schema.");
+        }
+
+        @Override
+        public void onVisitAnyAttribute(XmlSchemaElement element, XmlSchemaAnyAttribute anyAttr) {
+
+            throw new IllegalStateException("No anyAttribute types were expected in the schema.");
+        }
+
+        private static void checkMinAndMaxOccurs(StackEntry next, XmlSchemaParticle particle) {
+
+            if (next.minOccurs != particle.getMinOccurs()) {
+                throw new IllegalStateException("Expected a minOccurs of " + next.minOccurs + " for "
+                                                + next.type + " \"" + next.name
+                                                + "\", but found a minOccurs of " + particle.getMinOccurs());
+
+            } else if (next.maxOccurs != particle.getMaxOccurs()) {
+                throw new IllegalStateException("Expected a maxOccurs of " + next.maxOccurs + " for "
+                                                + next.type + " \"" + next.name
+                                                + "\", but found a maxOccurs of " + particle.getMaxOccurs());
+            }
+        }
+
+        private StackEntry pop() {
+            if (stack.isEmpty()) {
+                throw new IllegalStateException("Ran out of stack!");
+            }
+
+            StackEntry entry = stack.get(0);
+            stack.remove(entry);
+            return entry;
+        }
+
+        private List<StackEntry> stack;
+        private HashMap<String, List<Attribute>> attributes;
+    }
+
+    /**
+     * Test for src/main/resources/test_schema.xsd
+     */
+    @Test
+    public void test() throws Exception {
+        // Build the expectations.
+        ArrayList<Attribute> attrGroupAttrs = new ArrayList<Attribute>(43);
+
+        attrGroupAttrs.add(new Attribute("anySimpleType", "anySimpleType", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.ANYSIMPLETYPE, true));
+
+        HashSet<XmlSchemaRestriction> whiteSpaceCollapseFixedRestrictions = new HashSet<XmlSchemaRestriction>();
+
+        whiteSpaceCollapseFixedRestrictions
+            .add(new XmlSchemaRestriction(new XmlSchemaWhiteSpaceFacet("collapse", true)));
+
+        attrGroupAttrs.add(new Attribute("duration", "duration", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DURATION, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("dateTime", "dateTime", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DATETIME, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("date", "date", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DATE, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("time", "time", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.TIME, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gYearMonth", "gYearMonth", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.YEARMONTH, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gYear", "gYear", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.YEAR, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gDay", "gDay", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DAY, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gMonth", "gMonth", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.MONTH, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gMonthDay", "gMonthDay", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.MONTHDAY, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("boolean", "boolean", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.BOOLEAN, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("base64Binary", "base64Binary", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.BIN_BASE64, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("hexBinary", "hexBinary", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.BIN_HEX, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("float", "float", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.FLOAT, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("double", "double", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DOUBLE, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("anyURI", "anyURI", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.ANYURI, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("qname", "QName", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.QNAME, true,
+                                         (Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+
+        HashSet<XmlSchemaRestriction> decimalFacets = (HashSet<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+            .clone();
+        decimalFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.DIGITS_FRACTION, new Integer(0),
+                                                   false));
+
+        attrGroupAttrs.add(new Attribute("decimal", null, XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, decimalFacets));
+
+        HashSet<XmlSchemaRestriction> integerFacets = (HashSet<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+            .clone();
+        integerFacets.add(new XmlSchemaRestriction(new XmlSchemaFractionDigitsFacet(new Integer(0), true)));
+        integerFacets.add(new XmlSchemaRestriction(new XmlSchemaPatternFacet("[\\-+]?[0-9]+", false)));
+        attrGroupAttrs.add(new Attribute("integer", "integer", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, integerFacets));
+
+        HashSet<XmlSchemaRestriction> nonPositiveIntegerFacets = (HashSet<XmlSchemaRestriction>)integerFacets
+            .clone();
+        nonPositiveIntegerFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(new Integer(0),
+                                                                                             false)));
+        attrGroupAttrs.add(new Attribute("nonPositiveInteger", "nonPositiveInteger",
+                                         XmlSchemaTypeInfo.Type.ATOMIC, XmlSchemaBaseSimpleType.DECIMAL,
+                                         true, nonPositiveIntegerFacets));
+
+        HashSet<XmlSchemaRestriction> negativeIntegerFacets = (HashSet<XmlSchemaRestriction>)integerFacets
+            .clone();
+        negativeIntegerFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(new Integer(-1),
+                                                                                          false)));
+        attrGroupAttrs.add(new Attribute("negativeInteger", "negativeInteger", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, negativeIntegerFacets));
+
+        HashSet<XmlSchemaRestriction> longFacets = (HashSet<XmlSchemaRestriction>)integerFacets.clone();
+        longFacets
+            .add(new XmlSchemaRestriction(new XmlSchemaMinInclusiveFacet(new Long(-9223372036854775808L),
+                                                                         false)));
+        longFacets
+            .add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(new Long(9223372036854775807L),
+                                                                         false)));
+        attrGroupAttrs.add(new Attribute("long", "long", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, longFacets));
+
+        HashSet<XmlSchemaRestriction> intFacets = (HashSet<XmlSchemaRestriction>)integerFacets.clone();
+        intFacets
+            .add(new XmlSchemaRestriction(new XmlSchemaMinInclusiveFacet(new Integer(-2147483648), false)));
+        intFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(2147483647, false)));
+        attrGroupAttrs.add(new Attribute("int", "int", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, intFacets));
+
+        HashSet<XmlSchemaRestriction> shortFacets = (HashSet<XmlSchemaRestriction>)integerFacets.clone();
+        shortFacets.add(new XmlSchemaRestriction(new XmlSchemaMinInclusiveFacet(new Short((short)-32768),
+                                                                                false)));
+        shortFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(new Short((short)32767),
+                                                                                false)));
+        attrGroupAttrs.add(new Attribute("short", "short", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, shortFacets));
+
+        HashSet<XmlSchemaRestriction> byteFacets = (HashSet<XmlSchemaRestriction>)integerFacets.clone();
+        byteFacets.add(new XmlSchemaRestriction(new XmlSchemaMinInclusiveFacet(new Byte((byte)-128), false)));
+        byteFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(new Byte((byte)127), false)));
+        attrGroupAttrs.add(new Attribute("byte", "byte", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, byteFacets));
+
+        HashSet<XmlSchemaRestriction> nonNegativeIntegerFacets = (HashSet<XmlSchemaRestriction>)integerFacets
+            .clone();
+        nonNegativeIntegerFacets.add(new XmlSchemaRestriction(new XmlSchemaMinInclusiveFacet(new Integer(0),
+                                                                                             false)));
+        attrGroupAttrs.add(new Attribute("nonNegativeInteger", "nonNegativeInteger",
+                                         XmlSchemaTypeInfo.Type.ATOMIC, XmlSchemaBaseSimpleType.DECIMAL,
+                                         true, nonNegativeIntegerFacets));
+
+        HashSet<XmlSchemaRestriction> positiveIntegerFacets = (HashSet<XmlSchemaRestriction>)integerFacets
+            .clone();
+        positiveIntegerFacets.add(new XmlSchemaRestriction(new XmlSchemaMinInclusiveFacet(new Integer(1),
+                                                                                          false)));
+        attrGroupAttrs.add(new Attribute("positiveInteger", "positiveInteger", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, positiveIntegerFacets));
+
+        HashSet<XmlSchemaRestriction> unsignedLongFacets = (HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        unsignedLongFacets
+            .add(new XmlSchemaRestriction(
+                                          new XmlSchemaMaxInclusiveFacet(
+                                                                         new BigInteger(
+                                                                                        "18446744073709551615"),
+                                                                         false)));
+        attrGroupAttrs.add(new Attribute("unsignedLong", "unsignedLong", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, unsignedLongFacets));
+
+        HashSet<XmlSchemaRestriction> unsignedIntFacets = (HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        unsignedIntFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(new Long(4294967295L),
+                                                                                      false)));
+        attrGroupAttrs.add(new Attribute("unsignedInt", "unsignedInt", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, unsignedIntFacets));
+
+        HashSet<XmlSchemaRestriction> unsignedShortFacets = (HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        unsignedShortFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(new Integer(65535),
+                                                                                        false)));
+        attrGroupAttrs.add(new Attribute("unsignedShort", "unsignedShort", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, unsignedShortFacets));
+
+        HashSet<XmlSchemaRestriction> unsignedByteFacets = (HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        unsignedByteFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(new Short((short)255),
+                                                                                       false)));
+        attrGroupAttrs.add(new Attribute("unsignedByte", "unsignedByte", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, unsignedByteFacets));
+
+        HashSet<XmlSchemaRestriction> stringFacets = new HashSet<XmlSchemaRestriction>();
+        stringFacets.add(new XmlSchemaRestriction(new XmlSchemaWhiteSpaceFacet("preserve", false)));
+        attrGroupAttrs.add(new Attribute("string", "string", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, stringFacets));
+
+        HashSet<XmlSchemaRestriction> normalizedStringFacets = new HashSet<XmlSchemaRestriction>();
+        normalizedStringFacets.add(new XmlSchemaRestriction(new XmlSchemaWhiteSpaceFacet("replace", false)));
+        attrGroupAttrs.add(new Attribute("normalizedString", "normalizedString",
+                                         XmlSchemaTypeInfo.Type.ATOMIC, XmlSchemaBaseSimpleType.STRING, true,
+                                         normalizedStringFacets));
+
+        HashSet<XmlSchemaRestriction> tokenFacets = new HashSet<XmlSchemaRestriction>();
+        tokenFacets.add(new XmlSchemaRestriction(new XmlSchemaWhiteSpaceFacet("collapse", false)));
+        attrGroupAttrs.add(new Attribute("token", "token", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, tokenFacets));
+
+        HashSet<XmlSchemaRestriction> languageFacets = (HashSet<XmlSchemaRestriction>)tokenFacets.clone();
+        languageFacets
+            .add(new XmlSchemaRestriction(new XmlSchemaPatternFacet("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*",
+                                                                    false)));
+        attrGroupAttrs.add(new Attribute("language", "language", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, languageFacets));
+
+        HashSet<XmlSchemaRestriction> nmTokenFacets = (HashSet<XmlSchemaRestriction>)tokenFacets.clone();
+        nmTokenFacets.add(new XmlSchemaRestriction(new XmlSchemaPatternFacet("\\c+", false)));
+        attrGroupAttrs.add(new Attribute("nmtoken", "NMTOKEN", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, nmTokenFacets));
+
+        HashSet<XmlSchemaRestriction> nameFacets = (HashSet<XmlSchemaRestriction>)tokenFacets.clone();
+        nameFacets.add(new XmlSchemaRestriction(new XmlSchemaPatternFacet("\\i\\c*", false)));
+        attrGroupAttrs.add(new Attribute("name", "Name", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, nameFacets));
+
+        HashSet<XmlSchemaRestriction> ncNameFacets = (HashSet<XmlSchemaRestriction>)tokenFacets.clone();
+        ncNameFacets.add(new XmlSchemaRestriction(new XmlSchemaPatternFacet("[\\i-[:]][\\c-[:]]*", false)));
+        attrGroupAttrs.add(new Attribute("ncName", "NCName", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, ncNameFacets));
+
+        attrGroupAttrs.add(new Attribute("id", "ID", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true,
+                                         (Set<XmlSchemaRestriction>)ncNameFacets.clone()));
+        attrGroupAttrs.add(new Attribute("idref", "IDREF", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true,
+                                         (Set<XmlSchemaRestriction>)ncNameFacets.clone()));
+        attrGroupAttrs.add(new Attribute("idrefs", "IDREFS", XmlSchemaTypeInfo.Type.LIST,
+                                         XmlSchemaBaseSimpleType.STRING, true, null));
+        attrGroupAttrs.add(new Attribute("entity", "ENTITY", XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true,
+                                         (Set<XmlSchemaRestriction>)ncNameFacets.clone()));
+        attrGroupAttrs.add(new Attribute("entities", "ENTITIES", XmlSchemaTypeInfo.Type.LIST,
+                                         XmlSchemaBaseSimpleType.STRING, true, null));
+        attrGroupAttrs.add(new Attribute("nmtokens", "NMTOKENS", XmlSchemaTypeInfo.Type.LIST,
+                                         XmlSchemaBaseSimpleType.STRING, true, null));
+
+        HashSet<XmlSchemaRestriction> nonNullPrimitiveTypeFacets = new HashSet<XmlSchemaRestriction>(14);
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "boolean", false));
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION, "int",
+                                                                false));
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "long", false));
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "float", false));
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "double", false));
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "decimal", false));
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "bytes", false));
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "string", false));
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.PATTERN, "\\c+",
+                                                                false));
+        nonNullPrimitiveTypeFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.WHITESPACE,
+                                                                "collapse", false));
+
+        XmlSchemaBaseSimpleType nonNullPrimitiveType = XmlSchemaBaseSimpleType.STRING;
+        XmlSchemaBaseSimpleType primitiveType = XmlSchemaBaseSimpleType.STRING;
+
+        HashSet<XmlSchemaRestriction> primitiveTypeFacets = new HashSet<XmlSchemaRestriction>(15);
+        primitiveTypeFacets
+            .add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION, "null", false));
+        primitiveTypeFacets.addAll(nonNullPrimitiveTypeFacets);
+
+        LinkedList<StackEntry> stack = new LinkedList<StackEntry>();
+
+        // Indentation follows tree.
+        stack.add(new StackEntry(Type.ELEMENT, "root"));
+        stack.add(new StackEntry(Type.SEQUENCE));
+        stack.add(new StackEntry(Type.CHOICE, 0, Long.MAX_VALUE));
+        stack.add(new StackEntry(Type.ELEMENT, "primitive", "primitiveType", primitiveType,
+                                 (Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.ELEMENT, "nonNullPrimitive", "nonNullPrimitiveType",
+                                 nonNullPrimitiveType, (Set<XmlSchemaRestriction>)nonNullPrimitiveTypeFacets
+                                     .clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record"));
+        stack.add(new StackEntry(Type.ELEMENT, "record", "recordType"));
+        stack.add(new StackEntry(Type.SEQUENCE));
+        stack.add(new StackEntry(Type.CHOICE, 0, Long.MAX_VALUE));
+        /* 10 */stack.add(new StackEntry(Type.ELEMENT, "primitive", "primitiveType", primitiveType,
+                                         (Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.ELEMENT, "nonNullPrimitive", "nonNullPrimitiveType",
+                                 nonNullPrimitiveType, (Set<XmlSchemaRestriction>)nonNullPrimitiveTypeFacets
+                                     .clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record"));
+        stack.add(new StackEntry(Type.ELEMENT, "record", "recordType"));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.SEQUENCE));
+        stack.add(new StackEntry(Type.CHOICE, 0, Long.MAX_VALUE));
+        stack.add(new StackEntry(Type.ELEMENT, "primitive", "primitiveType", primitiveType,
+                                 (Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.ELEMENT, "nonNullPrimitive", "nonNullPrimitiveType",
+                                 nonNullPrimitiveType, (Set<XmlSchemaRestriction>)nonNullPrimitiveTypeFacets
+                                     .clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record"));
+        /* 20 */stack.add(new StackEntry(Type.ELEMENT, "record", "recordType"));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.ELEMENT, "list"));
+        stack.add(new StackEntry(Type.CHOICE));
+        stack.add(new StackEntry(Type.ELEMENT, "primitive", "primitiveType", primitiveType, 1, 100,
+                                 (Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record", "recordType", 1, 100));
+        stack.add(new StackEntry(Type.ELEMENT, "record", "recordType", 1, 1));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.ELEMENT, "tuple"));
+        stack.add(new StackEntry(Type.ALL));
+        /* 30 */stack.add(new StackEntry(Type.ELEMENT, "primitive", "primitiveType", primitiveType,
+                                         (Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.ELEMENT, "nonNullPrimitive", "nonNullPrimitiveType",
+                                 nonNullPrimitiveType, (Set<XmlSchemaRestriction>)nonNullPrimitiveTypeFacets
+                                     .clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record"));
+        stack.add(new StackEntry(Type.ELEMENT, "record", "recordType"));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.ELEMENT, "list"));
+        stack.add(new StackEntry(Type.ELEMENT, "list"));
+        stack.add(new StackEntry(Type.ELEMENT, "tuple"));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.ELEMENT, "list"));
+        stack.add(new StackEntry(Type.ELEMENT, "tuple"));
+
+        HashMap<String, List<Attribute>> attributes = new HashMap<String, List<Attribute>>();
+        attributes.put("root", attrGroupAttrs);
+
+        HashSet<XmlSchemaRestriction> listAttrFacets = (HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        listAttrFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.EXCLUSIVE_MAX, 100, false));
+        ArrayList<Attribute> listAttributes = new ArrayList<Attribute>(1);
+        listAttributes.add(new Attribute("size", null, XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, true, listAttrFacets));
+        attributes.put("list", listAttributes);
+
+        HashSet<XmlSchemaRestriction> mapAttrFacets = (HashSet<XmlSchemaRestriction>)ncNameFacets.clone();
+        mapAttrFacets.add(new XmlSchemaRestriction(XmlSchemaRestriction.Type.LENGTH_MIN, 1, false));
+        ArrayList<Attribute> mapAttributes = new ArrayList<Attribute>(1);
+        mapAttributes.add(new Attribute("id", null, XmlSchemaTypeInfo.Type.ATOMIC,
+                                        XmlSchemaBaseSimpleType.STRING, mapAttrFacets));
+        attributes.put("map", mapAttributes);
+
+        // Compare against the actual.
+        final Visitor visitor = new Visitor(stack, attributes);
+        final int numEntries = stack.size();
+
+        XmlSchemaCollection collection = null;
+        FileReader fileReader = null;
+        try {
+            File file = UtilsForTests.buildFile("src", "test", "resources", "test_schema.xsd");
+            fileReader = new FileReader(file);
+
+            collection = new XmlSchemaCollection();
+            collection.read(new StreamSource(fileReader, file.getAbsolutePath()));
+
+        } finally {
+            if (fileReader != null) {
+                try {
+                    fileReader.close();
+                } catch (IOException ioe) {
+                    ioe.printStackTrace();
+                }
+            }
+        }
+
+        XmlSchemaElement elem = getElementOf(collection, "root");
+        XmlSchemaWalker walker = new XmlSchemaWalker(collection, visitor);
+        try {
+            walker.walk(elem);
+        } catch (Exception e) {
+            throw new IllegalStateException("Failed on stack entry " + (numEntries - stack.size()), e);
+        }
+
+        Assert.assertTrue(stack.isEmpty());
+    }
+
+    private static void checkFacets(String nextName, XmlSchemaTypeInfo typeInfo,
+                                    Set<XmlSchemaRestriction> nextFacets) {
+        final HashMap<XmlSchemaRestriction.Type, List<XmlSchemaRestriction>> facets = typeInfo.getFacets();
+
+        if ((facets == null) && (nextFacets != null)) {
+            throw new IllegalStateException("Expected " + nextFacets.size() + " facets for element \""
+                                            + nextName + "\" but received null facets.");
+
+        } else if ((facets != null) && facets.isEmpty() && (nextFacets != null) && !nextFacets.isEmpty()) {
+            throw new IllegalStateException("Expected " + nextFacets.size() + " facets for element \""
+                                            + nextName + "\" but found none.");
+
+        } else if ((facets != null) && !facets.isEmpty() && (nextFacets != null) && nextFacets.isEmpty()) {
+
+            throw new IllegalStateException("Element " + nextName + " has facets, but none were expected.");
+        }
+
+        if (facets != null) {
+            for (Map.Entry<XmlSchemaRestriction.Type, List<XmlSchemaRestriction>> facetsForType : facets
+                .entrySet()) {
+
+                for (XmlSchemaRestriction facet : facetsForType.getValue()) {
+                    if (!nextFacets.remove(facet)) {
+                        throw new IllegalStateException("Element \"" + nextName
+                                                        + "\" has unexpected facet \"" + facet + "\".");
+                    }
+                }
+            }
+        }
+
+    }
+
+    private static XmlSchemaElement getElementOf(XmlSchemaCollection collection, String name) {
+
+        XmlSchemaElement elem = null;
+        for (XmlSchema schema : collection.getXmlSchemas()) {
+            elem = schema.getElementByName(name);
+            if (elem != null) {
+                break;
+            }
+        }
+        return elem;
+    }
+}

Propchange: webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message