FileDocCategorySizeDatePackage
JAXPValidatorComponent.javaAPI DocJava SE 5 API18193Fri Aug 26 14:55:54 BST 2005com.sun.org.apache.xerces.internal.jaxp

JAXPValidatorComponent

public class JAXPValidatorComponent extends TeeXMLDocumentFilterImpl implements 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)

Fields Summary
private final ValidatorHandler
validator
private final XNI2SAX
xni2sax
private final SAX2XNI
sax2xni
private final TypeInfoProvider
typeInfoProvider
private 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 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)

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.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 voidcharacters(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 voidemptyElement(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 voidendElement(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.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[]{Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY};
    
public voidignorableWhitespace(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 voidreset(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 voidsetFeature(java.lang.String featureId, boolean state)

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

        if(propertyId.equals(Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY)) {
            fEntityResolver = (XMLEntityResolver)value;
        }
    
public voidstartElement(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.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 );
        }
        

// 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);
//        }