1 16 17 package org.apache.xerces.jaxp; 18 19 import java.io.IOException ; 20 21 import javax.xml.validation.TypeInfoProvider ; 22 import javax.xml.validation.ValidatorHandler ; 23 24 import org.apache.xerces.dom.DOMInputImpl; 25 import org.apache.xerces.impl.Constants; 26 import org.apache.xerces.impl.XMLErrorReporter; 27 import org.apache.xerces.impl.xs.opti.DefaultXMLDocumentHandler; 28 import org.apache.xerces.util.AttributesProxy; 29 import org.apache.xerces.util.AugmentationsImpl; 30 import org.apache.xerces.util.ErrorHandlerProxy; 31 import org.apache.xerces.util.ErrorHandlerWrapper; 32 import org.apache.xerces.util.LocatorProxy; 33 import org.apache.xerces.util.SymbolTable; 34 import org.apache.xerces.util.XMLResourceIdentifierImpl; 35 import org.apache.xerces.xni.Augmentations; 36 import org.apache.xerces.xni.NamespaceContext; 37 import org.apache.xerces.xni.QName; 38 import org.apache.xerces.xni.XMLAttributes; 39 import org.apache.xerces.xni.XMLDocumentHandler; 40 import org.apache.xerces.xni.XMLLocator; 41 import org.apache.xerces.xni.XMLString; 42 import org.apache.xerces.xni.XNIException; 43 import org.apache.xerces.xni.parser.XMLComponent; 44 import org.apache.xerces.xni.parser.XMLComponentManager; 45 import org.apache.xerces.xni.parser.XMLConfigurationException; 46 import org.apache.xerces.xni.parser.XMLEntityResolver; 47 import org.apache.xerces.xni.parser.XMLErrorHandler; 48 import org.apache.xerces.xni.parser.XMLInputSource; 49 import org.w3c.dom.TypeInfo ; 50 import org.w3c.dom.ls.LSInput ; 51 import org.w3c.dom.ls.LSResourceResolver ; 52 import org.xml.sax.Attributes ; 53 import org.xml.sax.ContentHandler ; 54 import org.xml.sax.ErrorHandler ; 55 import org.xml.sax.SAXException ; 56 import org.xml.sax.SAXParseException ; 57 import org.xml.sax.helpers.DefaultHandler ; 58 59 83 final class JAXPValidatorComponent 84 extends TeeXMLDocumentFilterImpl implements XMLComponent { 85 86 87 private static final String ENTITY_MANAGER = 88 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; 89 90 91 private static final String ERROR_REPORTER = 92 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 93 94 95 private static final String SYMBOL_TABLE = 96 Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; 97 98 private final ValidatorHandler validator; 100 private final XNI2SAX xni2sax = new XNI2SAX(); 101 private final SAX2XNI sax2xni = new SAX2XNI(); 102 103 private final TypeInfoProvider typeInfoProvider; 105 106 113 private Augmentations fCurrentAug; 114 115 118 private XMLAttributes fCurrentAttributes; 119 120 122 private SymbolTable fSymbolTable; 123 private XMLErrorReporter fErrorReporter; 124 private XMLEntityResolver fEntityResolver; 125 126 129 public JAXPValidatorComponent( ValidatorHandler validatorHandler ) { 130 this.validator = validatorHandler; 131 TypeInfoProvider tip = validatorHandler.getTypeInfoProvider(); 132 if(tip==null) tip = noInfoProvider; 133 this.typeInfoProvider = tip; 134 135 xni2sax.setContentHandler(validator); 137 validator.setContentHandler(sax2xni); 138 this.setSide(xni2sax); 139 140 validator.setErrorHandler(new ErrorHandlerProxy() { 142 protected XMLErrorHandler getErrorHandler() { 143 XMLErrorHandler handler = fErrorReporter.getErrorHandler(); 144 if(handler!=null) return handler; 145 return new ErrorHandlerWrapper(DraconianErrorHandler.getInstance()); 146 } 147 }); 148 validator.setResourceResolver(new LSResourceResolver () { 149 public LSInput resolveResource(String type,String ns, String publicId, String systemId, String baseUri) { 150 if(fEntityResolver==null) return null; 151 try { 152 XMLInputSource is = fEntityResolver.resolveEntity( 153 new XMLResourceIdentifierImpl(publicId,systemId,baseUri,null)); 154 if(is==null) return null; 155 156 LSInput di = new DOMInputImpl(); 157 di.setBaseURI(is.getBaseSystemId()); 158 di.setByteStream(is.getByteStream()); 159 di.setCharacterStream(is.getCharacterStream()); 160 di.setEncoding(is.getEncoding()); 161 di.setPublicId(is.getPublicId()); 162 di.setSystemId(is.getSystemId()); 163 164 return di; 165 } catch( IOException e ) { 166 throw new XNIException(e); 169 } 170 } 171 }); 172 } 173 174 175 public void startElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException { 176 fCurrentAttributes = attributes; 177 fCurrentAug = augs; 178 xni2sax.startElement(element,attributes,null); 179 fCurrentAttributes = null; } 181 182 public void endElement(QName element, Augmentations augs) throws XNIException { 183 fCurrentAug = augs; 184 xni2sax.endElement(element,null); 185 } 186 187 public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException { 188 startElement(element,attributes,augs); 189 endElement(element,augs); 190 } 191 192 193 public void characters(XMLString text, Augmentations augs) throws XNIException { 194 fCurrentAug = augs; 197 xni2sax.characters(text,null); 198 } 199 200 public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException { 201 fCurrentAug = augs; 204 xni2sax.ignorableWhitespace(text,null); 205 } 206 207 public void reset(XMLComponentManager componentManager) throws XMLConfigurationException { 208 fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE); 210 fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); 211 try { 212 fEntityResolver = (XMLEntityResolver) componentManager.getProperty(ENTITY_MANAGER); 213 } 214 catch (XMLConfigurationException e) { 215 fEntityResolver = null; 216 } 217 } 218 219 228 private final class SAX2XNI extends DefaultHandler { 229 230 234 private final Augmentations fAugmentations = new AugmentationsImpl(); 235 236 240 private final QName fQName = new QName(); 241 242 public void characters(char[] ch, int start, int len) throws SAXException { 243 try { 244 handler().characters(new XMLString(ch,start,len),aug()); 245 } catch( XNIException e ) { 246 throw toSAXException(e); 247 } 248 } 249 250 public void ignorableWhitespace(char[] ch, int start, int len) throws SAXException { 251 try { 252 handler().ignorableWhitespace(new XMLString(ch,start,len),aug()); 253 } catch( XNIException e ) { 254 throw toSAXException(e); 255 } 256 } 257 258 public void startElement(String uri, String localName, String qname, Attributes atts) throws SAXException { 259 try { 260 updateAttributes(atts); 261 handler().startElement(toQName(uri,localName,qname), fCurrentAttributes, elementAug()); 262 } catch( XNIException e ) { 263 throw toSAXException(e); 264 } 265 } 266 267 public void endElement(String uri, String localName, String qname) throws SAXException { 268 try { 269 handler().endElement(toQName(uri,localName,qname),aug()); 270 } catch( XNIException e ) { 271 throw toSAXException(e); 272 } 273 } 274 275 private Augmentations elementAug() { 276 Augmentations aug = aug(); 277 278 return aug; 279 } 280 281 282 286 private Augmentations aug() { 287 if( fCurrentAug!=null ) { 288 Augmentations r = fCurrentAug; 289 fCurrentAug = null; return r; 291 } 292 fAugmentations.removeAllItems(); 293 return fAugmentations; 294 } 295 296 299 private XMLDocumentHandler handler() { 300 return JAXPValidatorComponent.this.getDocumentHandler(); 301 } 302 303 307 private SAXException toSAXException( XNIException xe ) { 308 Exception e = xe.getException(); 309 if( e==null ) e = xe; 310 if( e instanceof SAXException ) return (SAXException )e; 311 return new SAXException (e); 312 } 313 314 319 private QName toQName( String uri, String localName, String qname ) { 320 String prefix = null; 321 int idx = qname.indexOf(':'); 322 if( idx>0 ) 323 prefix = symbolize(qname.substring(0,idx)); 324 325 localName = symbolize(localName); 326 qname = symbolize(qname); 327 uri = symbolize(uri); 328 329 fQName.setValues(prefix, localName, qname, uri); 331 return fQName; 332 } 333 } 334 335 345 private final class XNI2SAX extends DefaultXMLDocumentHandler { 346 347 private ContentHandler fContentHandler; 348 349 private String fVersion; 350 351 352 protected NamespaceContext fNamespaceContext; 353 354 357 private final AttributesProxy fAttributesProxy = new AttributesProxy(null); 358 359 public void setContentHandler( ContentHandler handler ) { 360 this.fContentHandler = handler; 361 } 362 363 public ContentHandler getContentHandler() { 364 return fContentHandler; 365 } 366 367 368 public void xmlDecl(String version, String encoding, String standalone, Augmentations augs) throws XNIException { 369 this.fVersion = version; 370 } 371 372 public void startDocument(XMLLocator locator, String encoding, NamespaceContext namespaceContext, Augmentations augs) throws XNIException { 373 fNamespaceContext = namespaceContext; 374 fContentHandler.setDocumentLocator(new LocatorProxy(locator)); 375 try { 376 fContentHandler.startDocument(); 377 } catch (SAXException e) { 378 throw new XNIException(e); 379 } 380 } 381 382 public void endDocument(Augmentations augs) throws XNIException { 383 try { 384 fContentHandler.endDocument(); 385 } catch (SAXException e) { 386 throw new XNIException(e); 387 } 388 } 389 390 public void processingInstruction(String target, XMLString data, Augmentations augs) throws XNIException { 391 try { 392 fContentHandler.processingInstruction(target,data.toString()); 393 } catch (SAXException e) { 394 throw new XNIException(e); 395 } 396 } 397 398 public void startElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException { 399 try { 400 int count = fNamespaceContext.getDeclaredPrefixCount(); 402 if (count > 0) { 403 String prefix = null; 404 String uri = null; 405 for (int i = 0; i < count; i++) { 406 prefix = fNamespaceContext.getDeclaredPrefixAt(i); 407 uri = fNamespaceContext.getURI(prefix); 408 fContentHandler.startPrefixMapping(prefix, (uri == null)?"":uri); 409 } 410 } 411 412 String uri = element.uri != null ? element.uri : ""; 413 String localpart = element.localpart; 414 fAttributesProxy.setAttributes(attributes); 415 fContentHandler.startElement(uri, localpart, element.rawname, fAttributesProxy); 416 } catch( SAXException e ) { 417 throw new XNIException(e); 418 } 419 } 420 421 public void endElement(QName element, Augmentations augs) throws XNIException { 422 try { 423 String uri = element.uri != null ? element.uri : ""; 424 String localpart = element.localpart; 425 fContentHandler.endElement(uri, localpart, element.rawname); 426 427 int count = fNamespaceContext.getDeclaredPrefixCount(); 429 if (count > 0) { 430 for (int i = 0; i < count; i++) { 431 fContentHandler.endPrefixMapping(fNamespaceContext.getDeclaredPrefixAt(i)); 432 } 433 } 434 } catch( SAXException e ) { 435 throw new XNIException(e); 436 } 437 } 438 439 public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException { 440 startElement(element,attributes,augs); 441 endElement(element,augs); 442 } 443 444 public void characters(XMLString text, Augmentations augs) throws XNIException { 445 try { 446 fContentHandler.characters(text.ch,text.offset,text.length); 447 } catch (SAXException e) { 448 throw new XNIException(e); 449 } 450 } 451 452 public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException { 453 try { 454 fContentHandler.ignorableWhitespace(text.ch,text.offset,text.length); 455 } catch (SAXException e) { 456 throw new XNIException(e); 457 } 458 } 459 } 460 461 private static final class DraconianErrorHandler implements ErrorHandler { 462 463 466 private static final DraconianErrorHandler ERROR_HANDLER_INSTANCE 467 = new DraconianErrorHandler(); 468 469 private DraconianErrorHandler() {} 470 471 472 public static DraconianErrorHandler getInstance() { 473 return ERROR_HANDLER_INSTANCE; 474 } 475 476 477 public void warning(SAXParseException e) throws SAXException { 478 } 480 481 482 public void error(SAXParseException e) throws SAXException { 483 throw e; 484 } 485 486 487 public void fatalError(SAXParseException e) throws SAXException { 488 throw e; 489 } 490 491 } 493 494 498 private void updateAttributes( Attributes atts ) { 499 int len = atts.getLength(); 500 for( int i=0; i<len; i++ ) { 501 String aqn = atts.getQName(i); 502 int j = fCurrentAttributes.getIndex(aqn); 503 String av = atts.getValue(i); 504 if(j==-1) { 505 507 String prefix; 508 int idx = aqn.indexOf(':'); 509 if( idx<0 ) { 510 prefix = null; 511 } else { 512 prefix = symbolize(aqn.substring(0,idx)); 513 } 514 515 j = fCurrentAttributes.addAttribute( 516 new QName( 517 prefix, 518 symbolize(atts.getLocalName(i)), 519 symbolize(aqn), 520 symbolize(atts.getURI(i))), 521 atts.getType(i),av); 522 } else { 523 if( !av.equals(fCurrentAttributes.getValue(j)) ) { 525 fCurrentAttributes.setValue(j,av); 527 } 528 } 529 530 535 } 536 } 537 538 private String symbolize( String s ) { 539 return fSymbolTable.addSymbol(s); 540 } 541 542 543 546 private static final TypeInfoProvider noInfoProvider = new TypeInfoProvider () { 547 public TypeInfo getElementTypeInfo() { 548 return null; 549 } 550 public TypeInfo getAttributeTypeInfo(int index) { 551 return null; 552 } 553 public TypeInfo getAttributeTypeInfo(String attributeQName) { 554 return null; 555 } 556 public TypeInfo getAttributeTypeInfo(String attributeUri, String attributeLocalName) { 557 return null; 558 } 559 public boolean isIdAttribute(int index) { 560 return false; 561 } 562 public boolean isSpecified(int index) { 563 return false; 564 } 565 }; 566 567 573 public String [] getRecognizedFeatures() { 575 return null; 576 } 577 578 public void setFeature(String featureId, boolean state) throws XMLConfigurationException { 579 } 580 581 public String [] getRecognizedProperties() { 582 return new String []{ENTITY_MANAGER, ERROR_REPORTER, SYMBOL_TABLE}; 583 } 584 585 public void setProperty(String propertyId, Object value) throws XMLConfigurationException { 586 } 587 588 public Boolean getFeatureDefault(String featureId) { 589 return null; 590 } 591 592 public Object getPropertyDefault(String propertyId) { 593 return null; 594 } 595 596 } 597 | Popular Tags |