1 22 23 package org.xquark.schema.validation; 24 25 import org.xquark.schema.*; 26 27 public class ElementTreeContentIterator extends ContentIterator { 28 private static final String RCSRevision = "$Revision: 1.2 $"; 29 private static final String RCSName = "$Name: $"; 30 private java.util.LinkedList iterators = new java.util.LinkedList (); 31 private ContentIterator iterator; 32 private ElementDeclaration matchedDecl = null; 33 private SchemaManager manager; 34 35 public ElementTreeContentIterator(SchemaManager manager) { 36 this(manager, false); 37 } 38 39 public ElementTreeContentIterator(SchemaManager manager, boolean strict) { 40 this.manager = manager; 41 this.iterator = new DefaultContentIterator(manager, strict ? STRICT : LAX); 42 } 43 44 public ElementTreeContentIterator(ComplexType type) { 45 this.manager = type.getManager(); 46 DefaultContentIterator dummy = new DefaultContentIterator(manager); 47 dummy.setType(type); 48 iterators.addFirst(dummy); 49 this.iterator = type.childIterator(); 50 } 51 52 public ElementDeclaration getMatchedDeclaration() { 53 return matchedDecl; 54 } 55 56 public ElementDeclaration getModelDeclaration() { 57 if (iterator != null) 58 return iterator.getModelDeclaration(); 59 else 60 return null; 61 } 62 63 public int getProcessContents() { 64 return iterator.getProcessContents(); 65 } 66 67 public void startElement(String namespace, String localName, Type localType, boolean localTypePresent) 68 throws SchemaException { 69 if (done) 70 illegalState("Iterator terminated for element {" + namespace + "}" + localName); 71 72 if (endRequired) { 73 if (currentType.isSimpleType()) 74 invalidElement("cvc-type.3.1.2", currentType); 75 else if (currentType.getContentType() == EMPTY) 76 invalidElement("cvc-complex-type.2.1", currentType); 77 else if (currentType.getContentType() == TEXT_ONLY) 78 invalidElement("cvc-complex-type.2.2", currentType); 79 else 80 invalidElement("cvc-complex-type.2.4", currentType); 81 endRequired = false; 82 iterators.addFirst(iterator); 83 iterator = new DefaultContentIterator(manager); 84 } 85 Type parentType = null; 86 currentType = null; 87 switch (iterator.nextElement(namespace, localName)) { 88 case MATCHED : 89 matchedDecl = iterator.getMatchedDeclaration(); 90 currentType = checkDeclarationAndType(localType, localTypePresent); 91 if (currentType != null) { 92 iterator.setType(currentType); 94 ContentIterator nextIterator = currentType.childIterator(); 95 if (nextIterator != null) { 96 endRequired = false; 97 iterators.addFirst(iterator); 98 iterator = nextIterator; 99 } else { 100 endRequired = true; 101 } 102 checkPendingExceptions(); 103 return; 104 } else { 105 endRequired = false; 106 iterators.addFirst(iterator); 107 iterator = new DefaultContentIterator(manager); 108 checkPendingExceptions(); 109 return; 110 } 111 case UNKNOWN : 112 matchedDecl = null; 114 currentType = checkDeclarationAndType(localType, localTypePresent); 115 if (currentType != null) { 116 iterator.setType(currentType); 118 ContentIterator nextIterator = currentType.childIterator(); 119 if (nextIterator != null) { 120 endRequired = false; 121 iterators.addFirst(iterator); 122 iterator = nextIterator; 123 } else { 124 endRequired = true; 125 } 126 checkPendingExceptions(); 127 return; 128 } else { 129 endRequired = false; 130 iterators.addFirst(iterator); 131 iterator = new DefaultContentIterator(manager, iterator.getProcessContents()); 132 checkPendingExceptions(); 133 return; 134 } 135 case INVALID : 136 case TOO_MANY : 137 if (!iterators.isEmpty()) 138 parentType = ((ContentIterator) iterators.getFirst()).getType(); 139 invalidElement("cvc-complex-type.2.4", parentType, iterator.getExceptions()); 140 break; 141 case DONE : 142 if (!iterators.isEmpty()) 143 parentType = ((ContentIterator) iterators.getFirst()).getType(); 144 invalidElement( 145 "cvc-complex-type.2.4", 146 parentType, 147 SchemaException.computeException(iterator.getParticle())); 148 break; 149 } 150 151 if (parentType == null && iterator != null && iterator instanceof DefaultContentIterator) 152 invalidElement("cvc-complex-type.2.4", matchedDecl); 154 else { 155 if (parentType != null) 157 iterator = new DefaultContentIterator((ComplexType) parentType); 158 else 159 iterator = new DefaultContentIterator(manager); 160 endRequired = false; 161 startElement(namespace, localName, localType, localTypePresent); 163 } 164 } 165 166 private void checkPendingExceptions() throws SchemaException { 167 if (!isValid()) { 168 SchemaException exception = new SchemaException(getExceptions()); 169 resetExceptions(); 170 throw exception; 171 } 172 } 173 174 public void endElement(String namespace, String localName) throws SchemaException { 175 if (done) 176 illegalState("Iterator terminated for element {" + namespace + "}" + localName); 177 else if (!endRequired) { 178 if (iterator.stopProcessing() == INVALID) { 179 Type parentType = null; 180 if (!iterators.isEmpty()) 181 parentType = ((ContentIterator) iterators.getFirst()).getType(); 182 invalidElement("cvc-complex-type.2.4", parentType, iterator.getExceptions()); 183 } 184 if (iterators.isEmpty()) { 185 illegalState("Too many endElement statements before element {" + namespace + "}" + localName); 186 } else { 187 iterator = (ContentIterator) iterators.removeFirst(); 188 if (!iterators.isEmpty()) { 189 ContentIterator prev = (ContentIterator) iterators.getFirst(); 190 currentType = prev.getType(); 191 matchedDecl = prev.getMatchedDeclaration(); 192 } 193 } 194 } 195 endRequired = false; 196 checkPendingExceptions(); 197 } 198 199 public int getMinOccurs() { 200 return iterator.getMinOccurs(); 201 } 202 203 public int getMaxOccurs() { 204 return iterator.getMaxOccurs(); 205 } 206 207 public Particle getParticle() { 208 return iterator.getParticle(); 209 } 210 211 protected int nextElement(String namespace, String localName) { 212 return INVALID; 213 } 214 215 public int stopProcessing() { 216 return INVALID; 217 } 218 219 protected boolean nextValidElements(java.util.List elements) { 220 return iterator.nextValidElements(elements); 221 } 222 223 } 224 | Popular Tags |