in src/org/apache/xerces/impl/xs/traversers/XSDAbstractTraverser.java [279:596]
FacetInfo traverseFacets(Element content,
XSTypeDefinition typeDef,
XSSimpleType baseValidator,
XSDocumentInfo schemaDoc) {
short facetsPresent = 0 ;
short facetsFixed = 0; // facets that have fixed="true"
String facet;
boolean hasQName = containsQName(baseValidator);
Vector enumData = null;
XSObjectListImpl enumAnnotations = null;
XSObjectListImpl patternAnnotations = null;
Vector enumNSDecls = hasQName ? new Vector() : null;
int currentFacet = 0;
xsFacets.reset();
boolean seenPattern = false;
Element contextNode = (Element)content.getParentNode();
boolean hasLengthFacet = false, hasMinLengthFacet = false, hasMaxLengthFacet = false;
while (content != null) {
// General Attribute Checking
Object[] attrs = null;
facet = DOMUtil.getLocalName(content);
if (facet.equals(SchemaSymbols.ELT_ENUMERATION)) {
attrs = fAttrChecker.checkAttributes(content, false, schemaDoc, hasQName);
String enumVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
// The facet can't be used if the value is missing. Ignore
// this facet element.
if (enumVal == null) {
reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_ENUMERATION, SchemaSymbols.ATT_VALUE}, content);
fAttrChecker.returnAttrArray (attrs, schemaDoc);
content = DOMUtil.getNextSiblingElement(content);
continue;
}
NamespaceSupport nsDecls = (NamespaceSupport)attrs[XSAttributeChecker.ATTIDX_ENUMNSDECLS];
// for NOTATION types, need to check whether there is a notation
// declared with the same name as the enumeration value.
if (baseValidator.getVariety() == XSSimpleType.VARIETY_ATOMIC &&
baseValidator.getPrimitiveKind() == XSSimpleType.PRIMITIVE_NOTATION) {
// need to use the namespace context returned from checkAttributes
schemaDoc.fValidationContext.setNamespaceSupport(nsDecls);
Object notation = null;
try{
QName temp = (QName)fQNameDV.validate(enumVal, schemaDoc.fValidationContext, null);
// try to get the notation decl. if failed, getGlobalDecl
// reports an error, so we don't need to report one again.
notation = fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.NOTATION_TYPE, temp, content);
}catch(InvalidDatatypeValueException ex){
reportSchemaError(ex.getKey(), ex.getArgs(), content);
}
if (notation == null) {
// Either the QName value is invalid, or it doens't
// resolve to a notation declaration.
// Ignore this facet, to avoid instance validation problems
fAttrChecker.returnAttrArray (attrs, schemaDoc);
content = DOMUtil.getNextSiblingElement(content);
continue;
}
// restore to the normal namespace context
schemaDoc.fValidationContext.setNamespaceSupport(schemaDoc.fNamespaceSupport);
}
if (enumData == null){
enumData = new Vector();
enumAnnotations = new XSObjectListImpl();
}
enumData.addElement(enumVal);
enumAnnotations.addXSObject(null);
if (hasQName)
enumNSDecls.addElement(nsDecls);
Element child = DOMUtil.getFirstChildElement( content );
if (child != null &&
DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
// traverse annotation if any
enumAnnotations.addXSObject(enumAnnotations.getLength()-1,traverseAnnotationDecl(child, attrs, false, schemaDoc));
child = DOMUtil.getNextSiblingElement(child);
}
else {
String text = DOMUtil.getSyntheticAnnotation(content);
if (text != null) {
enumAnnotations.addXSObject(enumAnnotations.getLength()-1, traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc));
}
}
if (child !=null) {
reportSchemaError("s4s-elt-must-match.1", new Object[]{"enumeration", "(annotation?)", DOMUtil.getLocalName(child)}, child);
}
}
else if (facet.equals(SchemaSymbols.ELT_PATTERN)) {
attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
String patternVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
// The facet can't be used if the value is missing. Ignore
// this facet element.
if (patternVal == null) {
reportSchemaError("s4s-att-must-appear", new Object[]{SchemaSymbols.ELT_PATTERN, SchemaSymbols.ATT_VALUE}, content);
fAttrChecker.returnAttrArray (attrs, schemaDoc);
content = DOMUtil.getNextSiblingElement(content);
continue;
}
seenPattern = true;
if (fPattern.length() == 0) {
fPattern.append(patternVal);
} else {
// ---------------------------------------------
//datatypes: 5.2.4 pattern: src-multiple-pattern
// ---------------------------------------------
fPattern.append("|");
fPattern.append(patternVal);
}
Element child = DOMUtil.getFirstChildElement( content );
if (child != null &&
DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
// traverse annotation if any
if (patternAnnotations == null){
patternAnnotations = new XSObjectListImpl();
}
patternAnnotations.addXSObject(traverseAnnotationDecl(child, attrs, false, schemaDoc));
child = DOMUtil.getNextSiblingElement(child);
}
else {
String text = DOMUtil.getSyntheticAnnotation(content);
if (text != null) {
if (patternAnnotations == null){
patternAnnotations = new XSObjectListImpl();
}
patternAnnotations.addXSObject(traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc));
}
}
if (child !=null) {
reportSchemaError("s4s-elt-must-match.1", new Object[]{"pattern", "(annotation?)", DOMUtil.getLocalName(child)}, child);
}
}
else {
if (facet.equals(SchemaSymbols.ELT_MINLENGTH)) {
currentFacet = XSSimpleType.FACET_MINLENGTH;
}
else if (facet.equals(SchemaSymbols.ELT_MAXLENGTH)) {
currentFacet = XSSimpleType.FACET_MAXLENGTH;
}
else if (facet.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
currentFacet = XSSimpleType.FACET_MAXEXCLUSIVE;
}
else if (facet.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
currentFacet = XSSimpleType.FACET_MAXINCLUSIVE;
}
else if (facet.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
currentFacet = XSSimpleType.FACET_MINEXCLUSIVE;
}
else if (facet.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
currentFacet = XSSimpleType.FACET_MININCLUSIVE;
}
else if (facet.equals(SchemaSymbols.ELT_TOTALDIGITS)) {
currentFacet = XSSimpleType.FACET_TOTALDIGITS;
}
else if (facet.equals(SchemaSymbols.ELT_FRACTIONDIGITS)) {
currentFacet = XSSimpleType.FACET_FRACTIONDIGITS;
}
else if (facet.equals(SchemaSymbols.ELT_WHITESPACE)) {
currentFacet = XSSimpleType.FACET_WHITESPACE;
}
else if (facet.equals(SchemaSymbols.ELT_LENGTH)) {
currentFacet = XSSimpleType.FACET_LENGTH;
}
else {
break; // a non-facet
}
attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
// check for duplicate facets
if ((facetsPresent & currentFacet) != 0) {
// Ignore this facet, to avoid corrupting the previous facet
reportSchemaError("src-single-facet-value", new Object[]{facet}, content);
fAttrChecker.returnAttrArray (attrs, schemaDoc);
content = DOMUtil.getNextSiblingElement(content);
continue;
}
// The facet can't be used if the value is missing. Ignore
// this facet element.
if (attrs[XSAttributeChecker.ATTIDX_VALUE] == null) {
// Report an error if the "value" attribute is missing.
// If it's not missing, then its value is invalid, and an
// error should have already been reported by the
// attribute checker.
if (content.getAttributeNodeNS(null, "value") == null) {
reportSchemaError("s4s-att-must-appear", new Object[]{content.getLocalName(), SchemaSymbols.ATT_VALUE}, content);
}
fAttrChecker.returnAttrArray (attrs, schemaDoc);
content = DOMUtil.getNextSiblingElement(content);
continue;
}
facetsPresent |= currentFacet;
// check for fixed facet
if (((Boolean)attrs[XSAttributeChecker.ATTIDX_FIXED]).booleanValue()) {
facetsFixed |= currentFacet;
}
switch (currentFacet) {
case XSSimpleType.FACET_MINLENGTH:
xsFacets.minLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
hasMinLengthFacet = true;
break;
case XSSimpleType.FACET_MAXLENGTH:
xsFacets.maxLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
hasMaxLengthFacet = true;
break;
case XSSimpleType.FACET_MAXEXCLUSIVE:
xsFacets.maxExclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
break;
case XSSimpleType.FACET_MAXINCLUSIVE:
xsFacets.maxInclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
break;
case XSSimpleType.FACET_MINEXCLUSIVE:
xsFacets.minExclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
break;
case XSSimpleType.FACET_MININCLUSIVE:
xsFacets.minInclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
break;
case XSSimpleType.FACET_TOTALDIGITS:
xsFacets.totalDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
break;
case XSSimpleType.FACET_FRACTIONDIGITS:
xsFacets.fractionDigits = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
break;
case XSSimpleType.FACET_WHITESPACE:
xsFacets.whiteSpace = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).shortValue();
break;
case XSSimpleType.FACET_LENGTH:
xsFacets.length = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
hasLengthFacet = true;
break;
}
Element child = DOMUtil.getFirstChildElement( content );
XSAnnotationImpl annotation = null;
if (child != null &&
DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
// traverse annotation if any
annotation = traverseAnnotationDecl(child, attrs, false, schemaDoc);
child = DOMUtil.getNextSiblingElement(child);
}
else {
String text = DOMUtil.getSyntheticAnnotation(content);
if (text != null) {
annotation = traverseSyntheticAnnotation(content, text, attrs, false, schemaDoc);
}
}
switch (currentFacet) {
case XSSimpleType.FACET_MINLENGTH:
xsFacets.minLengthAnnotation = annotation;
break;
case XSSimpleType.FACET_MAXLENGTH:
xsFacets.maxLengthAnnotation = annotation;
break;
case XSSimpleType.FACET_MAXEXCLUSIVE:
xsFacets.maxExclusiveAnnotation = annotation;
break;
case XSSimpleType.FACET_MAXINCLUSIVE:
xsFacets.maxInclusiveAnnotation = annotation;
break;
case XSSimpleType.FACET_MINEXCLUSIVE:
xsFacets.minExclusiveAnnotation = annotation;
break;
case XSSimpleType.FACET_MININCLUSIVE:
xsFacets.minInclusiveAnnotation = annotation;
break;
case XSSimpleType.FACET_TOTALDIGITS:
xsFacets.totalDigitsAnnotation = annotation;
break;
case XSSimpleType.FACET_FRACTIONDIGITS:
xsFacets.fractionDigitsAnnotation = annotation;
break;
case XSSimpleType.FACET_WHITESPACE:
xsFacets.whiteSpaceAnnotation = annotation;
break;
case XSSimpleType.FACET_LENGTH:
xsFacets.lengthAnnotation = annotation;
break;
}
if (child != null) {
reportSchemaError("s4s-elt-must-match.1", new Object[]{facet, "(annotation?)", DOMUtil.getLocalName(child)}, child);
}
}
fAttrChecker.returnAttrArray (attrs, schemaDoc);
content = DOMUtil.getNextSiblingElement(content);
}
if (enumData !=null) {
facetsPresent |= XSSimpleType.FACET_ENUMERATION;
xsFacets.enumeration = enumData;
xsFacets.enumNSDecls = enumNSDecls;
xsFacets.enumAnnotations = enumAnnotations;
}
if (seenPattern) {
facetsPresent |= XSSimpleType.FACET_PATTERN;
xsFacets.pattern = fPattern.toString();
xsFacets.patternAnnotations = patternAnnotations;
}
fPattern.setLength(0);
// check if length, minLength and maxLength facets contradict with enumeration facets.
// currently considers the case when the baseValidator is a built-in type.
if (enumData != null) {
if (hasLengthFacet) {
checkEnumerationAndLengthInconsistency(baseValidator, enumData, contextNode, getSchemaTypeName(typeDef));
}
if (hasMinLengthFacet) {
checkEnumerationAndMinLengthInconsistency(baseValidator, enumData, contextNode, getSchemaTypeName(typeDef));
}
if (hasMaxLengthFacet) {
checkEnumerationAndMaxLengthInconsistency(baseValidator, enumData, contextNode, getSchemaTypeName(typeDef));
}
}
return new FacetInfo(xsFacets, content, facetsPresent, facetsFixed);
}