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(),