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 */ 21package org.apache.xalan.transformer; 22 23import java.io.IOException; 24 25import javax.xml.XMLConstants; 26import javax.xml.transform.ErrorListener; 27import javax.xml.transform.Templates; 28import javax.xml.transform.TransformerConfigurationException; 29 30import org.apache.xalan.res.XSLMessages; 31import org.apache.xalan.res.XSLTErrorResources; 32 33import org.xml.sax.ContentHandler; 34import org.xml.sax.DTDHandler; 35import org.xml.sax.EntityResolver; 36import org.xml.sax.InputSource; 37import org.xml.sax.XMLReader; 38import org.xml.sax.helpers.XMLFilterImpl; 39import org.xml.sax.helpers.XMLReaderFactory; 40 41 42public 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