blob: efdcfd71e38e0efe2a6e6ccdf262927ea8e6aa2e [file] [log] [blame]
package org.apache.xalan.transformer;
import java.io.IOException;
import javax.xml.transform.TransformerException;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.XMLFilter;
import org.xml.sax.ContentHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.DTDHandler;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.XMLFilterImpl;
import org.xml.sax.helpers.XMLReaderFactory;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.ErrorListener;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.res.XSLMessages;
public class TrAXFilter extends XMLFilterImpl
{
private Templates m_templates;
private TransformerImpl m_transformer;
/**
* Construct an empty XML filter, with no parent.
*
* <p>This filter will have no parent: you must assign a parent
* before you start a parse or do any configuration with
* setFeature or setProperty.</p>
*
* @see org.xml.sax.XMLReader#setFeature
* @see org.xml.sax.XMLReader#setProperty
*/
public TrAXFilter (Templates templates)
throws TransformerConfigurationException
{
m_templates = templates;
m_transformer = (TransformerImpl)templates.newTransformer();
}
/** Set the parent reader.
*
* <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which
* this filter will obtain its events and to which it will pass its
* configuration requests. The parent may itself be another filter.</p>
*
* <p>If there is no parent reader set, any attempt to parse
* or to set or get a feature or property will fail.</p>
*
* @param parent The parent XML reader.
* @throws java.lang.NullPointerException If the parent is null.
*/
public void setParent (XMLReader parent)
{
super.setParent(parent);
if(null != parent.getContentHandler())
this.setContentHandler(parent.getContentHandler());
// Not really sure if we should do this here, but
// it seems safer in case someone calls parse() on
// the parent.
setupParse ();
}
/**
* Parse a document.
*
* @param input The input source for the document entity.
* @throws org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
* @throws java.io.IOException An IO exception from the parser,
* possibly from a byte stream or character stream
* supplied by the application.
* @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
*/
public void parse (InputSource input)
throws org.xml.sax.SAXException, IOException
{
if(null == getParent())
{
XMLReader reader=null;
// Use JAXP1.1 ( if possible )
try {
javax.xml.parsers.SAXParserFactory factory=
javax.xml.parsers.SAXParserFactory.newInstance();
factory.setNamespaceAware( true );
javax.xml.parsers.SAXParser jaxpParser=
factory.newSAXParser();
reader=jaxpParser.getXMLReader();
} catch( javax.xml.parsers.ParserConfigurationException ex ) {
throw new org.xml.sax.SAXException( ex );
} catch( javax.xml.parsers.FactoryConfigurationError ex1 ) {
throw new org.xml.sax.SAXException( ex1.toString() );
} catch( NoSuchMethodError ex2 ) {
}
catch (AbstractMethodError ame){}
XMLReader parent;
if( reader==null )
parent= XMLReaderFactory.createXMLReader();
else
parent=reader;
try
{
parent.setFeature("http://xml.org/sax/features/namespace-prefixes",
true);
// Commented out as per discussion with Thomas2.Maesing@bgs-ag.de
// about bug 2124.
// parent.setFeature("http://apache.org/xml/features/validation/dynamic",
// true);
}
catch (org.xml.sax.SAXException se){}
// setParent calls setupParse...
setParent(parent);
}
else
{
// Make sure everything is set up.
setupParse ();
}
if(null == m_transformer.getContentHandler())
{
throw new org.xml.sax.SAXException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_CALL_PARSE, null)); //"parse can not be called if the ContentHandler has not been set!");
}
getParent().parse(input);
Exception e = m_transformer.getExceptionThrown();
if(null != e)
{
if(e instanceof org.xml.sax.SAXException)
throw (org.xml.sax.SAXException)e;
else
throw new org.xml.sax.SAXException(e);
}
}
/**
* Parse a document.
*
* @param systemId The system identifier as a fully-qualified URI.
* @throws org.xml.sax.SAXException Any SAX exception, possibly
* wrapping another exception.
* @throws java.io.IOException An IO exception from the parser,
* possibly from a byte stream or character stream
* supplied by the application.
* @see org.xml.sax.XMLReader#parse(java.lang.String)
*/
public void parse (String systemId)
throws org.xml.sax.SAXException, IOException
{
parse(new InputSource(systemId));
}
/**
* Set up before a parse.
*
* <p>Before every parse, check whether the parent is
* non-null, and re-register the filter for all of the
* events.</p>
*/
private void setupParse ()
{
XMLReader p = getParent();
if (p == null) {
throw new NullPointerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_PARENT_FOR_FILTER, null)); //"No parent for filter");
}
ContentHandler ch = m_transformer.getInputContentHandler();
// if(ch instanceof SourceTreeHandler)
// ((SourceTreeHandler)ch).setUseMultiThreading(true);
p.setContentHandler(ch);
if(ch instanceof EntityResolver)
p.setEntityResolver((EntityResolver)ch);
else
p.setEntityResolver(this);
if(ch instanceof DTDHandler)
p.setDTDHandler((DTDHandler)ch);
else
p.setDTDHandler(this);
ErrorListener elistener = m_transformer.getErrorListener();
if((null != elistener) && (elistener instanceof org.xml.sax.ErrorHandler))
p.setErrorHandler((org.xml.sax.ErrorHandler)elistener);
else
p.setErrorHandler(this);
}
/**
* Set the content event handler.
*
* @param resolver The new content handler.
* @throws java.lang.NullPointerException If the handler
* is null.
* @see org.xml.sax.XMLReader#setContentHandler
*/
public void setContentHandler (ContentHandler handler)
{
m_transformer.setContentHandler(handler);
// super.setContentHandler(m_transformer.getResultTreeHandler());
}
public void setErrorListener (ErrorListener handler)
{
m_transformer.setErrorListener(handler);
}
}