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 2002/04/27 00:03:43 UTC
cvs commit: xml-xerces/java/src/org/apache/xerces/impl/xs/traversers XSDAbstractParticleTraverser.java XSDComplexTypeTraverser.java XSDGroupTraverser.java
sandygao 02/04/26 15:03:43
Modified: java/src/org/apache/xerces/impl/xs SchemaGrammar.java
XMLSchemaValidator.java XSConstraints.java
XSDeclarationPool.java XSGroupDecl.java
XSParticleDecl.java
java/src/org/apache/xerces/impl/xs/models CMBuilder.java
XSCMBinOp.java XSCMLeaf.java XSDFACM.java
java/src/org/apache/xerces/impl/xs/traversers
XSDAbstractParticleTraverser.java
XSDComplexTypeTraverser.java XSDGroupTraverser.java
Added: java/src/org/apache/xerces/impl/xs XSModelGroup.java
Removed: java/src/org/apache/xerces/impl/xs/models XSSimpleCM.java
Log:
Many files are modified, mainly for reason 1 listed below. The other problems
are discovered and solved during this big change.
1. Use separate classes to represent "model group" and "particle";
2. Removed the simple content model, because it's not simpler than DFA
3. Rewrite the why how syntax tree is created: we only go through the tree
once, and create the CM tree at the same time, instead of creating a temprory
particle tree, then traverse it and create the CM tree;
4. Improved how UPA is checked in DFA: avoid cloning particles, but use
some distinct integer to differentiate leaf particles.
5. Fixed a bug in particle derivation: all/sequence/choice restricting wildcard.
Revision Changes Path
1.17 +19 -10 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.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- SchemaGrammar.java 24 Apr 2002 15:04:32 -0000 1.16
+++ SchemaGrammar.java 26 Apr 2002 22:03:42 -0000 1.17
@@ -82,7 +82,7 @@
* @author Sandy Gao, IBM
* @author Elena Litani, IBM
*
- * @version $Id: SchemaGrammar.java,v 1.16 2002/04/24 15:04:32 sandygao Exp $
+ * @version $Id: SchemaGrammar.java,v 1.17 2002/04/26 22:03:42 sandygao Exp $
*/
public class SchemaGrammar implements Grammar {
@@ -143,16 +143,16 @@
*/
protected SchemaGrammar(int grammar) {
SchemaDVFactory schemaFactory = SchemaDVFactory.getInstance();
-
+
if (grammar == GRAMMAR_XS) {
// target namespace
fTargetNamespace = SchemaSymbols.URI_SCHEMAFORSCHEMA;
-
+
// grammar description
fGrammarDescription = new XSDDescription();
fGrammarDescription.fContextType = XSDDescription.CONTEXT_PREPARSE;
fGrammarDescription.fTargetNamespace = SchemaSymbols.URI_SCHEMAFORSCHEMA;
-
+
// no global decls other than types
fGlobalAttrDecls = new SymbolHash(1);
fGlobalAttrGrpDecls = new SymbolHash(1);
@@ -160,7 +160,7 @@
fGlobalGroupDecls = new SymbolHash(1);
fGlobalNotationDecls = new SymbolHash(1);
fGlobalIDConstraintDecls = new SymbolHash(1);
-
+
// get all built-in types
fGlobalTypeDecls = schemaFactory.getBuiltInTypes();
// add anyType
@@ -169,7 +169,6 @@
else if (grammar == GRAMMAR_XSI) {
// target namespace
fTargetNamespace = SchemaSymbols.URI_XSI;
-
// grammar description
fGrammarDescription = new XSDDescription();
fGrammarDescription.fContextType = XSDDescription.CONTEXT_PREPARSE;
@@ -483,18 +482,28 @@
fAnyType.fBaseType = fAnyType;
fAnyType.fDerivedBy = SchemaSymbols.RESTRICTION;
fAnyType.fContentType = XSComplexTypeDecl.CONTENTTYPE_MIXED;
- XSWildcardDecl wildcard = new XSWildcardDecl();
+
+ // the wildcard used in anyType (content and attribute)
// the spec will change strict to lax for anyType
+ XSWildcardDecl wildcard = new XSWildcardDecl();
wildcard.fProcessContents = SchemaSymbols.ANY_LAX;
+ // the particle for the content wildcard
XSParticleDecl particleW = new XSParticleDecl();
particleW.fMinOccurs = 0;
particleW.fMaxOccurs = SchemaSymbols.OCCURRENCE_UNBOUNDED;
particleW.fType = XSParticleDecl.PARTICLE_WILDCARD;
particleW.fValue = wildcard;
+ // the model group of a sequence of the above particle
+ XSModelGroup group = new XSModelGroup();
+ group.fCompositor = XSModelGroup.MODELGROUP_SEQUENCE;
+ group.fParticleCount = 1;
+ group.fParticles = new XSParticleDecl[1];
+ group.fParticles[0] = particleW;
+ // the content of anyType: particle of the above model group
XSParticleDecl particleG = new XSParticleDecl();
- particleG.fType = XSParticleDecl.PARTICLE_SEQUENCE;
- particleG.fValue = particleW;
- particleG.fOtherValue = null;
+ particleG.fType = XSParticleDecl.PARTICLE_MODELGROUP;
+ particleG.fValue = group;
+
fAnyType.fParticle = particleG;
fAnyType.fAttrGrp.fAttributeWC = wildcard;
}
1.57 +0 -5 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.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- XMLSchemaValidator.java 26 Apr 2002 21:30:57 -0000 1.56
+++ XMLSchemaValidator.java 26 Apr 2002 22:03:42 -0000 1.57
@@ -141,7 +141,7 @@
* @author Elena Litani IBM
* @author Andy Clark IBM
* @author Neeraj Bajaj, Sun Microsystems, inc.
- * @version $Id: XMLSchemaValidator.java,v 1.56 2002/04/26 21:30:57 sandygao Exp $
+ * @version $Id: XMLSchemaValidator.java,v 1.57 2002/04/26 22:03:42 sandygao Exp $
*/
public class XMLSchemaValidator
implements XMLComponent, XMLDocumentFilter, FieldActivator {
@@ -2395,11 +2395,6 @@
reportSchemaError("cvc-elt.3.2.2", new Object[]{element.rawname, URI_XSI+","+XSI_NIL});
}
}
- // REVISIT: report an error for invalid boolean value?
- //else if (!value.equals(SchemaSymbols.ATTVAL_FALSE) &&
- // !value.equals(SchemaSymbols.ATTVAL_FALSE_0)) {
- // reportSchemaError("cvc-elt.3.2", new Object[]{element.rawname, URI_XSI+","+XSI_NIL, xsiNil});
- //}
}
}
1.20 +81 -81 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.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- XSConstraints.java 22 Apr 2002 13:26:35 -0000 1.19
+++ XSConstraints.java 26 Apr 2002 22:03:42 -0000 1.20
@@ -74,7 +74,7 @@
*
* @author Sandy Gao, IBM
*
- * @version $Id: XSConstraints.java,v 1.19 2002/04/22 13:26:35 sandygao Exp $
+ * @version $Id: XSConstraints.java,v 1.20 2002/04/26 22:03:42 sandygao Exp $
*/
public class XSConstraints {
@@ -338,6 +338,10 @@
SGHandler.addSubstitutionGroup(grammars[i].getSubstitutionGroups());
}
+ XSParticleDecl fakeDerived = new XSParticleDecl();
+ XSParticleDecl fakeBase = new XSParticleDecl();
+ fakeDerived.fType = XSParticleDecl.PARTICLE_MODELGROUP;
+ fakeBase.fType = XSParticleDecl.PARTICLE_MODELGROUP;
// before worrying about complexTypes, let's get
// groups redefined by restriction out of the way.
for (int g = grammars.length-1; g >= 0; g--) {
@@ -345,19 +349,20 @@
SimpleLocator [] rgLocators = grammars[g].getRGLocators();
for(int i=0; i<redefinedGroups.length; ) {
XSGroupDecl derivedGrp = redefinedGroups[i++];
- XSParticleDecl derivedParticle = derivedGrp.fParticle;
+ XSModelGroup derivedMG = derivedGrp.fModelGroup;
XSGroupDecl baseGrp = redefinedGroups[i++];
- XSParticleDecl baseParticle = baseGrp.fParticle;
- if(baseParticle == null) {
- if(derivedParticle != null) { // can't be a restriction!
+ XSModelGroup baseMG = baseGrp.fModelGroup;
+ if(baseMG == null) {
+ if(derivedMG != null) { // can't be a restriction!
reportSchemaError(errorReporter, rgLocators[i/2-1],
"src-redefine.6.2.2",
new Object[]{derivedGrp.fName, "rcase-Recurse.2"});
}
} else {
+ fakeDerived.fValue = derivedMG;
+ fakeBase.fValue = baseMG;
try {
- particleValidRestriction(SGHandler,
- derivedParticle, baseParticle);
+ particleValidRestriction(fakeDerived, SGHandler, fakeBase, SGHandler);
} catch (XMLSchemaException e) {
String key = e.getKey();
reportSchemaError(errorReporter, rgLocators[i/2-1],
@@ -420,8 +425,10 @@
(types[j].fBaseType instanceof XSComplexTypeDecl) &&
((XSComplexTypeDecl)(types[j].fBaseType)).fParticle != null) {
try {
- particleValidRestriction(SGHandler, types[j].fParticle,
- ((XSComplexTypeDecl)(types[j].fBaseType)).fParticle);
+ particleValidRestriction(types[j].fParticle,
+ SGHandler,
+ ((XSComplexTypeDecl)(types[j].fBaseType)).fParticle,
+ SGHandler);
} catch (XMLSchemaException e) {
reportSchemaError(errorReporter, ctLocators[j],
e.getKey(),
@@ -505,14 +512,9 @@
return;
}
- XSParticleDecl left = (XSParticleDecl)particle.fValue;
- checkElementDeclsConsistent(type, left, elemDeclHash, sgHandler);
-
- XSParticleDecl right = (XSParticleDecl)particle.fOtherValue;
- if (right != null) {
- checkElementDeclsConsistent(type, right, elemDeclHash, sgHandler);
- }
-
+ XSModelGroup group = (XSModelGroup)particle.fValue;
+ for (int i = 0; i < group.fParticleCount; i++)
+ checkElementDeclsConsistent(type, group.fParticles[i], elemDeclHash, sgHandler);
}
public static void findElemInTable(XSComplexTypeDecl type, XSElementDecl elem,
@@ -541,26 +543,22 @@
}
}
- // Invoke particleValidRestriction with a substitution group handler for each
/*
Check that a given particle is a valid restriction of a base particle.
*/
-
- public static void particleValidRestriction(SubstitutionGroupHandler sgHandler,
- XSParticleDecl dParticle,
- XSParticleDecl bParticle)
+ private static void particleValidRestriction(XSParticleDecl dParticle,
+ SubstitutionGroupHandler dSGHandler,
+ XSParticleDecl bParticle,
+ SubstitutionGroupHandler bSGHandler)
throws XMLSchemaException {
-
- // Invoke particleValidRestriction with a substitution group handler for each
- // particle.
-
- particleValidRestriction(dParticle, sgHandler, bParticle, sgHandler);
+ particleValidRestriction(dParticle, dSGHandler, bParticle, bSGHandler, true);
}
private static void particleValidRestriction(XSParticleDecl dParticle,
SubstitutionGroupHandler dSGHandler,
XSParticleDecl bParticle,
- SubstitutionGroupHandler bSGHandler)
+ SubstitutionGroupHandler bSGHandler,
+ boolean checkWCOccurrence)
throws XMLSchemaException {
Vector dChildren = null;
@@ -583,13 +581,12 @@
// - turning top-level elements with substitution groups into CHOICE groups.
//
- int dType = dParticle.fType;
+ short dType = dParticle.fType;
//
// Handle pointless groups for the derived particle
//
- if (dType == XSParticleDecl.PARTICLE_SEQUENCE ||
- dType == XSParticleDecl.PARTICLE_CHOICE ||
- dType == XSParticleDecl.PARTICLE_ALL) {
+ if (dType == XSParticleDecl.PARTICLE_MODELGROUP) {
+ dType = ((XSModelGroup)dParticle.fValue).fCompositor;
// Find a group, starting with this particle, with more than 1 child. There
// may be none, and the particle of interest trivially becomes an element or
@@ -599,6 +596,8 @@
// Particle has been replaced. Retrieve new type info.
dParticle = dtmp;
dType = dParticle.fType;
+ if (dType == XSParticleDecl.PARTICLE_MODELGROUP)
+ dType = ((XSModelGroup)dParticle.fValue).fCompositor;
}
// Fill in a vector with the children of the particle, removing any
@@ -623,9 +622,7 @@
if (subGroup.length >0 ) {
// Now, set the type to be CHOICE. The "group" will have the same
// occurrence information as the original particle.
- dType = XSParticleDecl.PARTICLE_CHOICE;
- dMinOccurs = dParticle.fMinOccurs;
- dMaxOccurs = dParticle.fMaxOccurs;
+ dType = XSModelGroup.MODELGROUP_CHOICE;
dMinEffectiveTotalRange = dMinOccurs;
dMaxEffectiveTotalRange = dMaxOccurs;
@@ -643,13 +640,12 @@
}
}
- int bType = bParticle.fType;
+ short bType = bParticle.fType;
//
// Handle pointless groups for the base particle
//
- if (bType == XSParticleDecl.PARTICLE_SEQUENCE ||
- bType == XSParticleDecl.PARTICLE_CHOICE ||
- bType == XSParticleDecl.PARTICLE_ALL) {
+ if (bType == XSParticleDecl.PARTICLE_MODELGROUP) {
+ bType = ((XSModelGroup)bParticle.fValue).fCompositor;
// Find a group, starting with this particle, with more than 1 child. There
// may be none, and the particle of interest trivially becomes an element or
@@ -659,6 +655,8 @@
// Particle has been replaced. Retrieve new type info.
bParticle = btmp;
bType = bParticle.fType;
+ if (bType == XSParticleDecl.PARTICLE_MODELGROUP)
+ bType = ((XSModelGroup)bParticle.fValue).fCompositor;
}
// Fill in a vector with the children of the particle, removing any
@@ -679,9 +677,7 @@
XSElementDecl[] bsubGroup = bSGHandler.getSubstitutionGroup(bElement);
if (bsubGroup.length >0 ) {
// Now, set the type to be CHOICE
- bType = XSParticleDecl.PARTICLE_CHOICE;
- bMinOccurs = bParticle.fMinOccurs;
- bMaxOccurs = bParticle.fMaxOccurs;
+ bType = XSModelGroup.MODELGROUP_CHOICE;
bChildren = new Vector(bsubGroup.length+1);
for (int i = 0; i < bsubGroup.length; i++) {
@@ -715,12 +711,13 @@
case XSParticleDecl.PARTICLE_WILDCARD:
{
checkNSCompat((XSElementDecl)dParticle.fValue,dMinOccurs,dMaxOccurs,
- (XSWildcardDecl)bParticle.fValue,bMinOccurs,bMaxOccurs);
+ (XSWildcardDecl)bParticle.fValue,bMinOccurs,bMaxOccurs,
+ checkWCOccurrence);
return;
}
// Elt:All RecurseAsIfGroup
- case XSParticleDecl.PARTICLE_CHOICE:
+ case XSModelGroup.MODELGROUP_CHOICE:
{
// Treat the element as if it were in a group of the same type
// as the base Particle
@@ -731,8 +728,8 @@
bChildren, bMinOccurs, bMaxOccurs, bSGHandler);
return;
}
- case XSParticleDecl.PARTICLE_SEQUENCE:
- case XSParticleDecl.PARTICLE_ALL:
+ case XSModelGroup.MODELGROUP_SEQUENCE:
+ case XSModelGroup.MODELGROUP_ALL:
{
// Treat the element as if it were in a group of the same type
// as the base Particle
@@ -764,9 +761,9 @@
return;
}
- case XSParticleDecl.PARTICLE_CHOICE:
- case XSParticleDecl.PARTICLE_SEQUENCE:
- case XSParticleDecl.PARTICLE_ALL:
+ case XSModelGroup.MODELGROUP_CHOICE:
+ case XSModelGroup.MODELGROUP_SEQUENCE:
+ case XSModelGroup.MODELGROUP_ALL:
case XSParticleDecl.PARTICLE_ELEMENT:
{
throw new XMLSchemaException("cos-particle-restrict.2",
@@ -781,7 +778,7 @@
}
}
- case XSParticleDecl.PARTICLE_ALL:
+ case XSModelGroup.MODELGROUP_ALL:
{
switch (bType) {
@@ -796,20 +793,21 @@
checkNSRecurseCheckCardinality(dChildren, dMinEffectiveTotalRange,
dMaxEffectiveTotalRange,
dSGHandler,
- bParticle,bMinOccurs,bMaxOccurs);
+ bParticle,bMinOccurs,bMaxOccurs,
+ checkWCOccurrence);
return;
}
- case XSParticleDecl.PARTICLE_ALL:
+ case XSModelGroup.MODELGROUP_ALL:
{
checkRecurse(dChildren, dMinOccurs, dMaxOccurs, dSGHandler,
bChildren, bMinOccurs, bMaxOccurs, bSGHandler);
return;
}
- case XSParticleDecl.PARTICLE_CHOICE:
- case XSParticleDecl.PARTICLE_SEQUENCE:
+ case XSModelGroup.MODELGROUP_CHOICE:
+ case XSModelGroup.MODELGROUP_SEQUENCE:
case XSParticleDecl.PARTICLE_ELEMENT:
{
throw new XMLSchemaException("cos-particle-restrict.2",
@@ -824,7 +822,7 @@
}
}
- case XSParticleDecl.PARTICLE_CHOICE:
+ case XSModelGroup.MODELGROUP_CHOICE:
{
switch (bType) {
@@ -839,19 +837,20 @@
checkNSRecurseCheckCardinality(dChildren, dMinEffectiveTotalRange,
dMaxEffectiveTotalRange,
dSGHandler,
- bParticle,bMinOccurs,bMaxOccurs);
+ bParticle,bMinOccurs,bMaxOccurs,
+ checkWCOccurrence);
return;
}
- case XSParticleDecl.PARTICLE_CHOICE:
+ case XSModelGroup.MODELGROUP_CHOICE:
{
checkRecurseLax(dChildren, dMinOccurs, dMaxOccurs, dSGHandler,
bChildren, bMinOccurs, bMaxOccurs, bSGHandler);
return;
}
- case XSParticleDecl.PARTICLE_ALL:
- case XSParticleDecl.PARTICLE_SEQUENCE:
+ case XSModelGroup.MODELGROUP_ALL:
+ case XSModelGroup.MODELGROUP_SEQUENCE:
case XSParticleDecl.PARTICLE_ELEMENT:
{
throw new XMLSchemaException("cos-particle-restrict.2",
@@ -867,7 +866,7 @@
}
- case XSParticleDecl.PARTICLE_SEQUENCE:
+ case XSModelGroup.MODELGROUP_SEQUENCE:
{
switch (bType) {
@@ -882,25 +881,26 @@
checkNSRecurseCheckCardinality(dChildren, dMinEffectiveTotalRange,
dMaxEffectiveTotalRange,
dSGHandler,
- bParticle,bMinOccurs,bMaxOccurs);
+ bParticle,bMinOccurs,bMaxOccurs,
+ checkWCOccurrence);
return;
}
- case XSParticleDecl.PARTICLE_ALL:
+ case XSModelGroup.MODELGROUP_ALL:
{
checkRecurseUnordered(dChildren, dMinOccurs, dMaxOccurs, dSGHandler,
bChildren, bMinOccurs, bMaxOccurs, bSGHandler);
return;
}
- case XSParticleDecl.PARTICLE_SEQUENCE:
+ case XSModelGroup.MODELGROUP_SEQUENCE:
{
checkRecurse(dChildren, dMinOccurs, dMaxOccurs, dSGHandler,
bChildren, bMinOccurs, bMaxOccurs, bSGHandler);
return;
}
- case XSParticleDecl.PARTICLE_CHOICE:
+ case XSModelGroup.MODELGROUP_CHOICE:
{
int min1 = dMinOccurs * dChildren.size();
int max1 = (dMaxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED)?
@@ -943,8 +943,8 @@
return p;
if (p.fMinOccurs==1 && p.fMaxOccurs==1 &&
- p.fValue!=null && p.fOtherValue==null)
- return getNonUnaryGroup((XSParticleDecl)p.fValue);
+ p.fValue!=null && ((XSModelGroup)p.fValue).fParticleCount == 1)
+ return getNonUnaryGroup(((XSModelGroup)p.fValue).fParticles[0]);
else
return p;
}
@@ -959,10 +959,9 @@
Vector children = new Vector();
- gatherChildren(p.fType, (XSParticleDecl)p.fValue, children);
- if (p.fOtherValue != null) {
- gatherChildren(p.fType, (XSParticleDecl)p.fOtherValue, children);
- }
+ XSModelGroup group = (XSModelGroup)p.fValue;
+ for (int i = 0; i < group.fParticleCount; i++)
+ gatherChildren(group.fCompositor, group.fParticles[i], children);
return children;
}
@@ -973,6 +972,8 @@
int min = p.fMinOccurs;
int max = p.fMaxOccurs;
int type = p.fType;
+ if (type == XSParticleDecl.PARTICLE_MODELGROUP)
+ type = ((XSModelGroup)p.fValue).fCompositor;
if (type == XSParticleDecl.PARTICLE_EMPTY)
return;
@@ -983,16 +984,13 @@
return;
}
- XSParticleDecl left = (XSParticleDecl)p.fValue;
- XSParticleDecl right = (XSParticleDecl)p.fOtherValue;
if (! (min==1 && max==1)) {
children.addElement(p);
}
else if (parentType == type) {
- gatherChildren(type,left,children);
- if (right != null) {
- gatherChildren(type,right,children);
- }
+ XSModelGroup group = (XSModelGroup)p.fValue;
+ for (int i = 0; i < group.fParticleCount; i++)
+ gatherChildren(type, group.fParticles[i], children);
}
else if (!p.isEmpty()) {
children.addElement(p);
@@ -1102,11 +1100,12 @@
}
private static void checkNSCompat(XSElementDecl elem, int min1, int max1,
- XSWildcardDecl wildcard, int min2, int max2)
+ XSWildcardDecl wildcard, int min2, int max2,
+ boolean checkWCOccurrence)
throws XMLSchemaException {
// check Occurrence ranges
- if (!checkOccurrenceRange(min1,max1,min2,max2)) {
+ if (checkWCOccurrence && !checkOccurrenceRange(min1,max1,min2,max2)) {
throw new XMLSchemaException("rcase-NSCompat.2",
new Object[]{elem.fName});
}
@@ -1139,12 +1138,13 @@
private static void checkNSRecurseCheckCardinality(Vector children, int min1, int max1,
SubstitutionGroupHandler dSGHandler,
- XSParticleDecl wildcard, int min2, int max2)
+ XSParticleDecl wildcard, int min2, int max2,
+ boolean checkWCOccurrence)
throws XMLSchemaException {
// check Occurrence ranges
- if (!checkOccurrenceRange(min1,max1,min2,max2)) {
+ if (checkWCOccurrence && !checkOccurrenceRange(min1,max1,min2,max2)) {
throw new XMLSchemaException("rcase-NSRecurseCheckCardinality.2", null);
}
@@ -1153,7 +1153,7 @@
try {
for (int i = 0; i < count; i++) {
XSParticleDecl particle1 = (XSParticleDecl)children.elementAt(i);
- particleValidRestriction(particle1, dSGHandler, wildcard, null);
+ particleValidRestriction(particle1, dSGHandler, wildcard, null, false);
}
}
1.5 +35 -1 xml-xerces/java/src/org/apache/xerces/impl/xs/XSDeclarationPool.java
Index: XSDeclarationPool.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XSDeclarationPool.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- XSDeclarationPool.java 10 Apr 2002 16:45:52 -0000 1.4
+++ XSDeclarationPool.java 26 Apr 2002 22:03:42 -0000 1.5
@@ -67,7 +67,7 @@
* Note: The cashing mechanism is not implemented yet.
*
* @author Elena Litani, IBM
- * @version $Id: XSDeclarationPool.java,v 1.4 2002/04/10 16:45:52 elena Exp $
+ * @version $Id: XSDeclarationPool.java,v 1.5 2002/04/26 22:03:42 sandygao Exp $
*/
public final class XSDeclarationPool {
/** Chunk shift (8). */
@@ -90,6 +90,10 @@
private XSParticleDecl fParticleDecl[][] = new XSParticleDecl[INITIAL_CHUNK_COUNT][];
private int fParticleDeclIndex = 0;
+ /** Particle declaration pool */
+ private XSModelGroup fModelGroup[][] = new XSModelGroup[INITIAL_CHUNK_COUNT][];
+ private int fModelGroupIndex = 0;
+
/** Attribute declaration pool */
private XSAttributeDecl fAttrDecl[][] = new XSAttributeDecl[INITIAL_CHUNK_COUNT][];
private int fAttrDeclIndex = 0;
@@ -188,6 +192,19 @@
return fParticleDecl[chunk][index];
}
+ public final XSModelGroup getModelGroup(){
+ int chunk = fModelGroupIndex >> CHUNK_SHIFT;
+ int index = fModelGroupIndex & CHUNK_MASK;
+ ensureModelGroupCapacity(chunk);
+ if (fModelGroup[chunk][index] == null) {
+ fModelGroup[chunk][index] = new XSModelGroup();
+ } else {
+ fModelGroup[chunk][index].reset();
+ }
+ fModelGroupIndex++;
+ return fModelGroup[chunk][index];
+ }
+
// REVISIT: do we need decl pool for group declarations, attribute group,
// notations?
// it seems like each schema would use a small number of those
@@ -222,12 +239,28 @@
return true;
}
+ private boolean ensureModelGroupCapacity(int chunk) {
+ if (chunk >= fModelGroup.length) {
+ fModelGroup = resize(fModelGroup, fModelGroup.length * 2);
+ } else if (fModelGroup[chunk] != null) {
+ return false;
+ }
+
+ fModelGroup[chunk] = new XSModelGroup[CHUNK_SIZE];
+ return true;
+ }
+
private static XSParticleDecl[][] resize(XSParticleDecl array[][], int newsize) {
XSParticleDecl newarray[][] = new XSParticleDecl[newsize][];
System.arraycopy(array, 0, newarray, 0, array.length);
return newarray;
}
+ private static XSModelGroup[][] resize(XSModelGroup array[][], int newsize) {
+ XSModelGroup newarray[][] = new XSModelGroup[newsize][];
+ System.arraycopy(array, 0, newarray, 0, array.length);
+ return newarray;
+ }
private boolean ensureAttrDeclCapacity(int chunk) {
if (chunk >= fAttrDecl.length) {
@@ -303,6 +336,7 @@
public void reset(){
fElementDeclIndex = 0;
fParticleDeclIndex = 0;
+ fModelGroupIndex = 0;
fSTDeclIndex = 0;
fCTDeclIndex = 0;
fAttrDeclIndex = 0;
1.4 +3 -3 xml-xerces/java/src/org/apache/xerces/impl/xs/XSGroupDecl.java
Index: XSGroupDecl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XSGroupDecl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- XSGroupDecl.java 29 Jan 2002 01:15:14 -0000 1.3
+++ XSGroupDecl.java 26 Apr 2002 22:03:42 -0000 1.4
@@ -62,7 +62,7 @@
* schema component is a global <group> element information item
*
* @author Sandy Gao, IBM
- * @version $Id: XSGroupDecl.java,v 1.3 2002/01/29 01:15:14 lehors Exp $
+ * @version $Id: XSGroupDecl.java,v 1.4 2002/04/26 22:03:42 sandygao Exp $
*/
public class XSGroupDecl {
@@ -70,7 +70,7 @@
public String fName = null;
// target namespace of the group
public String fTargetNamespace = null;
- // particle of the group
- public XSParticleDecl fParticle = null;
+ // model group of the group
+ public XSModelGroup fModelGroup = null;
} // class XSGroupDecl
1.7 +33 -136 xml-xerces/java/src/org/apache/xerces/impl/xs/XSParticleDecl.java
Index: XSParticleDecl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XSParticleDecl.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- XSParticleDecl.java 22 Apr 2002 22:43:24 -0000 1.6
+++ XSParticleDecl.java 26 Apr 2002 22:03:42 -0000 1.7
@@ -62,7 +62,7 @@
*
* @author Sandy Gao, IBM
*
- * @version $Id: XSParticleDecl.java,v 1.6 2002/04/22 22:43:24 sandygao Exp $
+ * @version $Id: XSParticleDecl.java,v 1.7 2002/04/26 22:03:42 sandygao Exp $
*/
public class XSParticleDecl {
@@ -70,59 +70,33 @@
public static final short PARTICLE_EMPTY = 0;
public static final short PARTICLE_ELEMENT = 1;
public static final short PARTICLE_WILDCARD = 2;
- public static final short PARTICLE_CHOICE = 3;
- public static final short PARTICLE_SEQUENCE = 4;
- public static final short PARTICLE_ALL = 5;
- public static final short PARTICLE_ZERO_OR_ONE = 6;
- public static final short PARTICLE_ZERO_OR_MORE = 7;
- public static final short PARTICLE_ONE_OR_MORE = 8;
+ public static final short PARTICLE_MODELGROUP = 3;
+ public static final short PARTICLE_ZERO_OR_MORE = 4;
+ public static final short PARTICLE_ZERO_OR_ONE = 5;
+ public static final short PARTICLE_ONE_OR_MORE = 6;
// type of the particle
public short fType = PARTICLE_EMPTY;
- // left-hand value of the particle
+
+ // term of the particle
// for PARTICLE_ELEMENT : the element decl
// for PARTICLE_WILDCARD: the wildcard decl
- // for PARTICLE_CHOICE/SEQUENCE/ALL: the particle of the first child
- // for PARTICLE_?*+: the child particle
+ // for PARTICLE_MODELGROUP: the model group
public Object fValue = null;
- // for PARTICLE_CHOICE/SEQUENCE/ALL: the particle of the other child
- public Object fOtherValue = null;
+
// minimum occurrence of this particle
public int fMinOccurs = 1;
// maximum occurrence of this particle
public int fMaxOccurs = 1;
// clone this decl
- public XSParticleDecl clone(boolean deep) {
+ public XSParticleDecl makeClone() {
XSParticleDecl particle = new XSParticleDecl();
particle.fType = fType;
particle.fMinOccurs = fMinOccurs;
particle.fMaxOccurs = fMaxOccurs;
particle.fDescription = fDescription;
- // if it's not a deep clone, or it's a leaf particle
- // just copy value and other value
- if (!deep ||
- fType == PARTICLE_EMPTY ||
- fType == PARTICLE_ELEMENT ||
- fType == PARTICLE_WILDCARD) {
- particle.fValue = fValue;
- particle.fOtherValue = fOtherValue;
- }
- // otherwise, we have to make clones of value and other value
- else {
- if (fValue != null) {
- particle.fValue = ((XSParticleDecl)fValue).clone(deep);
- }
- else {
- particle.fValue = null;
- }
- if (fOtherValue != null) {
- particle.fOtherValue = ((XSParticleDecl)fOtherValue).clone(deep);
- }
- else {
- particle.fOtherValue = null;
- }
- }
+ particle.fValue = fValue;
return particle;
}
@@ -134,16 +108,14 @@
return minEffectiveTotalRange() == 0;
}
+ // whether this particle contains nothing
public boolean isEmpty() {
- if (fType==PARTICLE_ELEMENT || fType==PARTICLE_WILDCARD) return false;
+ if (fType == PARTICLE_EMPTY)
+ return true;
+ if (fType == PARTICLE_ELEMENT || fType == PARTICLE_WILDCARD)
+ return false;
- if (fType==PARTICLE_EMPTY) return true;
-
- boolean leftIsEmpty = (fValue==null || ((XSParticleDecl)fValue).isEmpty());
- boolean rightIsEmpty = (fOtherValue==null ||
- ((XSParticleDecl)fOtherValue).isEmpty());
-
- return (leftIsEmpty && rightIsEmpty) ;
+ return ((XSModelGroup)fValue).isEmpty();
}
/**
@@ -154,79 +126,22 @@
* values from the spec are retrievable by these methods.
*/
public int minEffectiveTotalRange() {
- switch (fType) {
- case PARTICLE_ALL:
- case PARTICLE_SEQUENCE:
- return minEffectiveTotalRangeAllSeq();
- case PARTICLE_CHOICE:
- return minEffectiveTotalRangeChoice();
- default:
- return fMinOccurs;
- }
- }
-
- private int minEffectiveTotalRangeAllSeq() {
- int fromLeft = ((XSParticleDecl)fValue).minEffectiveTotalRange();
- if (fOtherValue != null)
- fromLeft += ((XSParticleDecl)fOtherValue).minEffectiveTotalRange();
- return fMinOccurs * fromLeft;
- }
-
- private int minEffectiveTotalRangeChoice() {
- int fromLeft = ((XSParticleDecl)fValue).minEffectiveTotalRange();
- if (fOtherValue != null) {
- int fromRight = ((XSParticleDecl)fOtherValue).minEffectiveTotalRange();
- if (fromRight < fromLeft)
- fromLeft = fromRight;
+ if (fType == PARTICLE_MODELGROUP) {
+ return ((XSModelGroup)fValue).minEffectiveTotalRange() * fMinOccurs;
}
- return fMinOccurs * fromLeft;
+ return fMinOccurs;
}
public int maxEffectiveTotalRange() {
- switch (fType) {
- case PARTICLE_ALL:
- case PARTICLE_SEQUENCE:
- return maxEffectiveTotalRangeAllSeq();
- case PARTICLE_CHOICE:
- return maxEffectiveTotalRangeChoice();
- default:
- return fMaxOccurs;
- }
- }
-
- private int maxEffectiveTotalRangeAllSeq() {
- int fromLeft = ((XSParticleDecl)fValue).maxEffectiveTotalRange();
- if (fromLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED)
- return SchemaSymbols.OCCURRENCE_UNBOUNDED;
- if (fOtherValue != null) {
- int fromRight = ((XSParticleDecl)fOtherValue).maxEffectiveTotalRange();
- if (fromRight == SchemaSymbols.OCCURRENCE_UNBOUNDED)
+ if (fType == PARTICLE_MODELGROUP) {
+ int max = ((XSModelGroup)fValue).maxEffectiveTotalRange();
+ if (max == SchemaSymbols.OCCURRENCE_UNBOUNDED)
return SchemaSymbols.OCCURRENCE_UNBOUNDED;
- fromLeft += fromRight;
- }
-
- if (fromLeft != 0 && fMaxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED)
- return SchemaSymbols.OCCURRENCE_UNBOUNDED;
-
- return fMaxOccurs * fromLeft;
- }
-
- private int maxEffectiveTotalRangeChoice() {
- int fromLeft = ((XSParticleDecl)fValue).maxEffectiveTotalRange();
- if (fromLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED)
- return SchemaSymbols.OCCURRENCE_UNBOUNDED;
- if (fOtherValue != null) {
- int fromRight = ((XSParticleDecl)fOtherValue).maxEffectiveTotalRange();
- if (fromRight == SchemaSymbols.OCCURRENCE_UNBOUNDED)
+ if (max != 0 && fMaxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED)
return SchemaSymbols.OCCURRENCE_UNBOUNDED;
- if (fromRight < fromLeft)
- fromLeft = fromRight;
+ return max * fMaxOccurs;
}
-
- if (fromLeft != 0 && fMaxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED)
- return SchemaSymbols.OCCURRENCE_UNBOUNDED;
-
- return fMaxOccurs * fromLeft;
+ return fMaxOccurs;
}
/**
@@ -255,46 +170,28 @@
* append the string description of this particle to the string buffer
* this is for error message.
*/
- void appendParticle(StringBuffer fBuffer) {
+ void appendParticle(StringBuffer buffer) {
switch (fType) {
case PARTICLE_EMPTY:
- fBuffer.append("EMPTY");
+ buffer.append("EMPTY");
break;
case PARTICLE_ELEMENT:
case PARTICLE_WILDCARD:
- fBuffer.append('(');
- fBuffer.append(fValue.toString());
- fBuffer.append(')');
+ buffer.append('(');
+ buffer.append(fValue.toString());
+ buffer.append(')');
break;
- case PARTICLE_CHOICE:
- case PARTICLE_SEQUENCE:
- case PARTICLE_ALL:
- if (fOtherValue == null) {
- fBuffer.append(fValue.toString());
- } else {
- if (fType == PARTICLE_ALL)
- fBuffer.append("all(");
- else
- fBuffer.append('(');
- fBuffer.append(fValue.toString());
- if (fType == PARTICLE_CHOICE)
- fBuffer.append('|');
- else
- fBuffer.append(',');
- fBuffer.append(fOtherValue.toString());
- fBuffer.append(')');
- }
+ case PARTICLE_MODELGROUP:
+ buffer.append(fValue.toString());
break;
}
}
-
public void reset(){
fType = PARTICLE_EMPTY;
fValue = null;
- fOtherValue = null;
fMinOccurs = 1;
fMaxOccurs = 1;
-
+ fDescription = null;
}
} // class XSParticle
1.1 xml-xerces/java/src/org/apache/xerces/impl/xs/XSModelGroup.java
Index: XSModelGroup.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001, 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xerces.impl.xs;
/**
* Store schema model group declaration.
*
* @author Sandy Gao, IBM
*
* @version $Id: XSModelGroup.java,v 1.1 2002/04/26 22:03:42 sandygao Exp $
*/
public class XSModelGroup {
// types of model groups
// REVISIT: can't use same constants as those in XSParticleDecl, because
// there are place where the constants are used together. For example,
// to check whether the content is an element or a sequence.
public static final short MODELGROUP_CHOICE = 11;
public static final short MODELGROUP_SEQUENCE = 12;
public static final short MODELGROUP_ALL = 13;
// compositor of the model group
public short fCompositor;
// particles
public XSParticleDecl[] fParticles = null;
public int fParticleCount = 0;
// whether this model group contains nothing
public boolean isEmpty() {
for (int i = 0; i < fParticleCount; i++) {
if (!fParticles[i].isEmpty())
return false;
}
return true;
}
/**
* 3.8.6 Effective Total Range (all and sequence) and
* Effective Total Range (choice)
* The following methods are used to return min/max range for a particle.
* They are not exactly the same as it's described in the spec, but all the
* values from the spec are retrievable by these methods.
*/
public int minEffectiveTotalRange() {
if (fCompositor == MODELGROUP_CHOICE)
return minEffectiveTotalRangeChoice();
else
return minEffectiveTotalRangeAllSeq();
}
// return the sum of all min values of the particles
private int minEffectiveTotalRangeAllSeq() {
int total = 0;
for (int i = 0; i < fParticleCount; i++)
total += fParticles[i].minEffectiveTotalRange();
return total;
}
// return the min of all min values of the particles
private int minEffectiveTotalRangeChoice() {
int min = 0, one;
if (fParticles.length > 0)
min = fParticles[0].minEffectiveTotalRange();
for (int i = 1; i < fParticleCount; i++) {
one = fParticles[i].minEffectiveTotalRange();
if (one < min)
min = one;
}
return min;
}
public int maxEffectiveTotalRange() {
if (fCompositor == MODELGROUP_CHOICE)
return maxEffectiveTotalRangeChoice();
else
return maxEffectiveTotalRangeAllSeq();
}
// if one of the max value of the particles is unbounded, return unbounded;
// otherwise return the sum of all max values
private int maxEffectiveTotalRangeAllSeq() {
int total = 0, one;
for (int i = 0; i < fParticleCount; i++) {
one = fParticles[i].maxEffectiveTotalRange();
if (one == SchemaSymbols.OCCURRENCE_UNBOUNDED)
return SchemaSymbols.OCCURRENCE_UNBOUNDED;
total += one;
}
return total;
}
// if one of the max value of the particles is unbounded, return unbounded;
// otherwise return the max of all max values
private int maxEffectiveTotalRangeChoice() {
int max = 0, one;
if (fParticles.length > 0) {
max = fParticles[0].minEffectiveTotalRange();
if (max == SchemaSymbols.OCCURRENCE_UNBOUNDED)
return SchemaSymbols.OCCURRENCE_UNBOUNDED;
}
for (int i = 1; i < fParticleCount; i++) {
one = fParticles[i].maxEffectiveTotalRange();
if (one == SchemaSymbols.OCCURRENCE_UNBOUNDED)
return SchemaSymbols.OCCURRENCE_UNBOUNDED;
if (one > max)
max = one;
}
return max;
}
/**
* get the string description of this particle
*/
private String fDescription = null;
public String toString() {
if (fDescription == null) {
StringBuffer buffer = new StringBuffer();
if (fCompositor == MODELGROUP_ALL)
buffer.append("all(");
else
buffer.append('(');
if (fParticles.length > 0)
buffer.append(fParticles[0].toString());
for (int i = 1; i < fParticleCount; i++) {
if (fCompositor == MODELGROUP_CHOICE)
buffer.append('|');
else
buffer.append(',');
buffer.append(fParticles[i].toString());
}
buffer.append(')');
fDescription = buffer.toString();
}
return fDescription;
}
public void reset(){
fCompositor = MODELGROUP_SEQUENCE;
fParticles = null;
fParticleCount = 0;
fDescription = null;
}
} // class XSParticle
1.8 +167 -375 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.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- CMBuilder.java 3 Apr 2002 23:48:27 -0000 1.7
+++ CMBuilder.java 26 Apr 2002 22:03:42 -0000 1.8
@@ -63,6 +63,7 @@
import org.apache.xerces.impl.xs.XSDeclarationPool;
import org.apache.xerces.impl.xs.XSComplexTypeDecl;
import org.apache.xerces.impl.xs.XSParticleDecl;
+import org.apache.xerces.impl.xs.XSModelGroup;
import org.apache.xerces.impl.xs.XSElementDecl;
import org.apache.xerces.impl.xs.models.*;
@@ -70,456 +71,247 @@
* This class constructs content models for a given grammar.
*
* @author Elena Litani, IBM
- * @version $Id: CMBuilder.java,v 1.7 2002/04/03 23:48:27 elena Exp $
+ * @author Sandy Gao, IBM
+ *
+ * @version $Id: CMBuilder.java,v 1.8 2002/04/26 22:03:42 sandygao Exp $
*/
public class CMBuilder {
- private final QName fQName1 = new QName();
- private final QName fQName2 = new QName();
-
+ // REVISIT: should update the decl pool to cache XSCM objects too
private XSDeclarationPool fDeclPool = null;
+
+ // It never changes, so a static member is good enough
+ private static XSEmptyCM fEmptyCM = new XSEmptyCM();
// needed for DFA construction
private int fLeafCount;
-
- public CMBuilder (XSDeclarationPool pool){
+ // needed for UPA
+ private int fParticleCount;
+
+ public CMBuilder(XSDeclarationPool pool) {
fDeclPool = pool;
}
- public void setDeclPool (XSDeclarationPool declPool){
+ public void setDeclPool(XSDeclarationPool declPool) {
fDeclPool = declPool;
}
/**
* Get content model for the a given type
*
- * @param elementDeclIndex
- * @param comparator
- * @return a content model validator
- * @exception RuntimeException
+ * @param typeDecl get content model for which complex type
+ * @return a content model validator
*/
public XSCMValidator getContentModel(XSComplexTypeDecl typeDecl) {
+ // for complex type with empty or simple content,
+ // there is no content model validator
short contentType = typeDecl.fContentType;
if (contentType == XSComplexTypeDecl.CONTENTTYPE_SIMPLE ||
contentType == XSComplexTypeDecl.CONTENTTYPE_EMPTY) {
return null;
}
- XSCMValidator cmValidator = null;
-
XSParticleDecl particle = typeDecl.fParticle;
-
- // This check is performed in XSComplexTypeDecl.
- //if (cmValidator != null)
- // return cmValidator;
-
-
- if (particle != null)
- particle = expandParticleTree( (XSParticleDecl)particle);
-
- // And create the content model according to the spec type
-
- if (particle == null) {
- // create special content model for no element content
- cmValidator = new XSEmptyCM();
- }
- else if (contentType == XSComplexTypeDecl.CONTENTTYPE_MIXED) {
- //
- // Create a child model as
- // per the element-only case
- cmValidator = createChildModel(particle, true);
- }
- else if (contentType == XSComplexTypeDecl.CONTENTTYPE_ELEMENT) {
- // This method will create an optimal model for the complexity
- // of the element's defined model. If its simple, it will create
- // a SimpleContentModel object. If its a simple list, it will
- // create a SimpleListContentModel object. If its complex, it
- // will create a DFAContentModel object.
- //
- cmValidator = createChildModel(particle, false);
+
+ // if the content is element only or mixed, but no particle
+ // is defined, return the empty content model
+ if (particle == null)
+ return fEmptyCM;
+
+ // if the content model contains "all" model group,
+ // we create an "all" content model, otherwise a DFA content model
+ XSCMValidator cmValidator = null;
+ if (particle.fType == XSParticleDecl.PARTICLE_MODELGROUP &&
+ ((XSModelGroup)particle.fValue).fCompositor == XSModelGroup.MODELGROUP_ALL) {
+ cmValidator = createAllCM(particle);
}
else {
- throw new RuntimeException("Unknown content type for a element decl "
- + "in getElementContentModelValidator() in Grammar class");
+ cmValidator = createDFACM(particle);
}
+ // if the validator returned is null, it means there is nothing in
+ // the content model, so we return the empty content model.
+ if (cmValidator == null)
+ cmValidator = fEmptyCM;
+
return cmValidator;
}
+ XSCMValidator createAllCM(XSParticleDecl particle) {
+ if (particle.fMaxOccurs == 0)
+ return null;
- private XSParticleDecl expandParticleTree( XSParticleDecl particle) {
+ // create an all content model. the parameter indicates whether
+ // the <all> itself is optional
+ XSAllCM allContent = new XSAllCM(particle.fMinOccurs == 0);
+
+ // get the model group, and add all children of it to the content model
+ XSModelGroup group = (XSModelGroup)particle.fValue;
+ for (int i = 0; i < group.fParticleCount; i++) {
+ // for all non-empty particles
+ if (group.fParticles[i].fType != XSParticleDecl.PARTICLE_EMPTY &&
+ group.fParticles[i].fMaxOccurs != 0)
+ // add the element decl to the all content model
+ allContent.addElement((XSElementDecl)group.fParticles[i].fValue,
+ group.fParticles[i].fMinOccurs == 0);
+ }
+ return allContent;
+ }
+
+ XSCMValidator createDFACM(XSParticleDecl particle) {
+ fLeafCount = 0;
+ fParticleCount = 0;
+ // convert particle tree to CM tree
+ CMNode node = buildSyntaxTree(particle);
+ if (node == null)
+ return null;
+ // build DFA content model from the CM tree
+ return new XSDFACM(node, fLeafCount);
+ }
- // We may want to consider trying to combine this with buildSyntaxTree at some
- // point (if possible)
+ // 1. convert particle tree to CM tree:
+ // 2. expand all occurrence values: a{n, unbounded} -> a, a, ..., a+
+ // a{n, m} -> a, a, ..., a?, a?, ...
+ // 3. convert model groups (a, b, c, ...) or (a | b | c | ...) to
+ // binary tree: (((a,b),c),...) or (((a|b)|c)|...)
+ // 4. make sure each leaf node (XSCMLeaf) has a distinct position
+ private CMNode buildSyntaxTree(XSParticleDecl particle) {
int maxOccurs = particle.fMaxOccurs;
int minOccurs = particle.fMinOccurs;
short type = particle.fType;
+ CMNode nodeRet = null;
+
if ((type == XSParticleDecl.PARTICLE_WILDCARD) ||
(type == XSParticleDecl.PARTICLE_ELEMENT)) {
- // Make a clone of the leaf particle, so that if there are two
- // references to the same group, we have two different leaf
- // particles for the same element or wildcard decl.
+ // (task 1) element and wildcard particles should be converted to
+ // leaf nodes
+ // REVISIT: Make a clone of the leaf particle, so that if there
+ // are two references to the same group, we have two different
+ // leaf particles for the same element or wildcard decl.
// This is useful for checking UPA.
- //return expandContentModel(particle.clone(false), minOccurs, maxOccurs);
- return expandContentModel(particle, minOccurs, maxOccurs);
- }
- else if (type == XSParticleDecl.PARTICLE_CHOICE ||
- type == XSParticleDecl.PARTICLE_ALL ||
- type == XSParticleDecl.PARTICLE_SEQUENCE) {
-
- Object left = particle.fValue;
- Object right = particle.fOtherValue;
-
- left = expandParticleTree( (XSParticleDecl)left);
- if (right != null)
- right = expandParticleTree( (XSParticleDecl)right);
-
- // At this point, by expanding the particle tree, we may have a null left or right
- if (left==null && right==null)
- return null;
-
- if (left == null)
- return expandContentModel((XSParticleDecl)right, minOccurs, maxOccurs);
-
- if (right == null)
- return expandContentModel((XSParticleDecl)left, minOccurs, maxOccurs);
-
- XSParticleDecl newParticle;
- if (fDeclPool !=null) {
- newParticle = fDeclPool.getParticleDecl();
- } else {
- newParticle = new XSParticleDecl();
- }
- newParticle.fType = particle.fType;
- newParticle.fValue = left;
- newParticle.fOtherValue = right;
- return expandContentModel((XSParticleDecl)newParticle, minOccurs, maxOccurs);
- }
- else if (type == XSParticleDecl.PARTICLE_EMPTY) {
- return null;
- }
-
- return particle;
- }
-
-
-
- /**
- * When the element has a 'CONTENTTYPE_ELEMENT' model, this method is called to
- * create the content model object. It looks for some special case simple
- * models and creates SimpleContentModel objects for those. For the rest
- * it creates the standard DFA style model.
- *
- * @param grammar
- * @param fParticleIndex
- * @return
- */
- private XSCMValidator createChildModel(XSParticleDecl particle, boolean isMixed) {
-
- //
- // Get the content spec node for the element we are working on.
- // This will tell us what kind of node it is, which tells us what
- // kind of model we will try to create.
- //
- //XMLContentSpec fParticle = new XMLContentSpec();
- short type = particle.fType;
- if (type == XSParticleDecl.PARTICLE_WILDCARD) {
- // let fall through to build a DFAContentModel
- }
- else if (isMixed) {
- if (type ==XSParticleDecl.PARTICLE_ALL) {
- // All the nodes under an ALL must be additional ALL nodes and
- // ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
- // We collapse the ELEMENTs into a single vector.
- XSAllCM allContent = new XSAllCM(false);
- gatherAllLeaves ((XSParticleDecl)(particle.fValue), allContent);
- gatherAllLeaves ((XSParticleDecl)(particle.fOtherValue), allContent);
- return allContent;
-
- }
- else if (type == XSParticleDecl.PARTICLE_ZERO_OR_ONE) {
- XSParticleDecl left = (XSParticleDecl)particle.fValue;
-
-
- // An ALL node can appear under a ZERO_OR_ONE node.
- if (type ==XSParticleDecl.PARTICLE_ALL) {
- XSAllCM allContent = new XSAllCM(true);
- gatherAllLeaves (left, allContent);
- return allContent;
-
+ nodeRet = new XSCMLeaf(particle.fType, particle.fValue, fParticleCount++, fLeafCount++);
+ // (task 2) expand occurrence values
+ nodeRet = expandContentModel(nodeRet, minOccurs, maxOccurs);
+ }
+ else if (type == XSParticleDecl.PARTICLE_MODELGROUP) {
+ // (task 1,3) convert model groups to binary trees
+ XSModelGroup group = (XSModelGroup)particle.fValue;
+ CMNode temp = null;
+ for (int i = 0; i < group.fParticleCount; i++) {
+ // first convert each child to a CM tree
+ temp = buildSyntaxTree(group.fParticles[i]);
+ // then combine them using binary operation
+ if (temp != null) {
+ if (nodeRet == null) {
+ nodeRet = temp;
+ }
+ else {
+ nodeRet = new XSCMBinOp(group.fCompositor, nodeRet, temp);
+ }
}
}
- // otherwise, let fall through to build a DFAContentModel
+ // (task 2) expand occurrence values
+ if (nodeRet != null)
+ nodeRet = expandContentModel(nodeRet, minOccurs, maxOccurs);
}
- else if (type == XSParticleDecl.PARTICLE_ELEMENT) {
- //
- // Check that the left value is not null, since any content model
- // with PCDATA should be MIXED, so we should not have gotten here.
- //
- if (particle.fValue == null &&
- particle.fOtherValue == null)
- throw new RuntimeException("ImplementationMessages.VAL_NPCD");
-
- //
- // Its a single leaf, so its an 'a' type of content model, i.e.
- // just one instance of one element. That one is definitely a
- // simple content model.
- //
- // pass element declaration
-
- return new XSSimpleCM(type, (XSElementDecl)particle.fValue);
- }
- else if ((type == XSParticleDecl.PARTICLE_CHOICE)
- || (type == XSParticleDecl.PARTICLE_SEQUENCE)) {
- //
- // Lets see if both of the children are leafs. If so, then it
- // it has to be a simple content model
- //
- XSParticleDecl left = (XSParticleDecl)particle.fValue;
- XSParticleDecl right = (XSParticleDecl)particle.fOtherValue;
-
- if ((right.fType == XSParticleDecl.PARTICLE_ELEMENT)
- && (left.fType == XSParticleDecl.PARTICLE_ELEMENT)) {
- //
- // Its a simple choice or sequence, so we can do a simple
- // content model for it.
- //
- // pass both element decls
- return new XSSimpleCM(type, (XSElementDecl)left.fValue, (XSElementDecl)right.fValue);
- }
-
- }
- else if (type == XSParticleDecl.PARTICLE_ALL) {
- XSParticleDecl left = (XSParticleDecl)particle.fValue;
- XSParticleDecl right = (XSParticleDecl)particle.fOtherValue;
-
- XSAllCM allContent = new XSAllCM(false);
-
- gatherAllLeaves (left, allContent);
- gatherAllLeaves (right, allContent);
- return allContent;
- }
- else if ((type == XSParticleDecl.PARTICLE_ZERO_OR_ONE)
- || (type == XSParticleDecl.PARTICLE_ZERO_OR_MORE)
- || (type == XSParticleDecl.PARTICLE_ONE_OR_MORE)) {
- //
- // Its a repetition, so see if its one child is a leaf. If so
- // its a repetition of a single element, so we can do a simple
- // content model for that.
- XSParticleDecl left = (XSParticleDecl) particle.fValue;
-
- if (left.fType == XSParticleDecl.PARTICLE_ELEMENT) {
- //
- // It is, so we can create a simple content model here that
- // will check for this repetition. We pass -1 for the unused
- // right node.
- //
- return new XSSimpleCM(type, (XSElementDecl)left.fValue);
- }
- else if (left.fType==XSParticleDecl.PARTICLE_ALL) {
- XSAllCM allContent = new XSAllCM(true);
- gatherAllLeaves (left, allContent);
- return allContent;
- }
-
-
- }
- else {
- throw new RuntimeException("ImplementationMessages.VAL_CST");
- }
-
- //
- // Its not a simple content model, so here we have to create a DFA
- // for this element. So we create a DFAContentModel object. He
- // encapsulates all of the work to create the DFA.
- //
-
- fLeafCount = 0;
- CMNode node = buildSyntaxTree(particle);
- return new XSDFACM(node, fLeafCount, isMixed);
+ return nodeRet;
}
+ // 2. expand all occurrence values: a{n, unbounded} -> a, a, ..., a+
+ // a{n, m} -> a, a, ..., a?, a?, ...
+ // 4. make sure each leaf node (XSCMLeaf) has a distinct position
+ private CMNode expandContentModel(CMNode node,
+ int minOccurs, int maxOccurs) {
+ CMNode nodeRet = null;
- private XSParticleDecl expandContentModel(XSParticleDecl particle,
- int minOccurs, int maxOccurs) {
-
- XSParticleDecl leafParticle = particle;
- XSParticleDecl optional = null;
if (minOccurs==1 && maxOccurs==1) {
- return particle;
+ nodeRet = node;
}
else if (minOccurs==0 && maxOccurs==1) {
//zero or one
- return createParticle ( XSParticleDecl.PARTICLE_ZERO_OR_ONE,particle,null);
+ nodeRet = new XSCMUniOp(XSParticleDecl.PARTICLE_ZERO_OR_ONE, node);
}
else if (minOccurs == 0 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) {
//zero or more
- return createParticle (XSParticleDecl.PARTICLE_ZERO_OR_MORE, particle, null);
+ nodeRet = new XSCMUniOp(XSParticleDecl.PARTICLE_ZERO_OR_MORE, node);
}
else if (minOccurs == 1 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) {
//one or more
- return createParticle (XSParticleDecl.PARTICLE_ONE_OR_MORE, particle, null);
+ nodeRet = new XSCMUniOp(XSParticleDecl.PARTICLE_ONE_OR_MORE, node);
}
else if (maxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED) {
// => a,a,..,a+
- particle = createParticle (XSParticleDecl.PARTICLE_ONE_OR_MORE,
- particle, null);
-
- for (int i=0; i < (minOccurs-1); i++) {
- particle = createParticle (XSParticleDecl.PARTICLE_SEQUENCE, leafParticle, particle);
+ // create a+ node first, then put minOccurs-1 a's in front of it
+ // for the first time "node" is used, we don't need to make a copy
+ // and for other references to node, we make copies
+ nodeRet = new XSCMUniOp(XSParticleDecl.PARTICLE_ONE_OR_MORE, node);
+ for (int i=0; i < minOccurs-1; i++) {
+ // (task 4) we need to call copyNode here, so that we append
+ // an entire new copy of the node (a subtree). this is to ensure
+ // all leaf nodes have distinct position
+ nodeRet = new XSCMBinOp(XSModelGroup.MODELGROUP_SEQUENCE,
+ copyNode(node), nodeRet);
}
- return particle;
-
}
else {
// {n,m} => a,a,a,...(a),(a),...
-
-
- if (minOccurs==0) {
- optional = createParticle (XSParticleDecl.PARTICLE_ZERO_OR_ONE,
- leafParticle,
- null);
- particle = optional;
- for (int i=0; i < (maxOccurs-minOccurs-1); i++) {
- particle = createParticle (XSParticleDecl.PARTICLE_SEQUENCE,
- particle,
- optional);
+ // first n a's, then m-n a?'s.
+ // copyNode is called, for the same reason as above
+ if (minOccurs > 0) {
+ nodeRet = node;
+ for (int i=0; i<minOccurs-1; i++) {
+ nodeRet = new XSCMBinOp(XSModelGroup.MODELGROUP_SEQUENCE,
+ nodeRet, copyNode(node));
}
}
- else {
- for (int i=0; i<(minOccurs-1); i++) {
- particle = createParticle (XSParticleDecl.PARTICLE_SEQUENCE,
- particle,
- leafParticle);
+ if (maxOccurs > minOccurs) {
+ node = new XSCMUniOp(XSParticleDecl.PARTICLE_ZERO_OR_ONE, node);
+ if (nodeRet == null) {
+ nodeRet = node;
}
-
- optional = createParticle(XSParticleDecl.PARTICLE_ZERO_OR_ONE,
- leafParticle,
- null);
-
- for (int i=0; i < (maxOccurs-minOccurs); i++) {
- particle = createParticle(XSParticleDecl.PARTICLE_SEQUENCE,
- particle,
- optional);
+ else {
+ nodeRet = new XSCMBinOp(XSModelGroup.MODELGROUP_SEQUENCE,
+ nodeRet, copyNode(node));
+ }
+ for (int i=minOccurs; i<maxOccurs-1; i++) {
+ nodeRet = new XSCMBinOp(XSModelGroup.MODELGROUP_SEQUENCE,
+ nodeRet, node);
}
}
}
- return particle;
- }
-
- /**
- * Recursively builds an AllContentModel based on a particle tree
- * rooted at an ALL node.
- */
- private void gatherAllLeaves(XSParticleDecl particle,
- XSAllCM allContent) {
- Object left = particle.fValue;
- Object right = particle.fOtherValue;
- int type = particle.fType;
-
- if (type == XSParticleDecl.PARTICLE_ALL) {
-
- // At an all node, visit left and right subtrees
- gatherAllLeaves ((XSParticleDecl)left, allContent);
- gatherAllLeaves ((XSParticleDecl) particle.fOtherValue, allContent);
- }
- else if (type == XSParticleDecl.PARTICLE_ELEMENT) {
-
- // At leaf, add the element to list of elements permitted in the all
- allContent.addElement ((XSElementDecl)left, false);
- }
- else if (type == XSParticleDecl.PARTICLE_ZERO_OR_ONE) {
-
- // At ZERO_OR_ONE node, subtree must be an element
- // that was specified with minOccurs=0, maxOccurs=1
- // Add the optional element to list of elements permitted in the all
-
- if (((XSParticleDecl)left).fType == XSParticleDecl.PARTICLE_ELEMENT) {
- allContent.addElement ((XSElementDecl)(((XSParticleDecl)left).fValue), true);
- }
- else {
- // report error
- throw new RuntimeException("ImplementationMessages.VAL_CST");
- }
- }
- else {
- // report error
- throw new RuntimeException("ImplementationMessages.VAL_CSTA");
- }
- }
-
- private XSParticleDecl createParticle (short type,
- XSParticleDecl left,
- XSParticleDecl right) {
-
- XSParticleDecl newParticle;
- if (fDeclPool !=null) {
- newParticle = fDeclPool.getParticleDecl();
- } else {
- newParticle = new XSParticleDecl();
- }
- newParticle.fType = type;
- newParticle.fValue = (Object) left;
- newParticle.fOtherValue = (Object)right;
- return newParticle;
+ return nodeRet;
}
-
- // this method is needed to convert a tree of ParticleDecl
- // nodes into a tree of content models that XSDFACM methods can then use as input.
- private final CMNode buildSyntaxTree(XSParticleDecl startNode) {
-
- // We will build a node at this level for the new tree
- CMNode nodeRet = null;
- if (startNode.fType == XSParticleDecl.PARTICLE_WILDCARD) {
- nodeRet = new XSCMLeaf(startNode, fLeafCount++);
- }
- //
- // If this node is a leaf, then its an easy one. We just add it
- // to the tree.
- //
- else if (startNode.fType == XSParticleDecl.PARTICLE_ELEMENT) {
- //
- // Create a new leaf node, and pass it the current leaf count,
- // which is its DFA state position. Bump the leaf count after
- // storing it. This makes the positions zero based since we
- // store first and then increment.
- //
- nodeRet = new XSCMLeaf(startNode, fLeafCount++);
+
+ // 4. make sure each leaf node (XSCMLeaf) has a distinct position
+ private CMNode copyNode(CMNode node) {
+ int type = node.type();
+ // for choice or sequence, copy the two subtrees, and combine them
+ if (type == XSModelGroup.MODELGROUP_CHOICE ||
+ type == XSModelGroup.MODELGROUP_SEQUENCE) {
+ XSCMBinOp bin = (XSCMBinOp)node;
+ node = new XSCMBinOp(type, copyNode(bin.getLeft()),
+ copyNode(bin.getRight()));
+ }
+ // for ?+*, copy the subtree, and put it in a new ?+* node
+ else if (type == XSParticleDecl.PARTICLE_ZERO_OR_MORE ||
+ type == XSParticleDecl.PARTICLE_ONE_OR_MORE ||
+ type == XSParticleDecl.PARTICLE_ZERO_OR_ONE) {
+ XSCMUniOp uni = (XSCMUniOp)node;
+ node = new XSCMUniOp(type, copyNode(uni.getChild()));
+ }
+ // for element/wildcard (leaf), make a new leaf node,
+ // with a distinct position
+ else if (type == XSParticleDecl.PARTICLE_ELEMENT ||
+ type == XSParticleDecl.PARTICLE_WILDCARD) {
+ XSCMLeaf leaf = (XSCMLeaf)node;
+ node = new XSCMLeaf(leaf.type(), leaf.getLeaf(), leaf.getParticleId(), fLeafCount++);
}
- else {
- //
- // Its not a leaf, so we have to recurse its left and maybe right
- // nodes. Save both values before we recurse and trash the node.
- final XSParticleDecl leftNode = ((XSParticleDecl)startNode.fValue);
- final XSParticleDecl rightNode = ((XSParticleDecl)startNode.fOtherValue);
-
- if ((startNode.fType == XSParticleDecl.PARTICLE_CHOICE)
- || (startNode.fType == XSParticleDecl.PARTICLE_SEQUENCE)) {
- //
- // Recurse on both children, and return a binary op node
- // with the two created sub nodes as its children. The node
- // type is the same type as the source.
- //
-
- nodeRet = new XSCMBinOp( startNode.fType, buildSyntaxTree(leftNode)
- , buildSyntaxTree(rightNode));
- }
- else if (startNode.fType == XSParticleDecl.PARTICLE_ZERO_OR_MORE
- || startNode.fType == XSParticleDecl.PARTICLE_ZERO_OR_ONE
- || startNode.fType == XSParticleDecl.PARTICLE_ONE_OR_MORE) {
- nodeRet = new XSCMUniOp(startNode.fType, buildSyntaxTree(leftNode));
- }
- else {
- throw new RuntimeException("ImplementationMessages.VAL_CST");
- }
- }
- // And return our new node for this level
- return nodeRet;
+
+ return node;
}
-
}
1.3 +9 -8 xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSCMBinOp.java
Index: XSCMBinOp.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/models/XSCMBinOp.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- XSCMBinOp.java 29 Jan 2002 01:15:16 -0000 1.2
+++ XSCMBinOp.java 26 Apr 2002 22:03:42 -0000 1.3
@@ -60,6 +60,7 @@
import org.apache.xerces.impl.dtd.models.CMNode;
import org.apache.xerces.impl.dtd.models.CMStateSet;
import org.apache.xerces.impl.xs.XSParticleDecl;
+import org.apache.xerces.impl.xs.XSModelGroup;
/**
*
@@ -77,8 +78,8 @@
super(type);
// Insure that its one of the types we require
- if ((type() != XSParticleDecl.PARTICLE_CHOICE)
- && (type() != XSParticleDecl.PARTICLE_SEQUENCE)) {
+ if ((type() != XSModelGroup.MODELGROUP_CHOICE)
+ && (type() != XSModelGroup.MODELGROUP_SEQUENCE)) {
throw new RuntimeException("ImplementationMessages.VAL_BST");
}
@@ -109,9 +110,9 @@
// this node is nullable. If its a concatenation, then both of
// them have to be nullable.
//
- if (type() == XSParticleDecl.PARTICLE_CHOICE)
+ if (type() == XSModelGroup.MODELGROUP_CHOICE)
return (fLeftChild.isNullable() || fRightChild.isNullable());
- else if (type() == XSParticleDecl.PARTICLE_SEQUENCE)
+ else if (type() == XSModelGroup.MODELGROUP_SEQUENCE)
return (fLeftChild.isNullable() && fRightChild.isNullable());
else
throw new RuntimeException("ImplementationMessages.VAL_BST");
@@ -122,12 +123,12 @@
// Protected, inherited methods
// -------------------------------------------------------------------
protected void calcFirstPos(CMStateSet toSet) {
- if (type() == XSParticleDecl.PARTICLE_CHOICE) {
+ if (type() == XSModelGroup.MODELGROUP_CHOICE) {
// Its the the union of the first positions of our children.
toSet.setTo(fLeftChild.firstPos());
toSet.union(fRightChild.firstPos());
}
- else if (type() == XSParticleDecl.PARTICLE_SEQUENCE) {
+ else if (type() == XSModelGroup.MODELGROUP_SEQUENCE) {
//
// If our left child is nullable, then its the union of our
// children's first positions. Else is our left child's first
@@ -143,12 +144,12 @@
}
protected void calcLastPos(CMStateSet toSet) {
- if (type() == XSParticleDecl.PARTICLE_CHOICE) {
+ if (type() == XSModelGroup.MODELGROUP_CHOICE) {
// Its the the union of the first positions of our children.
toSet.setTo(fLeftChild.lastPos());
toSet.union(fRightChild.lastPos());
}
- else if (type() == XSParticleDecl.PARTICLE_SEQUENCE) {
+ else if (type() == XSModelGroup.MODELGROUP_SEQUENCE) {
//
// If our right child is nullable, then its the union of our
// children's last positions. Else is our right child's last
1.4 +16 -11 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.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- XSCMLeaf.java 29 Jan 2002 01:15:16 -0000 1.3
+++ XSCMLeaf.java 26 Apr 2002 22:03:42 -0000 1.4
@@ -76,8 +76,13 @@
// Data
//
- /** This is the leaf particle. */
- private XSParticleDecl fLeaf = null;
+ /** This is the leaf: element decl or wildcard decl. */
+ private Object fLeaf = null;
+
+ /**
+ * Identify the particle: for UPA checking
+ */
+ private int fParticleId = -1;
/**
* Part of the algorithm to convert a regex directly to a DFA
@@ -91,26 +96,26 @@
//
/** Constructs a content model leaf. */
- public XSCMLeaf(XSParticleDecl leaf, int position) {
- super(leaf.fType);
+ public XSCMLeaf(int type, Object leaf, int id, int position) {
+ super(type);
// Store the element index and position
fLeaf = leaf;
+ fParticleId = id;
fPosition = position;
}
- /** Constructs a content model leaf. */
- public XSCMLeaf(XSParticleDecl leaf) {
- this(leaf, -1);
- }
-
//
// Package methods
//
- final XSParticleDecl getLeaf() {
+ final Object getLeaf() {
return fLeaf;
}
+
+ final int getParticleId() {
+ return fParticleId;
+ }
final int getPosition() {
return fPosition;
@@ -132,7 +137,7 @@
}
public String toString() {
- StringBuffer strRet = new StringBuffer(fLeaf.fValue.toString());
+ StringBuffer strRet = new StringBuffer(fLeaf.toString());
if (fPosition >= 0) {
strRet.append
(
1.5 +65 -92 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.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- XSDFACM.java 15 Mar 2002 23:01:57 -0000 1.4
+++ XSDFACM.java 26 Apr 2002 22:03:42 -0000 1.5
@@ -64,6 +64,7 @@
import org.apache.xerces.impl.xs.SubstitutionGroupHandler;
import org.apache.xerces.impl.xs.XSElementDecl;
import org.apache.xerces.impl.xs.XSParticleDecl;
+import org.apache.xerces.impl.xs.XSModelGroup;
import org.apache.xerces.impl.xs.XSWildcardDecl;
import org.apache.xerces.impl.xs.XMLSchemaException;
import org.apache.xerces.impl.xs.XSConstraints;
@@ -75,7 +76,7 @@
* it then uses in its validation algorithm.
*
* @author Neil Graham, IBM
- * @version $Id: XSDFACM.java,v 1.4 2002/03/15 23:01:57 sandygao Exp $
+ * @version $Id: XSDFACM.java,v 1.5 2002/04/26 22:03:42 sandygao Exp $
*/
public class XSDFACM
implements XSCMValidator {
@@ -103,7 +104,7 @@
* actual validation. Note tat since either XSElementDecl or XSParticleDecl object
* can live here, we've got to use an Object.
*/
- private XSParticleDecl fElemMap[] = null;
+ private Object fElemMap[] = null;
/**
* This is a map of whether the element map contains information
@@ -111,21 +112,13 @@
*/
private int fElemMapType[] = null;
- /** The element map size. */
- private int fElemMapSize = 0;
-
- /* Used to indicate a mixed model */
- private boolean fMixed;
-
/**
- * The string index for the 'end of content' string that we add to
- * the string pool. This is used as the special name of an element
- * that represents the end of the syntax tree.
+ * id of the unique input symbol
*/
- private static final XSParticleDecl fEOCParticle = new XSParticleDecl();
- static {
- fEOCParticle.fType = XSParticleDecl.PARTICLE_ELEMENT;
- }
+ private int fElemMapId[] = null;
+
+ /** The element map size. */
+ private int fElemMapSize = 0;
/**
* The NFA position of the special EOC (end of content) node. This
@@ -216,24 +209,8 @@
* @exception RuntimeException Thrown if DFA can't be built.
*/
- public XSDFACM(CMNode syntaxTree,
- int leafCount) {
- this(syntaxTree, leafCount, false);
- }
-
- /**
- * Constructs a DFA content model.
- *
- * @param symbolTable The symbol table.
- * @param syntaxTree The syntax tree of the content model.
- * @param leafCount The number of leaves.
- *
- * @exception RuntimeException Thrown if DFA can't be built.
- */
-
- public XSDFACM(CMNode syntaxTree,
- int leafCount, boolean mixed) {
-
+ public XSDFACM(CMNode syntaxTree, int leafCount) {
+
// Store away our index and pools in members
fLeafCount = leafCount;
@@ -243,8 +220,6 @@
// (already done in static initialization...
//
- fMixed = mixed;
-
//
// Ok, so lets grind through the building of the DFA. This method
// handles the high level logic of the algorithm, but it uses a
@@ -321,14 +296,14 @@
continue;
int type = fElemMapType[elemIndex] ;
if (type == XSParticleDecl.PARTICLE_ELEMENT) {
- matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex].fValue);
+ matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex]);
if (matchingDecl != null) {
break;
}
}
else if (type == XSParticleDecl.PARTICLE_WILDCARD) {
- if(((XSWildcardDecl)fElemMap[elemIndex].fValue).allowNamespace(curElem.uri)) {
- matchingDecl = fElemMap[elemIndex].fValue;
+ if(((XSWildcardDecl)fElemMap[elemIndex]).allowNamespace(curElem.uri)) {
+ matchingDecl = fElemMap[elemIndex];
break;
}
}
@@ -351,14 +326,14 @@
for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) {
int type = fElemMapType[elemIndex] ;
if (type == XSParticleDecl.PARTICLE_ELEMENT) {
- matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex].fValue);
+ matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex]);
if (matchingDecl != null) {
return matchingDecl;
}
}
else if (type == XSParticleDecl.PARTICLE_WILDCARD) {
- if(((XSWildcardDecl)fElemMap[elemIndex].fValue).allowNamespace(curElem.uri))
- return fElemMap[elemIndex].fValue;
+ if(((XSWildcardDecl)fElemMap[elemIndex]).allowNamespace(curElem.uri))
+ return fElemMap[elemIndex];
}
}
@@ -433,13 +408,6 @@
* "(a, (b, a+, (c, (b, a+)+, a+, (d, (c, (b, a+)+, a+)+, (b, a+)+, a+)+)+)+)+"
*/
- XSCMLeaf nodeEOC = new XSCMLeaf(fEOCParticle);
- fHeadNode = new XSCMBinOp(
- XSParticleDecl.PARTICLE_SEQUENCE
- , syntaxTree
- , nodeEOC
- );
-
//
// And handle specially the EOC node, which also must be numbered
// and counted as a non-epsilon leaf node. It could not be handled
@@ -448,7 +416,12 @@
// building loop.
//
fEOCPos = fLeafCount;
- nodeEOC.setPosition(fLeafCount++);
+ XSCMLeaf nodeEOC = new XSCMLeaf(XSParticleDecl.PARTICLE_ELEMENT, null, -1, fLeafCount++);
+ fHeadNode = new XSCMBinOp(
+ XSModelGroup.MODELGROUP_SEQUENCE,
+ syntaxTree,
+ nodeEOC
+ );
//
// Ok, so now we have to iterate the new tree and do a little more
@@ -466,7 +439,7 @@
//
fLeafList = new XSCMLeaf[fLeafCount];
fLeafListType = new int[fLeafCount];
- postTreeBuildInit(fHeadNode, 0);
+ postTreeBuildInit(fHeadNode);
//
// And, moving onward... We now need to build the follow position
@@ -488,8 +461,9 @@
// 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 XSParticleDecl[fLeafCount];
+ fElemMap = new Object[fLeafCount];
fElemMapType = new int[fLeafCount];
+ fElemMapId = new int[fLeafCount];
fElemMapSize = 0;
for (int outIndex = 0; outIndex < fLeafCount; outIndex++) {
// optimization from Henry Zongaro:
@@ -497,16 +471,17 @@
fElemMap[outIndex] = null;
int inIndex = 0;
- final XSParticleDecl decl = fLeafList[outIndex].getLeaf();
+ final int id = fLeafList[outIndex].getParticleId();
for (; inIndex < fElemMapSize; inIndex++) {
- if (decl == fElemMap[inIndex])
+ if (id == fElemMapId[inIndex])
break;
}
// If it was not in the list, then add it, if not the EOC node
if (inIndex == fElemMapSize) {
- fElemMap[fElemMapSize] = decl;
+ fElemMap[fElemMapSize] = fLeafList[outIndex].getLeaf();
fElemMapType[fElemMapSize] = fLeafListType[outIndex];
+ fElemMapId[fElemMapSize] = id;
fElemMapSize++;
}
}
@@ -514,7 +489,7 @@
// the last entry in the element map must be the EOC element.
// remove it from the map.
if (DEBUG) {
- if (fElemMap[fElemMapSize-1] != fEOCParticle)
+ if (fElemMapId[fElemMapSize-1] != -1)
System.err.println("interal error in DFA: last element is not EOC.");
}
fElemMapSize--;
@@ -529,9 +504,9 @@
int fSortCount = 0;
for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) {
- final XSParticleDecl decl = fElemMap[elemIndex];
+ final int id = fElemMapId[elemIndex];
for (int leafIndex = 0; leafIndex < fLeafCount; leafIndex++) {
- if (decl == fLeafList[leafIndex].getLeaf())
+ if (id == fLeafList[leafIndex].getParticleId())
fLeafSorter[fSortCount++] = leafIndex;
}
fLeafSorter[fSortCount++] = -1;
@@ -734,7 +709,8 @@
fHeadNode = null;
fLeafList = null;
fFollowList = null;
-
+ fLeafListType = null;
+ fElemMapId = null;
}
/**
@@ -746,12 +722,12 @@
*/
private void calcFollowList(CMNode nodeCur) {
// Recurse as required
- if (nodeCur.type() == XSParticleDecl.PARTICLE_CHOICE) {
+ if (nodeCur.type() == XSModelGroup.MODELGROUP_CHOICE) {
// Recurse only
calcFollowList(((XSCMBinOp)nodeCur).getLeft());
calcFollowList(((XSCMBinOp)nodeCur).getRight());
}
- else if (nodeCur.type() == XSParticleDecl.PARTICLE_SEQUENCE) {
+ else if (nodeCur.type() == XSModelGroup.MODELGROUP_SEQUENCE) {
// Recurse first
calcFollowList(((XSCMBinOp)nodeCur).getLeft());
calcFollowList(((XSCMBinOp)nodeCur).getRight());
@@ -820,9 +796,9 @@
switch(type ) {
- case XSParticleDecl.PARTICLE_CHOICE:
- case XSParticleDecl.PARTICLE_SEQUENCE: {
- if (type == XSParticleDecl.PARTICLE_CHOICE)
+ case XSModelGroup.MODELGROUP_CHOICE:
+ case XSModelGroup.MODELGROUP_SEQUENCE: {
+ if (type == XSModelGroup.MODELGROUP_CHOICE)
System.out.print("Choice Node ");
else
System.out.print("Seq Node ");
@@ -861,9 +837,8 @@
"Leaf: (pos="
+ ((XSCMLeaf)nodeCur).getPosition()
+ "), "
- + ((XSCMLeaf)nodeCur).getLeaf().fValue
+ "(elemIndex="
- + ((XSCMLeaf)nodeCur).getLeaf().fValue
+ + ((XSCMLeaf)nodeCur).getLeaf()
+ ") "
);
@@ -906,42 +881,40 @@
}
/** Post tree build initialization. */
- private int postTreeBuildInit(CMNode nodeCur, int curIndex) throws RuntimeException {
+ private void postTreeBuildInit(CMNode nodeCur) throws RuntimeException {
// Set the maximum states on this node
nodeCur.setMaxStates(fLeafCount);
+ XSCMLeaf leaf = null;
+ int pos = 0;
// Recurse as required
if (nodeCur.type() == XSParticleDecl.PARTICLE_WILDCARD) {
- fLeafList[curIndex] = (XSCMLeaf)nodeCur;
- fLeafListType[curIndex] = XSParticleDecl.PARTICLE_WILDCARD;
- curIndex++;
- }
- else if ((nodeCur.type() == XSParticleDecl.PARTICLE_CHOICE)
- || (nodeCur.type() == XSParticleDecl.PARTICLE_SEQUENCE))
- {
- curIndex = postTreeBuildInit(((XSCMBinOp)nodeCur).getLeft(), curIndex);
- curIndex = postTreeBuildInit(((XSCMBinOp)nodeCur).getRight(), curIndex);
+ leaf = (XSCMLeaf)nodeCur;
+ pos = leaf.getPosition();
+ fLeafList[pos] = leaf;
+ fLeafListType[pos] = XSParticleDecl.PARTICLE_WILDCARD;
+ }
+ else if ((nodeCur.type() == XSModelGroup.MODELGROUP_CHOICE) ||
+ (nodeCur.type() == XSModelGroup.MODELGROUP_SEQUENCE)) {
+ postTreeBuildInit(((XSCMBinOp)nodeCur).getLeft());
+ postTreeBuildInit(((XSCMBinOp)nodeCur).getRight());
+ }
+ else if (nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_MORE ||
+ nodeCur.type() == XSParticleDecl.PARTICLE_ONE_OR_MORE ||
+ nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_ONE) {
+ postTreeBuildInit(((XSCMUniOp)nodeCur).getChild());
}
- else if (nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_MORE
- || nodeCur.type() == XSParticleDecl.PARTICLE_ONE_OR_MORE
- || nodeCur.type() == XSParticleDecl.PARTICLE_ZERO_OR_ONE)
- {
- curIndex = postTreeBuildInit(((XSCMUniOp)nodeCur).getChild(), curIndex);
- }
- else if (nodeCur.type() == XSParticleDecl.PARTICLE_ELEMENT) {
- //
+ else if (nodeCur.type() == XSParticleDecl.PARTICLE_ELEMENT) {
// Put this node in the leaf list at the current index if its
// a non-epsilon leaf.
- //
- fLeafList[curIndex] = (XSCMLeaf)nodeCur;
- fLeafListType[curIndex] = XSParticleDecl.PARTICLE_ELEMENT;
- curIndex++;
+ leaf = (XSCMLeaf)nodeCur;
+ pos = leaf.getPosition();
+ fLeafList[pos] = leaf;
+ fLeafListType[pos] = XSParticleDecl.PARTICLE_ELEMENT;
}
- else
- {
+ else {
throw new RuntimeException("ImplementationMessages.VAL_NIICM");
}
- return curIndex;
}
/**
@@ -965,7 +938,7 @@
fTransTable[i][k] != -1) {
if (conflictTable[j][k] == 0) {
conflictTable[j][k] = XSConstraints.overlapUPA
- (fElemMap[j].fValue,fElemMap[k].fValue,
+ (fElemMap[j],fElemMap[k],
subGroupHandler) ?
(byte)1 : (byte)-1;
}
@@ -991,7 +964,7 @@
// 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;
+ XSWildcardDecl wildcard = (XSWildcardDecl)fElemMap[i];
if (wildcard.fType == XSWildcardDecl.WILDCARD_LIST ||
wildcard.fType == XSWildcardDecl.WILDCARD_OTHER) {
return true;
1.8 +136 -104 xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDAbstractParticleTraverser.java
Index: XSDAbstractParticleTraverser.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDAbstractParticleTraverser.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- XSDAbstractParticleTraverser.java 4 Apr 2002 18:36:26 -0000 1.7
+++ XSDAbstractParticleTraverser.java 26 Apr 2002 22:03:43 -0000 1.8
@@ -60,6 +60,7 @@
import org.apache.xerces.impl.xs.SchemaGrammar;
import org.apache.xerces.impl.xs.SchemaSymbols;
import org.apache.xerces.impl.xs.XSParticleDecl;
+import org.apache.xerces.impl.xs.XSModelGroup;
import org.apache.xerces.util.DOMUtil;
import org.apache.xerces.impl.xs.util.XInt;
import org.w3c.dom.Element;
@@ -67,13 +68,12 @@
/**
* @author Elena Litani, IBM
* @author Sandy Gao, IBM
- * @version $Id: XSDAbstractParticleTraverser.java,v 1.7 2002/04/04 18:36:26 sandygao Exp $
+ * @version $Id: XSDAbstractParticleTraverser.java,v 1.8 2002/04/26 22:03:43 sandygao Exp $
*/
abstract class XSDAbstractParticleTraverser extends XSDAbstractTraverser {
XSDAbstractParticleTraverser (XSDHandler handler,
XSAttributeChecker gAttrCheck) {
-
super(handler, gAttrCheck);
}
@@ -106,10 +106,10 @@
child = DOMUtil.getNextSiblingElement(child);
}
}
- XSParticleDecl left = null;
- XSParticleDecl right = null;
String childName = null;
- XSParticleDecl particle, temp;
+ XSParticleDecl particle;
+ fPArray.pushContext();
+
for (; child != null; child = DOMUtil.getNextSiblingElement(child)) {
particle = null;
@@ -124,58 +124,42 @@
reportSchemaError("s4s-elt-must-match", args, child);
}
- if (left == null) {
- left = particle;
- }
- else if (right == null) {
- right = particle;
- }
- else {
- if (fSchemaHandler.fDeclPool !=null) {
- temp = fSchemaHandler.fDeclPool.getParticleDecl();
- } else {
- temp = new XSParticleDecl();
- }
- temp.fType = XSParticleDecl.PARTICLE_ALL;
- temp.fValue = left;
- temp.fOtherValue = right;
- left = temp;
- right = particle;
- }
- }
-
- if (left != null) {
- if (fSchemaHandler.fDeclPool !=null) {
- temp = fSchemaHandler.fDeclPool.getParticleDecl();
- } else {
- temp = new XSParticleDecl();
- }
- temp.fType = XSParticleDecl.PARTICLE_ALL;
- temp.fValue = left;
- temp.fOtherValue = right;
- left = temp;
+ if (particle != null)
+ fPArray.addParticle(particle);
}
+ particle = null;
// REVISIT: model group
// Quick fix for the case that particle <all> does not have any children.
// For now we return null. In the future we might want to return model group decl.
- if (left != null) {
+ if (fPArray.getParticleCount() != 0) {
XInt minAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MINOCCURS];
XInt maxAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MAXOCCURS];
Long defaultVals = (Long)attrValues[XSAttributeChecker.ATTIDX_FROMDEFAULT];
- left.fMinOccurs = minAtt.intValue();
- left.fMaxOccurs = maxAtt.intValue();
-
- left = checkOccurrences(left,
- SchemaSymbols.ELT_ALL,
- (Element)allDecl.getParentNode(),
- allContextFlags,
- defaultVals.longValue());
+
+ XSModelGroup group = new XSModelGroup();
+ group.fCompositor = XSModelGroup.MODELGROUP_ALL;
+ group.fParticleCount = fPArray.getParticleCount();
+ group.fParticles = fPArray.popContext();
+ particle = new XSParticleDecl();
+ particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
+ particle.fMinOccurs = minAtt.intValue();
+ particle.fMaxOccurs = maxAtt.intValue();
+ particle.fValue = group;
+
+ particle = checkOccurrences(particle,
+ SchemaSymbols.ELT_ALL,
+ (Element)allDecl.getParentNode(),
+ allContextFlags,
+ defaultVals.longValue());
+ }
+ else {
+ fPArray.discardContext();
}
fAttrChecker.returnAttrArray(attrValues, schemaDoc);
- return left;
+ return particle;
}
/**
@@ -250,11 +234,11 @@
child = DOMUtil.getNextSiblingElement(child);
}
}
- XSParticleDecl left = null;
- XSParticleDecl right = null;
boolean hadContent = false;
String childName = null;
- XSParticleDecl particle, temp;
+ XSParticleDecl particle;
+ fPArray.pushContext();
+
for (;child != null;child = DOMUtil.getNextSiblingElement(child)) {
particle = null;
@@ -277,10 +261,10 @@
}
else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
- particle = traverseChoice( child,schemaDoc, grammar, NOT_ALL_CONTEXT);
+ particle = traverseChoice(child, schemaDoc, grammar, NOT_ALL_CONTEXT);
}
else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
- particle = traverseSequence(child,schemaDoc, grammar, NOT_ALL_CONTEXT);
+ particle = traverseSequence(child, schemaDoc, grammar, NOT_ALL_CONTEXT);
}
else if (childName.equals(SchemaSymbols.ELT_ANY)) {
particle = fSchemaHandler.fWildCardTraverser.traverseAny(child, schemaDoc, grammar);
@@ -296,80 +280,128 @@
reportSchemaError("s4s-elt-must-match", args, child);
}
-
- if (left == null) {
- left = particle;
- }
- else if (right == null) {
- right = particle;
- }
- else {
- if (fSchemaHandler.fDeclPool !=null) {
- temp = fSchemaHandler.fDeclPool.getParticleDecl();
- } else {
- temp = new XSParticleDecl();
- }
- if (choice)
- temp.fType = XSParticleDecl.PARTICLE_CHOICE;
- else
- temp.fType = XSParticleDecl.PARTICLE_SEQUENCE;
- temp.fValue = left;
- temp.fOtherValue = right;
- left = temp;
- right = particle;
- }
+ if (particle != null)
+ fPArray.addParticle(particle);
}
+ particle = null;
+
// REVISIT: model group
// Quick fix for the case that particles <choice> | <sequence> do not have any children.
// For now we return null. In the future we might want to return model group decl.
-
- if (left != null) {
- if (fSchemaHandler.fDeclPool !=null) {
- temp = fSchemaHandler.fDeclPool.getParticleDecl();
- } else {
- temp = new XSParticleDecl();
- }
- if (choice)
- temp.fType = XSParticleDecl.PARTICLE_CHOICE;
- else
- temp.fType = XSParticleDecl.PARTICLE_SEQUENCE;
- temp.fValue = left;
- temp.fOtherValue = right;
- left = temp;
+ if (fPArray.getParticleCount() != 0) {
XInt minAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MINOCCURS];
XInt maxAtt = (XInt)attrValues[XSAttributeChecker.ATTIDX_MAXOCCURS];
Long defaultVals = (Long)attrValues[XSAttributeChecker.ATTIDX_FROMDEFAULT];
- left.fMinOccurs = minAtt.intValue();
- left.fMaxOccurs = maxAtt.intValue();
- left = checkOccurrences(left,
- choice ? SchemaSymbols.ELT_CHOICE : SchemaSymbols.ELT_SEQUENCE,
- (Element)decl.getParentNode(),
- allContextFlags,
- defaultVals.longValue());
+
+ XSModelGroup group = new XSModelGroup();
+ group.fCompositor = choice ? XSModelGroup.MODELGROUP_CHOICE : XSModelGroup.MODELGROUP_SEQUENCE;
+ group.fParticleCount = fPArray.getParticleCount();
+ group.fParticles = fPArray.popContext();
+ particle = new XSParticleDecl();
+ particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
+ particle.fMinOccurs = minAtt.intValue();
+ particle.fMaxOccurs = maxAtt.intValue();
+ particle.fValue = group;
+
+ particle = checkOccurrences(particle,
+ choice ? SchemaSymbols.ELT_CHOICE : SchemaSymbols.ELT_SEQUENCE,
+ (Element)decl.getParentNode(),
+ allContextFlags,
+ defaultVals.longValue());
+ }
+ else {
+ fPArray.discardContext();
}
fAttrChecker.returnAttrArray(attrValues, schemaDoc);
- return left;
+ return particle;
}
// Determines whether a content spec tree represents an "all" content model
protected boolean hasAllContent(XSParticleDecl particle) {
// If the content is not empty, is the top node ALL?
- if (particle != null) {
-
- // REVISIT: defered?
- // An ALL node could be optional, so we have to be prepared
- // to look one level below a ZERO_OR_ONE node for an ALL.
- //if (fParticle.type == XSParticleDecl.CONTENTSPECNODE_ZERO_OR_ONE) {
- // fSchemaGrammar.getContentSpec(content.value, content);
- //}
-
- return(particle.fType == XSParticleDecl.PARTICLE_ALL);
+ if (particle != null && particle.fType == XSParticleDecl.PARTICLE_MODELGROUP) {
+ return ((XSModelGroup)particle.fValue).fCompositor == XSModelGroup.MODELGROUP_ALL;
}
return false;
}
+ // the inner class: used to store particles for model groups
+ // to avoid creating a new Vector in each model group, or when traversing
+ // each model group, we use this one big array to store all particles
+ // for model groups. when the traversal finishes, this class returns an
+ // XSParticleDecl[] containing all particles for the current model group.
+ // it's possible that we need to traverse another model group while
+ // traversing one (one inside another one; referring to a global group,
+ // etc.), so we have push/pos context methods to save the same of the
+ // current traversal before starting the traversal of another model group.
+ protected static class ParticleArray {
+ // big array to contain all particles
+ XSParticleDecl[] fParticles = new XSParticleDecl[10];
+ // the ending position of particles in the array for each context
+ // index 0 is reserved, with value 0. index 1 is used for the fist
+ // context. so that the number of particles for context 'i' can be
+ // computed simply by fPos[i] - fPos[i-1].
+ int[] fPos = new int[5];
+ // number of contexts
+ int fContextCount = 0;
+
+ // start a new context (start traversing a new model group)
+ void pushContext() {
+ fContextCount++;
+ // resize position array if necessary
+ if (fContextCount == fPos.length) {
+ int newSize = fContextCount * 2;
+ int[] newArray = new int[newSize];
+ System.arraycopy(fPos, 0, newArray, 0, fContextCount);
+ fPos = newArray;
+ }
+ // the initial ending position of the current context is the
+ // ending position of the previsous context. which means there is
+ // no particle for the current context yet.
+ fPos[fContextCount] = fPos[fContextCount-1];
+ }
+
+ // get the number of particles of this context (model group)
+ int getParticleCount() {
+ return fPos[fContextCount] - fPos[fContextCount-1];
+ }
+
+ // add a particle to the current context
+ void addParticle(XSParticleDecl particle) {
+ // resize the particle array if necessary
+ if (fPos[fContextCount] == fParticles.length) {
+ int newSize = fPos[fContextCount] * 2;
+ XSParticleDecl[] newArray = new XSParticleDecl[newSize];
+ System.arraycopy(fParticles, 0, newArray, 0, fPos[fContextCount]);
+ fParticles = newArray;
+ }
+ fParticles[fPos[fContextCount]++] = particle;
+ }
+
+ // end the current context, and return an array of particles
+ XSParticleDecl[] popContext() {
+ int count = fPos[fContextCount] - fPos[fContextCount-1];
+ XSParticleDecl[] array = new XSParticleDecl[count];
+ System.arraycopy(fParticles, fPos[fContextCount-1], array, 0, count);
+ // clear the particle array, to release memory
+ for (int i = fPos[fContextCount-1]; i < fPos[fContextCount]; i++)
+ fParticles[i] = null;
+ fContextCount--;
+ return array;
+ }
+
+ void discardContext() {
+ // clear the particle array, to release memory
+ for (int i = fPos[fContextCount-1]; i < fPos[fContextCount]; i++)
+ fParticles[i] = null;
+ fContextCount--;
+ }
+ }
+
+ // the big particle array to hold all particles in model groups
+ ParticleArray fPArray = new ParticleArray();
}
1.18 +29 -13 xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDComplexTypeTraverser.java
Index: XSDComplexTypeTraverser.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDComplexTypeTraverser.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- XSDComplexTypeTraverser.java 4 Apr 2002 18:36:26 -0000 1.17
+++ XSDComplexTypeTraverser.java 26 Apr 2002 22:03:43 -0000 1.18
@@ -69,6 +69,7 @@
import org.apache.xerces.impl.xs.XSAttributeUse;
import org.apache.xerces.impl.xs.XSWildcardDecl;
import org.apache.xerces.impl.xs.XSParticleDecl;
+import org.apache.xerces.impl.xs.XSModelGroup;
import org.apache.xerces.util.DOMUtil;
import org.apache.xerces.impl.xs.util.XInt;
import org.apache.xerces.impl.xs.util.XIntPool;
@@ -91,7 +92,7 @@
* ((group | all | choice | sequence)?,
* ((attribute | attributeGroup)*, anyAttribute?))))
* </complexType>
- * @version $Id: XSDComplexTypeTraverser.java,v 1.17 2002/04/04 18:36:26 sandygao Exp $
+ * @version $Id: XSDComplexTypeTraverser.java,v 1.18 2002/04/26 22:03:43 sandygao Exp $
*/
class XSDComplexTypeTraverser extends XSDAbstractParticleTraverser {
@@ -721,16 +722,27 @@
else if (baseContent==null) {
}
else {
- if (typeInfo.fParticle.fType == XSParticleDecl.PARTICLE_ALL ||
- baseType.fParticle.fType == XSParticleDecl.PARTICLE_ALL) {
+ // if the content of either type is an "all" model group, error.
+ if (typeInfo.fParticle.fType == XSParticleDecl.PARTICLE_MODELGROUP &&
+ ((XSModelGroup)typeInfo.fParticle.fValue).fCompositor == XSModelGroup.MODELGROUP_ALL ||
+ baseType.fParticle.fType == XSParticleDecl.PARTICLE_MODELGROUP &&
+ ((XSModelGroup)baseType.fParticle.fValue).fCompositor == XSModelGroup.MODELGROUP_ALL) {
throw new ComplexTypeRecoverableError("cos-all-limited.1.2",
null, complexContent);
}
- XSParticleDecl temp = new XSParticleDecl();
- temp.fType = XSParticleDecl.PARTICLE_SEQUENCE;
- temp.fValue = baseContent;
- temp.fOtherValue = typeInfo.fParticle;
- typeInfo.fParticle = temp;
+ // the "sequence" model group to contain both particles
+ XSModelGroup group = new XSModelGroup();
+ group.fCompositor = XSModelGroup.MODELGROUP_SEQUENCE;
+ group.fParticleCount = 2;
+ group.fParticles = new XSParticleDecl[2];
+ group.fParticles[0] = baseType.fParticle;
+ group.fParticles[1] = typeInfo.fParticle;
+ // the particle to contain the above sequence
+ XSParticleDecl particle = new XSParticleDecl();
+ particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
+ particle.fValue = group;
+
+ typeInfo.fParticle = particle;
}
// Set the contentType
@@ -949,17 +961,21 @@
private static synchronized XSParticleDecl getErrorContent() {
if (fErrorContent==null) {
- fErrorContent = new XSParticleDecl();
- fErrorContent.fType = XSParticleDecl.PARTICLE_SEQUENCE;
- XSParticleDecl particle = new XSParticleDecl();
fErrorWildcard = new XSWildcardDecl();
fErrorWildcard.fProcessContents = XSWildcardDecl.WILDCARD_SKIP;
+ XSParticleDecl particle = new XSParticleDecl();
particle.fType = XSParticleDecl.PARTICLE_WILDCARD;
particle.fValue = fErrorWildcard;
particle.fMinOccurs = 0;
particle.fMaxOccurs = SchemaSymbols.OCCURRENCE_UNBOUNDED;
- fErrorContent.fValue = particle;
- fErrorContent.fOtherValue = null;
+ XSModelGroup group = new XSModelGroup();
+ group.fCompositor = XSModelGroup.MODELGROUP_SEQUENCE;
+ group.fParticleCount = 1;
+ group.fParticles = new XSParticleDecl[1];
+ group.fParticles[0] = particle;
+ fErrorContent = new XSParticleDecl();
+ fErrorContent.fType = XSParticleDecl.PARTICLE_MODELGROUP;
+ fErrorContent.fValue = group;
}
return fErrorContent;
1.11 +16 -20 xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDGroupTraverser.java
Index: XSDGroupTraverser.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDGroupTraverser.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- XSDGroupTraverser.java 4 Apr 2002 18:36:26 -0000 1.10
+++ XSDGroupTraverser.java 26 Apr 2002 22:03:43 -0000 1.11
@@ -59,6 +59,7 @@
import org.apache.xerces.impl.xs.SchemaGrammar;
import org.apache.xerces.impl.xs.SchemaSymbols;
import org.apache.xerces.impl.xs.XSParticleDecl;
+import org.apache.xerces.impl.xs.XSModelGroup;
import org.apache.xerces.impl.xs.XSGroupDecl;
import org.apache.xerces.impl.xs.XSMessageFormatter;
import org.apache.xerces.util.DOMUtil;
@@ -77,7 +78,7 @@
* @author Rahul Srivastava, Sun Microsystems Inc.
* @author Elena Litani, IBM
* @author Lisa Martin, IBM
- * @version $Id: XSDGroupTraverser.java,v 1.10 2002/04/04 18:36:26 sandygao Exp $
+ * @version $Id: XSDGroupTraverser.java,v 1.11 2002/04/26 22:03:43 sandygao Exp $
*/
class XSDGroupTraverser extends XSDAbstractParticleTraverser {
@@ -119,25 +120,19 @@
XSParticleDecl particle = null;
- if (group != null) {
- // empty particle
- if (minOccurs == 0 && maxOccurs == 0) {
- } else if (minOccurs == 1 && maxOccurs == 1) {
- particle = group.fParticle;
- }
- else if (!( minOccurs == 1 && maxOccurs == 1)) {
- // if minOccurs==maxOccurs==1 we don't need to create new particle
- // create new particle in the grammar if minOccurs<maxOccurs
- if (fSchemaHandler.fDeclPool !=null) {
- particle = fSchemaHandler.fDeclPool.getParticleDecl();
- } else {
- particle = new XSParticleDecl();
- }
- particle.fType = group.fParticle.fType;
- particle.fValue = group.fParticle;
- particle.fMinOccurs = minOccurs;
- particle.fMaxOccurs = maxOccurs;
+ // not empty group, not empty particle
+ if (group != null && group.fModelGroup != null &&
+ !(minOccurs == 0 && maxOccurs == 0)) {
+ // create a particle to contain this model group
+ if (fSchemaHandler.fDeclPool != null) {
+ particle = fSchemaHandler.fDeclPool.getParticleDecl();
+ } else {
+ particle = new XSParticleDecl();
}
+ particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
+ particle.fValue = group.fModelGroup;
+ particle.fMinOccurs = minOccurs;
+ particle.fMaxOccurs = maxOccurs;
}
fAttrChecker.returnAttrArray(attrValues, schemaDoc);
@@ -206,7 +201,8 @@
group = new XSGroupDecl();
group.fName = strNameAttr;
group.fTargetNamespace = schemaDoc.fTargetNamespace;
- group.fParticle = particle;
+ if (particle != null)
+ group.fModelGroup = (XSModelGroup)particle.fValue;
grammar.addGlobalGroupDecl(group);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org