1 16 17 package org.apache.xerces.impl.xs.models; 18 19 import org.apache.xerces.impl.dtd.models.CMNode; 20 import org.apache.xerces.impl.xs.SchemaSymbols; 21 import org.apache.xerces.impl.xs.XSComplexTypeDecl; 22 import org.apache.xerces.impl.xs.XSDeclarationPool; 23 import org.apache.xerces.impl.xs.XSElementDecl; 24 import org.apache.xerces.impl.xs.XSModelGroupImpl; 25 import org.apache.xerces.impl.xs.XSParticleDecl; 26 27 37 public class CMBuilder { 38 39 private XSDeclarationPool fDeclPool = null; 41 42 private static XSEmptyCM fEmptyCM = new XSEmptyCM(); 44 45 private int fLeafCount; 47 private int fParticleCount; 49 private CMNodeFactory fNodeFactory ; 51 52 public CMBuilder(CMNodeFactory nodeFactory) { 53 fDeclPool = null; 54 fNodeFactory = nodeFactory ; 55 } 56 57 public void setDeclPool(XSDeclarationPool declPool) { 58 fDeclPool = declPool; 59 } 60 61 67 public XSCMValidator getContentModel(XSComplexTypeDecl typeDecl) { 68 69 short contentType = typeDecl.getContentType(); 72 if (contentType == XSComplexTypeDecl.CONTENTTYPE_SIMPLE || 73 contentType == XSComplexTypeDecl.CONTENTTYPE_EMPTY) { 74 return null; 75 } 76 77 XSParticleDecl particle = (XSParticleDecl)typeDecl.getParticle(); 78 79 if (particle == null) 82 return fEmptyCM; 83 84 XSCMValidator cmValidator = null; 87 if (particle.fType == XSParticleDecl.PARTICLE_MODELGROUP && 88 ((XSModelGroupImpl)particle.fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL) { 89 cmValidator = createAllCM(particle); 90 } 91 else { 92 cmValidator = createDFACM(particle); 93 } 94 95 fNodeFactory.resetNodeCount() ; 98 99 if (cmValidator == null) 102 cmValidator = fEmptyCM; 103 104 return cmValidator; 105 } 106 107 XSCMValidator createAllCM(XSParticleDecl particle) { 108 if (particle.fMaxOccurs == 0) 109 return null; 110 111 XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue; 113 XSAllCM allContent = new XSAllCM(particle.fMinOccurs == 0, group.fParticleCount); 116 for (int i = 0; i < group.fParticleCount; i++) { 117 allContent.addElement((XSElementDecl)group.fParticles[i].fValue, 119 group.fParticles[i].fMinOccurs == 0); 120 } 121 return allContent; 122 } 123 124 XSCMValidator createDFACM(XSParticleDecl particle) { 125 fLeafCount = 0; 126 fParticleCount = 0; 127 CMNode node = buildSyntaxTree(particle); 129 if (node == null) 130 return null; 131 return new XSDFACM(node, fLeafCount); 133 } 134 135 private CMNode buildSyntaxTree(XSParticleDecl particle) { 142 143 int maxOccurs = particle.fMaxOccurs; 144 int minOccurs = particle.fMinOccurs; 145 short type = particle.fType; 146 CMNode nodeRet = null; 147 148 if ((type == XSParticleDecl.PARTICLE_WILDCARD) || 149 (type == XSParticleDecl.PARTICLE_ELEMENT)) { 150 nodeRet = fNodeFactory.getCMLeafNode(particle.fType, particle.fValue, fParticleCount++, fLeafCount++); 157 nodeRet = expandContentModel(nodeRet, minOccurs, maxOccurs); 159 } 160 else if (type == XSParticleDecl.PARTICLE_MODELGROUP) { 161 XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue; 163 CMNode temp = null; 164 boolean twoChildren = false; 175 for (int i = 0; i < group.fParticleCount; i++) { 176 temp = buildSyntaxTree(group.fParticles[i]); 178 if (temp != null) { 180 if (nodeRet == null) { 181 nodeRet = temp; 182 } 183 else { 184 nodeRet = fNodeFactory.getCMBinOpNode(group.fCompositor, nodeRet, temp); 185 twoChildren = true; 187 } 188 } 189 } 190 if (nodeRet != null) { 192 if (group.fCompositor == XSModelGroupImpl.MODELGROUP_CHOICE && 197 !twoChildren && group.fParticleCount > 1) { 198 nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, nodeRet); 199 } 200 nodeRet = expandContentModel(nodeRet, minOccurs, maxOccurs); 201 } 202 } 203 204 return nodeRet; 205 } 206 207 private CMNode expandContentModel(CMNode node, 211 int minOccurs, int maxOccurs) { 212 213 CMNode nodeRet = null; 214 215 if (minOccurs==1 && maxOccurs==1) { 216 nodeRet = node; 217 } 218 else if (minOccurs==0 && maxOccurs==1) { 219 nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, node); 221 } 222 else if (minOccurs == 0 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) { 223 nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_MORE, node); 225 } 226 else if (minOccurs == 1 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) { 227 nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ONE_OR_MORE, node); 229 } 230 else if (maxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED) { 231 nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ONE_OR_MORE, node); 236 nodeRet = fNodeFactory.getCMBinOpNode(XSModelGroupImpl.MODELGROUP_SEQUENCE, 241 multiNodes(node, minOccurs-1, true), nodeRet); 242 } 243 else { 244 if (minOccurs > 0) { 248 nodeRet = multiNodes(node, minOccurs, false); 249 } 250 if (maxOccurs > minOccurs) { 251 node = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, node); 252 if (nodeRet == null) { 253 nodeRet = multiNodes(node, maxOccurs-minOccurs, false); 254 } 255 else { 256 nodeRet = fNodeFactory.getCMBinOpNode(XSModelGroupImpl.MODELGROUP_SEQUENCE, 257 nodeRet, multiNodes(node, maxOccurs-minOccurs, true)); 258 } 259 } 260 } 261 262 return nodeRet; 263 } 264 265 private CMNode multiNodes(CMNode node, int num, boolean copyFirst) { 266 if (num == 0) { 267 return null; 268 } 269 if (num == 1) { 270 return copyFirst ? copyNode(node) : node; 271 } 272 int num1 = num/2; 273 return fNodeFactory.getCMBinOpNode(XSModelGroupImpl.MODELGROUP_SEQUENCE, 274 multiNodes(node, num1, copyFirst), 275 multiNodes(node, num-num1, true)); 276 } 277 278 private CMNode copyNode(CMNode node) { 280 int type = node.type(); 281 if (type == XSModelGroupImpl.MODELGROUP_CHOICE || 283 type == XSModelGroupImpl.MODELGROUP_SEQUENCE) { 284 XSCMBinOp bin = (XSCMBinOp)node; 285 node = fNodeFactory.getCMBinOpNode(type, copyNode(bin.getLeft()), 286 copyNode(bin.getRight())); 287 } 288 else if (type == XSParticleDecl.PARTICLE_ZERO_OR_MORE || 290 type == XSParticleDecl.PARTICLE_ONE_OR_MORE || 291 type == XSParticleDecl.PARTICLE_ZERO_OR_ONE) { 292 XSCMUniOp uni = (XSCMUniOp)node; 293 node = fNodeFactory.getCMUniOpNode(type, copyNode(uni.getChild())); 294 } 295 else if (type == XSParticleDecl.PARTICLE_ELEMENT || 298 type == XSParticleDecl.PARTICLE_WILDCARD) { 299 XSCMLeaf leaf = (XSCMLeaf)node; 300 node = fNodeFactory.getCMLeafNode(leaf.type(), leaf.getLeaf(), leaf.getParticleId(), fLeafCount++); 301 } 302 303 return node; 304 } 305 } 306 | Popular Tags |