| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 2001 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Xerces" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 2001, International |
| * Business Machines, Inc., http://www.apache.org. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| |
| package org.apache.xerces.impl.xs.traversers; |
| |
| import org.apache.xerces.impl.xs.util.XInt; |
| import org.apache.xerces.impl.dv.XSSimpleType; |
| import org.apache.xerces.impl.dv.XSFacets; |
| import org.apache.xerces.impl.dv.InvalidDatatypeValueException; |
| import org.apache.xerces.impl.xs.SchemaGrammar; |
| import org.apache.xerces.impl.xs.SchemaSymbols; |
| import org.apache.xerces.impl.xs.XSMessageFormatter; |
| import org.apache.xerces.impl.xs.XSNotationDecl; |
| import org.apache.xerces.impl.xs.XSAttributeGroupDecl; |
| import org.apache.xerces.impl.xs.XSAttributeUse; |
| import org.apache.xerces.impl.xs.XSWildcardDecl; |
| import org.apache.xerces.impl.xs.XSTypeDecl; |
| import org.apache.xerces.impl.xs.XSParticleDecl; |
| import org.apache.xerces.xni.QName; |
| import org.apache.xerces.impl.XMLErrorReporter; |
| import org.apache.xerces.util.SymbolTable; |
| import org.apache.xerces.impl.validation.ValidationState; |
| import org.w3c.dom.Element; |
| import java.util.Hashtable; |
| import java.util.Vector; |
| import java.lang.reflect.*; |
| import org.apache.xerces.util.DOMUtil; |
| |
| /** |
| * 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. |
| * |
| * @author Elena Litani, IBM |
| * @author Rahul Srivastava, Sun Microsystems Inc. |
| * @author Neeraj Bajaj, Sun Microsystems Inc. |
| * |
| * @version $Id$ |
| */ |
| 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 XMLErrorReporter fErrorReporter = null; |
| |
| // used to validate default/fixed attribute values |
| ValidationState fValidationState = new ValidationState(); |
| |
| XSDAbstractTraverser (XSDHandler handler, |
| XSAttributeChecker attrChecker) { |
| fSchemaHandler = handler; |
| fAttrChecker = attrChecker; |
| } |
| |
| void reset(XMLErrorReporter errorReporter, SymbolTable symbolTable) { |
| fErrorReporter = errorReporter; |
| fSymbolTable = symbolTable; |
| fValidationState.setExtraChecking(false); |
| fValidationState.setSymbolTable(symbolTable); |
| } |
| |
| // traverse the annotation declaration |
| // REVISIT: store annotation information for PSVI |
| // REVISIT: how to pass the parentAttrs? as DOM attributes? |
| // as name/value pairs (string)? in parsed form? |
| // REVISIT: what to return |
| void traverseAnnotationDecl(Element annotationDecl, Object[] parentAttrs, |
| boolean isGlobal, XSDocumentInfo schemaDoc) { |
| // General Attribute Checking |
| Object[] attrValues = fAttrChecker.checkAttributes(annotationDecl, isGlobal, schemaDoc); |
| fAttrChecker.returnAttrArray(attrValues, schemaDoc); |
| |
| for (Element child = DOMUtil.getFirstChildElement(annotationDecl); |
| child != null; |
| child = DOMUtil.getNextSiblingElement(child)) { |
| 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)))) { |
| reportGenericSchemaError("an <annotation> can only contain <appinfo> and <documentation> elements"); |
| } |
| |
| // 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); |
| } |
| |
| // REVISIT: an annotation decl should be returned when we support PSVI |
| } |
| |
| // 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(); |
| |
| class FacetInfo { |
| XSFacets facetdata; |
| Element nodeAfterFacets; |
| short fPresentFacets; |
| short fFixedFacets; |
| } |
| |
| FacetInfo traverseFacets(Element content, Object[] contentAttrs, String simpleTypeName, |
| XSSimpleType baseValidator, XSDocumentInfo schemaDoc, |
| SchemaGrammar grammar) { |
| |
| short facetsPresent = 0 ; |
| short facetsFixed = 0; // facets that have fixed="true" |
| |
| String facet; |
| Vector enumData = new Vector(); |
| int currentFacet = 0; |
| while (content != null) { |
| // General Attribute Checking |
| Object[] attrs = null; |
| facet = DOMUtil.getLocalName(content); |
| /*if (facet.equals(SchemaSymbols.ELT_ANNOTATION) || facet.equals(SchemaSymbols.ELT_SIMPLETYPE)) { |
| Object[] args = {simpleTypeName}; |
| fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, |
| "ListUnionRestrictionError", |
| args, |
| XMLErrorReporter.SEVERITY_ERROR); |
| }*/ |
| if (facet.equals(SchemaSymbols.ELT_ENUMERATION)) { |
| attrs = fAttrChecker.checkAttributes(content, false, schemaDoc); |
| String enumVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE]; |
| |
| if (baseValidator.isNOTATIONType()) { |
| try{ |
| QName temp = (QName)fQNameDV.validate(enumVal, schemaDoc.fValidationContext, null); |
| if (fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.NOTATION_TYPE, temp) == null) { |
| reportGenericSchemaError("Notation '" + temp.localpart + |
| "' not found in the grammar "+ temp.uri); |
| } |
| }catch(InvalidDatatypeValueException ex){ |
| reportGenericSchemaError(ex.getMessage()); |
| } |
| } |
| |
| enumData.addElement(enumVal); |
| Element child = DOMUtil.getFirstChildElement( content ); |
| |
| if (child != null) { |
| // traverse annotation if any |
| if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { |
| traverseAnnotationDecl(child, attrs, false, schemaDoc); |
| child = DOMUtil.getNextSiblingElement(child); |
| } |
| if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { |
| reportGenericSchemaError("Enumeration facet has more than one annotation."); |
| } |
| } |
| } |
| else if (facet.equals(SchemaSymbols.ELT_PATTERN)) { |
| attrs = fAttrChecker.checkAttributes(content, false, schemaDoc); |
| if (fPattern.length() == 0) { |
| fPattern.append((String)attrs[XSAttributeChecker.ATTIDX_VALUE]); |
| } else { |
| // --------------------------------------------- |
| //datatypes: 5.2.4 pattern: src-multiple-pattern |
| // --------------------------------------------- |
| fPattern.append("|"); |
| fPattern.append((String)attrs[XSAttributeChecker.ATTIDX_VALUE]); |
| |
| Element child = DOMUtil.getFirstChildElement( content ); |
| if (child != null) { |
| // traverse annotation if any |
| if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { |
| traverseAnnotationDecl(child, attrs, false, schemaDoc); |
| child = DOMUtil.getNextSiblingElement(child); |
| } |
| if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { |
| reportGenericSchemaError("Pattern facet has more than one annotation."); |
| } |
| } |
| } |
| } |
| 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) { |
| fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, |
| "DatatypeError", |
| new Object[]{"The facet '" + facet + "' is defined more than once."}, |
| XMLErrorReporter.SEVERITY_ERROR); |
| } else if (attrs[XSAttributeChecker.ATTIDX_VALUE] != null) { |
| 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 ); |
| if (child != null) { |
| // traverse annotation if any |
| if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { |
| traverseAnnotationDecl(child, attrs, false, schemaDoc); |
| child = DOMUtil.getNextSiblingElement(child); |
| } |
| if (child !=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { |
| reportGenericSchemaError(facet+" facet has more than one annotation."); |
| } |
| } |
| } |
| // REVISIT: when to return the array |
| fAttrChecker.returnAttrArray (attrs, schemaDoc); |
| content = DOMUtil.getNextSiblingElement(content); |
| } |
| if (enumData.size() > 0) { |
| facetsPresent |= XSSimpleType.FACET_ENUMERATION; |
| xsFacets.enumeration = enumData; |
| } |
| if (fPattern.length() != 0) { |
| facetsPresent |= XSSimpleType.FACET_PATTERN; |
| xsFacets.pattern = fPattern.toString(); |
| } |
| |
| fPattern.setLength(0); |
| |
| FacetInfo fi = new FacetInfo(); |
| fi.facetdata = xsFacets; |
| fi.nodeAfterFacets = content; |
| fi.fPresentFacets = facetsPresent; |
| fi.fFixedFacets = facetsFixed; |
| return fi; |
| } |
| |
| // |
| // 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 ) { |
| |
| Element child=null; |
| XSAttributeGroupDecl tempAttrGrp = null; |
| XSAttributeUse tempAttrUse = 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); |
| if (tempAttrUse == null) break; |
| if (attrGrp.getAttributeUse(tempAttrUse.fAttrDecl.fTargetNamespace, |
| tempAttrUse.fAttrDecl.fName)==null) { |
| String idName = attrGrp.addAttributeUse(tempAttrUse); |
| if (idName != null) { |
| reportGenericSchemaError("Two distinct members of the {attribute uses} '" + |
| idName + "' and '" + tempAttrUse.fAttrDecl.fName + |
| "' have {attribute declaration}s both of whose {type definition}s are or are derived from ID"); |
| } |
| } |
| else { |
| // REVISIT: what if one of the attribute uses is "prohibited" |
| reportGenericSchemaError("Duplicate attribute " + |
| tempAttrUse.fAttrDecl.fName + " found "); |
| } |
| } |
| 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 ) break; |
| XSAttributeUse[] attrUseS = tempAttrGrp.getAttributeUses(); |
| XSAttributeUse existingAttrUse = null; |
| for (int i=0; i<attrUseS.length; i++) { |
| existingAttrUse = attrGrp.getAttributeUse(attrUseS[i].fAttrDecl.fTargetNamespace, |
| attrUseS[i].fAttrDecl.fName); |
| if (existingAttrUse == null) { |
| String idName = attrGrp.addAttributeUse(attrUseS[i]); |
| if (idName != null) { |
| reportGenericSchemaError("Two distinct members of the {attribute uses} '" + |
| idName + "' and '" + attrUseS[i].fAttrDecl.fName + |
| "' have {attribute declaration}s both of whose {type definition}s are or are derived from ID"); |
| } |
| } |
| else { |
| // REVISIT: what if one of the attribute uses is "prohibited" |
| reportGenericSchemaError("Duplicate attribute " + |
| existingAttrUse.fAttrDecl.fName + " found "); |
| } |
| } |
| |
| 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) { |
| reportGenericSchemaError("intersection of wildcards is not expressible"); |
| } |
| } |
| } |
| } |
| 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) { |
| reportGenericSchemaError("intersection of wildcards is not expressible"); |
| } |
| } |
| child = DOMUtil.getNextSiblingElement(child); |
| } |
| } |
| |
| // Success |
| return child; |
| |
| } |
| |
| void reportSchemaError (String key, Object[] args) { |
| fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, |
| key, args, |
| XMLErrorReporter.SEVERITY_ERROR); |
| } |
| |
| // REVISIT: is it how we want to handle error reporting? |
| void reportGenericSchemaError (String error) { |
| fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, |
| "General", |
| new Object[]{error}, |
| XMLErrorReporter.SEVERITY_ERROR); |
| } |
| |
| |
| /** |
| * Element/Attribute traversers call this method to check whether |
| * the type is NOTATION without enumeration facet |
| */ |
| void checkNotationType(String refName, XSTypeDecl typeDecl) { |
| if (typeDecl.getXSType() == typeDecl.SIMPLE_TYPE && ((XSSimpleType)typeDecl).isNOTATIONType()) { |
| if ((((XSSimpleType)typeDecl).getDefinedFacets() & XSSimpleType.FACET_ENUMERATION) == 0) { |
| reportSchemaError("dt-enumeration-notation", new Object[]{refName}); |
| } |
| } |
| } |
| |
| // 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 && (!defaultMin || !defaultMax)) { |
| Object[] args = new Object[]{parent.getAttribute(SchemaSymbols.ATT_NAME), |
| particleName}; |
| fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, |
| "MinMaxOnGroupChild", |
| args, |
| XMLErrorReporter.SEVERITY_ERROR); |
| min = 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 || groupRefWithAll || processingAllGP) { |
| String errorMsg; |
| if ((processingAllGP||groupRefWithAll||min!=0) && min !=1) { |
| if (processingAllEl) { |
| errorMsg = "BadMinMaxForAllElem"; |
| } |
| else if (processingAllGP) { |
| errorMsg = "BadMinMaxForAllGp"; |
| } |
| else { |
| errorMsg = "BadMinMaxForGroupWithAll"; |
| } |
| Object[] args = new Object [] {"minOccurs", Integer.toString(min)}; |
| fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, |
| errorMsg, |
| args, |
| XMLErrorReporter.SEVERITY_ERROR); |
| min = 1; |
| } |
| |
| if (max != 1) { |
| |
| if (processingAllEl) { |
| errorMsg = "BadMinMaxForAllElem"; |
| } |
| else if (processingAllGP) { |
| errorMsg = "BadMinMaxForAllGp"; |
| } |
| else { |
| errorMsg = "BadMinMaxForGroupWithAll"; |
| } |
| |
| Object[] args = new Object [] {"maxOccurs", Integer.toString(max)}; |
| fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, |
| errorMsg, |
| args, |
| XMLErrorReporter.SEVERITY_ERROR); |
| max = 1; |
| } |
| } |
| |
| particle.fMaxOccurs = min; |
| particle.fMaxOccurs = max; |
| |
| return particle; |
| } |
| } |