001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: TrAXFilter.java 468645 2006-10-28 06:57:24Z minchau $ 020 */ 021 package org.apache.xalan.transformer; 022 023 import java.io.IOException; 024 025 import javax.xml.XMLConstants; 026 import javax.xml.transform.ErrorListener; 027 import javax.xml.transform.Templates; 028 import javax.xml.transform.TransformerConfigurationException; 029 030 import org.apache.xalan.res.XSLMessages; 031 import org.apache.xalan.res.XSLTErrorResources; 032 033 import org.xml.sax.ContentHandler; 034 import org.xml.sax.DTDHandler; 035 import org.xml.sax.EntityResolver; 036 import org.xml.sax.InputSource; 037 import org.xml.sax.XMLReader; 038 import org.xml.sax.helpers.XMLFilterImpl; 039 import org.xml.sax.helpers.XMLReaderFactory; 040 041 042 public class TrAXFilter extends XMLFilterImpl 043 { 044 private Templates m_templates; 045 private TransformerImpl m_transformer; 046 047 /** 048 * Construct an empty XML filter, with no parent. 049 * 050 * <p>This filter will have no parent: you must assign a parent 051 * before you start a parse or do any configuration with 052 * setFeature or setProperty.</p> 053 * 054 * @see org.xml.sax.XMLReader#setFeature 055 * @see org.xml.sax.XMLReader#setProperty 056 */ 057 public TrAXFilter (Templates templates) 058 throws TransformerConfigurationException 059 { 060 m_templates = templates; 061 m_transformer = (TransformerImpl)templates.newTransformer(); 062 } 063 064 /** 065 * Return the Transformer object used for this XML filter. 066 */ 067 public TransformerImpl getTransformer() 068 { 069 return m_transformer; 070 } 071 072 /** Set the parent reader. 073 * 074 * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which 075 * this filter will obtain its events and to which it will pass its 076 * configuration requests. The parent may itself be another filter.</p> 077 * 078 * <p>If there is no parent reader set, any attempt to parse 079 * or to set or get a feature or property will fail.</p> 080 * 081 * @param parent The parent XML reader. 082 * @throws java.lang.NullPointerException If the parent is null. 083 */ 084 public void setParent (XMLReader parent) 085 { 086 super.setParent(parent); 087 088 if(null != parent.getContentHandler()) 089 this.setContentHandler(parent.getContentHandler()); 090 091 // Not really sure if we should do this here, but 092 // it seems safer in case someone calls parse() on 093 // the parent. 094 setupParse (); 095 } 096 097 /** 098 * Parse a document. 099 * 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 }