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

cvs commit: xml-xerces/java/src/org/apache/xerces/impl/xs/models CMBuilder.java XSAllCM.java XSCMLeaf.java XSCMValidator.java XSDFACM.java XSEmptyCM.java XSSimpleCM.java

sandygao    01/11/13 12:32:32

  Modified:    java/src/org/apache/xerces/impl Constants.java
               java/src/org/apache/xerces/impl/v2/new_datatypes
                        XSSimpleTypeDecl.java
               java/src/org/apache/xerces/impl/xs SchemaGrammar.java
                        SubstitutionGroupHandler.java
                        XMLSchemaException.java XMLSchemaValidator.java
                        XSConstraints.java XSGrammarResolver.java
               java/src/org/apache/xerces/impl/xs/models CMBuilder.java
                        XSAllCM.java XSCMLeaf.java XSCMValidator.java
                        XSDFACM.java XSEmptyCM.java XSSimpleCM.java
  Log:
  Full schema constraint checking and Unique Particle Attribution checking:
  1. A new feature is added "validation/schema-full-checking" (as in Xerces-J),
  which controls whether the 3 special constraints are checked against schema:
  Unique Particle Attribution, Particle Derivation, Element Consistent.
  2. Update schema validator to check the 3 constraints if the feature is on.
  3. Code for Unique Particle Attribution checking
  4. Updated all content models to check for UPA
  5. Code for computing the substitution group for a given element decl
  
  Revision  Changes    Path
  1.5       +4 -1      xml-xerces/java/src/org/apache/xerces/impl/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/Constants.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Constants.java	2001/10/16 15:11:37	1.4
  +++ Constants.java	2001/11/13 20:32:31	1.5
  @@ -65,7 +65,7 @@
    *
    * @author Andy Clark, IBM
    *
  - * @version $Id: Constants.java,v 1.4 2001/10/16 15:11:37 elena Exp $
  + * @version $Id: Constants.java,v 1.5 2001/11/13 20:32:31 sandygao Exp $
    */
   public final class Constants {
   
  @@ -120,6 +120,9 @@
   
       /** Schema validation feature ("validation/schema"). */
       public static final String SCHEMA_VALIDATION_FEATURE = "validation/schema";
  +
  +    /** Schema full constraint checking ("validation/schema-full-checking"). */
  +    public static final String SCHEMA_FULL_CHECKING = "validation/schema-full-checking";
   
       /** Dynamic validation feature ("validation/dynamic"). */
       public static final String DYNAMIC_VALIDATION_FEATURE = "validation/dynamic";
  
  
  
  1.7       +5 -5      xml-xerces/java/src/org/apache/xerces/impl/v2/new_datatypes/XSSimpleTypeDecl.java
  
  Index: XSSimpleTypeDecl.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/v2/new_datatypes/XSSimpleTypeDecl.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XSSimpleTypeDecl.java	2001/11/09 17:49:49	1.6
  +++ XSSimpleTypeDecl.java	2001/11/13 20:32:31	1.7
  @@ -67,7 +67,7 @@
    * @author Sandy Gao, IBM
    * @author Neeraj Bajaj, Sun Microsystems, inc.
    *
  - * @version $Id: XSSimpleTypeDecl.java,v 1.6 2001/11/09 17:49:49 sandygao Exp $
  + * @version $Id: XSSimpleTypeDecl.java,v 1.7 2001/11/13 20:32:31 sandygao Exp $
    */
   class XSSimpleTypeDecl implements XSAtomicSimpleType, XSListSimpleType, XSUnionSimpleType {
   
  @@ -924,12 +924,12 @@
           }
           // inherit pattern //???
           if ( (fBase.fFacetsDefined & FACET_PATTERN) != 0 ) {
  -            if ((fFacetsDefined & FACET_PATTERN) == 0)
  +            if ((fFacetsDefined & FACET_PATTERN) == 0) {
                   fPattern = new Vector();
  -            fFacetsDefined |= FACET_PATTERN;
  +                fFacetsDefined |= FACET_PATTERN;
  +            }
               for (int i = fBase.fPattern.size()-1; i >= 0; i--)
                   fPattern.addElement(fBase.fPattern.elementAt(i));
  -            fEnumeration = fBase.fEnumeration;
           }
           // inherit whiteSpace
           if ( (fFacetsDefined & FACET_WHITESPACE) == 0 &&  (fBase.fFacetsDefined & FACET_WHITESPACE) != 0 ) {
  @@ -1252,7 +1252,7 @@
       }//isEqual()
   
       // normalize the string according to the whiteSpace facet
  -    public static String normalize(String content, short ws) {
  +    static String normalize(String content, short ws) {
           int len = content == null ? 0 : content.length();
           if (len == 0 || ws == WS_PRESERVE)
               return content;
  
  
  
  1.4       +4 -4      xml-xerces/java/src/org/apache/xerces/impl/xs/SchemaGrammar.java
  
  Index: SchemaGrammar.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/SchemaGrammar.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SchemaGrammar.java	2001/11/02 23:03:16	1.3
  +++ SchemaGrammar.java	2001/11/13 20:32:31	1.4
  @@ -71,7 +71,7 @@
    * @author Sandy Gao, IBM
    * @author Elena Litani, IBM
    *
  - * @version $Id: SchemaGrammar.java,v 1.3 2001/11/02 23:03:16 sandygao Exp $
  + * @version $Id: SchemaGrammar.java,v 1.4 2001/11/13 20:32:31 sandygao Exp $
    */
   
   public class SchemaGrammar {
  @@ -400,9 +400,9 @@
       private int fCTCount = 0;
       private XSComplexTypeDecl[] fComplexTypeDecls = new XSComplexTypeDecl[INITIAL_SIZE];
   
  -    // a flag to indicate whether we need to check 3 constraints against each
  -    // complex type, or only need to check UPA.
  -    boolean fOnlyCheckUPA = false;
  +    // a flag to indicate whether we have checked the 3 constraints on this
  +    // grammar.
  +    boolean fFullChecked = false;
   
       /**
        * add one complex type decl: for later constraint checking
  
  
  
  1.3       +78 -24    xml-xerces/java/src/org/apache/xerces/impl/xs/SubstitutionGroupHandler.java
  
  Index: SubstitutionGroupHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/SubstitutionGroupHandler.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SubstitutionGroupHandler.java	2001/11/01 20:06:54	1.2
  +++ SubstitutionGroupHandler.java	2001/11/13 20:32:31	1.3
  @@ -58,13 +58,15 @@
   package org.apache.xerces.impl.xs;
   
   import org.apache.xerces.xni.QName;
  +import java.util.Hashtable;
  +import java.util.Vector;
   
   /**
    * To store and validate information about substitutionGroup
    *
    * @author Sandy Gao, IBM
    *
  - * @version $Id: SubstitutionGroupHandler.java,v 1.2 2001/11/01 20:06:54 sandygao Exp $
  + * @version $Id: SubstitutionGroupHandler.java,v 1.3 2001/11/13 20:32:31 sandygao Exp $
    */
   public class SubstitutionGroupHandler {
   
  @@ -78,29 +80,6 @@
           fGrammarResolver = grammarResolver;
       }
   
  -    /**
  -     * clear the internal registry of substitutionGroup information
  -     */
  -    public void reset() {
  -        // REVISIT: to implement
  -    }
  -
  -    /**
  -     * add one substitution group pair
  -     */
  -    public void addSubstitutionGroup(XSElementDecl element) {
  -        // REVISIT: to implement
  -    }
  -
  -    /**
  -     * get all elements that can substitute the given element,
  -     * according to the spec, we shouldn't consider the {block} constraints.
  -     */
  -    public XSElementDecl[] getSubstitutionGroup(String elementUri, String elementName) {
  -        // REVISIT: to implement
  -        return null;
  -    }
  -
       // 3.9.4 Element Sequence Locally Valid (Particle) 2.3.3
       // check whether one element decl matches an element with the given qname
       public XSElementDecl getMatchingElemDecl(QName element, XSElementDecl exemplar) {
  @@ -193,6 +172,81 @@
               element = element.fSubGroup;
           }
           return (element != null);
  +    }
  +
  +    // to store substitution group information
  +    // the key to the hashtable is an element decl, and the value is
  +    // - a Vector, which contains all elements that has this element as their
  +    //   substitution group affilication
  +    // - an array, which contains its substitution group.
  +    Hashtable fSubGroups = new Hashtable();
  +    private static XSElementDecl[] EMPTY_VECTOR = new XSElementDecl[0];
  +
  +    /**
  +     * clear the internal registry of substitutionGroup information
  +     */
  +    public void reset() {
  +        fSubGroups.clear();
  +    }
  +
  +    /**
  +     * add a list of substitution group information.
  +     */
  +    public void addSubstitutionGroup(XSElementDecl[] elements) {
  +        XSElementDecl subHead, element;
  +        Vector subGroup;
  +        // for all elements with substitution group affiliation
  +        for (int i = elements.length-1; i >= 0; i--) {
  +            element = elements[i];
  +            subHead = element.fSubGroup;
  +            // check whether this an entry for this element
  +            subGroup = (Vector)fSubGroups.get(subHead);
  +            if (subGroup == null) {
  +                // if not, create a new one
  +                subGroup = new Vector();
  +                fSubGroups.put(subHead, subGroup);
  +            }
  +            // add to the vactor
  +            subGroup.add(element);
  +        }
  +    }
  +
  +    /**
  +     * get all elements that can substitute the given element,
  +     * according to the spec, we shouldn't consider the {block} constraints.
  +     *
  +     * from the spec, substitution group of a given element decl also contains
  +     * the element itself. but the array returned from this method doesn't
  +     * containt this element.
  +     */
  +    public XSElementDecl[] getSubstitutionGroup(XSElementDecl element) {
  +        XSElementDecl[] ret;
  +        Object subGroup = fSubGroups.get(element);
  +        if (subGroup == null) {
  +            // substitution group for this one is empty
  +            ret = EMPTY_VECTOR;
  +            fSubGroups.put(element, ret);
  +        } else if (subGroup instanceof XSElementDecl[]) {
  +            // we've already calculated the element, just return.
  +            ret = (XSElementDecl[])subGroup;
  +        } else {
  +            // we only have the *direct* substitutions
  +            Vector group = (Vector)subGroup;
  +            XSElementDecl[] group1;
  +            // then for each of the direct substitutions, get its substitution
  +            // group, and combine the groups together.
  +            for (int i = group.size()-1, j; i >= 0; i--) {
  +                group1 = getSubstitutionGroup((XSElementDecl)group.get(i));
  +                for (j = group1.length-1; j >= 0; j--)
  +                    group.add(group1[j]);
  +            }
  +            ret = new XSElementDecl[group.size()];
  +            for (int i = group.size()-1; i >= 0; i--)
  +                ret[i] = (XSElementDecl)group.elementAt(i);
  +            fSubGroups.put(element, ret);
  +        }
  +
  +        return ret;
       }
   
   } // class SubstitutionGroupHandler
  
  
  
  1.2       +31 -17    xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaException.java
  
  Index: XMLSchemaException.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaException.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XMLSchemaException.java	2001/10/25 20:36:02	1.1
  +++ XMLSchemaException.java	2001/11/13 20:32:32	1.2
  @@ -1,9 +1,8 @@
  -
   /*
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 2001 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2001 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -11,7 +10,7 @@
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer. 
  + *    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
  @@ -19,7 +18,7 @@
    *    distribution.
    *
    * 3. The end-user documentation included with the redistribution,
  - *    if any, must include the following acknowledgment:  
  + *    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,
  @@ -27,7 +26,7 @@
    *
    * 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 
  + *    software without prior written permission. For written
    *    permission, please contact apache@apache.org.
    *
    * 5. Products derived from this software may not be called "Apache",
  @@ -58,20 +57,35 @@
   package org.apache.xerces.impl.xs;
   
   /**
  - * This exception might be thrown by any of traverser classes.
  - * <strong>Note:</strong> By extending the Java
  - * <code>RuntimeException</code>, schema traversers are
  - * not required to catch XMLSchema exceptions but may explicitly catch
  - * them, if so desired.
  - * XMLSchema exceptions should be caught by XSDHandler.
  - * 
  + * This exception might be thrown by any constraint checking method.
  + *
    * @author Elena Litani, IBM
  - * @version $Id: XMLSchemaException.java,v 1.1 2001/10/25 20:36:02 elena Exp $
  + *
  + * @version $Id: XMLSchemaException.java,v 1.2 2001/11/13 20:32:32 sandygao Exp $
    */
  -public class XMLSchemaException extends RuntimeException {
  +public class XMLSchemaException extends Exception {
  +
  +    // this one is like reportGenericSchemaError: remove it later
  +    public XMLSchemaException(String msg) {
  +        this("general", new Object[]{msg});
  +    }
  +
  +    // store a datatype error: error code plus the arguments
  +    String key;
  +    Object[] args;
  +
  +    // report an error
  +    public XMLSchemaException(String key, Object[] args) {
  +        this.key = key;
  +        this.args = args;
  +    }
  +
  +    public String getKey() {
  +        return key;
  +    }
   
  +    public Object[] getArgs() {
  +        return args;
  +    }
   
  -    public XMLSchemaException(String message) {
  -        super(message);
  -    } // <init>(String)
   }
  
  
  
  1.7       +19 -3     xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java
  
  Index: XMLSchemaValidator.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XMLSchemaValidator.java	2001/11/06 14:24:11	1.6
  +++ XMLSchemaValidator.java	2001/11/13 20:32:32	1.7
  @@ -118,7 +118,7 @@
    * @author Eric Ye IBM
    * @author Andy Clark IBM
    * @author Jeffrey Rodriguez IBM
  - * @version $Id: XMLSchemaValidator.java,v 1.6 2001/11/06 14:24:11 elena Exp $
  + * @version $Id: XMLSchemaValidator.java,v 1.7 2001/11/13 20:32:32 sandygao Exp $
    */
   public class XMLSchemaValidator
                implements XMLComponent, XMLDocumentFilter, FieldActivator {
  @@ -141,6 +141,10 @@
       protected static final String SCHEMA_VALIDATION =
       Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
   
  +    /** Feature identifier: schema full checking*/
  +    protected static final String SCHEMA_FULL_CHECKING =
  +    Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING;
  +
       /** Feature identifier: dynamic validation. */
       protected static final String DYNAMIC_VALIDATION =
       Constants.XERCES_FEATURE_PREFIX + Constants.DYNAMIC_VALIDATION_FEATURE;
  @@ -174,6 +178,7 @@
           NAMESPACES,
           SCHEMA_VALIDATION,
           DYNAMIC_VALIDATION,
  +        SCHEMA_FULL_CHECKING,
       };
   
       /** Recognized properties. */
  @@ -197,6 +202,7 @@
       protected boolean fValidation = false;
       protected boolean fDynamicValidation = false;
       protected boolean fDoValidation = false;
  +    protected boolean fFullChecking = false;
   
       // properties
   
  @@ -878,6 +884,7 @@
           catch (XMLConfigurationException e) {
               fValidation = false;
           }
  +
           try {
               // REVISIT: should schema validation depend on validation?
               // NOTE: YES! That's the way it's documented and has worked
  @@ -890,6 +897,13 @@
               fValidation = false;
           }
   
  +        try {
  +            fFullChecking = componentManager.getFeature(SCHEMA_FULL_CHECKING);
  +        }
  +        catch (XMLConfigurationException e) {
  +            fFullChecking = false;
  +        }
  +
           // Xerces features
           try {
               fDynamicValidation = componentManager.getFeature(DYNAMIC_VALIDATION);
  @@ -1422,7 +1436,9 @@
                   if (!fValidationState.checkIDRefID()) {
                       reportSchemaError("ValidationRoot",null);
                   }
  -                // REVISIT: is this the right place to check the 3 contraints?
  +                // check extra schema constraints
  +                if (fFullChecking)
  +                    XSConstraints.fullSchemaChecking(fGrammarResolver, fSubGroupHandler, fCMBuilder, fErrorReporter);
               }
           }
           else {
  @@ -1724,7 +1740,7 @@
               if (!isSpecified && constType != XSAttributeDecl.NO_CONSTRAINT) {
                   attName = new QName(null, currDecl.fName, currDecl.fName, currDecl.fTargetNamespace);
                   // REVISIT: fType on decl must be simpleType decl, using which we can find
  -                // out the type. In the mean time, we must at least set CDATA, 
  +                // out the type. In the mean time, we must at least set CDATA,
                   // and we really need to know what attributes are of type ID:
                   // DOM requires some special handling for those ones.
                   attributes.addAttribute(attName, "CDATA", (defaultValue !=null)?defaultValue.toString():"");
  
  
  
  1.3       +180 -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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XSConstraints.java	2001/11/01 21:25:36	1.2
  +++ XSConstraints.java	2001/11/13 20:32:32	1.3
  @@ -57,7 +57,10 @@
   
   package org.apache.xerces.impl.xs;
   
  +import org.apache.xerces.impl.XMLErrorReporter;
   import org.apache.xerces.impl.dv.xs.*;
  +import org.apache.xerces.impl.xs.models.CMBuilder;
  +import org.apache.xerces.impl.xs.models.XSCMValidator;
   import java.util.Vector;
   
   /**
  @@ -65,7 +68,7 @@
    *
    * @author Sandy Gao, IBM
    *
  - * @version $Id: XSConstraints.java,v 1.2 2001/11/01 21:25:36 sandygao Exp $
  + * @version $Id: XSConstraints.java,v 1.3 2001/11/13 20:32:32 sandygao Exp $
    */
   public class XSConstraints {
   
  @@ -287,4 +290,180 @@
           return actualValue;
       }
   
  +    /**
  +     * used to check the 3 constraints against each complex type
  +     * (should be each model group):
  +     * Unique Particle Attribution, Particle Derivation (Restriction),
  +     * Element Declrations Consistent.
  +     */
  +    public static void fullSchemaChecking(XSGrammarResolver grammarResolver,
  +                                          SubstitutionGroupHandler SGHandler,
  +                                          CMBuilder cmBuilder,
  +                                          XMLErrorReporter errorReporter) {
  +        // get all grammars, and put all substitution group information
  +        // in the substitution group handler
  +        SchemaGrammar[] grammars = grammarResolver.getGrammars();
  +        for (int i = grammars.length-1; i >= 0; i--) {
  +            SGHandler.addSubstitutionGroup(grammars[i].getSubstitutionGroups());
  +        }
  +
  +        // for each complex type, check the 3 constraints.
  +        // types need to be checked
  +        XSComplexTypeDecl[] types;
  +        // to hold the errors
  +        // REVISIT: do we want to report all errors? or just one?
  +        //XMLSchemaError1D errors = new XMLSchemaError1D();
  +        // whether need to check this type again;
  +        // whether only do UPA checking
  +        boolean further, fullChecked;
  +        // if do all checkings, how many need to be checked again.
  +        int keepType;
  +        // i: grammar; j: type; k: error
  +        // for all grammars
  +        for (int i = grammars.length-1, j, k; i >= 0; i--) {
  +            // get whether only check UPA, and types need to be checked
  +            keepType = 0;
  +            fullChecked = grammars[i].fFullChecked;
  +            types = grammars[i].getUncheckedComplexTypeDecls();
  +            // for each type
  +            for (j = types.length-1; j >= 0; j--) {
  +                // if only do UPA checking, skip the other two constraints
  +                if (!fullChecked) {
  +                // 1. Element Decl Consistent
  +                }
  +
  +                // 2. Particle Derivation
  +
  +                // 3. UPA
  +                // get the content model and check UPA
  +                XSCMValidator cm = types[j].getContentModel(cmBuilder);
  +                further = false;
  +                if (cm != null) {
  +                    try {
  +                        further = cm.checkUniqueParticleAttribution(SGHandler);
  +                    } catch (XMLSchemaException e) {
  +                        errorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  +                                                  e.getKey(),
  +                                                  e.getArgs(),
  +                                                  XMLErrorReporter.SEVERITY_ERROR);
  +                    }
  +                }
  +                // now report all errors
  +                // REVISIT: do we want to report all errors? or just one?
  +                /*for (k = errors.getErrorCodeNum()-1; k >= 0; k--) {
  +                    errorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  +                                              errors.getErrorCode(k),
  +                                              errors.getArgs(k),
  +                                              XMLErrorReporter.SEVERITY_ERROR);
  +                }*/
  +
  +                // if we are doing all checkings, and this one needs further
  +                // checking, store it in the type array.
  +                if (!fullChecked && further)
  +                    types[keepType++] = types[j];
  +
  +                // clear errors for the next type.
  +                // REVISIT: do we want to report all errors? or just one?
  +                //errors.clear();
  +            }
  +            // we've done with the types in this grammar. if we are checking
  +            // all constraints, need to trim type array to a proper size:
  +            // only contain those need further checking.
  +            // and mark this grammar that it only needs UPA checking.
  +            if (!fullChecked) {
  +                grammars[i].setUncheckedTypeNum(keepType);
  +                grammars[i].fFullChecked = true;
  +            }
  +        }
  +    }
  +
  +    // to check whether two element overlap, as defined in constraint UPA
  +    public static boolean overlapUPA(XSElementDecl element1,
  +                                     XSElementDecl element2,
  +                                     SubstitutionGroupHandler sgHandler) {
  +        // if the two element have the same name and namespace,
  +        if (element1.fName == element2.fName &&
  +            element1.fTargetNamespace == element2.fTargetNamespace) {
  +            return true;
  +        }
  +
  +        // or if there is an element decl in element1's substitution group,
  +        // who has the same name/namespace with element2
  +        XSElementDecl[] subGroup = sgHandler.getSubstitutionGroup(element1);
  +        for (int i = subGroup.length-1; i >= 0; i--) {
  +            if (subGroup[i].fName == element2.fName &&
  +                subGroup[i].fTargetNamespace == element2.fTargetNamespace) {
  +                return true;
  +            }
  +        }
  +
  +        // or if there is an element decl in element2's substitution group,
  +        // who has the same name/namespace with element1
  +        subGroup = sgHandler.getSubstitutionGroup(element2);
  +        for (int i = subGroup.length-1; i >= 0; i--) {
  +            if (subGroup[i].fName == element1.fName &&
  +                subGroup[i].fTargetNamespace == element1.fTargetNamespace) {
  +                return true;
  +            }
  +        }
  +
  +        return false;
  +    }
  +
  +    // to check whether an element overlaps with a wildcard,
  +    // as defined in constraint UPA
  +    public static boolean overlapUPA(XSElementDecl element,
  +                                     XSWildcardDecl wildcard,
  +                                     SubstitutionGroupHandler sgHandler) {
  +        // if the wildcard allows the element
  +        if (wildcard.allowNamespace(element.fTargetNamespace))
  +            return true;
  +
  +        // or if the wildcard allows any element in the substitution group
  +        XSElementDecl[] subGroup = sgHandler.getSubstitutionGroup(element);
  +        for (int i = subGroup.length-1; i >= 0; i--) {
  +            if (wildcard.allowNamespace(subGroup[i].fTargetNamespace))
  +                return true;
  +        }
  +
  +        return false;
  +    }
  +
  +    public static boolean overlapUPA(XSWildcardDecl wildcard1,
  +                                     XSWildcardDecl wildcard2) {
  +        // if the intersection of the two wildcard is not empty list
  +        XSWildcardDecl intersect = wildcard1.performIntersectionWith(wildcard2, wildcard1.fProcessContents);
  +        if (intersect == null ||
  +            intersect.fType != XSWildcardDecl.WILDCARD_LIST ||
  +            intersect.fNamespaceList.length != 0) {
  +            return true;
  +        }
  +
  +        return false;
  +    }
  +
  +    // call one of the above methods according to the type of decls
  +    public static boolean overlapUPA(Object decl1, Object decl2,
  +                                     SubstitutionGroupHandler sgHandler) {
  +        if (decl1 instanceof XSElementDecl) {
  +            if (decl2 instanceof XSElementDecl) {
  +                return overlapUPA((XSElementDecl)decl1,
  +                                  (XSElementDecl)decl2,
  +                                  sgHandler);
  +            } else {
  +                return overlapUPA((XSElementDecl)decl1,
  +                                  (XSWildcardDecl)decl2,
  +                                  sgHandler);
  +            }
  +        } else {
  +            if (decl2 instanceof XSElementDecl) {
  +                return overlapUPA((XSElementDecl)decl2,
  +                                  (XSWildcardDecl)decl1,
  +                                  sgHandler);
  +            } else {
  +                return overlapUPA((XSWildcardDecl)decl1,
  +                                  (XSWildcardDecl)decl2);
  +            }
  +        }
  +    }
   } // class XSContraints
  
  
  
  1.2       +17 -8     xml-xerces/java/src/org/apache/xerces/impl/xs/XSGrammarResolver.java
  
  Index: XSGrammarResolver.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XSGrammarResolver.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSGrammarResolver.java	2001/10/25 20:36:02	1.1
  +++ XSGrammarResolver.java	2001/11/13 20:32:32	1.2
  @@ -58,11 +58,12 @@
   package org.apache.xerces.impl.xs;
   
   import java.util.Hashtable;
  +import java.util.Enumeration;
   
   /**
    * A class used to hold the internal schema grammar set for the current instance
    * @author Sandy Gao, IBM
  - * @version $Id: XSGrammarResolver.java,v 1.1 2001/10/25 20:36:02 elena Exp $
  + * @version $Id: XSGrammarResolver.java,v 1.2 2001/11/13 20:32:32 sandygao Exp $
    */
   public class XSGrammarResolver {
   
  @@ -115,15 +116,23 @@
       }
   
       /**
  -     * Check if a grammar for the specified namespace is in the registry
  +     * get all grammars in the registry
        *
  -     * @param namespace
  -     * @return boolean true if contains
  +     * @return an array of SchemaGrammars.
        */
  -    public boolean contains(String namespace) {
  -        if (namespace == null)
  -            return (fNoNSGrammar != null);
  -        return fGrammarRegistry.containsKey(namespace);
  +    public SchemaGrammar[] getGrammars() {
  +        // get the number of grammars
  +        int count = fGrammarRegistry.size() + (fNoNSGrammar==null ? 0 : 1);
  +        SchemaGrammar[] grammars = new SchemaGrammar[count];
  +        // get grammars with target namespace
  +        Enumeration enum = fGrammarRegistry.elements();
  +        int i = 0;
  +        while (enum.hasMoreElements())
  +            grammars[i++] = (SchemaGrammar)enum.nextElement();
  +        // add the grammar without target namespace, if any
  +        if (fNoNSGrammar != null)
  +            grammars[count-1] = fNoNSGrammar;
  +        return grammars;
       }
   
       /**
  
  
  
  1.3       +3 -3      xml-xerces/java/src/org/apache/xerces/impl/xs/models/CMBuilder.java
  
  Index: CMBuilder.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/models/CMBuilder.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- CMBuilder.java	2001/11/02 23:07:04	1.2
  +++ CMBuilder.java	2001/11/13 20:32:32	1.3
  @@ -70,7 +70,7 @@
    * This class constructs content models for a given grammar.
    *
    * @author Elena Litani, IBM
  - * @version $Id: CMBuilder.java,v 1.2 2001/11/02 23:07:04 sandygao Exp $
  + * @version $Id: CMBuilder.java,v 1.3 2001/11/13 20:32:32 sandygao Exp $
    */
   public class CMBuilder {
   
  @@ -471,7 +471,7 @@
           // We will build a node at this level for the new tree
           CMNode nodeRet = null;
           if (startNode.fType == XSParticleDecl.PARTICLE_WILDCARD) {
  -            nodeRet = new XSCMLeaf(XSParticleDecl.PARTICLE_WILDCARD, startNode.fValue, fLeafCount++);
  +            nodeRet = new XSCMLeaf(startNode, fLeafCount++);
           }
           //
           //  If this node is a leaf, then its an easy one. We just add it
  @@ -484,7 +484,7 @@
               //  storing it. This makes the positions zero based since we
               //  store first and then increment.
               //
  -            nodeRet = new XSCMLeaf(XSParticleDecl.PARTICLE_ELEMENT, startNode.fValue, fLeafCount++);
  +            nodeRet = new XSCMLeaf(startNode, fLeafCount++);
           }
           else {
               //
  
  
  
  1.2       +24 -1     xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSAllCM.java
  
  Index: XSAllCM.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSAllCM.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSAllCM.java	2001/10/25 20:36:03	1.1
  +++ XSAllCM.java	2001/11/13 20:32:32	1.2
  @@ -60,12 +60,14 @@
   import org.apache.xerces.xni.QName;
   import org.apache.xerces.impl.xs.XSElementDecl;
   import org.apache.xerces.impl.xs.SubstitutionGroupHandler;
  +import org.apache.xerces.impl.xs.XMLSchemaException;
  +import org.apache.xerces.impl.xs.XSConstraints;
   
   /**
    * XSAllCM implements XSCMValidator and handles <all>
    *
    * @author Pavani Mukthipudi, Sun Microsystems Inc.
  - * @version $Id: XSAllCM.java,v 1.1 2001/10/25 20:36:03 elena Exp $
  + * @version $Id: XSAllCM.java,v 1.2 2001/11/13 20:32:32 sandygao Exp $
    */
   public class XSAllCM implements XSCMValidator {
   
  @@ -235,6 +237,27 @@
   
           if (fNumRequired == numRequiredSeen ) {
               return true;
  +        }
  +
  +        return false;
  +    }
  +
  +    /**
  +     * check whether this content violates UPA constraint.
  +     *
  +     * @param errors to hold the UPA errors
  +     * @return true if this content model contains other or list wildcard
  +     */
  +    public boolean checkUniqueParticleAttribution(SubstitutionGroupHandler subGroupHandler) throws XMLSchemaException {
  +        // check whether there is conflict between any two leaves
  +        for (int i = 0; i < fNumElements; i++) {
  +            for (int j = i+1; j < fNumElements; j++) {
  +                if (XSConstraints.overlapUPA(fAllElements[i], fAllElements[j], subGroupHandler)) {
  +                    // REVISIT: do we want to report all errors? or just one?
  +                    throw new XMLSchemaException("cos-nonambig", new Object[]{fAllElements[i].toString(),
  +                                                                              fAllElements[j].toString()});
  +                }
  +            }
           }
   
           return false;
  
  
  
  1.2       +10 -23    xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSCMLeaf.java
  
  Index: XSCMLeaf.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSCMLeaf.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSCMLeaf.java	2001/10/25 20:36:03	1.1
  +++ XSCMLeaf.java	2001/11/13 20:32:32	1.2
  @@ -76,8 +76,8 @@
       // Data
       //
   
  -    /** This is the element that this leaf represents. */
  -    private Object fElement = null;
  +    /** This is the leaf particle. */
  +    private XSParticleDecl fLeaf = null;
   
       /**
        * Part of the algorithm to convert a regex directly to a DFA
  @@ -91,28 +91,25 @@
       //
   
       /** Constructs a content model leaf. */
  -    public XSCMLeaf(int type, Object element, int position)  {
  -        super(type);
  +    public XSCMLeaf(XSParticleDecl leaf, int position)  {
  +        super(leaf.fType);
   
           // Store the element index and position
  -        fElement = element;
  +        fLeaf = leaf;
           fPosition = position;
       }
   
       /** Constructs a content model leaf. */
  -    public XSCMLeaf(XSElementDecl element)  {
  -        super(XSParticleDecl.PARTICLE_ELEMENT);
  -
  -        // Store the element index and position
  -        fElement = element;
  +    public XSCMLeaf(XSParticleDecl leaf)  {
  +        this(leaf, -1);
       }
   
       //
       // Package methods
       //
   
  -    final Object getDecl() {
  -        return fElement;
  +    final XSParticleDecl getLeaf() {
  +        return fLeaf;
       }
   
       final int getPosition() {
  @@ -135,17 +132,7 @@
       }
   
       public String toString() {
  -        StringBuffer strRet = new StringBuffer(fElement.toString());
  -        strRet.append(" (");
  -        if(this.type() == XSParticleDecl.PARTICLE_ELEMENT) {
  -            strRet.append(((XSElementDecl)fElement).fTargetNamespace);
  -            strRet.append(',');
  -            strRet.append(((XSElementDecl)fElement).fName);
  -        } else {
  -            strRet.append("##any:uri=");
  -            strRet.append(((XSWildcardDecl)fElement).fNamespaceList[0]);
  -        }
  -        strRet.append(')');
  +        StringBuffer strRet = new StringBuffer(fLeaf.fValue.toString());
           if (fPosition >= 0) {
               strRet.append
               (
  
  
  
  1.2       +10 -1     xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSCMValidator.java
  
  Index: XSCMValidator.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSCMValidator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSCMValidator.java	2001/10/25 20:36:03	1.1
  +++ XSCMValidator.java	2001/11/13 20:32:32	1.2
  @@ -59,13 +59,14 @@
   
   import org.apache.xerces.xni.QName;
   import org.apache.xerces.impl.xs.SubstitutionGroupHandler;
  +import org.apache.xerces.impl.xs.XMLSchemaException;
   
   /**
    * Note: State of the content model is stored in the validator
    *
    * @author Sandy Gao, IBM
    * @author Elena Litani, IBM
  - * @version $Id: XSCMValidator.java,v 1.1 2001/10/25 20:36:03 elena Exp $
  + * @version $Id: XSCMValidator.java,v 1.2 2001/11/13 20:32:32 sandygao Exp $
    */
   public interface XSCMValidator {
   
  @@ -104,5 +105,13 @@
        * @return true if the last state was a valid final state
        */
       public boolean endContentModel (int[] state);
  +
  +    /**
  +     * check whether this content violates UPA constraint.
  +     *
  +     * @param errors to hold the UPA errors
  +     * @return true if this content model contains other or list wildcard
  +     */
  +    public boolean checkUniqueParticleAttribution(SubstitutionGroupHandler subGroupHandler) throws XMLSchemaException;
   
   } // XSCMValidator
  
  
  
  1.2       +86 -153   xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSDFACM.java
  
  Index: XSDFACM.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSDFACM.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSDFACM.java	2001/10/25 20:36:03	1.1
  +++ XSDFACM.java	2001/11/13 20:32:32	1.2
  @@ -65,6 +65,8 @@
   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.XMLSchemaException;
  +import org.apache.xerces.impl.xs.XSConstraints;
   
   /**
    * DFAContentModel is the implementation of XSCMValidator that does
  @@ -73,7 +75,7 @@
    * it then uses in its validation algorithm.
    *
    * @author Neil Graham, IBM
  - * @version $Id: XSDFACM.java,v 1.1 2001/10/25 20:36:03 elena Exp $
  + * @version $Id: XSDFACM.java,v 1.2 2001/11/13 20:32:32 sandygao Exp $
    */
   public class XSDFACM
       implements XSCMValidator {
  @@ -85,12 +87,6 @@
   
       // special strings
   
  -    /** Epsilon string. */
  -    private static final int EPSILON = -2;
  -
  -    /** End-of-content string. */
  -    private static final int EOC     = -3;
  -
       // debugging
   
       /** Set to true to debug content model validation. */
  @@ -107,7 +103,7 @@
        * actual validation.  Note tat since either XSElementDecl or XSParticleDecl object
        * can live here, we've got to use an Object.
        */
  -    private Object fElemMap[] = null;
  +    private XSParticleDecl fElemMap[] = null;
   
       /**
        * This is a map of whether the element map contains information
  @@ -126,7 +122,10 @@
        * the string pool. This is used as the special name of an element
        * that represents the end of the syntax tree.
        */
  -    private static String fEOCString = "<<CMNODE_EOC>>";
  +    private static final XSParticleDecl fEOCParticle = new XSParticleDecl();
  +    static {
  +        fEOCParticle.fType = XSParticleDecl.PARTICLE_ELEMENT;
  +    }
   
       /**
        * The NFA position of the special EOC (end of content) node. This
  @@ -135,13 +134,6 @@
       private int fEOCPos = 0;
   
       /**
  -     * The string index for the 'epsilon' string that we add to the
  -     * string pool. This represents epsilon node transitions in the
  -     * syntax tree.
  -     */
  -    private static String fEpsilonString = "<<CMNODE_EPSILON>>";
  -
  -    /**
        * This is an array of booleans, one per state (there are
        * fTransTableSize states in the DFA) that indicates whether that
        * state is a final state.
  @@ -210,15 +202,6 @@
   
       // temp variables
   
  -    /** Temporary element declaration. */
  -    private Object fElementDecl = new Object();
  -
  -    /** initializing static members **/
  -    static {
  -        fEpsilonString = fEpsilonString.intern();
  -        fEOCString = fEOCString.intern();
  -    }
  -
       //
       // Constructors
       //
  @@ -335,7 +318,7 @@
           for (; elemIndex < fElemMapSize; elemIndex++) {
               int type = fElemMapType[elemIndex] ;
               if (type == XSParticleDecl.PARTICLE_ELEMENT) {
  -                matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex]);
  +                matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex].fValue);
   
                   if (matchingDecl != null) {
                       nextState = fTransTable[curState][elemIndex];
  @@ -344,8 +327,8 @@
                   }
               }
               else if (type == XSParticleDecl.PARTICLE_WILDCARD) {
  -                if(((XSWildcardDecl)fElemMap[elemIndex]).allowNamespace(curElem.uri)) {
  -                    matchingDecl = fElemMap[elemIndex];
  +                if(((XSWildcardDecl)fElemMap[elemIndex].fValue).allowNamespace(curElem.uri)) {
  +                    matchingDecl = fElemMap[elemIndex].fValue;
                       nextState = fTransTable[curState][elemIndex];
                       if (nextState != -1)
                         break;
  @@ -370,14 +353,14 @@
           for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) {
               int type = fElemMapType[elemIndex] ;
               if (type == XSParticleDecl.PARTICLE_ELEMENT) {
  -                matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex]);
  +                matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex].fValue);
                   if (matchingDecl != null) {
                       return matchingDecl;
                   }
               }
               else if (type == XSParticleDecl.PARTICLE_WILDCARD) {
  -                if(((XSWildcardDecl)fElemMap[elemIndex]).allowNamespace(curElem.uri))
  -                    return fElemMap[elemIndex];
  +                if(((XSWildcardDecl)fElemMap[elemIndex].fValue).allowNamespace(curElem.uri))
  +                    return fElemMap[elemIndex].fValue;
               }
           }
   
  @@ -399,52 +382,6 @@
       // Killed off whatCanGoHere; we may need it for DOM canInsert(...) etc.,
       // but we can put it back later.
   
  -    // Unique Particle Attribution
  -    // REVISIT:  implement UPA!
  -    // store the conflict results between any two elements in fElemMap
  -    // -1: not compared; 0: no conflict; 1: conflict
  -    /******
  -    private byte fConflictTable[][];
  -
  -    // check UPA after build the DFA
  -    public void checkUniqueParticleAttribution(SchemaGrammar gram) {
  -        // rename back
  -        for (int i = 0; i < fElemMapSize; i++)
  -            fElemMap[i].uri = gram.getContentSpecOrgUri(fElemMap[i].uri);
  -
  -        // initialize the conflict table
  -        fConflictTable = new byte[fElemMapSize][fElemMapSize];
  -        for (int j = 0; j < fElemMapSize; j++) {
  -            for (int k = j+1; k < fElemMapSize; k++)
  -                fConflictTable[j][k] = -1;
  -        }
  -
  -        // for each state, check whether it has overlap transitions
  -        for (int i = 0; i < fTransTable.length && fTransTable[i] != null; i++) {
  -            for (int j = 0; j < fElemMapSize; j++) {
  -                for (int k = j+1; k < fElemMapSize; k++) {
  -                    if (fTransTable[i][j] != -1 &&
  -                        fTransTable[i][k] != -1) {
  -                        if (fConflictTable[j][k] == -1) {
  -                            fConflictTable[j][k] = ElementWildcard.conflict
  -                                                   (fElemMapType[j],
  -                                                    fElemMap[j].localpart,
  -                                                    fElemMap[j].uri,
  -                                                    fElemMapType[k],
  -                                                    fElemMap[k].localpart,
  -                                                    fElemMap[k].uri,
  -                                                    comparator) ? (byte)1 : (byte)0;
  -                        }
  -                    }
  -                }
  -            }
  -        }
  -
  -        fConflictTable = null;
  -    }
  -    // Unique Particle Attribution
  -    ******** End commented-out code *****/
  -
       //
       // Private methods
       //
  @@ -498,9 +435,7 @@
            * "(a, (b, a+, (c, (b, a+)+, a+, (d,  (c, (b, a+)+, a+)+, (b, a+)+, a+)+)+)+)+"
            */
   
  -        fElementDecl = new XSElementDecl();
  -        ((XSElementDecl)fElementDecl).fName = fEOCString;
  -        XSCMLeaf nodeEOC = new XSCMLeaf((XSElementDecl)fElementDecl);
  +        XSCMLeaf nodeEOC = new XSCMLeaf(fEOCParticle);
           fHeadNode = new XSCMBinOp(
           XSParticleDecl.PARTICLE_SEQUENCE
               , syntaxTree
  @@ -555,7 +490,7 @@
           //  input element. So we need to a zero based range of indexes that
           //  map to element types. This element map provides that mapping.
           //
  -        fElemMap = new Object [fLeafCount];
  +        fElemMap = new XSParticleDecl[fLeafCount];
           fElemMapType = new int[fLeafCount];
           fElemMapSize = 0;
           for (int outIndex = 0; outIndex < fLeafCount; outIndex++) {
  @@ -564,35 +499,10 @@
               fElemMap[outIndex] = null;
   
               int inIndex = 0;
  -            final Object decl = fLeafList[outIndex].getDecl();
  -            // REVISIT: shouldn't we always compare the decls by reference?
  -            //          if we ever combine two different element decls with
  -            //          the same name and namespace, then this content model
  -            //          violates UPA.
  -            //          Comparing by name/namespace was inherited from Xerces1,
  -            //          where we only store name and uri, and couldn't compare
  -            //          whether two decls are the same.
  -            //          After we support UPA, change the following big "if"
  -            //          to the following 4 lines.
  -            //for (; inIndex < fElemMapSize; inIndex++) {
  -            //    if (decl == fElemMap[inIndex])
  -            //        break;
  -            //}
  -            if (fLeafListType[outIndex] == XSParticleDecl.PARTICLE_WILDCARD) {
  -                for (; inIndex < fElemMapSize; inIndex++) {
  -                    if (decl == fElemMap[inIndex])
  -                        break;
  -                }
  -            } else {
  -                // Get the current leaf's element
  -                final XSElementDecl element = (XSElementDecl)decl;
  -                // See if the current leaf node's element index is in the list
  -                for (; inIndex < fElemMapSize; inIndex++) {
  -                    if (fElemMapType[inIndex] == fLeafListType[outIndex] &&
  -                        ((XSElementDecl)fElemMap[inIndex]).fTargetNamespace == element.fTargetNamespace &&
  -                        ((XSElementDecl)fElemMap[inIndex]).fName == element.fName)
  -                        break;
  -                }
  +            final XSParticleDecl decl = fLeafList[outIndex].getLeaf();
  +            for (; inIndex < fElemMapSize; inIndex++) {
  +                if (decl == fElemMap[inIndex])
  +                    break;
               }
   
               // If it was not in the list, then add it, if not the EOC node
  @@ -606,18 +516,11 @@
           // the last entry in the element map must be the EOC element.
           // remove it from the map.
           if (DEBUG) {
  -            if (((XSElementDecl)fElemMap[fElemMapSize-1]).fName != fEOCString)
  +            if (fElemMap[fElemMapSize-1] != fEOCParticle)
                   System.err.println("interal error in DFA: last element is not EOC.");
           }
           fElemMapSize--;
   
  -        // set up the fLeafNameTypeVector object if there is one.
  -        /**** but apparently there never will be since this was commented out for some reason...
  -        if (fLeafNameTypeVector != null) {
  -            fLeafNameTypeVector.setValues(fElemMap, fElemMapType, fElemMapSize);
  -        }
  -        ******/
  -
           /***
            * Optimization(Jan, 2001); We sort fLeafList according to
            * elemIndex which is *uniquely* associated to each leaf.
  @@ -628,33 +531,10 @@
           int fSortCount = 0;
   
           for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) {
  -            final Object decl = fElemMap[elemIndex];
  +            final XSParticleDecl decl = fElemMap[elemIndex];
               for (int leafIndex = 0; leafIndex < fLeafCount; leafIndex++) {
  -                // REVISIT: shouldn't we always compare the decls by reference?
  -                //          if we ever combine two different element decls with
  -                //          the same name and namespace, then this content model
  -                //          violates UPA.
  -                //          Comparing by name/namespace was inherited from Xerces1,
  -                //          where we only store name and uri, and couldn't compare
  -                //          whether two decls are the same.
  -                //          After we support UPA, change the following 2 "if"s
  -                //          to the following 2 lines.
  -                //if (decl == fLeafList[leafIndex].getDecl())
  -                //    fLeafSorter[fSortCount++] = leafIndex;
  -                if (fElemMapType[elemIndex] != fLeafListType[leafIndex])
  -                    continue;
  -
  -                if (fLeafListType[leafIndex] == XSParticleDecl.PARTICLE_WILDCARD) {
  -                    if (decl == fLeafList[leafIndex].getDecl())
  -                        fLeafSorter[fSortCount++] = leafIndex;
  -                } else {
  -                    final XSElementDecl leaf = (XSElementDecl)fLeafList[leafIndex].getDecl();
  -                    final XSElementDecl element = (XSElementDecl)decl;
  -                    if (leaf.fTargetNamespace == element.fTargetNamespace &&
  -                        leaf.fName == element.fName ) {
  -                        fLeafSorter[fSortCount++] = leafIndex;
  -                    }
  -                }
  +                if (decl == fLeafList[leafIndex].getLeaf())
  +                    fLeafSorter[fSortCount++] = leafIndex;
               }
               fLeafSorter[fSortCount++] = -1;
           }
  @@ -983,9 +863,9 @@
                   "Leaf: (pos="
                   + ((XSCMLeaf)nodeCur).getPosition()
                   + "), "
  -                + ((XSCMLeaf)nodeCur).getDecl()
  +                + ((XSCMLeaf)nodeCur).getLeaf().fValue
                   + "(elemIndex="
  -                + ((XSCMLeaf)nodeCur).getDecl()
  +                + ((XSCMLeaf)nodeCur).getLeaf().fValue
                   + ") "
               );
   
  @@ -1034,7 +914,6 @@
   
           // Recurse as required
           if (nodeCur.type() == XSParticleDecl.PARTICLE_WILDCARD) {
  -            fElementDecl = ((XSCMLeaf)nodeCur).getDecl();
               fLeafList[curIndex] = (XSCMLeaf)nodeCur;
               fLeafListType[curIndex] = XSParticleDecl.PARTICLE_WILDCARD;
               curIndex++;
  @@ -1056,12 +935,9 @@
               //  Put this node in the leaf list at the current index if its
               //  a non-epsilon leaf.
               //
  -            final XSElementDecl elementDecl = (XSElementDecl)((XSCMLeaf)nodeCur).getDecl();
  -            if (elementDecl.fName != fEpsilonString) {
  -                fLeafList[curIndex] = (XSCMLeaf)nodeCur;
  -                fLeafListType[curIndex] = XSParticleDecl.PARTICLE_ELEMENT;
  -                curIndex++;
  -            }
  +            fLeafList[curIndex] = (XSCMLeaf)nodeCur;
  +            fLeafListType[curIndex] = XSParticleDecl.PARTICLE_ELEMENT;
  +            curIndex++;
           }
            else
           {
  @@ -1070,5 +946,62 @@
           return curIndex;
       }
   
  +    /**
  +     * check whether this content violates UPA constraint.
  +     *
  +     * @param errors to hold the UPA errors
  +     * @return true if this content model contains other or list wildcard
  +     */
  +    public boolean checkUniqueParticleAttribution(SubstitutionGroupHandler subGroupHandler) throws XMLSchemaException {
  +        // Unique Particle Attribution
  +        // store the conflict results between any two elements in fElemMap
  +        // 0: not compared; -1: no conflict; 1: conflict
  +        // initialize the conflict table (all 0 initially)
  +        byte conflictTable[][] = new byte[fElemMapSize][fElemMapSize];
  +
  +        // for each state, check whether it has overlap transitions
  +        for (int i = 0; i < fTransTable.length && fTransTable[i] != null; i++) {
  +            for (int j = 0; j < fElemMapSize; j++) {
  +                for (int k = j+1; k < fElemMapSize; k++) {
  +                    if (fTransTable[i][j] != -1 &&
  +                        fTransTable[i][k] != -1) {
  +                        if (conflictTable[j][k] == 0) {
  +                            conflictTable[j][k] = XSConstraints.overlapUPA
  +                                                   (fElemMap[j].fValue,fElemMap[k].fValue,
  +                                                   subGroupHandler) ?
  +                                                   (byte)1 : (byte)-1;
  +                        }
  +                    }
  +                }
  +            }
  +        }
  +
  +        // report all errors
  +        for (int i = 0; i < fElemMapSize; i++) {
  +            for (int j = 0; j < fElemMapSize; j++) {
  +                if (conflictTable[i][j] == 1) {
  +                    //errors.newError("cos-nonambig", new Object[]{fElemMap[i].toString(),
  +                    //                                             fElemMap[j].toString()});
  +                    // REVISIT: do we want to report all errors? or just one?
  +                    throw new XMLSchemaException("cos-nonambig", new Object[]{fElemMap[i].toString(),
  +                                                                              fElemMap[j].toString()});
  +                }
  +            }
  +        }
  +
  +        // if there is a other or list wildcard, we need to check this CM
  +        // again, if this grammar is cached.
  +        for (int i = 0; i < fElemMapSize; i++) {
  +            if (fElemMapType[i] == XSParticleDecl.PARTICLE_WILDCARD) {
  +                XSWildcardDecl wildcard = (XSWildcardDecl)fElemMap[i].fValue;
  +                if (wildcard.fType == XSWildcardDecl.WILDCARD_LIST ||
  +                    wildcard.fType == XSWildcardDecl.WILDCARD_OTHER) {
  +                    return true;
  +                }
  +            }
  +        }
  +
  +        return false;
  +    }
   
   } // class DFAContentModel
  
  
  
  1.2       +10 -0     xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSEmptyCM.java
  
  Index: XSEmptyCM.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSEmptyCM.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSEmptyCM.java	2001/10/25 20:36:03	1.1
  +++ XSEmptyCM.java	2001/11/13 20:32:32	1.2
  @@ -59,6 +59,7 @@
   
   import org.apache.xerces.xni.QName;
   import org.apache.xerces.impl.xs.SubstitutionGroupHandler;
  +import org.apache.xerces.impl.xs.XMLSchemaException;
   
   /**
    * XSEmptyCM is a derivative of the abstract content model base class that
  @@ -138,5 +139,14 @@
           return true;
       }
   
  +    /**
  +     * check whether this content violates UPA constraint.
  +     *
  +     * @param errors to hold the UPA errors
  +     * @return true if this content model contains other or list wildcard
  +     */
  +    public boolean checkUniqueParticleAttribution(SubstitutionGroupHandler subGroupHandler) throws XMLSchemaException {
  +        return false;
  +    }
   
   } // class XSEmptyCM
  
  
  
  1.2       +21 -1     xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSSimpleCM.java
  
  Index: XSSimpleCM.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSSimpleCM.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XSSimpleCM.java	2001/10/25 20:36:03	1.1
  +++ XSSimpleCM.java	2001/11/13 20:32:32	1.2
  @@ -61,6 +61,8 @@
   import org.apache.xerces.impl.xs.SubstitutionGroupHandler;
   import org.apache.xerces.impl.xs.XSParticleDecl;
   import org.apache.xerces.impl.xs.XSElementDecl;
  +import org.apache.xerces.impl.xs.XMLSchemaException;
  +import org.apache.xerces.impl.xs.XSConstraints;
   
   /**
    * XSSimpleCM is a derivative of the abstract content model base
  @@ -84,7 +86,7 @@
    * This model validated on the way in.
    *
    * @author Elena Litani, IBM
  - * @version $Id: XSSimpleCM.java,v 1.1 2001/10/25 20:36:03 elena Exp $
  + * @version $Id: XSSimpleCM.java,v 1.2 2001/11/13 20:32:32 sandygao Exp $
    */
   public class XSSimpleCM
   implements XSCMValidator {
  @@ -285,5 +287,23 @@
           return isFinal;
       }
   
  +    /**
  +     * check whether this content violates UPA constraint.
  +     *
  +     * @param errors to hold the UPA errors
  +     * @return true if this content model contains other or list wildcard
  +     */
  +    public boolean checkUniqueParticleAttribution(SubstitutionGroupHandler subGroupHandler) throws XMLSchemaException{
  +        if (fOperator == XSParticleDecl.PARTICLE_CHOICE) {
  +            // only when it's a choice, and the two elements overlap,
  +            // is it a UPA violation.
  +            if (XSConstraints.overlapUPA(fFirstElement, fSecondElement, subGroupHandler)) {
  +                throw new XMLSchemaException("cos-nonambig", new Object[]{fFirstElement.toString(),
  +                                                                          fSecondElement.toString()});
  +            }
  +        }
  +
  +        return false;
  +    }
   
   } // class XSSimpleCM
  
  
  

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