xml.parser
Class SchemaAutoLoader

java.lang.Object
  extended by org.xml.sax.helpers.XMLFilterImpl
      extended by xml.parser.SchemaAutoLoader
All Implemented Interfaces:
org.xml.sax.ContentHandler, org.xml.sax.DTDHandler, org.xml.sax.EntityResolver, org.xml.sax.ErrorHandler, org.xml.sax.ext.EntityResolver2, org.xml.sax.XMLFilter, org.xml.sax.XMLReader

public class SchemaAutoLoader
extends org.xml.sax.helpers.XMLFilterImpl
implements org.xml.sax.ext.EntityResolver2

XMLFilter inserting a Validator based upon rules defined in a SchemaMapping. The schema is inserted between the parser and this SchemaAutoLoader in the chain. If a schema is found, a RewindException is thrown, because it saves a tedious replay mecanism (see the commented out Replay class). If this is not acceptable, don't forget to call startElement with the document element, and to filter out the startDocument(), startElement() events. This component is only interested in introducing Validators, not providing completion. If the inserted VerifierFilter doesn't implement EntityResolver2, entity resolution might fail. finding a test case is not easy, since resolution is mainly used to load a schema...

Version:
$Id: SchemaAutoLoader.java 21624 2012-05-02 19:40:46Z daleanson $
Author:
Eric Le Lay

Constructor Summary
SchemaAutoLoader(org.xml.sax.XMLReader parent, SchemaMapping mapping, org.gjt.sp.jedit.Buffer requestingBuffer)
           
 
Method Summary
 void forceSchema(java.lang.String baseURI, java.lang.String schemaURI)
          force the schema to use for validation and CompletionInfo.
 java.util.Map<java.lang.String,CompletionInfo> getCompletionInfo()
          only Relax NG schemas are supported for the moment
 org.xml.sax.InputSource getExternalSubset(java.lang.String name, java.lang.String baseURI)
          manually implement EntityResolver2 because XMLFilterImpl only implements EntityResolver, and we need EntityResolver2 for Resolver to work properly
 java.lang.String getSchemaURL()
          this doesn't return the schema bound using xsi:schemalocation nor the DTD file : only a schema discovered via the SchemaMapping instance.
 void parse(org.xml.sax.InputSource input)
          capture system and public ID to find a matching schema mapping,
 void parse(java.lang.String systemId)
          capture sytem ID to find a matching schema mapping
 org.xml.sax.InputSource resolveEntity(java.lang.String name, java.lang.String publicId, java.lang.String baseURI, java.lang.String systemId)
          manually implement EntityResolver2 because XMLFilterImpl only implements EntityResolver, and we need EntityResolver2 for Resolver to work properly
 void setDocumentLocator(org.xml.sax.Locator l)
          capture the locator, in case we need to pass it to a schema
 void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, org.xml.sax.Attributes atts)
          if this is the root element, try to find a matching schema, instantiate it and insert it in the parsing chain.
 void startPrefixMapping(java.lang.String prefix, java.lang.String ns)
           
 
Methods inherited from class org.xml.sax.helpers.XMLFilterImpl
characters, endDocument, endElement, endPrefixMapping, error, fatalError, getContentHandler, getDTDHandler, getEntityResolver, getErrorHandler, getFeature, getParent, getProperty, ignorableWhitespace, notationDecl, processingInstruction, resolveEntity, setContentHandler, setDTDHandler, setEntityResolver, setErrorHandler, setFeature, setParent, setProperty, skippedEntity, startDocument, unparsedEntityDecl, warning
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface org.xml.sax.EntityResolver
resolveEntity
 

Constructor Detail

SchemaAutoLoader

public SchemaAutoLoader(org.xml.sax.XMLReader parent,
                        SchemaMapping mapping,
                        org.gjt.sp.jedit.Buffer requestingBuffer)
Parameters:
parent - parent in the XML parsing chain
mapping - schema-mapping rules or null if you plan to force the schema
Method Detail

forceSchema

public void forceSchema(java.lang.String baseURI,
                        java.lang.String schemaURI)
                 throws org.xml.sax.SAXException,
                        java.io.IOException,
                        java.net.URISyntaxException
force the schema to use for validation and CompletionInfo. It disables autodiscovery and doesn't cancel any existing verifier, so it should be called before parsing.

Parameters:
baseURI - baseURI to resolve the schemaURI against (may be null if schemaURI is absolute)
schemaURI - URI of the schema to install
Throws:
org.xml.sax.SAXException
java.io.IOException
java.net.URISyntaxException

getSchemaURL

public java.lang.String getSchemaURL()
this doesn't return the schema bound using xsi:schemalocation nor the DTD file : only a schema discovered via the SchemaMapping instance.

Returns:
URL of the schema used for validation or null if no schema was installed

getCompletionInfo

public java.util.Map<java.lang.String,CompletionInfo> getCompletionInfo()
only Relax NG schemas are supported for the moment

Returns:
CompletionInfo constructed from the schema or null if no Relax NG schema was used

parse

public void parse(org.xml.sax.InputSource input)
           throws org.xml.sax.SAXException,
                  java.io.IOException
capture system and public ID to find a matching schema mapping,

Specified by:
parse in interface org.xml.sax.XMLReader
Overrides:
parse in class org.xml.sax.helpers.XMLFilterImpl
Parameters:
input - input to parse
Throws:
org.xml.sax.SAXException
java.io.IOException

parse

public void parse(java.lang.String systemId)
           throws org.xml.sax.SAXException,
                  java.io.IOException
capture sytem ID to find a matching schema mapping

Specified by:
parse in interface org.xml.sax.XMLReader
Overrides:
parse in class org.xml.sax.helpers.XMLFilterImpl
Parameters:
systemId - systemId of the input to parse
Throws:
org.xml.sax.SAXException
java.io.IOException

startPrefixMapping

public void startPrefixMapping(java.lang.String prefix,
                               java.lang.String ns)
                        throws org.xml.sax.SAXException
Specified by:
startPrefixMapping in interface org.xml.sax.ContentHandler
Overrides:
startPrefixMapping in class org.xml.sax.helpers.XMLFilterImpl
Throws:
org.xml.sax.SAXException

startElement

public void startElement(java.lang.String uri,
                         java.lang.String localName,
                         java.lang.String qName,
                         org.xml.sax.Attributes atts)
                  throws org.xml.sax.SAXException
if this is the root element, try to find a matching schema, instantiate it and insert it in the parsing chain.

Specified by:
startElement in interface org.xml.sax.ContentHandler
Overrides:
startElement in class org.xml.sax.helpers.XMLFilterImpl
Throws:
org.xml.sax.SAXException

resolveEntity

public org.xml.sax.InputSource resolveEntity(java.lang.String name,
                                             java.lang.String publicId,
                                             java.lang.String baseURI,
                                             java.lang.String systemId)
                                      throws org.xml.sax.SAXException,
                                             java.io.IOException
manually implement EntityResolver2 because XMLFilterImpl only implements EntityResolver, and we need EntityResolver2 for Resolver to work properly

Specified by:
resolveEntity in interface org.xml.sax.ext.EntityResolver2
Throws:
java.lang.UnsupportedOperationException - if getEntityResolver() doesn't implement EntityResolver2
org.xml.sax.SAXException
java.io.IOException

getExternalSubset

public org.xml.sax.InputSource getExternalSubset(java.lang.String name,
                                                 java.lang.String baseURI)
                                          throws org.xml.sax.SAXException,
                                                 java.io.IOException
manually implement EntityResolver2 because XMLFilterImpl only implements EntityResolver, and we need EntityResolver2 for Resolver to work properly

Specified by:
getExternalSubset in interface org.xml.sax.ext.EntityResolver2
Throws:
java.lang.UnsupportedOperationException - if getEntityResolver() doesn't implement EntityResolver2
org.xml.sax.SAXException
java.io.IOException

setDocumentLocator

public void setDocumentLocator(org.xml.sax.Locator l)
capture the locator, in case we need to pass it to a schema

Specified by:
setDocumentLocator in interface org.xml.sax.ContentHandler
Overrides:
setDocumentLocator in class org.xml.sax.helpers.XMLFilterImpl
See Also:
installJaxpGrammar(java.net.URI,String,boolean)