FileDocCategorySizeDatePackage
JAXPValidatorComponent.javaAPI DocApache Xerces 3.0.122657Fri Sep 14 20:33:56 BST 2007org.apache.xerces.jaxp

JAXPValidatorComponent

public final class JAXPValidatorComponent extends TeeXMLDocumentFilterImpl implements org.apache.xerces.xni.parser.XMLComponent
Runs 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.

author
Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
version
$Id: JAXPValidatorComponent.java 548088 2007-06-17 18:25:17Z mrglavas $

Fields Summary
private static final String
ENTITY_MANAGER
Property identifier: entity manager.
private static final String
ERROR_REPORTER
Property identifier: error reporter.
private static final String
SYMBOL_TABLE
Property identifier: symbol table.
private final ValidatorHandler
validator
private final XNI2SAX
xni2sax
private final SAX2XNI
sax2xni
private final TypeInfoProvider
typeInfoProvider
private org.apache.xerces.xni.Augmentations
fCurrentAug
Used 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 org.apache.xerces.xni.XMLAttributes
fCurrentAttributes
{@link XMLAttributes} version of {@link #fCurrentAug}.
private org.apache.xerces.util.SymbolTable
fSymbolTable
private org.apache.xerces.impl.XMLErrorReporter
fErrorReporter
private org.apache.xerces.xni.parser.XMLEntityResolver
fEntityResolver
private static final TypeInfoProvider
noInfoProvider
{@link TypeInfoProvider} that returns no info.
Constructors Summary
public JAXPValidatorComponent(ValidatorHandler validatorHandler)

param
validatorHandler may not be null.

    
               
         
        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.getInstance());
            }
        });
        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,null));
                    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 voidcharacters(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)

        // since a validator may change the contents,
        // let this one go through a validator
        fCurrentAug = augs;
        xni2sax.characters(text,null);
    
public voidemptyElement(org.apache.xerces.xni.QName element, org.apache.xerces.xni.XMLAttributes attributes, org.apache.xerces.xni.Augmentations augs)

        startElement(element,attributes,augs);
        endElement(element,augs);
    
public voidendElement(org.apache.xerces.xni.QName element, org.apache.xerces.xni.Augmentations augs)

        fCurrentAug = augs;
        xni2sax.endElement(element,null);
    
public java.lang.BooleangetFeatureDefault(java.lang.String featureId)

        return null;
    
public java.lang.ObjectgetPropertyDefault(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[]{ENTITY_MANAGER, ERROR_REPORTER, SYMBOL_TABLE};
    
public voidignorableWhitespace(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)

        // since a validator may change the contents,
        // let this one go through a validator
        fCurrentAug = augs;
        xni2sax.ignorableWhitespace(text,null);
    
public voidreset(org.apache.xerces.xni.parser.XMLComponentManager componentManager)

        // obtain references from the manager
        fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
        fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
        try {
            fEntityResolver = (XMLEntityResolver) componentManager.getProperty(ENTITY_MANAGER);
        }
        catch (XMLConfigurationException e) {
            fEntityResolver = null;
        }
    
public voidsetFeature(java.lang.String featureId, boolean state)

    
public voidsetProperty(java.lang.String propertyId, java.lang.Object value)

    
public voidstartElement(org.apache.xerces.xni.QName element, org.apache.xerces.xni.XMLAttributes attributes, org.apache.xerces.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.Stringsymbolize(java.lang.String s)

        return fSymbolTable.addSymbol(s);
    
private voidupdateAttributes(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 ); **/
        }