You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by er...@locus.apache.org on 2000/07/14 05:53:46 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/validators/common DFAContentModel.java MixedContentModel.java SimpleContentModel.java XMLContentModel.java XMLValidator.java

ericye      00/07/13 20:53:46

  Modified:    java/src/org/apache/xerces/validators/common
                        DFAContentModel.java MixedContentModel.java
                        SimpleContentModel.java XMLContentModel.java
                        XMLValidator.java
  Log:
  Added full equivClass support in Content Models and validation
  --ericye
  
  Revision  Changes    Path
  1.10      +113 -5    xml-xerces/java/src/org/apache/xerces/validators/common/DFAContentModel.java
  
  Index: DFAContentModel.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/validators/common/DFAContentModel.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- DFAContentModel.java	2000/06/30 01:10:59	1.9
  +++ DFAContentModel.java	2000/07/14 03:53:43	1.10
  @@ -60,6 +60,7 @@
   import org.apache.xerces.framework.XMLContentSpec;
   import org.apache.xerces.utils.ImplementationMessages;
   import org.apache.xerces.utils.QName;
  +import org.apache.xerces.validators.schema.EquivClassComparator;
   //import org.apache.xerces.utils.StringPool;
   
   /**
  @@ -74,7 +75,7 @@
    * are very constrained in form and easily handled via a special case. 
    * This also makes implementation of this class much easier.
    *
  - * @version $Id: DFAContentModel.java,v 1.9 2000/06/30 01:10:59 ericye Exp $
  + * @version $Id: DFAContentModel.java,v 1.10 2000/07/14 03:53:43 ericye Exp $
    */
   public class DFAContentModel 
       implements XMLContentModel {
  @@ -101,6 +102,9 @@
       // Data
       //
   
  +    /* this is the EquivClassComparator object */
  +    private EquivClassComparator comparator = null;
  +
       /**
        * This is the map of unique input symbol elements to indices into
        * each state's per-input symbol transition table entry. This is part
  @@ -356,7 +360,8 @@
               {
                   int type = fElemMapType[elemIndex];
                   if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  -                    if (isEqual(fElemMap[elemIndex], curElem))
  +                    if (fElemMap[elemIndex].uri==curElem.uri
  +                         && fElemMap[elemIndex].localpart == curElem.localpart)
                           break;
                   }
                   else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
  @@ -421,14 +426,117 @@
       }
   
       private boolean isEqual(QName name1, QName name2) {
  -        if (name1 != null && name2 != null) {
  -                
               return name1.localpart == name2.localpart &&
                   name1.uri == name2.uri;
  +    }
  +    
  +    public int validateContentSpecial(QName children[], int offset, int length) throws Exception{
  +        if (DEBUG_VALIDATE_CONTENT) 
  +            System.out.println("DFAContentModel#validateContentSpecial");
   
  +        if (comparator==null) {
  +            return validateContent(children,offset, length);
           }
  -        return false;
   
  +
  +        if (length == 0) {
  +            if (DEBUG_VALIDATE_CONTENT) {
  +                System.out.println("!!! no children");
  +                System.out.println("elemMap="+fElemMap);
  +                for (int i = 0; i < fElemMap.length; i++) {
  +                    int uriIndex = fElemMap[i].uri;
  +                    int localpartIndex = fElemMap[i].localpart;
  +                }
  +                System.out.println("EOCIndex="+fEOCIndex);
  +            }
  +
  +            return fEmptyContentIsValid ? -1 : 0;
  +
  +        } // if child count == 0
  +
  +        //
  +        //  Lets loop through the children in the array and move our way
  +        //  through the states. Note that we use the fElemMap array to map
  +        //  an element index to a state index.
  +        //
  +        int curState = 0;
  +        for (int childIndex = 0; childIndex < length; childIndex++)
  +        {
  +            // Get the current element index out
  +            final QName curElem = children[offset + childIndex];
  +
  +            // Look up this child in our element map
  +            int elemIndex = 0;
  +            for (; elemIndex < fElemMapSize; elemIndex++)
  +            {
  +                int type = fElemMapType[elemIndex];
  +                if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  +                    if (comparator.isEquivalentTo(curElem,fElemMap[elemIndex] ) )
  +                        break;
  +                }
  +                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
  +                    int uri = fElemMap[elemIndex].uri;
  +                    if (uri == -1 || uri == curElem.uri) {
  +                        break;
  +                    }
  +                }
  +                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
  +                    if (curElem.uri == -1) {
  +                        break;
  +                    }
  +                }
  +                else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
  +                    if (fElemMap[elemIndex].uri != curElem.uri) {
  +                        break;
  +                    }
  +                }
  +            }
  +
  +            // If we didn't find it, then obviously not valid
  +            if (elemIndex == fElemMapSize) {
  +                if (!DEBUG_VALIDATE_CONTENT) {
  +                    System.out.println("!!! didn't find it");
  +
  +                    System.out.println("curElem : " +curElem );
  +                    for (int i=0; i<fElemMapSize; i++) {
  +                        System.out.println("fElemMap["+i+"] = " +fElemMap[i] );
  +                        System.out.println("fElemMapType["+i+"] = " +fElemMapType[i] );
  +                    }
  +                }
  +
  +                return childIndex;
  +            }
  +
  +            //
  +            //  Look up the next state for this input symbol when in the
  +            //  current state.
  +            //
  +            curState = fTransTable[curState][elemIndex];
  +
  +            // If its not a legal transition, then invalid
  +            if (curState == -1) {
  +                if (DEBUG_VALIDATE_CONTENT) 
  +                    System.out.println("!!! not a legal transition");
  +                return childIndex;
  +            }
  +        }
  +
  +        //
  +        //  We transitioned all the way through the input list. However, that
  +        //  does not mean that we ended in a final state. So check whether
  +        //  our ending state is a final state.
  +        //
  +        if (DEBUG_VALIDATE_CONTENT) 
  +            System.out.println("curState="+curState+", childCount="+length);
  +        if (!fFinalStateFlags[curState])
  +            return length;
  +
  +        // success!
  +        return -1;
  +    }
  +
  +    public void setEquivClassComparator(EquivClassComparator comparator) {
  +        this.comparator = comparator;
       }
   
       /**
  
  
  
  1.5       +14 -1     xml-xerces/java/src/org/apache/xerces/validators/common/MixedContentModel.java
  
  Index: MixedContentModel.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/validators/common/MixedContentModel.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- MixedContentModel.java	2000/06/16 18:13:34	1.4
  +++ MixedContentModel.java	2000/07/14 03:53:43	1.5
  @@ -59,6 +59,7 @@
   
   import org.apache.xerces.framework.XMLContentSpec;
   import org.apache.xerces.utils.QName;
  +import org.apache.xerces.validators.schema.EquivClassComparator;
   
   /**
    * MixedContentModel is a derivative of the abstract content model base
  @@ -73,7 +74,7 @@
    * validate by just looking up each child being validated by looking it up
    * in the list.
    *
  - * @version $Id: MixedContentModel.java,v 1.4 2000/06/16 18:13:34 andyc Exp $
  + * @version $Id: MixedContentModel.java,v 1.5 2000/07/14 03:53:43 ericye Exp $
    */
   public class MixedContentModel 
       implements XMLContentModel {
  @@ -92,6 +93,9 @@
       /** The type of the children to support ANY. */
       private int fChildrenType[];
   
  +    /* this is the EquivClassComparator object */
  +    private EquivClassComparator comparator = null;
  +    
       /** 
        * True if mixed content model is ordered. DTD mixed content models
        * are <em>always</em> unordered.
  @@ -266,6 +270,15 @@
           // Everything seems to be in order, so return success
           return -1;
   
  +    }
  +
  +    public int validateContentSpecial(QName children[], int offset, int length) throws Exception{
  +         //TO DO here. cause Mixed Content is only for DTD, Schema is kind of different.
  +            return validateContent(children,offset, length);
  +    }
  +
  +    public void setEquivClassComparator(EquivClassComparator comparator) {
  +        this.comparator = comparator;
       }
   
       /**
  
  
  
  1.7       +149 -1    xml-xerces/java/src/org/apache/xerces/validators/common/SimpleContentModel.java
  
  Index: SimpleContentModel.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/validators/common/SimpleContentModel.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- SimpleContentModel.java	2000/06/23 17:29:44	1.6
  +++ SimpleContentModel.java	2000/07/14 03:53:43	1.7
  @@ -61,6 +61,8 @@
   import org.apache.xerces.utils.ImplementationMessages;
   import org.apache.xerces.utils.QName;
   
  +import org.apache.xerces.validators.schema.EquivClassComparator;
  +
   /**
    * SimpleContentModel is a derivative of the abstract content model base
    * class that handles a small set of simple content models that are just
  @@ -81,7 +83,7 @@
    * in a simple way without a DFA and without the overhead of setting up a
    * DFA for such a simple check.
    *
  - * @version $Id: SimpleContentModel.java,v 1.6 2000/06/23 17:29:44 andyc Exp $
  + * @version $Id: SimpleContentModel.java,v 1.7 2000/07/14 03:53:43 ericye Exp $
    */
   public class SimpleContentModel 
       implements XMLContentModel {
  @@ -112,6 +114,9 @@
        */
       private int fOp;
   
  +    /* this is the EquivClassComparator object */
  +    private EquivClassComparator comparator = null;
  +    
       //
       // Constructors
       //
  @@ -298,6 +303,149 @@
   
           // We survived, so return success status
           return -1;
  +    }
  +    
  +    public int validateContentSpecial(QName children[], int offset, int length) throws Exception{
  +
  +        if (comparator==null) {
  +            return validateContent(children,offset, length);
  +        }
  +        //
  +        //  According to the type of operation, we do the correct type of
  +        //  content check.
  +        //
  +        switch(fOp)
  +        {
  +            case XMLContentSpec.CONTENTSPECNODE_LEAF :
  +                // If there is not a child, then report an error at index 0
  +                if (length == 0)
  +                    return 0;
  +
  +                // If the 0th child is not the right kind, report an error at 0
  +                if (children[offset].uri != fFirstChild.uri || 
  +                    children[offset].localpart != fFirstChild.localpart)
  +                    if (!comparator.isEquivalentTo(children[offset], fFirstChild)) 
  +                        return 0;
  +
  +                // If more than one child, report an error at index 1
  +                if (length > 1)
  +                    return 1;
  +                break;
  +
  +            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE :
  +                //
  +                //  If there is one child, make sure its the right type. If not,
  +                //  then its an error at index 0.
  +                //
  +                if (length == 1 && 
  +                    (children[offset].uri != fFirstChild.uri || 
  +                     children[offset].localpart != fFirstChild.localpart))
  +                    if (!comparator.isEquivalentTo(children[offset], fFirstChild)) 
  +                        return 0;
  +
  +                //
  +                //  If the child count is greater than one, then obviously
  +                //  bad, so report an error at index 1.
  +                //
  +                if (length > 1)
  +                    return 1;
  +                break;
  +
  +            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE :
  +                //
  +                //  If the child count is zero, that's fine. If its more than
  +                //  zero, then make sure that all children are of the element
  +                //  type that we stored. If not, report the index of the first
  +                //  failed one.
  +                //
  +                if (length > 0)
  +                {
  +                    for (int index = 0; index < length; index++)
  +                    {
  +                        if (children[offset + index].uri != fFirstChild.uri || 
  +                            children[offset + index].localpart != fFirstChild.localpart)
  +                            if (!comparator.isEquivalentTo(children[offset+index], fFirstChild)) 
  +                                return index;
  +                    }
  +                }
  +                break;
  +
  +            case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE :
  +                //
  +                //  If the child count is zero, that's an error so report
  +                //  an error at index 0.
  +                //
  +                if (length == 0)
  +                    return 0;
  +
  +                //
  +                //  Otherwise we have to check them all to make sure that they
  +                //  are of the correct child type. If not, then report the index
  +                //  of the first one that is not.
  +                //
  +                for (int index = 0; index < length; index++)
  +                {
  +                    if (children[offset + index].uri != fFirstChild.uri || 
  +                        children[offset + index].localpart != fFirstChild.localpart)
  +                        if (!comparator.isEquivalentTo(children[offset+index], fFirstChild)) 
  +                            return index;
  +                }
  +                break;
  +
  +            case XMLContentSpec.CONTENTSPECNODE_CHOICE :
  +                //
  +                //  There must be one and only one child, so if the element count
  +                //  is zero, return an error at index 0.
  +                //
  +                if (length == 0)
  +                    return 0;
  +
  +                // If the zeroth element isn't one of our choices, error at 0
  +                if ((children[offset].uri != fFirstChild.uri || children[offset].localpart != fFirstChild.localpart) &&
  +                    (children[offset].uri != fSecondChild.uri || children[offset].localpart != fSecondChild.localpart))
  +                    if (   !comparator.isEquivalentTo(children[offset], fFirstChild) 
  +                        && !comparator.isEquivalentTo(children[offset], fSecondChild) ) 
  +                        return 0;
  +
  +                // If there is more than one element, then an error at 1
  +                if (length > 1)
  +                    return 1;
  +                break;
  +
  +            case XMLContentSpec.CONTENTSPECNODE_SEQ :
  +                //
  +                //  There must be two children and they must be the two values
  +                //  we stored, in the stored order.
  +                //
  +                if (length == 2) {
  +                    if (children[offset].uri != fFirstChild.uri || children[offset].localpart != fFirstChild.localpart)
  +                        if (!comparator.isEquivalentTo(children[offset], fFirstChild)) 
  +                            return 0;
  +
  +                    if (children[offset + 1].uri != fSecondChild.uri || children[offset + 1].localpart != fSecondChild.localpart)
  +                        if (!comparator.isEquivalentTo(children[offset+1], fSecondChild)) 
  +                            return 1;
  +                }
  +                else {
  +                    if (length > 2) {
  +                        return 2;
  +                    }
  +
  +                    return length;
  +                }
  +
  +                break;
  +
  +            default :
  +                throw new CMException(ImplementationMessages.VAL_CST);
  +        }
  +
  +        // We survived, so return success status
  +        return -1;
  +    }
  +
  +    public void setEquivClassComparator(EquivClassComparator comparator) {
  +        this.comparator = comparator;
       }
   
       /**
  
  
  
  1.4       +37 -2     xml-xerces/java/src/org/apache/xerces/validators/common/XMLContentModel.java
  
  Index: XMLContentModel.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/validators/common/XMLContentModel.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XMLContentModel.java	2000/05/19 02:27:21	1.3
  +++ XMLContentModel.java	2000/07/14 03:53:44	1.4
  @@ -58,6 +58,7 @@
   package org.apache.xerces.validators.common;
   
   import org.apache.xerces.utils.QName;
  +import org.apache.xerces.validators.schema.EquivClassComparator;
   
   /**
    * ContentModel is an interface that can be used by your own custom validators
  @@ -76,8 +77,8 @@
    * model to be validated. Therefore the validateContent() method accepts
    * this standard view of the elements to be validated.
    *
  - * @author  Dean Roddey
  - * @version $Id: XMLContentModel.java,v 1.3 2000/05/19 02:27:21 andyc Exp $
  + * @author  Dean Roddey, Eric Ye
  + * @version $Id: XMLContentModel.java,v 1.4 2000/07/14 03:53:44 ericye Exp $
    */
   public interface XMLContentModel {
   
  @@ -106,6 +107,40 @@
        * @exception Exception Thrown on error.
        */
       public int validateContent(QName children[], int offset, int length) throws Exception;
  +
  +    /**
  +     * This method is different from "validateContent" in that it will try to use
  +     * the EquivClassComparator to match children against the content model.
  +     * <p>
  +     * A value of -1 in the children array indicates a PCDATA node. All other 
  +     * indexes will be positive and represent child elements. The count can be
  +     * zero, since some elements have the EMPTY content model and that must be 
  +     * confirmed.
  +     *
  +     * @param children The children of this element.  Each integer is an index within
  +     *                 the <code>StringPool</code> of the child element name.  An index
  +     *                 of -1 is used to indicate an occurrence of non-whitespace character
  +     *                 data.
  +     * @param offset Offset into the array where the children starts.
  +     * @param length The number of entries in the <code>children</code> array.
  +     *
  +     * @return The value -1 if fully valid, else the 0 based index of the child
  +     *         that first failed. If the value returned is equal to the number
  +     *         of children, then the specified children are valid but additional
  +     *         content is required to reach a valid ending state.
  +     *
  +     * @exception Exception Thrown on error.
  +     */
  +    public int validateContentSpecial(QName children[], int offset, int length) throws Exception;
  +
  +    /**
  +     * The setter method to pass in the EquivCLassComparator.
  +     *
  +     * @param comparator a EquivClassComparator object.
  +     * @return 
  +     * @exception 
  +     */
  +    public void setEquivClassComparator(EquivClassComparator comparator);// should really use a Comparator interface
   
       /**
        * Returns information about which elements can be placed at a particular point
  
  
  
  1.43      +10 -48    xml-xerces/java/src/org/apache/xerces/validators/common/XMLValidator.java
  
  Index: XMLValidator.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/validators/common/XMLValidator.java,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- XMLValidator.java	2000/07/07 23:35:35	1.42
  +++ XMLValidator.java	2000/07/14 03:53:44	1.43
  @@ -94,6 +94,7 @@
   
   import org.apache.xerces.validators.dtd.DTDGrammar;
   
  +import org.apache.xerces.validators.schema.EquivClassComparator;
   import org.apache.xerces.validators.schema.SchemaGrammar;
   import org.apache.xerces.validators.schema.SchemaMessageProvider;
   import org.apache.xerces.validators.schema.SchemaSymbols;
  @@ -105,7 +106,7 @@
   /**
    * This class is the super all-in-one validator used by the parser.
    *
  - * @version $Id: XMLValidator.java,v 1.42 2000/07/07 23:35:35 ericye Exp $
  + * @version $Id: XMLValidator.java,v 1.43 2000/07/14 03:53:44 ericye Exp $
    */
   public final class XMLValidator
       implements DefaultEntityHandler.EventHandler,
  @@ -2719,7 +2720,14 @@
               XMLContentModel cmElem = null;
               try {
                   cmElem = getContentModel(elementIndex);
  -                return cmElem.validateContent(children, childOffset, childCount);
  +                int result = cmElem.validateContent(children, childOffset, childCount);
  +                if (result != -1 && fGrammarIsSchemaGrammar) {
  +                    // REVISIT: not optimized for performance, 
  +                    EquivClassComparator comparator = new EquivClassComparator(fGrammarResolver, fStringPool);
  +                    cmElem.setEquivClassComparator(comparator);
  +                    result = cmElem.validateContentSpecial(children, childOffset, childCount);
  +                }
  +                return result;
               }
               catch(CMException excToCatch) {
                   // REVISIT - Translate the caught exception to the protected error API
  @@ -2769,52 +2777,6 @@
                                              new Object [] { idve.getMessage() },
                                              XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
               }
  -            /*
  -            boolean DEBUG_DATATYPES = false;
  -            if (DEBUG_DATATYPES) {
  -                System.out.println("Checking content of datatype");
  -                String strTmp = fStringPool.toString(elementTypeIndex);
  -                int contentSpecIndex = fElementDeclPool.getContentSpec(elementIndex);
  -                XMLContentSpec csn = new XMLContentSpec();
  -                fElementDeclPool.getContentSpecNode(contentSpecIndex, csn);
  -                String contentSpecString = fStringPool.toString(csn.value);
  -                System.out.println
  -                (
  -                    "Name: "
  -                    + strTmp
  -                    + ", Count: "
  -                    + childCount
  -                    + ", ContentSpec: "
  -                    + contentSpecString
  -                );
  -                for (int index = 0; index < childCount && index < 10; index++) {
  -                    if (index == 0) System.out.print("  (");
  -                    String childName = (children[index] == -1) ? "#PCDATA" : fStringPool.toString(children[index]);
  -                    if (index + 1 == childCount)
  -                        System.out.println(childName + ")");
  -                    else if (index + 1 == 10)
  -                        System.out.println(childName + ",...)");
  -                    else
  -                        System.out.print(childName + ",");
  -                }
  -            }
  -            try { // REVISIT - integrate w/ error handling
  -                int contentSpecIndex = fElementDeclPool.getContentSpec(elementIndex);
  -                XMLContentSpec csn = new XMLContentSpec();
  -                fElementDeclPool.getContentSpecNode(contentSpecIndex, csn);
  -                String type = fStringPool.toString(csn.value);
  -                DatatypeValidator v = fDatatypeRegistry.getValidatorFor(type);
  -                if (v != null)
  -                    v.validate(fDatatypeBuffer.toString());
  -                else
  -                    System.out.println("No validator for datatype "+type);
  -            } catch (InvalidDatatypeValueException idve) {
  -                System.out.println("Incorrect datatype: "+idve.getMessage());
  -            } catch (Exception e) {
  -                e.printStackTrace();
  -                System.out.println("Internal error in datatype validation");
  -            }
  -            */
           }
           else {
               fErrorReporter.reportError(fErrorReporter.getLocator(),