JAXPValidatorComponentpublic class JAXPValidatorComponent extends TeeXMLDocumentFilterImpl implements XMLComponentRuns events through a {@link javax.xml.validation.ValidatorHandler}
and performs validation/infoset-augmentation by an external validator.
This component sets up the pipeline as follows:
__ __
/ |==> XNI2SAX --> Validator --> SAX2XNI ==>|
/ | |
==>| Tee| | next
\ | | component
\ |============other XNI events============>|
~~ ~~
only those events that need to go through Validator will go the 1st route,
and other events go the 2nd direct route. |
Fields Summary |
---|
private final ValidatorHandler | validator | private final XNI2SAX | xni2sax | private final SAX2XNI | sax2xni | private final TypeInfoProvider | typeInfoProvider | private Augmentations | fCurrentAugUsed to store the {@link Augmentations} associated with the
current event, so that we can pick it up again
when the event is forwarded by the {@link ValidatorHandler}.
UGLY HACK. | private XMLAttributes | fCurrentAttributes{@link XMLAttributes} version of {@link #fCurrentAug}. | private SymbolTable | fSymbolTable | private XMLErrorReporter | fErrorReporter | private XMLEntityResolver | fEntityResolver | private static final TypeInfoProvider | noInfoProvider{@link TypeInfoProvider} that returns no info. |
Constructors Summary |
---|
public JAXPValidatorComponent(ValidatorHandler validatorHandler)
this.validator = validatorHandler;
TypeInfoProvider tip = validatorHandler.getTypeInfoProvider();;
if(tip==null) tip = noInfoProvider;
this.typeInfoProvider = tip;
// configure wiring between internal components.
xni2sax.setContentHandler(validator);
validator.setContentHandler(sax2xni);
this.setSide(xni2sax);
// configure validator with proper EntityResolver/ErrorHandler.
validator.setErrorHandler(new ErrorHandlerProxy() {
protected XMLErrorHandler getErrorHandler() {
XMLErrorHandler handler = fErrorReporter.getErrorHandler();
if(handler!=null) return handler;
return new ErrorHandlerWrapper(DraconianErrorHandler.theInstance);
}
});
validator.setResourceResolver(new LSResourceResolver() {
public LSInput resolveResource(String type,String ns, String publicId, String systemId, String baseUri) {
if(fEntityResolver==null) return null;
try {
XMLInputSource is = fEntityResolver.resolveEntity(
new XMLResourceIdentifierImpl(publicId,systemId,baseUri,systemId));
if(is==null) return null;
LSInput di = new DOMInputImpl();
di.setBaseURI(is.getBaseSystemId());
di.setByteStream(is.getByteStream());
di.setCharacterStream(is.getCharacterStream());
di.setEncoding(is.getEncoding());
di.setPublicId(is.getPublicId());
di.setSystemId(is.getSystemId());
return di;
} catch( IOException e ) {
// erors thrown by the callback is not supposed to be
// reported to users.
throw new XNIException(e);
}
}
});
|
Methods Summary |
---|
public void | characters(com.sun.org.apache.xerces.internal.xni.XMLString text, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
// since a validator may change the contents,
// let this one go through a validator
fCurrentAug = augs;
xni2sax.characters(text,null);
| public void | emptyElement(com.sun.org.apache.xerces.internal.xni.QName element, com.sun.org.apache.xerces.internal.xni.XMLAttributes attributes, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
startElement(element,attributes,augs);
endElement(element,augs);
| public void | endElement(com.sun.org.apache.xerces.internal.xni.QName element, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
fCurrentAug = augs;
xni2sax.endElement(element,null);
| public java.lang.Boolean | getFeatureDefault(java.lang.String featureId)
return null;
| public java.lang.Object | getPropertyDefault(java.lang.String propertyId)
return null;
| public java.lang.String[] | getRecognizedFeatures()
//
//
// XMLComponent implementation.
//
//
// no property/feature supported
return null;
| public java.lang.String[] | getRecognizedProperties()
return new String[]{Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY};
| public void | ignorableWhitespace(com.sun.org.apache.xerces.internal.xni.XMLString text, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
// since a validator may change the contents,
// let this one go through a validator
fCurrentAug = augs;
xni2sax.ignorableWhitespace(text,null);
| public void | reset(com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager componentManager)
// obtain references from the manager
fSymbolTable = (SymbolTable)componentManager.getProperty(
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY);
fErrorReporter = (XMLErrorReporter)componentManager.getProperty(
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY);
| public void | setFeature(java.lang.String featureId, boolean state)
| public void | setProperty(java.lang.String propertyId, java.lang.Object value)
if(propertyId.equals(Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY)) {
fEntityResolver = (XMLEntityResolver)value;
}
| public void | startElement(com.sun.org.apache.xerces.internal.xni.QName element, com.sun.org.apache.xerces.internal.xni.XMLAttributes attributes, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
fCurrentAttributes = attributes;
fCurrentAug = augs;
xni2sax.startElement(element,attributes,null);
fCurrentAttributes = null; // mostly to make it easy to find any bug.
| private java.lang.String | symbolize(java.lang.String s)
return fSymbolTable.addSymbol(s);
| private void | updateAttributes(org.xml.sax.Attributes atts)Compares the given {@link Attributes} with {@link #fCurrentAttributes}
and update the latter accordingly.
int len = atts.getLength();
for( int i=0; i<len; i++ ) {
String aqn = atts.getQName(i);
int j = fCurrentAttributes.getIndex(aqn);
String av = atts.getValue(i);
if(j==-1) {
// newly added attribute. add to the current attribute list.
String prefix;
int idx = aqn.indexOf(':");
if( idx<0 ) {
prefix = null;
} else {
prefix = symbolize(aqn.substring(0,idx));
}
j = fCurrentAttributes.addAttribute(
new QName(
prefix,
symbolize(atts.getLocalName(i)),
symbolize(aqn),
symbolize(atts.getURI(i))),
atts.getType(i),av);
} else {
// the attribute is present.
if( !av.equals(fCurrentAttributes.getValue(j)) ) {
// but the value was changed.
fCurrentAttributes.setValue(j,av);
}
}
Augmentations augs = fCurrentAttributes.getAugmentations(j);
augs.putItem( Constants.TYPEINFO,
typeInfoProvider.getAttributeTypeInfo(i) );
augs.putItem( Constants.ID_ATTRIBUTE,
typeInfoProvider.isIdAttribute(i)?Boolean.TRUE:Boolean.FALSE );
}
// spec says attributes won't be removed.
//
// // we might remove attributes as we go through,
// // so iterate in the reverse order.
// for( int j=fCurrentAttributes.getLength()-1; j>=0; j-- ) {
// String aqn = fCurrentAttributes.getQName(j);
// int i = atts.getIndex(aqn);
// if(i==-1)
// // this attribute is removed.
// fCurrentAttributes.removeAttributeAt(j);
// }
|
|