diff -r 4ebc2e2fb97c -r 71c04702a3d5 src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDAbstractTraverser.java --- /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 XSDAbstractTraverser serves as the base class for all + * other XSD???Traversers. 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 + // PROCESSING_ALL_EL - processing an in an + // GROUP_REF_WITH_ALL - processing reference that contained + // CHILD_OF_GROUP - processing a child of a model group definition + // PROCESSING_ALL_GP - processing an 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 , minOccurs attribute + // must be zero or one, and maxOccurs attribute must be one. + // For a complex type definition that contains an or a + // reference a 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(); + } +}