--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDAbstractTraverser.java Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,853 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * 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 com.sun.org.apache.xerces.internal.impl.xs.traversers;
+
+import java.util.Locale;
+import java.util.Vector;
+
+import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
+import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
+import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
+import com.sun.org.apache.xerces.internal.impl.validation.ValidationState;
+import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
+import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
+import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
+import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
+import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeUseImpl;
+import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
+import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl;
+import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl;
+import com.sun.org.apache.xerces.internal.impl.xs.XSWildcardDecl;
+import com.sun.org.apache.xerces.internal.impl.xs.util.XInt;
+import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
+import com.sun.org.apache.xerces.internal.util.DOMUtil;
+import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
+import com.sun.org.apache.xerces.internal.util.SymbolTable;
+import com.sun.org.apache.xerces.internal.xni.QName;
+import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
+import com.sun.org.apache.xerces.internal.xs.XSObjectList;
+import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
+import org.w3c.dom.Element;
+
+/**
+ * Class <code>XSDAbstractTraverser</code> serves as the base class for all
+ * other <code>XSD???Traverser</code>s. It holds the common data and provide
+ * a unified way to initialize these data.
+ *
+ * @xerces.internal
+ *
+ * @author Elena Litani, IBM
+ * @author Rahul Srivastava, Sun Microsystems Inc.
+ * @author Neeraj Bajaj, Sun Microsystems Inc.
+ *
+ */
+abstract class XSDAbstractTraverser {
+
+ protected static final String NO_NAME = "(no name)";
+
+ // Flags for checkOccurrences to indicate any special
+ // restrictions on minOccurs and maxOccurs relating to "all".
+ // NOT_ALL_CONTEXT - not processing an <all>
+ // PROCESSING_ALL_EL - processing an <element> in an <all>
+ // GROUP_REF_WITH_ALL - processing <group> reference that contained <all>
+ // CHILD_OF_GROUP - processing a child of a model group definition
+ // PROCESSING_ALL_GP - processing an <all> group itself
+
+ protected static final int NOT_ALL_CONTEXT = 0;
+ protected static final int PROCESSING_ALL_EL = 1;
+ protected static final int GROUP_REF_WITH_ALL = 2;
+ protected static final int CHILD_OF_GROUP = 4;
+ protected static final int PROCESSING_ALL_GP = 8;
+
+ //Shared data
+ protected XSDHandler fSchemaHandler = null;
+ protected SymbolTable fSymbolTable = null;
+ protected XSAttributeChecker fAttrChecker = null;
+ protected boolean fValidateAnnotations = false;
+
+ // used to validate default/fixed attribute values
+ ValidationState fValidationState = new ValidationState();
+
+ XSDAbstractTraverser (XSDHandler handler,
+ XSAttributeChecker attrChecker) {
+ fSchemaHandler = handler;
+ fAttrChecker = attrChecker;
+ }
+
+ void reset(SymbolTable symbolTable, boolean validateAnnotations, Locale locale) {
+ fSymbolTable = symbolTable;
+ fValidateAnnotations = validateAnnotations;
+ fValidationState.setExtraChecking(false);
+ fValidationState.setSymbolTable(symbolTable);
+ fValidationState.setLocale(locale);
+ }
+
+ // traverse the annotation declaration
+ // REVISIT: how to pass the parentAttrs? as DOM attributes?
+ // as name/value pairs (string)? in parsed form?
+ // @return XSAnnotationImpl object
+ XSAnnotationImpl traverseAnnotationDecl(Element annotationDecl, Object[] parentAttrs,
+ boolean isGlobal, XSDocumentInfo schemaDoc) {
+ // General Attribute Checking
+ Object[] attrValues = fAttrChecker.checkAttributes(annotationDecl, isGlobal, schemaDoc);
+ fAttrChecker.returnAttrArray(attrValues, schemaDoc);
+
+ String contents = DOMUtil.getAnnotation(annotationDecl);
+ Element child = DOMUtil.getFirstChildElement(annotationDecl);
+ if (child != null) {
+ do {
+ String name = DOMUtil.getLocalName(child);
+
+ // the only valid children of "annotation" are
+ // "appinfo" and "documentation"
+ if (!((name.equals(SchemaSymbols.ELT_APPINFO)) ||
+ (name.equals(SchemaSymbols.ELT_DOCUMENTATION)))) {
+ reportSchemaError("src-annotation", new Object[]{name}, child);
+ }
+ else {
+ // General Attribute Checking
+ // There is no difference between global or local appinfo/documentation,
+ // so we assume it's always global.
+ attrValues = fAttrChecker.checkAttributes(child, true, schemaDoc);
+ fAttrChecker.returnAttrArray(attrValues, schemaDoc);
+ }
+
+ child = DOMUtil.getNextSiblingElement(child);
+ }
+ while (child != null);
+ }
+ // if contents was null, must have been some kind of error;
+ // nothing to contribute to PSVI
+ if (contents == null) return null;
+
+ // find the grammar; fSchemaHandler must be known!
+ SchemaGrammar grammar = fSchemaHandler.getGrammar(schemaDoc.fTargetNamespace);
+ // fish out local attributes passed from parent
+ Vector annotationLocalAttrs = (Vector)parentAttrs[XSAttributeChecker.ATTIDX_NONSCHEMA];
+ // optimize for case where there are no local attributes
+ if(annotationLocalAttrs != null && !annotationLocalAttrs.isEmpty()) {
+ StringBuffer localStrBuffer = new StringBuffer(64);
+ localStrBuffer.append(" ");
+ // Vector should contain rawname value pairs
+ int i = 0;
+ while (i < annotationLocalAttrs.size()) {
+ String rawname = (String)annotationLocalAttrs.elementAt(i++);
+ int colonIndex = rawname.indexOf(':');
+ String prefix, localpart;
+ if (colonIndex == -1) {
+ prefix = "";
+ localpart = rawname;
+ }
+ else {
+ prefix = rawname.substring(0,colonIndex);
+ localpart = rawname.substring(colonIndex+1);
+ }
+ String uri = schemaDoc.fNamespaceSupport.getURI(fSymbolTable.addSymbol(prefix));
+ if (annotationDecl.getAttributeNS(uri, localpart).length() != 0) {
+ i++; // skip the next value, too
+ continue;
+ }
+ localStrBuffer.append(rawname)
+ .append("=\"");
+ String value = (String)annotationLocalAttrs.elementAt(i++);
+ // search for pesky "s and <s within attr value:
+ value = processAttValue(value);
+ localStrBuffer.append(value)
+ .append("\" ");
+ }
+ // and now splice it into place; immediately after the annotation token, for simplicity's sake
+ StringBuffer contentBuffer = new StringBuffer(contents.length() + localStrBuffer.length());
+ int annotationTokenEnd = contents.indexOf(SchemaSymbols.ELT_ANNOTATION);
+ // annotation must occur somewhere or we're in big trouble...
+ if(annotationTokenEnd == -1) return null;
+ annotationTokenEnd += SchemaSymbols.ELT_ANNOTATION.length();
+ contentBuffer.append(contents.substring(0,annotationTokenEnd));
+ contentBuffer.append(localStrBuffer.toString());
+ contentBuffer.append(contents.substring(annotationTokenEnd, contents.length()));
+ final String annotation = contentBuffer.toString();
+ if (fValidateAnnotations) {
+ schemaDoc.addAnnotation(new XSAnnotationInfo(annotation, annotationDecl));
+ }
+ return new XSAnnotationImpl(annotation, grammar);
+ } else {
+ if (fValidateAnnotations) {
+ schemaDoc.addAnnotation(new XSAnnotationInfo(contents, annotationDecl));
+ }
+ return new XSAnnotationImpl(contents, grammar);
+ }
+
+ }
+
+ XSAnnotationImpl traverseSyntheticAnnotation(Element annotationParent, String initialContent,
+ Object[] parentAttrs, boolean isGlobal, XSDocumentInfo schemaDoc) {
+
+ String contents = initialContent;
+
+ // find the grammar; fSchemaHandler must be known!
+ SchemaGrammar grammar = fSchemaHandler.getGrammar(schemaDoc.fTargetNamespace);
+ // fish out local attributes passed from parent
+ Vector annotationLocalAttrs = (Vector)parentAttrs[XSAttributeChecker.ATTIDX_NONSCHEMA];
+ // optimize for case where there are no local attributes
+ if (annotationLocalAttrs != null && !annotationLocalAttrs.isEmpty()) {
+ StringBuffer localStrBuffer = new StringBuffer(64);
+ localStrBuffer.append(" ");
+ // Vector should contain rawname value pairs
+ int i = 0;
+ while (i < annotationLocalAttrs.size()) {
+ String rawname = (String)annotationLocalAttrs.elementAt(i++);
+ int colonIndex = rawname.indexOf(':');
+ String prefix, localpart;
+ if (colonIndex == -1) {
+ prefix = "";
+ localpart = rawname;
+ }
+ else {
+ prefix = rawname.substring(0,colonIndex);
+ localpart = rawname.substring(colonIndex+1);
+ }
+ String uri = schemaDoc.fNamespaceSupport.getURI(fSymbolTable.addSymbol(prefix));
+ localStrBuffer.append(rawname)
+ .append("=\"");
+ String value = (String)annotationLocalAttrs.elementAt(i++);
+ // search for pesky "s and <s within attr value:
+ value = processAttValue(value);
+ localStrBuffer.append(value)
+ .append("\" ");
+ }
+ // and now splice it into place; immediately after the annotation token, for simplicity's sake
+ StringBuffer contentBuffer = new StringBuffer(contents.length() + localStrBuffer.length());
+ int annotationTokenEnd = contents.indexOf(SchemaSymbols.ELT_ANNOTATION);
+ // annotation must occur somewhere or we're in big trouble...
+ if(annotationTokenEnd == -1) return null;
+ annotationTokenEnd += SchemaSymbols.ELT_ANNOTATION.length();
+ contentBuffer.append(contents.substring(0,annotationTokenEnd));
+ contentBuffer.append(localStrBuffer.toString());
+ contentBuffer.append(contents.substring(annotationTokenEnd, contents.length()));
+ final String annotation = contentBuffer.toString();
+ if (fValidateAnnotations) {
+ schemaDoc.addAnnotation(new XSAnnotationInfo(annotation, annotationParent));
+ }
+ return new XSAnnotationImpl(annotation, grammar);
+ } else {
+ if (fValidateAnnotations) {
+ schemaDoc.addAnnotation(new XSAnnotationInfo(contents, annotationParent));
+ }
+ return new XSAnnotationImpl(contents, grammar);
+ }
+ }
+
+ // the QName simple type used to resolve qnames
+ private static final XSSimpleType fQNameDV = (XSSimpleType)SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(SchemaSymbols.ATTVAL_QNAME);
+ // Temp data structures to be re-used in traversing facets
+ private StringBuffer fPattern = new StringBuffer();
+ private final XSFacets xsFacets = new XSFacets();
+
+ static final class FacetInfo {
+
+ final XSFacets facetdata;
+ final Element nodeAfterFacets;
+ final short fPresentFacets;
+ final short fFixedFacets;
+
+ FacetInfo(XSFacets facets, Element nodeAfterFacets, short presentFacets, short fixedFacets) {
+ facetdata = facets;
+ this.nodeAfterFacets = nodeAfterFacets;
+ fPresentFacets = presentFacets;
+ fFixedFacets = fixedFacets;
+ }
+ }
+
+ FacetInfo traverseFacets(Element content,
+ 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();
+ 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)) {
+ facetsPresent |= XSSimpleType.FACET_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;
+ }
+
+ 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();
+ break;
+ case XSSimpleType.FACET_MAXLENGTH:
+ xsFacets.maxLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
+ 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();
+ 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 ((facetsPresent & XSSimpleType.FACET_PATTERN) != 0) {
+ xsFacets.pattern = fPattern.toString();
+ xsFacets.patternAnnotations = patternAnnotations;
+ }
+
+ fPattern.setLength(0);
+
+ return new FacetInfo(xsFacets, content, facetsPresent, facetsFixed);
+ }
+
+
+ // return whether QName/NOTATION is part of the given type
+ private boolean containsQName(XSSimpleType type) {
+ if (type.getVariety() == XSSimpleType.VARIETY_ATOMIC) {
+ short primitive = type.getPrimitiveKind();
+ return (primitive == XSSimpleType.PRIMITIVE_QNAME ||
+ primitive == XSSimpleType.PRIMITIVE_NOTATION);
+ }
+ else if (type.getVariety() == XSSimpleType.VARIETY_LIST) {
+ return containsQName((XSSimpleType)type.getItemType());
+ }
+ else if (type.getVariety() == XSSimpleType.VARIETY_UNION) {
+ XSObjectList members = type.getMemberTypes();
+ for (int i = 0; i < members.getLength(); i++) {
+ if (containsQName((XSSimpleType)members.item(i)))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //
+ // Traverse a set of attribute and attribute group elements
+ // Needed by complexType and attributeGroup traversal
+ // This method will return the first non-attribute/attrgrp found
+ //
+ Element traverseAttrsAndAttrGrps(Element firstAttr, XSAttributeGroupDecl attrGrp,
+ XSDocumentInfo schemaDoc, SchemaGrammar grammar,
+ XSComplexTypeDecl enclosingCT) {
+
+ Element child=null;
+ XSAttributeGroupDecl tempAttrGrp = null;
+ XSAttributeUseImpl tempAttrUse = null;
+ XSAttributeUse otherUse = null;
+ String childName;
+
+ for (child=firstAttr; child!=null; child=DOMUtil.getNextSiblingElement(child)) {
+ childName = DOMUtil.getLocalName(child);
+ if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
+ tempAttrUse = fSchemaHandler.fAttributeTraverser.traverseLocal(child,
+ schemaDoc,
+ grammar,
+ enclosingCT);
+ if (tempAttrUse == null) continue;
+ if (tempAttrUse.fUse == SchemaSymbols.USE_PROHIBITED) {
+ attrGrp.addAttributeUse(tempAttrUse);
+ continue;
+ }
+ otherUse = attrGrp.getAttributeUseNoProhibited(
+ tempAttrUse.fAttrDecl.getNamespace(),
+ tempAttrUse.fAttrDecl.getName());
+ if (otherUse==null) {
+ String idName = attrGrp.addAttributeUse(tempAttrUse);
+ if (idName != null) {
+ String code = (enclosingCT == null) ? "ag-props-correct.3" : "ct-props-correct.5";
+ String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
+ reportSchemaError(code, new Object[]{name, tempAttrUse.fAttrDecl.getName(), idName}, child);
+ }
+ }
+ else if (otherUse != tempAttrUse) {
+ String code = (enclosingCT == null) ? "ag-props-correct.2" : "ct-props-correct.4";
+ String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
+ reportSchemaError(code, new Object[]{name, tempAttrUse.fAttrDecl.getName()}, child);
+ }
+ }
+ else if (childName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
+ //REVISIT: do we need to save some state at this point??
+ tempAttrGrp = fSchemaHandler.fAttributeGroupTraverser.traverseLocal(
+ child, schemaDoc, grammar);
+ if(tempAttrGrp == null ) continue;
+ XSObjectList attrUseS = tempAttrGrp.getAttributeUses();
+ XSAttributeUseImpl oneAttrUse;
+ int attrCount = attrUseS.getLength();
+ for (int i=0; i<attrCount; i++) {
+ oneAttrUse = (XSAttributeUseImpl)attrUseS.item(i);
+ if (oneAttrUse.fUse == SchemaSymbols.USE_PROHIBITED) {
+ attrGrp.addAttributeUse(oneAttrUse);
+ continue;
+ }
+ otherUse = attrGrp.getAttributeUseNoProhibited(
+ oneAttrUse.fAttrDecl.getNamespace(),
+ oneAttrUse.fAttrDecl.getName());
+ if (otherUse==null) {
+ String idName = attrGrp.addAttributeUse(oneAttrUse);
+ if (idName != null) {
+ String code = (enclosingCT == null) ? "ag-props-correct.3" : "ct-props-correct.5";
+ String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
+ reportSchemaError(code, new Object[]{name, oneAttrUse.fAttrDecl.getName(), idName}, child);
+ }
+ }
+ else if (oneAttrUse != otherUse) {
+ String code = (enclosingCT == null) ? "ag-props-correct.2" : "ct-props-correct.4";
+ String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
+ reportSchemaError(code, new Object[]{name, oneAttrUse.fAttrDecl.getName()}, child);
+ }
+ }
+
+ if (tempAttrGrp.fAttributeWC != null) {
+ if (attrGrp.fAttributeWC == null) {
+ attrGrp.fAttributeWC = tempAttrGrp.fAttributeWC;
+ }
+ // perform intersection of attribute wildcard
+ else {
+ attrGrp.fAttributeWC = attrGrp.fAttributeWC.
+ performIntersectionWith(tempAttrGrp.fAttributeWC, attrGrp.fAttributeWC.fProcessContents);
+ if (attrGrp.fAttributeWC == null) {
+ String code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
+ String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
+ reportSchemaError(code, new Object[]{name}, child);
+ }
+ }
+ }
+ }
+ else
+ break;
+ } // for
+
+ if (child != null) {
+ childName = DOMUtil.getLocalName(child);
+ if (childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE)) {
+ XSWildcardDecl tempAttrWC = fSchemaHandler.fWildCardTraverser.
+ traverseAnyAttribute(child, schemaDoc, grammar);
+ if (attrGrp.fAttributeWC == null) {
+ attrGrp.fAttributeWC = tempAttrWC;
+ }
+ // perform intersection of attribute wildcard
+ else {
+ attrGrp.fAttributeWC = tempAttrWC.
+ performIntersectionWith(attrGrp.fAttributeWC, tempAttrWC.fProcessContents);
+ if (attrGrp.fAttributeWC == null) {
+ String code = (enclosingCT == null) ? "src-attribute_group.2" : "src-ct.4";
+ String name = (enclosingCT == null) ? attrGrp.fName : enclosingCT.getName();
+ reportSchemaError(code, new Object[]{name}, child);
+ }
+ }
+ child = DOMUtil.getNextSiblingElement(child);
+ }
+ }
+
+ // Success
+ return child;
+
+ }
+
+ void reportSchemaError (String key, Object[] args, Element ele) {
+ fSchemaHandler.reportSchemaError(key, args, ele);
+ }
+
+ /**
+ * Element/Attribute traversers call this method to check whether
+ * the type is NOTATION without enumeration facet
+ */
+ void checkNotationType(String refName, XSTypeDefinition typeDecl, Element elem) {
+ if (typeDecl.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE &&
+ ((XSSimpleType)typeDecl).getVariety() == XSSimpleType.VARIETY_ATOMIC &&
+ ((XSSimpleType)typeDecl).getPrimitiveKind() == XSSimpleType.PRIMITIVE_NOTATION) {
+ if ((((XSSimpleType)typeDecl).getDefinedFacets() & XSSimpleType.FACET_ENUMERATION) == 0) {
+ reportSchemaError("enumeration-required-notation", new Object[]{typeDecl.getName(), refName, DOMUtil.getLocalName(elem)}, elem);
+ }
+ }
+ }
+
+ // Checks constraints for minOccurs, maxOccurs
+ protected XSParticleDecl checkOccurrences(XSParticleDecl particle,
+ String particleName, Element parent,
+ int allContextFlags,
+ long defaultVals) {
+
+ int min = particle.fMinOccurs;
+ int max = particle.fMaxOccurs;
+ boolean defaultMin = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MINOCCURS)) != 0;
+ boolean defaultMax = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MAXOCCURS)) != 0;
+
+ boolean processingAllEl = ((allContextFlags & PROCESSING_ALL_EL) != 0);
+ boolean processingAllGP = ((allContextFlags & PROCESSING_ALL_GP) != 0);
+ boolean groupRefWithAll = ((allContextFlags & GROUP_REF_WITH_ALL) != 0);
+ boolean isGroupChild = ((allContextFlags & CHILD_OF_GROUP) != 0);
+
+ // Neither minOccurs nor maxOccurs may be specified
+ // for the child of a model group definition.
+ if (isGroupChild) {
+ if (!defaultMin) {
+ Object[] args = new Object[]{particleName, "minOccurs"};
+ reportSchemaError("s4s-att-not-allowed", args, parent);
+ min = 1;
+ }
+ if (!defaultMax) {
+ Object[] args = new Object[]{particleName, "maxOccurs"};
+ reportSchemaError("s4s-att-not-allowed", args, parent);
+ max = 1;
+ }
+ }
+
+ // If minOccurs=maxOccurs=0, no component is specified
+ if (min == 0 && max== 0) {
+ particle.fType = XSParticleDecl.PARTICLE_EMPTY;
+ return null;
+ }
+
+ // For the elements referenced in an <all>, minOccurs attribute
+ // must be zero or one, and maxOccurs attribute must be one.
+ // For a complex type definition that contains an <all> or a
+ // reference a <group> whose model group is an all model group,
+ // minOccurs and maxOccurs must be one.
+ if (processingAllEl) {
+ if (max != 1) {
+ reportSchemaError("cos-all-limited.2", new Object[]{
+ (max == SchemaSymbols.OCCURRENCE_UNBOUNDED) ? SchemaSymbols.ATTVAL_UNBOUNDED : Integer.toString(max),
+ ((XSElementDecl)particle.fValue).getName()}, parent);
+ max = 1;
+ if (min > 1)
+ min = 1;
+ }
+ }
+ else if (processingAllGP || groupRefWithAll) {
+ if (max != 1) {
+ reportSchemaError("cos-all-limited.1.2", null, parent);
+ if (min > 1)
+ min = 1;
+ max = 1;
+ }
+ }
+
+ particle.fMinOccurs = min;
+ particle.fMaxOccurs = max;
+
+ return particle;
+ }
+
+ private static String processAttValue(String original) {
+ final int length = original.length();
+ // normally, nothing will happen
+ for (int i = 0; i < length; ++i) {
+ char currChar = original.charAt(i);
+ if (currChar == '"' || currChar == '<' || currChar == '&' ||
+ currChar == 0x09 || currChar == 0x0A || currChar == 0x0D) {
+ return escapeAttValue(original, i);
+ }
+ }
+ return original;
+ }
+
+ // this is not terribly performant!
+ private static String escapeAttValue(String original, int from) {
+ int i;
+ final int length = original.length();
+ StringBuffer newVal = new StringBuffer(length);
+ newVal.append(original.substring(0, from));
+ for (i = from; i < length; ++i) {
+ char currChar = original.charAt(i);
+ if (currChar == '"') {
+ newVal.append(""");
+ }
+ else if (currChar == '<') {
+ newVal.append("<");
+ }
+ else if (currChar == '&') {
+ newVal.append("&");
+ }
+ // Must escape 0x09, 0x0A and 0x0D if they appear in attribute
+ // value so that they may be round-tripped. They would otherwise
+ // be transformed to a 0x20 during attribute value normalization.
+ else if (currChar == 0x09) {
+ newVal.append("	");
+ }
+ else if (currChar == 0x0A) {
+ newVal.append("
");
+ }
+ else if (currChar == 0x0D) {
+ newVal.append("
");
+ }
+ else {
+ newVal.append(currChar);
+ }
+ }
+ return newVal.toString();
+ }
+}