1 16 17 package org.apache.xerces.impl.xs.opti; 18 19 import java.io.IOException ; 20 21 import org.apache.xerces.impl.Constants; 22 import org.apache.xerces.impl.XMLErrorReporter; 23 import org.apache.xerces.impl.xs.SchemaSymbols; 24 import org.apache.xerces.impl.xs.XSMessageFormatter; 25 import org.apache.xerces.util.XMLAttributesImpl; 26 import org.apache.xerces.util.XMLChar; 27 import org.apache.xerces.xni.Augmentations; 28 import org.apache.xerces.xni.NamespaceContext; 29 import org.apache.xerces.xni.QName; 30 import org.apache.xerces.xni.XMLAttributes; 31 import org.apache.xerces.xni.XMLLocator; 32 import org.apache.xerces.xni.XMLString; 33 import org.apache.xerces.xni.XNIException; 34 import org.apache.xerces.xni.parser.XMLEntityResolver; 35 import org.apache.xerces.xni.parser.XMLInputSource; 36 import org.apache.xerces.xni.parser.XMLParserConfiguration; 37 import org.w3c.dom.Document ; 38 39 47 public class SchemaDOMParser extends DefaultXMLDocumentHandler { 48 49 53 54 public static final String ERROR_REPORTER = 55 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 56 57 58 public static final String GENERATE_SYNTHETIC_ANNOTATION = 59 Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE; 60 61 protected XMLLocator fLocator; 63 64 protected NamespaceContext fNamespaceContext = null; 67 68 SchemaDOM schemaDOM; 69 70 XMLParserConfiguration config; 71 72 76 77 public SchemaDOMParser(XMLParserConfiguration config) { 78 this.config = config; 79 } 80 81 private int fAnnotationDepth = -1; 84 private int fInnerAnnotationDepth = -1; 87 private int fDepth = -1; 89 XMLErrorReporter fErrorReporter; 91 92 private boolean fGenerateSyntheticAnnotation = false; 94 private BooleanStack fHasNonSchemaAttributes = new BooleanStack(); 95 private BooleanStack fSawAnnotation = new BooleanStack(); 96 private XMLAttributes fEmptyAttr = new XMLAttributesImpl(); 97 98 102 public void startDocument(XMLLocator locator, String encoding, 103 NamespaceContext namespaceContext, Augmentations augs) 104 throws XNIException { 105 fErrorReporter = (XMLErrorReporter)config.getProperty(ERROR_REPORTER); 106 fGenerateSyntheticAnnotation = config.getFeature(GENERATE_SYNTHETIC_ANNOTATION); 107 fHasNonSchemaAttributes.clear(); 108 fSawAnnotation.clear(); 109 schemaDOM = new SchemaDOM(); 110 fAnnotationDepth = -1; 111 fInnerAnnotationDepth = -1; 112 fDepth = -1; 113 fLocator = locator; 114 fNamespaceContext = namespaceContext; 115 schemaDOM.setDocumentURI(locator.getExpandedSystemId()); 116 } 118 124 public void endDocument(Augmentations augs) throws XNIException { 125 } 129 130 139 public void comment(XMLString text, Augmentations augs) throws XNIException { 140 if(fAnnotationDepth > -1) { 141 schemaDOM.comment(text); 142 } 143 } 144 145 163 public void processingInstruction(String target, XMLString data, Augmentations augs) 164 throws XNIException { 165 if(fAnnotationDepth > -1) { 166 schemaDOM.processingInstruction(target, data.toString()); 167 } 168 } 169 170 179 public void characters(XMLString text, Augmentations augs) throws XNIException { 180 if (fInnerAnnotationDepth == -1 ) { 182 for (int i=text.offset; i<text.offset+text.length; i++) { 183 if (!XMLChar.isSpace(text.ch[i])) { 185 String txt = new String (text.ch, i, text.length+text.offset-i); 187 fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN, 189 "s4s-elt-character", 190 new Object []{txt}, 191 XMLErrorReporter.SEVERITY_ERROR); 192 break; 193 } 194 } 195 } 199 else { 202 schemaDOM.characters(text); 203 } 204 205 } 206 207 208 218 public void startElement(QName element, XMLAttributes attributes, Augmentations augs) 219 throws XNIException { 220 221 fDepth++; 222 if (fAnnotationDepth == -1) { 228 if (element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && 229 element.localpart == SchemaSymbols.ELT_ANNOTATION) { 230 if (fGenerateSyntheticAnnotation) { 231 if (fSawAnnotation.size() > 0) { 232 fSawAnnotation.pop(); 233 } 234 fSawAnnotation.push(true); 235 } 236 fAnnotationDepth = fDepth; 237 schemaDOM.startAnnotation(element, attributes, fNamespaceContext); 238 } 239 else if (element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && fGenerateSyntheticAnnotation) { 240 fSawAnnotation.push(false); 241 fHasNonSchemaAttributes.push(hasNonSchemaAttributes(element, attributes)); 242 } 243 } else if(fDepth == fAnnotationDepth+1) { 244 fInnerAnnotationDepth = fDepth; 245 schemaDOM.startAnnotationElement(element, attributes); 246 } else { 247 schemaDOM.startAnnotationElement(element, attributes); 248 return; 250 } 251 schemaDOM.startElement(element, attributes, 252 fLocator.getLineNumber(), 253 fLocator.getColumnNumber(), 254 fLocator.getCharacterOffset()); 255 256 } 257 258 259 269 public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs) 270 throws XNIException { 271 272 if (fGenerateSyntheticAnnotation && fAnnotationDepth == -1 && 273 element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && element.localpart != SchemaSymbols.ELT_ANNOTATION && hasNonSchemaAttributes(element, attributes)) { 274 275 schemaDOM.startElement(element, attributes, 276 fLocator.getLineNumber(), 277 fLocator.getColumnNumber(), 278 fLocator.getCharacterOffset()); 279 280 attributes.removeAllAttributes(); 281 String schemaPrefix = fNamespaceContext.getPrefix(SchemaSymbols.URI_SCHEMAFORSCHEMA); 282 QName annQName = new QName(schemaPrefix, SchemaSymbols.ELT_ANNOTATION, schemaPrefix + (schemaPrefix.length() == 0?"":":") + SchemaSymbols.ELT_ANNOTATION, SchemaSymbols.URI_SCHEMAFORSCHEMA); 283 schemaDOM.startAnnotation(annQName, attributes, fNamespaceContext); 284 QName elemQName = new QName(schemaPrefix, SchemaSymbols.ELT_DOCUMENTATION, schemaPrefix + (schemaPrefix.length() == 0?"":":") + SchemaSymbols.ELT_DOCUMENTATION, SchemaSymbols.URI_SCHEMAFORSCHEMA); 285 schemaDOM.startAnnotationElement(elemQName, attributes); 286 schemaDOM.characters(new XMLString("SYNTHETIC_ANNOTATION".toCharArray(), 0, 20 )); 287 schemaDOM.endSyntheticAnnotationElement(elemQName, false); 288 schemaDOM.endSyntheticAnnotationElement(annQName, true); 289 290 schemaDOM.endElement(); 291 292 return; 293 } 294 if (fAnnotationDepth == -1) { 306 if (element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && 308 element.localpart == SchemaSymbols.ELT_ANNOTATION) { 309 schemaDOM.startAnnotation(element, attributes, fNamespaceContext); 310 } 311 } else { 312 schemaDOM.startAnnotationElement(element, attributes); 313 } 314 315 schemaDOM.emptyElement(element, attributes, 316 fLocator.getLineNumber(), 317 fLocator.getColumnNumber(), 318 fLocator.getCharacterOffset()); 319 320 if (fAnnotationDepth == -1) { 321 if (element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && 323 element.localpart == SchemaSymbols.ELT_ANNOTATION) { 324 schemaDOM.endAnnotationElement(element, true); 325 } 326 } else { 327 schemaDOM.endAnnotationElement(element, false); 328 } 329 } 330 331 332 341 public void endElement(QName element, Augmentations augs) throws XNIException { 342 343 if(fAnnotationDepth > -1) { 346 if (fInnerAnnotationDepth == fDepth) { 347 fInnerAnnotationDepth = -1; 348 schemaDOM.endAnnotationElement(element, false); 349 schemaDOM.endElement(); 350 } else if (fAnnotationDepth == fDepth) { 351 fAnnotationDepth = -1; 352 schemaDOM.endAnnotationElement(element, true); 353 schemaDOM.endElement(); 354 } else { schemaDOM.endAnnotationElement(element, false); 356 } 357 } else { if(element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && fGenerateSyntheticAnnotation) { 359 boolean value = fHasNonSchemaAttributes.pop(); 360 boolean sawann = fSawAnnotation.pop(); 361 if (value && !sawann) { 362 String schemaPrefix = fNamespaceContext.getPrefix(SchemaSymbols.URI_SCHEMAFORSCHEMA); 363 QName annQName = new QName(schemaPrefix, SchemaSymbols.ELT_ANNOTATION, schemaPrefix + (schemaPrefix.length() == 0?"":":") + SchemaSymbols.ELT_ANNOTATION, SchemaSymbols.URI_SCHEMAFORSCHEMA); 364 schemaDOM.startAnnotation(annQName, fEmptyAttr, fNamespaceContext); 365 QName elemQName = new QName(schemaPrefix, SchemaSymbols.ELT_DOCUMENTATION, schemaPrefix + (schemaPrefix.length() == 0?"":":") + SchemaSymbols.ELT_DOCUMENTATION, SchemaSymbols.URI_SCHEMAFORSCHEMA); 366 schemaDOM.startAnnotationElement(elemQName, fEmptyAttr); 367 schemaDOM.characters(new XMLString("SYNTHETIC_ANNOTATION".toCharArray(), 0, 20 )); 368 schemaDOM.endSyntheticAnnotationElement(elemQName, false); 369 schemaDOM.endSyntheticAnnotationElement(annQName, true); 370 } 371 } 372 schemaDOM.endElement(); 373 } 374 fDepth--; 375 376 } 377 378 382 private boolean hasNonSchemaAttributes(QName element, XMLAttributes attributes) { 383 final int length = attributes.getLength(); 384 for (int i = 0; i < length; ++i) { 385 String uri = attributes.getURI(i); 386 if (uri != null && uri != SchemaSymbols.URI_SCHEMAFORSCHEMA && 387 uri != NamespaceContext.XMLNS_URI && 388 !(uri == NamespaceContext.XML_URI && 389 attributes.getQName(i) == SchemaSymbols.ATT_XML_LANG && element.localpart == SchemaSymbols.ELT_SCHEMA)) { 390 return true; 391 } 392 } 393 return false; 394 } 395 396 410 public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException { 411 if (fAnnotationDepth != -1 ) { 413 schemaDOM.characters(text); 414 } 415 } 416 417 425 public void startCDATA(Augmentations augs) throws XNIException { 426 if (fAnnotationDepth != -1) { 428 schemaDOM.startAnnotationCDATA(); 429 } 430 } 431 432 440 public void endCDATA(Augmentations augs) throws XNIException { 441 if (fAnnotationDepth != -1) { 443 schemaDOM.endAnnotationCDATA(); 444 } 445 } 446 447 448 452 455 public Document getDocument() { 456 return schemaDOM; 457 } 458 459 464 public void setFeature(String featureId, boolean state){ 465 config.setFeature(featureId, state); 466 } 467 468 473 public boolean getFeature(String featureId){ 474 return config.getFeature(featureId); 475 } 476 477 482 public void setProperty(String propertyId, Object value){ 483 config.setProperty(propertyId, value); 484 } 485 486 491 public Object getProperty(String propertyId){ 492 return config.getProperty(propertyId); 493 } 494 495 499 public void setEntityResolver(XMLEntityResolver er) { 500 config.setEntityResolver(er); 501 } 502 503 509 public void parse(XMLInputSource inputSource) throws IOException { 510 config.parse(inputSource); 511 } 512 513 517 public Document getDocument2() { 518 return ((SchemaParsingConfig)config).getDocument(); 519 } 520 521 524 public void reset() { 525 ((SchemaParsingConfig)config).reset(); 526 } 527 528 531 public void resetNodePool() { 532 ((SchemaParsingConfig)config).resetNodePool(); 533 } 534 535 540 private static final class BooleanStack { 541 542 546 547 private int fDepth; 548 549 550 private boolean[] fData; 551 552 556 public BooleanStack () {} 557 558 562 563 public int size() { 564 return fDepth; 565 } 566 567 568 public void push(boolean value) { 569 ensureCapacity(fDepth + 1); 570 fData[fDepth++] = value; 571 } 572 573 574 public boolean pop() { 575 return fData[--fDepth]; 576 } 577 578 579 public void clear() { 580 fDepth = 0; 581 } 582 583 587 588 private void ensureCapacity(int size) { 589 if (fData == null) { 590 fData = new boolean[32]; 591 } 592 else if (fData.length <= size) { 593 boolean[] newdata = new boolean[fData.length * 2]; 594 System.arraycopy(fData, 0, newdata, 0, fData.length); 595 fData = newdata; 596 } 597 } 598 } 599 } 600 | Popular Tags |