org.iso_relax.dispatcher.impl.DispatcherImpl Maven / Gradle / Ivy
/*
* @(#)$Id: DispatcherImpl.java,v 1.5 2003/05/30 23:46:32 kkawa Exp $
*
* Copyright 2001 Kohsuke KAWAGUCHI
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.iso_relax.dispatcher.impl;
import java.util.Enumeration;
import java.util.Vector;
import org.iso_relax.dispatcher.ElementDecl;
import org.iso_relax.dispatcher.IslandVerifier;
import org.iso_relax.dispatcher.SchemaProvider;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.NamespaceSupport;
/**
* reference implementation of Dispatcher interface.
*
* @author
* Kohsuke KAWAGUCHI
*/
public class DispatcherImpl implements org.iso_relax.dispatcher.Dispatcher
{
/**
* depth of the nesting of elements from the start of the current IslandVerifier.
*
* this value has to start with 1 to prevent initial IslandVerifier
* from being cut in.
*/
private int depth =1;
protected Locator documentLocator =null;
protected final NamespaceSupport nsMap = new NamespaceSupport();
protected ErrorHandler errorHandler;
/** current validating processor which processes this island. */
private IslandVerifier currentHandler =null;
/** Dispatcher will consult this object about schema information */
protected final SchemaProvider schema;
public SchemaProvider getSchemaProvider() { return schema; }
/** this object passes SAX events to IslandVerifier. */
protected Transponder transponder;
public DispatcherImpl( SchemaProvider schema )
{
this.schema = schema;
this.transponder = new Transponder();
this.currentHandler = schema.createTopLevelVerifier();
this.currentHandler.setDispatcher(this);
}
protected static final class Context
{
public final IslandVerifier handler;
public final int depth;
public final Context previous;
public Context( IslandVerifier handler, int depth, Context previous )
{
this.handler = handler;
this.depth = depth;
this.previous = previous;
}
}
protected Context contextStack = null;
public void attachXMLReader( XMLReader reader )
{
reader.setContentHandler(transponder);
}
public void switchVerifier( IslandVerifier newVerifier ) throws SAXException
{
// push context
contextStack = new Context( currentHandler, depth, contextStack );
currentHandler = newVerifier;
currentHandler.setDispatcher(this);
currentHandler.setDocumentLocator(documentLocator);
depth = 0;
// inform new IslandHandler about all prefix mappings
Enumeration e = nsMap.getDeclaredPrefixes();
while( e.hasMoreElements() )
{
String prefix = (String)e.nextElement();
currentHandler.startPrefixMapping( prefix, nsMap.getURI(prefix) );
}
}
public void setErrorHandler( ErrorHandler handler )
{
this.errorHandler = handler;
}
public ErrorHandler getErrorHandler()
{
return errorHandler;
}
protected final Vector unparsedEntityDecls = new Vector();
public int countUnparsedEntityDecls()
{
return unparsedEntityDecls.size();
}
public UnparsedEntityDecl getUnparsedEntityDecl( int index )
{
return (UnparsedEntityDecl)unparsedEntityDecls.get(index);
}
protected final Vector notationDecls = new Vector();
public int countNotationDecls()
{
return notationDecls.size();
}
public NotationDecl getNotationDecl( int index )
{
return (NotationDecl)notationDecls.get(index);
}
/**
* relays SAX events to IslandVerifiers.
*
* This class is kept separate to make document of Dispatcher cleaner
* (by removing SAX events from Dispatcher).
*/
private class Transponder implements ContentHandler, DTDHandler
{
public void unparsedEntityDecl( String name, String systemId, String publicId, String notation )
{// memorize unparsedEntityDecl
unparsedEntityDecls.add( new UnparsedEntityDecl(name,systemId,publicId,notation) );
}
public void notationDecl( String name, String systemId, String publicId )
{// memorize notationDecl
notationDecls.add( new NotationDecl(name,systemId,publicId) );
}
public void setDocumentLocator( Locator locator )
{
documentLocator = locator;
currentHandler.setDocumentLocator(locator);
}
public void startElement( String uri, String localName, String qName, Attributes attributes )
throws SAXException
{
currentHandler.startElement(uri,localName,qName,attributes);
depth++;
nsMap.pushContext();
}
public void endElement (String uri, String localName, String qName)
throws SAXException
{
nsMap.popContext();
currentHandler.endElement(uri,localName,qName);
if( --depth == 0 )
{// cut in and restore the previos IslandVerifier.
// call endPrefixMapping for all pre-declared prefixes.
Enumeration e = nsMap.getDeclaredPrefixes();
while( e.hasMoreElements() )
currentHandler.endPrefixMapping( (String)e.nextElement() );
// gets labels which are actually verified.
ElementDecl[] results = currentHandler.endIsland();
// pop context
depth = contextStack.depth;
currentHandler = contextStack.handler;
contextStack = contextStack.previous;
// report assigned label to the parent
currentHandler.endChildIsland(uri,results);
}
}
public void characters (char ch[], int start, int length)
throws SAXException
{
currentHandler.characters(ch, start, length);
}
public void ignorableWhitespace (char ch[], int start, int length)
throws SAXException
{
currentHandler.ignorableWhitespace(ch, start, length);
}
public void processingInstruction (String target, String data)
throws SAXException
{
currentHandler.processingInstruction (target, data);
}
public void skippedEntity( String name )
throws SAXException
{
currentHandler.skippedEntity(name);
}
// those events should not be reported to island verifier.
public void startDocument() {}
public void endDocument() {}
public void startPrefixMapping(String prefix,String uri)
throws SAXException
{
nsMap.declarePrefix(prefix,uri);
currentHandler.startPrefixMapping(prefix,uri);
}
public void endPrefixMapping(String prefix)
throws SAXException
{
currentHandler.endPrefixMapping(prefix);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy