blob: c4ab3b4e632e9c884477a4ae5536e5cca3656293 [file] [log] [blame]
/**
* 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() != 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() != 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)
&& attribute.getSchemaType() != 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 != null && !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 != null && 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 != null && 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;
}
public void test(File aFile) 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, Integer.valueOf(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(Integer.valueOf(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(Integer.valueOf(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(Integer.valueOf(-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(Long.valueOf(-9223372036854775808L),
false)));
longFacets
.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(Long.valueOf(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(Integer.valueOf(-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(Short.valueOf((short)-32768),
false)));
shortFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(Short.valueOf((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(Byte.valueOf((byte)-128), false)));
byteFacets.add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(Byte.valueOf((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(Integer.valueOf(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(Integer.valueOf(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(Long.valueOf(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(Integer.valueOf(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(Short.valueOf((short)255),
false)));
attrGroupAttrs.add(new Attribute("unsignedByte", "unsignedByte", XmlSchemaTypeInfo.Type.ATOMIC,
XmlSchemaBaseSimpleType.DECIMAL, true, unsignedByteFacets));
attrGroupAttrs.add(new Attribute("unknown", null, null, null, true));
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 {
fileReader = new FileReader(aFile);
collection = new XmlSchemaCollection();
collection.read(new StreamSource(fileReader, aFile.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());
}
/**
* test for test_schema.xsd
*/
@Test
public void testSchemaWalker() throws Exception {
File file = UtilsForTests.buildFile("src", "test", "resources", "test_schema.xsd");
test(file);
}
/**
* test for test_multiple_files_per_namespace2.xsd, which is test_schema.xsd distributed between three files
*/
@Test
public void testMultipleFilesPerNamespace2() throws Exception {
File file = UtilsForTests.buildFile("src", "test", "resources", "test_multiple_files_per_namespace2.xsd");
test(file);
}
private static void checkFacets(String nextName, XmlSchemaTypeInfo typeInfo,
Set<XmlSchemaRestriction> nextFacets) {
if (typeInfo == null) {
return;
}
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;
}
}