
org.apache.xerces.impl.xs.traversers.XSDAbstractTraverser Maven / Gradle / Ivy
/*
* 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.xerces.impl.xs.traversers;
import java.util.Vector;
import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
import org.apache.xerces.impl.dv.XSFacets;
import org.apache.xerces.impl.dv.XSSimpleType;
import org.apache.xerces.impl.validation.ValidationState;
import org.apache.xerces.impl.xs.SchemaGrammar;
import org.apache.xerces.impl.xs.SchemaSymbols;
import org.apache.xerces.impl.xs.XSAnnotationImpl;
import org.apache.xerces.impl.xs.XSAttributeGroupDecl;
import org.apache.xerces.impl.xs.XSAttributeUseImpl;
import org.apache.xerces.impl.xs.XSComplexTypeDecl;
import org.apache.xerces.impl.xs.XSElementDecl;
import org.apache.xerces.impl.xs.XSParticleDecl;
import org.apache.xerces.impl.xs.XSWildcardDecl;
import org.apache.xerces.impl.xs.util.XInt;
import org.apache.xerces.impl.xs.util.XSObjectListImpl;
import org.apache.xerces.util.DOMUtil;
import org.apache.xerces.util.NamespaceSupport;
import org.apache.xerces.util.SymbolTable;
import org.apache.xerces.xni.QName;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.XSTypeDefinition;
import org.w3c.dom.Element;
/**
* Class XSDAbstractTraverser
serves as the base class for all
* other XSD???Traverser
s. It holds the common data and provides
* 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.
*
* @version $Id: XSDAbstractTraverser.java 446725 2006-09-15 20:40:10Z mrglavas $
*/
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) {
fSymbolTable = symbolTable;
fValidateAnnotations = validateAnnotations;
fValidationState.setExtraChecking(false);
fValidationState.setSymbolTable(symbolTable);
}
// 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);
}
// 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).equals("")) {
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[]{new Integer(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.fMaxOccurs = 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();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy