// 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, boolean optimize) {
CMNode nodeRet = null;
if (minOccurs==1 && maxOccurs==1) {
nodeRet = node;
}
else if (minOccurs==0 && maxOccurs==1) {
//zero or one
nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, node);
}
else if (minOccurs == 0 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) {
//zero or more
nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_MORE, node);
}
else if (minOccurs == 1 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) {
//one or more
nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ONE_OR_MORE, node);
}
else if (optimize && node.type() == XSParticleDecl.PARTICLE_ELEMENT ||
node.type() == XSParticleDecl.PARTICLE_WILDCARD) {
// Only for elements and wildcards, subsume e{n,m} and e{n,unbounded} to e*
// or e+ and, once the DFA reaches a final state, check if the actual number
// of elements is between minOccurs and maxOccurs. This new algorithm runs
// in constant space.
// TODO: What is the impact of this optimization on the PSVI?
nodeRet = fNodeFactory.getCMUniOpNode(
minOccurs == 0 ? XSParticleDecl.PARTICLE_ZERO_OR_MORE
: XSParticleDecl.PARTICLE_ONE_OR_MORE, node);
nodeRet.setUserData(new int[] { minOccurs, maxOccurs });
}
else if (maxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED) {
// => a,a,..,a+
// 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