Home | History | Annotate | Download | only in transformer
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one
      3  * or more contributor license agreements. See the NOTICE file
      4  * distributed with this work for additional information
      5  * regarding copyright ownership. The ASF licenses this file
      6  * to you under the Apache License, Version 2.0 (the  "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 /*
     19  * $Id: TrAXFilter.java 468645 2006-10-28 06:57:24Z minchau $
     20  */
     21 package org.apache.xalan.transformer;
     22 
     23 import java.io.IOException;
     24 
     25 import javax.xml.XMLConstants;
     26 import javax.xml.transform.ErrorListener;
     27 import javax.xml.transform.Templates;
     28 import javax.xml.transform.TransformerConfigurationException;
     29 
     30 import org.apache.xalan.res.XSLMessages;
     31 import org.apache.xalan.res.XSLTErrorResources;
     32 
     33 import org.xml.sax.ContentHandler;
     34 import org.xml.sax.DTDHandler;
     35 import org.xml.sax.EntityResolver;
     36 import org.xml.sax.InputSource;
     37 import org.xml.sax.XMLReader;
     38 import org.xml.sax.helpers.XMLFilterImpl;
     39 import org.xml.sax.helpers.XMLReaderFactory;
     40 
     41 
     42 public class TrAXFilter extends XMLFilterImpl
     43 {
     44   private Templates m_templates;
     45   private TransformerImpl m_transformer;
     46 
     47   /**
     48    * Construct an empty XML filter, with no parent.
     49    *
     50    * <p>This filter will have no parent: you must assign a parent
     51    * before you start a parse or do any configuration with
     52    * setFeature or setProperty.</p>
     53    *
     54    * @see org.xml.sax.XMLReader#setFeature
     55    * @see org.xml.sax.XMLReader#setProperty
     56    */
     57   public TrAXFilter (Templates templates)
     58     throws TransformerConfigurationException
     59   {
     60     m_templates = templates;
     61     m_transformer = (TransformerImpl)templates.newTransformer();
     62   }
     63 
     64   /**
     65    * Return the Transformer object used for this XML filter.
     66    */
     67   public TransformerImpl getTransformer()
     68   {
     69     return m_transformer;
     70   }
     71 
     72   /** Set the parent reader.
     73    *
     74    * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which
     75    * this filter will obtain its events and to which it will pass its
     76    * configuration requests.  The parent may itself be another filter.</p>
     77    *
     78    * <p>If there is no parent reader set, any attempt to parse
     79    * or to set or get a feature or property will fail.</p>
     80    *
     81    * @param parent The parent XML reader.
     82    * @throws java.lang.NullPointerException If the parent is null.
     83    */
     84   public void setParent (XMLReader parent)
     85   {
     86     super.setParent(parent);
     87 
     88     if(null != parent.getContentHandler())
     89       this.setContentHandler(parent.getContentHandler());
     90 
     91     // Not really sure if we should do this here, but
     92     // it seems safer in case someone calls parse() on
     93     // the parent.
     94     setupParse ();
     95   }
     96 
     97   /**
     98    * Parse a document.
     99    *
    100    * @param input The input source for the document entity.
    101    * @throws org.xml.sax.SAXException Any SAX exception, possibly
    102    *            wrapping another exception.
    103    * @throws java.io.IOException An IO exception from the parser,
    104    *            possibly from a byte stream or character stream
    105    *            supplied by the application.
    106    * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
    107    */
    108   public void parse (InputSource input)
    109     throws org.xml.sax.SAXException, IOException
    110   {
    111     if(null == getParent())
    112     {
    113       XMLReader reader=null;
    114 
    115       // Use JAXP1.1 ( if possible )
    116       try {
    117           javax.xml.parsers.SAXParserFactory factory=
    118               javax.xml.parsers.SAXParserFactory.newInstance();
    119           factory.setNamespaceAware( true );
    120 
    121           if (m_transformer.getStylesheet().isSecureProcessing()) {
    122               try {
    123                   factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
    124               }
    125               catch (org.xml.sax.SAXException se) {}
    126           }
    127 
    128           javax.xml.parsers.SAXParser jaxpParser=
    129               factory.newSAXParser();
    130           reader=jaxpParser.getXMLReader();
    131 
    132       } catch( javax.xml.parsers.ParserConfigurationException ex ) {
    133           throw new org.xml.sax.SAXException( ex );
    134       } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) {
    135           throw new org.xml.sax.SAXException( ex1.toString() );
    136       } catch( NoSuchMethodError ex2 ) {
    137       }
    138       catch (AbstractMethodError ame){}
    139 
    140       XMLReader parent;
    141       if( reader==null )
    142           parent= XMLReaderFactory.createXMLReader();
    143       else
    144           parent=reader;
    145       try
    146       {
    147         parent.setFeature("http://xml.org/sax/features/namespace-prefixes",
    148                           true);
    149       }
    150       catch (org.xml.sax.SAXException se){}
    151       // setParent calls setupParse...
    152       setParent(parent);
    153     }
    154     else
    155     {
    156       // Make sure everything is set up.
    157       setupParse ();
    158     }
    159     if(null == m_transformer.getContentHandler())
    160     {
    161       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!");
    162     }
    163 
    164     getParent().parse(input);
    165     Exception e = m_transformer.getExceptionThrown();
    166     if(null != e)
    167     {
    168       if(e instanceof org.xml.sax.SAXException)
    169         throw (org.xml.sax.SAXException)e;
    170       else
    171         throw new org.xml.sax.SAXException(e);
    172     }
    173   }
    174 
    175   /**
    176    * Parse a document.
    177    *
    178    * @param systemId The system identifier as a fully-qualified URI.
    179    * @throws org.xml.sax.SAXException Any SAX exception, possibly
    180    *            wrapping another exception.
    181    * @throws java.io.IOException An IO exception from the parser,
    182    *            possibly from a byte stream or character stream
    183    *            supplied by the application.
    184    * @see org.xml.sax.XMLReader#parse(java.lang.String)
    185    */
    186   public void parse (String systemId)
    187     throws org.xml.sax.SAXException, IOException
    188   {
    189     parse(new InputSource(systemId));
    190   }
    191 
    192 
    193   /**
    194    * Set up before a parse.
    195    *
    196    * <p>Before every parse, check whether the parent is
    197    * non-null, and re-register the filter for all of the
    198    * events.</p>
    199    */
    200   private void setupParse ()
    201   {
    202     XMLReader p = getParent();
    203     if (p == null) {
    204       throw new NullPointerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_PARENT_FOR_FILTER, null)); //"No parent for filter");
    205     }
    206 
    207     ContentHandler ch = m_transformer.getInputContentHandler();
    208 //    if(ch instanceof SourceTreeHandler)
    209 //      ((SourceTreeHandler)ch).setUseMultiThreading(true);
    210     p.setContentHandler(ch);
    211     p.setEntityResolver(this);
    212     p.setDTDHandler(this);
    213     p.setErrorHandler(this);
    214   }
    215 
    216   /**
    217    * Set the content event handler.
    218    *
    219    * @param handler The new content handler.
    220    * @throws java.lang.NullPointerException If the handler
    221    *            is null.
    222    * @see org.xml.sax.XMLReader#setContentHandler
    223    */
    224   public void setContentHandler (ContentHandler handler)
    225   {
    226     m_transformer.setContentHandler(handler);
    227     // super.setContentHandler(m_transformer.getResultTreeHandler());
    228   }
    229 
    230   public void setErrorListener (ErrorListener handler)
    231   {
    232     m_transformer.setErrorListener(handler);
    233   }
    234 
    235 }
    236