You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by lm...@apache.org on 2001/11/25 19:46:13 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/impl/xs XSConstraints.java

lmartin     01/11/25 10:46:13

  Modified:    java/src/org/apache/xerces/impl/xs XSConstraints.java
  Log:
  Added particle restriction checking
  
  Revision  Changes    Path
  1.4       +759 -1    xml-xerces/java/src/org/apache/xerces/impl/xs/XSConstraints.java
  
  Index: XSConstraints.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XSConstraints.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XSConstraints.java	2001/11/13 20:32:32	1.3
  +++ XSConstraints.java	2001/11/25 18:46:13	1.4
  @@ -68,10 +68,11 @@
    *
    * @author Sandy Gao, IBM
    *
  - * @version $Id: XSConstraints.java,v 1.3 2001/11/13 20:32:32 sandygao Exp $
  + * @version $Id: XSConstraints.java,v 1.4 2001/11/25 18:46:13 lmartin Exp $
    */
   public class XSConstraints {
   
  +    static final int OCCURRENCE_UNKNOWN = SchemaSymbols.OCCURRENCE_UNBOUNDED-1;
       /**
        * check whether derived is valid derived from base, given a subset
        * of {restriction, extension}.
  @@ -333,6 +334,27 @@
                   }
   
                   // 2. Particle Derivation
  +                if (types[j].fBaseType != null &&
  +                    types[j].fBaseType != SchemaGrammar.fAnyType &&
  +                    types[j].fDerivedBy == SchemaSymbols.RESTRICTION &&
  +                    types[j].fParticle !=null && 
  +                    (types[j].fBaseType instanceof XSComplexTypeDecl) && 
  +                    ((XSComplexTypeDecl)(types[j].fBaseType)).fParticle != null) {
  +                  try {
  +                      particleValidRestriction(types[j].fParticle, 
  +                         ((XSComplexTypeDecl)(types[j].fBaseType)).fParticle,
  +                         SGHandler);
  +                  } catch (XMLSchemaException e) {
  +                      errorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  +                                                e.getKey(),
  +                                                e.getArgs(),
  +                                                XMLErrorReporter.SEVERITY_ERROR);
  +                      errorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  +                                                "derivation-ok-restriction.5.3", 
  +                                                new Object[]{types[j].fName}, 
  +                                                XMLErrorReporter.SEVERITY_ERROR);
  +                  }
  +                }
   
                   // 3. UPA
                   // get the content model and check UPA
  @@ -377,6 +399,742 @@
           }
       }
   
  +    /*
  +       Check that a given particle is a valid restriction of a base particle. 
  +    */
  +
  +    public static void particleValidRestriction(XSParticleDecl dParticle, 
  +                                     XSParticleDecl bParticle, 
  +				     SubstitutionGroupHandler sgHandler)              
  +                                     throws XMLSchemaException {
  +       
  +       Vector dChildren = null;
  +       Vector bChildren = null;
  +       int dMinEffectiveTotalRange=OCCURRENCE_UNKNOWN;
  +       int dMaxEffectiveTotalRange=OCCURRENCE_UNKNOWN; 
  +
  +
  +       // Check for empty particles.   If either base or derived particle is empty, 
  +       // (and the other isn't) it's an error. 
  +       if (! (dParticle.isEmpty() == bParticle.isEmpty())) {
  +         throw new XMLSchemaException("cos-particle-restrict", null);
  +       }
  +
  +       //
  +       // Do setup prior to invoking the Particle (Restriction) cases. 
  +       // This involves: 
  +       //   - removing pointless occurrences for groups, and retrieving a vector of 
  +       //     non-pointless children
  +       //   - turning top-level elements with substitution groups into CHOICE groups. 
  +       //
  +
  +       int dType = dParticle.fType;
  +       //
  +       // Handle pointless groups for the derived particle
  +       //
  +       if (dType == XSParticleDecl.PARTICLE_SEQUENCE ||
  +           dType == XSParticleDecl.PARTICLE_CHOICE ||
  +           dType == XSParticleDecl.PARTICLE_ALL) {
  +
  +         // Find a group, starting with this particle, with more than 1 child.   There 
  +         // may be none, and the particle of interest trivially becomes an element or 
  +         // wildcard. 
  +         XSParticleDecl dtmp = getNonUnaryGroup(dParticle);
  +         if (dtmp != dParticle) {
  +            // Particle has been replaced.   Retrieve new type info.
  +            dParticle = dtmp; 
  +            dType = dParticle.fType;
  +         }
  +       
  +         // Fill in a vector with the children of the particle, removing any 
  +         // pointless model groups in the process.   
  +         dChildren = removePointlessChildren(dParticle);
  +       } 
  +
  +       int dMinOccurs = dParticle.fMinOccurs;
  +       int dMaxOccurs = dParticle.fMaxOccurs;
  +
  +       //
  +       // For elements which are the heads of substitution groups, treat as CHOICE
  +       //
  +       if (dType == XSParticleDecl.PARTICLE_ELEMENT) {
  +           XSElementDecl dElement = (XSElementDecl)dParticle.fValue;
  +
  +           if (dElement.isGlobal()) {
  +             // Check for subsitution groups.   Treat any element that has a 
  +             // subsitution group as a choice.   Fill in the children vector with the 
  +             // members of the substitution group 
  +             XSElementDecl[] subGroup = sgHandler.getSubstitutionGroup(dElement);
  +             if (subGroup.length >0 ) {
  +                // Now, set the type to be CHOICE.  The "group" will have the same 
  +                // occurrence information as the original particle.
  +                dType = XSParticleDecl.PARTICLE_CHOICE;
  +                dMinOccurs = dParticle.fMinOccurs;
  +                dMaxOccurs = dParticle.fMaxOccurs;
  +                dMinEffectiveTotalRange = dMinOccurs;
  +                dMaxEffectiveTotalRange = dMaxOccurs; 
  +
  +                // Fill in the vector of children                      
  +                for (int i = 0; i < subGroup.length; i++) {
  +                  dChildren.addElement(subGroup[i]);
  +                }
  +                dChildren.addElement(dElement);
  +             }
  +           }
  +       }
  +        
  +       int bType = bParticle.fType;
  +       //
  +       // Handle pointless groups for the base particle 
  +       //
  +       if (bType == XSParticleDecl.PARTICLE_SEQUENCE ||
  +           bType == XSParticleDecl.PARTICLE_CHOICE ||
  +           bType == XSParticleDecl.PARTICLE_ALL) {
  +
  +         // Find a group, starting with this particle, with more than 1 child.   There 
  +         // may be none, and the particle of interest trivially becomes an element or 
  +         // wildcard. 
  +         XSParticleDecl btmp = getNonUnaryGroup(bParticle);
  +         if (btmp != bParticle) {
  +            // Particle has been replaced.   Retrieve new type info.
  +            bParticle = btmp; 
  +            bType = bParticle.fType;
  +         }
  +       
  +         // Fill in a vector with the children of the particle, removing any 
  +         // pointless model groups in the process. 
  +         bChildren = removePointlessChildren(bParticle);
  +       } 
  +
  +       int bMinOccurs = bParticle.fMinOccurs;
  +       int bMaxOccurs = bParticle.fMaxOccurs;
  +
  +       if (bType == XSParticleDecl.PARTICLE_ELEMENT) {
  +           XSElementDecl bElement = (XSElementDecl)bParticle.fValue;
  +
  +           if (bElement.isGlobal()) {
  +             // Check for subsitution groups.   Treat any element that has a 
  +             // subsitution group as a choice.   Fill in the children vector with the 
  +             // members of the substitution group 
  +             XSElementDecl[] bsubGroup = sgHandler.getSubstitutionGroup(bElement);
  +             if (bsubGroup.length >0 ) {
  +                // Now, set the type to be CHOICE                      
  +                bType = XSParticleDecl.PARTICLE_CHOICE;
  +                bMinOccurs = bParticle.fMinOccurs;
  +                bMaxOccurs = bParticle.fMaxOccurs;
  +
  +                for (int i = 0; i < bsubGroup.length; i++) {
  +                  bChildren.addElement(bsubGroup[i]);
  +                }
  +                bChildren.addElement(bElement);
  +             }
  +           }
  +       }
  +        
  +       //
  +       // O.K. - Figure out which particle derivation rule applies and call it 
  +       //
  +       switch (dType) {
  +         case XSParticleDecl.PARTICLE_ELEMENT:
  +         {
  +            switch (bType) {
  +
  +              // Elt:Elt NameAndTypeOK
  +              case XSParticleDecl.PARTICLE_ELEMENT:
  +              {
  +                 checkNameAndTypeOK((XSElementDecl)dParticle.fValue,dMinOccurs,dMaxOccurs,
  +                                    (XSElementDecl)bParticle.fValue,bMinOccurs,bMaxOccurs);  
  +                 return;
  +              }
  +
  +              // Elt:Any NSCompat
  +              case XSParticleDecl.PARTICLE_WILDCARD:
  +              {
  +                 checkNSCompat((XSElementDecl)dParticle.fValue,dMinOccurs,dMaxOccurs,
  +                               (XSWildcardDecl)bParticle.fValue,bMinOccurs,bMaxOccurs); 
  +                 return;
  +              }
  +
  +              // Elt:All RecurseAsIfGroup
  +              case XSParticleDecl.PARTICLE_CHOICE:
  +              {
  +                 // Treat the element as if it were in a group of the same type 
  +                 // as the base Particle 
  +                 dChildren = new Vector();
  +                 dChildren.addElement(dParticle);
  +
  +                 checkRecurseLax(dChildren, dMinOccurs, dMaxOccurs, 
  +                                 bChildren, bMinOccurs, bMaxOccurs, sgHandler);
  +                 return;
  +              }
  +              case XSParticleDecl.PARTICLE_SEQUENCE:
  +              case XSParticleDecl.PARTICLE_ALL:
  +              {
  +                 // Treat the element as if it were in a group of the same type 
  +                 // as the base Particle 
  +                 dChildren = new Vector();
  +                 dChildren.addElement(dParticle);
  +
  +                 checkRecurse(dChildren, dMinOccurs, dMaxOccurs, 
  +                              bChildren, bMinOccurs, bMaxOccurs, sgHandler);
  +                 return;
  +              }
  +
  +              default:
  +              {
  +           	throw new XMLSchemaException("Internal-Error", 
  +                                             new Object[]{"in particleValidRestriction"});
  +              }
  +            }
  +         }
  +
  +         case XSParticleDecl.PARTICLE_WILDCARD:
  +         {
  +            switch (bType) {
  +
  +              // Any:Any NSSubset
  +              case XSParticleDecl.PARTICLE_WILDCARD:
  +              {
  +                 checkNSSubset((XSWildcardDecl)dParticle.fValue, dMinOccurs, dMaxOccurs, 
  +                               (XSWildcardDecl)bParticle.fValue, bMinOccurs, bMaxOccurs);
  +                 return;
  +              }
  +
  +              case XSParticleDecl.PARTICLE_CHOICE:
  +              case XSParticleDecl.PARTICLE_SEQUENCE:
  +              case XSParticleDecl.PARTICLE_ALL:
  +              case XSParticleDecl.PARTICLE_ELEMENT:
  +              {
  +                 throw new XMLSchemaException("cos-particle-restrict.2",  
  +                                        new Object[]{"any:choice,sequence,all,elt"});
  +              }
  +
  +              default:
  +              {
  +           	throw new XMLSchemaException("Internal-Error", 
  +                                             new Object[]{"in particleValidRestriction"});
  +              }
  +            }
  +         }
  +
  +         case XSParticleDecl.PARTICLE_ALL:
  +         {
  +            switch (bType) {
  +
  +              // All:Any NSRecurseCheckCardinality
  +              case XSParticleDecl.PARTICLE_WILDCARD:
  +              {
  +                 if (dMinEffectiveTotalRange != OCCURRENCE_UNKNOWN) 
  +                    dMinEffectiveTotalRange = dParticle.minEffectiveTotalRange();
  +                 if (dMaxEffectiveTotalRange != OCCURRENCE_UNKNOWN) 
  +                    dMaxEffectiveTotalRange = dParticle.maxEffectiveTotalRange();
  +
  +                 checkNSRecurseCheckCardinality(dChildren, dMinEffectiveTotalRange, 
  +                                                dMaxEffectiveTotalRange,
  +                                                bParticle,bMinOccurs,bMaxOccurs, 
  +                                                sgHandler);
  +                 return;
  +              }
  +
  +              case XSParticleDecl.PARTICLE_ALL:
  +              {
  +                 checkRecurse(dChildren, dMinOccurs, dMaxOccurs, 
  +                              bChildren, bMinOccurs, bMaxOccurs, sgHandler);
  +                 return;
  +              }
  +
  +              case XSParticleDecl.PARTICLE_CHOICE:
  +              case XSParticleDecl.PARTICLE_SEQUENCE:
  +              case XSParticleDecl.PARTICLE_ELEMENT:
  +              {
  +                 throw new XMLSchemaException("cos-particle-restrict.2",  
  +                                        new Object[]{"all:choice,sequence,elt"});
  +              }
  +
  +              default:
  +              {
  +           	throw new XMLSchemaException("Internal-Error", 
  +                                             new Object[]{"in particleValidRestriction"});
  +              }
  +            }
  +         }
  +
  +         case XSParticleDecl.PARTICLE_CHOICE:
  +         {
  +            switch (bType) {
  +
  +              // Choice:Any NSRecurseCheckCardinality
  +              case XSParticleDecl.PARTICLE_WILDCARD:
  +              {
  +                 if (dMinEffectiveTotalRange != OCCURRENCE_UNKNOWN) 
  +                    dMinEffectiveTotalRange = dParticle.minEffectiveTotalRange();
  +                 if (dMaxEffectiveTotalRange != OCCURRENCE_UNKNOWN) 
  +                    dMaxEffectiveTotalRange = dParticle.maxEffectiveTotalRange();
  +
  +                 checkNSRecurseCheckCardinality(dChildren, dMinEffectiveTotalRange, 
  +                                                dMaxEffectiveTotalRange,
  +                                                bParticle,bMinOccurs,bMaxOccurs,
  +                                                sgHandler);
  +                 return;
  +              }
  +
  +              case XSParticleDecl.PARTICLE_CHOICE:
  +              {
  +                 checkRecurseLax(dChildren, dMinOccurs, dMaxOccurs, 
  +                                 bChildren, bMinOccurs, bMaxOccurs, sgHandler);
  +                 return;
  +              }
  +
  +              case XSParticleDecl.PARTICLE_ALL:
  +              case XSParticleDecl.PARTICLE_SEQUENCE:
  +              case XSParticleDecl.PARTICLE_ELEMENT:
  +              {
  +                 throw new XMLSchemaException("cos-particle-restrict.2",  
  +                                        new Object[]{"choice:all,sequence,elt"});
  +              }
  +
  +              default:
  +              {
  +           	throw new XMLSchemaException("Internal-Error", 
  +                                             new Object[]{"in particleValidRestriction"});
  +              }
  +            }
  +         }
  +
  +
  +         case XSParticleDecl.PARTICLE_SEQUENCE:
  +         {
  +            switch (bType) {
  +
  +              // Choice:Any NSRecurseCheckCardinality
  +              case XSParticleDecl.PARTICLE_WILDCARD:
  +              {
  +                 if (dMinEffectiveTotalRange != OCCURRENCE_UNKNOWN) 
  +                    dMinEffectiveTotalRange = dParticle.minEffectiveTotalRange();
  +                 if (dMaxEffectiveTotalRange != OCCURRENCE_UNKNOWN) 
  +                    dMaxEffectiveTotalRange = dParticle.maxEffectiveTotalRange();
  +
  +                 checkNSRecurseCheckCardinality(dChildren, dMinEffectiveTotalRange, 
  +                                                dMaxEffectiveTotalRange,
  +                                                bParticle,bMinOccurs,bMaxOccurs, 
  +                                                sgHandler);
  +                 return;
  +              }
  +
  +              case XSParticleDecl.PARTICLE_ALL:
  +              {
  +                 checkRecurseUnordered(dChildren, dMinOccurs, dMaxOccurs, 
  +                                       bChildren, bMinOccurs, bMaxOccurs, sgHandler);
  +                 return;
  +              }
  +
  +              case XSParticleDecl.PARTICLE_SEQUENCE:
  +              {
  +                 checkRecurse(dChildren, dMinOccurs, dMaxOccurs, 
  +                              bChildren, bMinOccurs, bMaxOccurs, sgHandler);
  +                 return;
  +              }
  +
  +              case XSParticleDecl.PARTICLE_CHOICE:
  +              {
  +                 int min1 = dMinOccurs * dChildren.size(); 
  +                 int max1 = (dMaxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED)? 
  +                             dMaxOccurs : dMaxOccurs * dChildren.size(); 
  +                 checkMapAndSum(dChildren, min1, max1,  
  +                                bChildren, bMinOccurs, bMaxOccurs, sgHandler);
  +                 return;
  +              }
  +
  +              case XSParticleDecl.PARTICLE_ELEMENT:
  +              {
  +                 throw new XMLSchemaException("cos-particle-restrict.2",  
  +                                        new Object[]{"seq:elt"});
  +              }
  +
  +              default:
  +              {
  +           	throw new XMLSchemaException("Internal-Error", 
  +                                             new Object[]{"in particleValidRestriction"});
  +              }
  +            }
  +         }
  +
  +       }
  +    }
  +
  +    private static XSParticleDecl getNonUnaryGroup(XSParticleDecl p) {
  +
  +       if (p.fType == XSParticleDecl.PARTICLE_ELEMENT || 
  +           p.fType == XSParticleDecl.PARTICLE_WILDCARD) 
  +         return p;
  +
  +       if (p.fMinOccurs==1 && p.fMaxOccurs==1 && 
  +           p.fValue!=null && p.fOtherValue==null)  
  +         return getNonUnaryGroup((XSParticleDecl)p.fValue);
  +       else
  +         return p;
  +    }
  +
  +    private static Vector removePointlessChildren(XSParticleDecl p)  {
  +
  +
  +       if (p.fType == XSParticleDecl.PARTICLE_ELEMENT || 
  +           p.fType == XSParticleDecl.PARTICLE_WILDCARD ||
  +           p.fType == XSParticleDecl.PARTICLE_EMPTY)
  +         return null;
  +
  +       Vector children = new Vector(); 
  +
  +       gatherChildren(p.fType, (XSParticleDecl)p.fValue, children);
  +       if (p.fOtherValue != null) {
  +         gatherChildren(p.fType, (XSParticleDecl)p.fOtherValue, children);
  +       }
  +
  +       return children; 
  +    }
  +
  +
  +    private static void gatherChildren(int parentType, XSParticleDecl p, Vector children) {
  +
  +       int min = p.fMinOccurs; 
  +       int max = p.fMaxOccurs; 
  +       int type = p.fType; 
  +
  +       if (type == XSParticleDecl.PARTICLE_ELEMENT ||
  +           type== XSParticleDecl.PARTICLE_WILDCARD) {
  +          children.addElement(p);
  +          return;
  +       }
  +
  +       XSParticleDecl left = (XSParticleDecl)p.fValue; 
  +       XSParticleDecl right = (XSParticleDecl)p.fOtherValue; 
  +       if (! (min==1 && max==1)) {
  +          children.addElement(p);
  +       }
  +       else if (parentType == type) {
  +          gatherChildren(type,left,children);
  +          if (right != null) {
  +            gatherChildren(type,right,children);
  +          }
  +       }
  +       else if (!p.isEmpty()) {
  +          children.addElement(p);
  +       }
  +
  +    }
  +
  +    private static void checkNameAndTypeOK(XSElementDecl dElement, int dMin, int dMax, 
  +                                           XSElementDecl bElement, int bMin, int bMax)  
  +                                   throws XMLSchemaException {
  +
  +      
  +      //
  +      // Check that the names are the same 
  +      //
  +      if (dElement.fName != bElement.fName ||
  +          dElement.fTargetNamespace != bElement.fTargetNamespace) {
  +          throw new XMLSchemaException(
  +              "rcase-NameAndTypeOK.1",new Object[]{dElement.fName,        
  +               dElement.fTargetNamespace, bElement.fName, bElement.fTargetNamespace});
  +      }
  +
  +      //
  +      // Check nillable                   
  +      //
  +      if (! (bElement.isNillable() || !dElement.isNillable())) {
  +        throw new XMLSchemaException("rcase-NameAndTypeOK.2", 
  +                                      new Object[]{dElement.fName});
  +      }
  +
  +      //
  +      // Check occurrence range                   
  +      //
  +      if (!checkOccurrenceRange(dMin, dMax, bMin, bMax)) { 
  +        throw new XMLSchemaException("rcase-NameAndTypeOK.3", 
  +                                      new Object[]{dElement.fName});
  +      }
  +
  +
  +      //
  +      // Check for consistent fixed values
  +      //
  +      if (bElement.getConstraintType() == XSElementDecl.FIXED_VALUE) {
  +         // check the values are the same.  NB - this should not be a string
  +         // comparison REVISIT when we have new datatype design!
  +         String baseFixedValue=(String) bElement.fDefault;
  +         String thisFixedValue=(String) dElement.fDefault; 
  +         if (dElement.getConstraintType() != XSElementDecl.FIXED_VALUE ||
  +            !baseFixedValue.equals(thisFixedValue)) {
  +            throw new XMLSchemaException("rcase-NameAndTypeOK.4", 
  +                                      new Object[]{dElement.fName});
  +         
  +         }
  +      }
  +
  +      //
  +      // Check identity constraints
  +      //
  +      checkIDConstraintRestriction(dElement, bElement); 
  +
  +      //
  +      // Check for disallowed substitutions 
  +      //
  +      int blockSet1 = dElement.fBlock; 
  +      int blockSet2 = bElement.fBlock; 
  +      if (((blockSet1 & blockSet2)!=blockSet2) ||
  +            (blockSet1==SchemaSymbols.EMPTY_SET && blockSet2!=SchemaSymbols.EMPTY_SET))
  +	throw new XMLSchemaException("rcase-NameAndTypeOK.6", 
  +				  new Object[]{dElement.fName});
  +
  +
  +      //
  +      // Check that the derived element's type is derived from the base's. 
  +      //
  +      if (!checkTypeDerivationOk(dElement.fType, bElement.fType, bElement.fFinal)) {
  +	  throw new XMLSchemaException("rcase-NameAndTypeOK.7", 
  +				  new Object[]{dElement.fName});
  +      }
  +
  +    }
  +
  +
  +    private static void checkIDConstraintRestriction(XSElementDecl derivedElemDecl, 
  +                                                     XSElementDecl baseElemDecl)
  +                                             throws XMLSchemaException {
  +        // TODO 
  +    } // checkIDConstraintRestriction
  +
  +
  +    private static boolean checkOccurrenceRange(int min1, int max1, int min2, int max2) {
  +
  +      if ((min1 >= min2) &&
  +          ((max2==SchemaSymbols.OCCURRENCE_UNBOUNDED) || 
  +           (max1!=SchemaSymbols.OCCURRENCE_UNBOUNDED && max1<=max2)))
  +        return true;
  +      else
  +        return false;
  +    }
  +
  +    private static void checkNSCompat(XSElementDecl elem, int min1, int max1, 
  +                                      XSWildcardDecl wildcard, int min2, int max2) 
  +                              throws XMLSchemaException {
  +
  +      // check Occurrence ranges
  +      if (!checkOccurrenceRange(min1,max1,min2,max2)) {
  +	throw new XMLSchemaException("rcase-NSCompat.2", 
  +				  new Object[]{elem.fName});
  +      }
  +
  +      // check wildcard allows namespace of element
  +      if (!wildcard.allowNamespace(elem.fTargetNamespace))  {
  +	throw new XMLSchemaException("rcase-NSCompat.1", 
  +				  new Object[]{elem.fName,elem.fTargetNamespace});
  +      }
  +
  +    }
  +
  +    private static void checkNSSubset(XSWildcardDecl dWildcard, int min1, int max1, 
  +                                      XSWildcardDecl bWildcard, int min2, int max2) 
  +                              throws XMLSchemaException {
  +
  +      // check Occurrence ranges
  +      if (!checkOccurrenceRange(min1,max1,min2,max2)) {
  +	throw new XMLSchemaException("rcase-NSSubset.2",null);
  +      }
  +
  +      // check wildcard subset
  +      if (!dWildcard.isSubsetOf(bWildcard)) {
  +	 throw new XMLSchemaException("rcase-NSSubset.1",null);
  +      }
  +
  +
  +    }
  +
  +
  +    private static void checkNSRecurseCheckCardinality(Vector children, int min1, int max1, 
  +                                          XSParticleDecl wildcard, int min2, int max2, 
  +                                          SubstitutionGroupHandler sgHandler)
  +                                          throws XMLSchemaException {
  +
  +
  +      // check Occurrence ranges
  +      if (!checkOccurrenceRange(min1,max1,min2,max2)) {
  +         throw new XMLSchemaException("rcase-NSRecurseCheckCardinality.2", null); 
  +      }
  +
  +      // Check that each member of the group is a valid restriction of the wildcard
  +      int count = children.size();
  +      try {
  +        for (int i = 0; i < count; i++) {
  +           XSParticleDecl particle1 = (XSParticleDecl)children.elementAt(i);
  +           particleValidRestriction(particle1, wildcard, sgHandler);
  +       
  +        }
  +      }
  +      catch (XMLSchemaException e) {
  +         throw new XMLSchemaException("rcase-NSRecurseCheckCardinality.1", null); 
  +      }
  +
  +    }
  +
  +    private static void checkRecurse(Vector dChildren, int min1, int max1, 
  +                                     Vector bChildren, int min2, int max2, 
  +                                     SubstitutionGroupHandler sgHandler) 
  +                                     throws XMLSchemaException {
  +
  +      // check Occurrence ranges
  +      if (!checkOccurrenceRange(min1,max1,min2,max2)) {
  +        throw new XMLSchemaException("rcase-Recurse.1", null); 
  +      }
  +
  +      int count1= dChildren.size();
  +      int count2= bChildren.size();
  +
  +      int current = 0;
  +      label: for (int i = 0; i<count1; i++) {
  +
  +        XSParticleDecl particle1 = (XSParticleDecl)dChildren.elementAt(i);
  +        for (int j = current; j<count2; j++) {
  +           XSParticleDecl particle2 = (XSParticleDecl)bChildren.elementAt(j);
  +           current +=1;
  +           try {
  +             particleValidRestriction(particle1, particle2, sgHandler);
  +             continue label;
  +           }
  +           catch (XMLSchemaException e) {
  +             if (!particle2.emptiable())
  +                throw new XMLSchemaException("rcase-Recurse.2", null); 
  +           }
  +        }
  +        throw new XMLSchemaException("rcase-Recurse.2", null); 
  +      }
  +
  +      // Now, see if there are some elements in the base we didn't match up
  +      for (int j=current; j < count2; j++) {
  +        XSParticleDecl particle2 = (XSParticleDecl)bChildren.elementAt(j);
  +        if (!particle2.emptiable()) {
  +          throw new XMLSchemaException("rcase-Recurse.2", null); 
  +        }
  +      }
  +
  +    }
  +
  +    private static void checkRecurseUnordered(Vector dChildren, int min1, int max1, 
  +                                       Vector bChildren, int min2, int max2, 
  +                                       SubstitutionGroupHandler sgHandler)
  +                                       throws XMLSchemaException {
  +
  +
  +      // check Occurrence ranges
  +      if (!checkOccurrenceRange(min1,max1,min2,max2)) {
  +        throw new XMLSchemaException("rcase-RecurseUnordered.1", null); 
  +      }
  +
  +      int count1= dChildren.size();
  +      int count2 = bChildren.size();
  +
  +      boolean foundIt[] = new boolean[count2];
  +
  +      label: for (int i = 0; i<count1; i++) {
  +        XSParticleDecl particle1 = (XSParticleDecl)dChildren.elementAt(i);
  +
  +        for (int j = 0; j<count2; j++) {
  +           XSParticleDecl particle2 = (XSParticleDecl)bChildren.elementAt(j);
  +           try {
  +             particleValidRestriction(particle1, particle2, sgHandler);
  +             if (foundIt[j])
  +                throw new XMLSchemaException("rcase-RecurseUnordered.2", null); 
  +             else
  +                foundIt[j]=true;
  +
  +             continue label;
  +           }
  +           catch (XMLSchemaException e) {
  +           }
  +        }
  +        // didn't find a match.  Detect an error
  +        throw new XMLSchemaException("rcase-RecurseUnordered.2", null); 
  +      }
  +
  +    }
  +
  +    private static void checkRecurseLax(Vector dChildren, int min1, int max1, 
  +                                       Vector bChildren, int min2, int max2, 
  +                                       SubstitutionGroupHandler sgHandler)
  +                                       throws XMLSchemaException {
  +
  +      // check Occurrence ranges
  +      if (!checkOccurrenceRange(min1,max1,min2,max2)) {
  +        throw new XMLSchemaException("rcase-RecurseLax.1", null); 
  +      }
  +
  +      int count1= dChildren.size();
  +      int count2 = bChildren.size();
  +
  +      int current = 0;
  +      label: for (int i = 0; i<count1; i++) {
  +
  +        XSParticleDecl particle1 = (XSParticleDecl)dChildren.elementAt(i);
  +        for (int j = current; j<count2; j++) {
  +           XSParticleDecl particle2 = (XSParticleDecl)bChildren.elementAt(j);
  +           current +=1;
  +           try {
  +             particleValidRestriction(particle1, particle2, sgHandler);
  +             continue label;
  +           }
  +           catch (XMLSchemaException e) {
  +           }
  +        }
  +        // didn't find a match.  Detect an error
  +        throw new XMLSchemaException("rcase-RecurseLax.2", null); 
  +
  +      }
  +
  +    }
  +
  +    private static void checkMapAndSum(Vector dChildren, int min1, int max1, 
  +                                       Vector bChildren, int min2, int max2, 
  +                                       SubstitutionGroupHandler sgHandler)
  +                                       throws XMLSchemaException {
  +
  +      // See if the sequence group is a valid restriction of the choice
  +
  +      // Here is an example of a valid restriction:
  +      //   <choice minOccurs="2">
  +      //       <a/>
  +      //       <b/>
  +      //       <c/>
  +      //   </choice>
  +      //
  +      //   <sequence>
  +      //        <b/>
  +      //        <a/>
  +      //   </sequence>
  +
  +      // check Occurrence ranges
  +      if (!checkOccurrenceRange(min1,max1,min2,max2)) {
  +        throw new XMLSchemaException("rcase-MapAndSum.2", null); 
  +      }
  +
  +      int count1 = dChildren.size();
  +      int count2 = bChildren.size();
  +
  +      label: for (int i = 0; i<count1; i++) {
  +
  +        XSParticleDecl particle1 = (XSParticleDecl)dChildren.elementAt(i);
  +        for (int j = 0; j<count2; j++) {
  +           XSParticleDecl particle2 = (XSParticleDecl)bChildren.elementAt(j);
  +           try {
  +             particleValidRestriction(particle1, particle2, sgHandler);
  +             continue label;
  +           }
  +           catch (XMLSchemaException e) {
  +           }
  +        }
  +        // didn't find a match.  Detect an error
  +        throw new XMLSchemaException("rcase-MapAndSum.1", null); 
  +      }
  +    }
       // to check whether two element overlap, as defined in constraint UPA
       public static boolean overlapUPA(XSElementDecl element1,
                                        XSElementDecl element2,
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org