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: SmartTransformerFactoryImpl.java 468653 2006-10-28 07:07:05Z minchau $ 020 */ 021 022 023 package org.apache.xalan.xsltc.trax; 024 025 import javax.xml.XMLConstants; 026 import javax.xml.transform.ErrorListener; 027 import javax.xml.transform.Source; 028 import javax.xml.transform.Templates; 029 import javax.xml.transform.Transformer; 030 import javax.xml.transform.TransformerConfigurationException; 031 import javax.xml.transform.TransformerException; 032 import javax.xml.transform.URIResolver; 033 import javax.xml.transform.dom.DOMResult; 034 import javax.xml.transform.dom.DOMSource; 035 import javax.xml.transform.sax.SAXResult; 036 import javax.xml.transform.sax.SAXSource; 037 import javax.xml.transform.sax.SAXTransformerFactory; 038 import javax.xml.transform.sax.TemplatesHandler; 039 import javax.xml.transform.sax.TransformerHandler; 040 import javax.xml.transform.stream.StreamResult; 041 import javax.xml.transform.stream.StreamSource; 042 043 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 044 import org.xml.sax.XMLFilter; 045 046 /** 047 * Implementation of a transformer factory that uses an XSLTC 048 * transformer factory for the creation of Templates objects 049 * and uses the Xalan processor transformer factory for the 050 * creation of Transformer objects. 051 * @author G. Todd Miller 052 */ 053 public class SmartTransformerFactoryImpl extends SAXTransformerFactory 054 { 055 /** 056 * <p>Name of class as a constant to use for debugging.</p> 057 */ 058 private static final String CLASS_NAME = "SmartTransformerFactoryImpl"; 059 060 private SAXTransformerFactory _xsltcFactory = null; 061 private SAXTransformerFactory _xalanFactory = null; 062 private SAXTransformerFactory _currFactory = null; 063 private ErrorListener _errorlistener = null; 064 private URIResolver _uriresolver = null; 065 066 /** 067 * <p>State of secure processing feature.</p> 068 */ 069 private boolean featureSecureProcessing = false; 070 071 /** 072 * implementation of the SmartTransformerFactory. This factory 073 * uses org.apache.xalan.xsltc.trax.TransformerFactory 074 * to return Templates objects; and uses 075 * org.apache.xalan.processor.TransformerFactory 076 * to return Transformer objects. 077 */ 078 public SmartTransformerFactoryImpl() { } 079 080 private void createXSLTCTransformerFactory() { 081 _xsltcFactory = new TransformerFactoryImpl(); 082 _currFactory = _xsltcFactory; 083 } 084 085 private void createXalanTransformerFactory() { 086 final String xalanMessage = 087 "org.apache.xalan.xsltc.trax.SmartTransformerFactoryImpl "+ 088 "could not create an "+ 089 "org.apache.xalan.processor.TransformerFactoryImpl."; 090 // try to create instance of Xalan factory... 091 try { 092 Class xalanFactClass = ObjectFactory.findProviderClass( 093 "org.apache.xalan.processor.TransformerFactoryImpl", 094 ObjectFactory.findClassLoader(), true); 095 _xalanFactory = (SAXTransformerFactory) 096 xalanFactClass.newInstance(); 097 } 098 catch (ClassNotFoundException e) { 099 System.err.println(xalanMessage); 100 } 101 catch (InstantiationException e) { 102 System.err.println(xalanMessage); 103 } 104 catch (IllegalAccessException e) { 105 System.err.println(xalanMessage); 106 } 107 _currFactory = _xalanFactory; 108 } 109 110 public void setErrorListener(ErrorListener listener) 111 throws IllegalArgumentException 112 { 113 _errorlistener = listener; 114 } 115 116 public ErrorListener getErrorListener() { 117 return _errorlistener; 118 } 119 120 public Object getAttribute(String name) 121 throws IllegalArgumentException 122 { 123 // GTM: NB: 'debug' should change to something more unique... 124 if ((name.equals("translet-name")) || (name.equals("debug"))) { 125 if (_xsltcFactory == null) { 126 createXSLTCTransformerFactory(); 127 } 128 return _xsltcFactory.getAttribute(name); 129 } 130 else { 131 if (_xalanFactory == null) { 132 createXalanTransformerFactory(); 133 } 134 return _xalanFactory.getAttribute(name); 135 } 136 } 137 138 public void setAttribute(String name, Object value) 139 throws IllegalArgumentException { 140 // GTM: NB: 'debug' should change to something more unique... 141 if ((name.equals("translet-name")) || (name.equals("debug"))) { 142 if (_xsltcFactory == null) { 143 createXSLTCTransformerFactory(); 144 } 145 _xsltcFactory.setAttribute(name, value); 146 } 147 else { 148 if (_xalanFactory == null) { 149 createXalanTransformerFactory(); 150 } 151 _xalanFactory.setAttribute(name, value); 152 } 153 } 154 155 /** 156 * <p>Set a feature for this <code>SmartTransformerFactory</code> and <code>Transformer</code>s 157 * or <code>Template</code>s created by this factory.</p> 158 * 159 * <p> 160 * Feature names are fully qualified {@link java.net.URI}s. 161 * Implementations may define their own features. 162 * An {@link TransformerConfigurationException} is thrown if this <code>TransformerFactory</code> or the 163 * <code>Transformer</code>s or <code>Template</code>s it creates cannot support the feature. 164 * It is possible for an <code>TransformerFactory</code> to expose a feature value but be unable to change its state. 165 * </p> 166 * 167 * <p>See {@link javax.xml.transform.TransformerFactory} for full documentation of specific features.</p> 168 * 169 * @param name Feature name. 170 * @param value Is feature state <code>true</code> or <code>false</code>. 171 * 172 * @throws TransformerConfigurationException if this <code>TransformerFactory</code> 173 * or the <code>Transformer</code>s or <code>Template</code>s it creates cannot support this feature. 174 * @throws NullPointerException If the <code>name</code> parameter is null. 175 */ 176 public void setFeature(String name, boolean value) 177 throws TransformerConfigurationException { 178 179 // feature name cannot be null 180 if (name == null) { 181 ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_SET_FEATURE_NULL_NAME); 182 throw new NullPointerException(err.toString()); 183 } 184 // secure processing? 185 else if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { 186 featureSecureProcessing = value; 187 // all done processing feature 188 return; 189 } 190 else { 191 // unknown feature 192 ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNSUPPORTED_FEATURE, name); 193 throw new TransformerConfigurationException(err.toString()); 194 } 195 } 196 197 /** 198 * javax.xml.transform.sax.TransformerFactory implementation. 199 * Look up the value of a feature (to see if it is supported). 200 * This method must be updated as the various methods and features of this 201 * class are implemented. 202 * 203 * @param name The feature name 204 * @return 'true' if feature is supported, 'false' if not 205 */ 206 public boolean getFeature(String name) { 207 // All supported features should be listed here 208 String[] features = { 209 DOMSource.FEATURE, 210 DOMResult.FEATURE, 211 SAXSource.FEATURE, 212 SAXResult.FEATURE, 213 StreamSource.FEATURE, 214 StreamResult.FEATURE 215 }; 216 217 // feature name cannot be null 218 if (name == null) { 219 ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_GET_FEATURE_NULL_NAME); 220 throw new NullPointerException(err.toString()); 221 } 222 223 // Inefficient, but it really does not matter in a function like this 224 for (int i = 0; i < features.length; i++) { 225 if (name.equals(features[i])) 226 return true; 227 } 228 229 // secure processing? 230 if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { 231 return featureSecureProcessing; 232 } 233 234 // unknown feature 235 return false; 236 } 237 238 public URIResolver getURIResolver() { 239 return _uriresolver; 240 } 241 242 public void setURIResolver(URIResolver resolver) { 243 _uriresolver = resolver; 244 } 245 246 public Source getAssociatedStylesheet(Source source, String media, 247 String title, String charset) 248 throws TransformerConfigurationException 249 { 250 if (_currFactory == null) { 251 createXSLTCTransformerFactory(); 252 } 253 return _currFactory.getAssociatedStylesheet(source, media, 254 title, charset); 255 } 256 257 /** 258 * Create a Transformer object that copies the input document to the 259 * result. Uses the org.apache.xalan.processor.TransformerFactory. 260 * @return A Transformer object. 261 */ 262 public Transformer newTransformer() 263 throws TransformerConfigurationException 264 { 265 if (_xalanFactory == null) { 266 createXalanTransformerFactory(); 267 } 268 if (_errorlistener != null) { 269 _xalanFactory.setErrorListener(_errorlistener); 270 } 271 if (_uriresolver != null) { 272 _xalanFactory.setURIResolver(_uriresolver); 273 } 274 _currFactory = _xalanFactory; 275 return _currFactory.newTransformer(); 276 } 277 278 /** 279 * Create a Transformer object that from the input stylesheet 280 * Uses the org.apache.xalan.processor.TransformerFactory. 281 * @param source the stylesheet. 282 * @return A Transformer object. 283 */ 284 public Transformer newTransformer(Source source) throws 285 TransformerConfigurationException 286 { 287 if (_xalanFactory == null) { 288 createXalanTransformerFactory(); 289 } 290 if (_errorlistener != null) { 291 _xalanFactory.setErrorListener(_errorlistener); 292 } 293 if (_uriresolver != null) { 294 _xalanFactory.setURIResolver(_uriresolver); 295 } 296 _currFactory = _xalanFactory; 297 return _currFactory.newTransformer(source); 298 } 299 300 /** 301 * Create a Templates object that from the input stylesheet 302 * Uses the org.apache.xalan.xsltc.trax.TransformerFactory. 303 * @param source the stylesheet. 304 * @return A Templates object. 305 */ 306 public Templates newTemplates(Source source) 307 throws TransformerConfigurationException 308 { 309 if (_xsltcFactory == null) { 310 createXSLTCTransformerFactory(); 311 } 312 if (_errorlistener != null) { 313 _xsltcFactory.setErrorListener(_errorlistener); 314 } 315 if (_uriresolver != null) { 316 _xsltcFactory.setURIResolver(_uriresolver); 317 } 318 _currFactory = _xsltcFactory; 319 return _currFactory.newTemplates(source); 320 } 321 322 /** 323 * Get a TemplatesHandler object that can process SAX ContentHandler 324 * events into a Templates object. Uses the 325 * org.apache.xalan.xsltc.trax.TransformerFactory. 326 */ 327 public TemplatesHandler newTemplatesHandler() 328 throws TransformerConfigurationException 329 { 330 if (_xsltcFactory == null) { 331 createXSLTCTransformerFactory(); 332 } 333 if (_errorlistener != null) { 334 _xsltcFactory.setErrorListener(_errorlistener); 335 } 336 if (_uriresolver != null) { 337 _xsltcFactory.setURIResolver(_uriresolver); 338 } 339 return _xsltcFactory.newTemplatesHandler(); 340 } 341 342 /** 343 * Get a TransformerHandler object that can process SAX ContentHandler 344 * events based on a copy transformer. 345 * Uses org.apache.xalan.processor.TransformerFactory. 346 */ 347 public TransformerHandler newTransformerHandler() 348 throws TransformerConfigurationException 349 { 350 if (_xalanFactory == null) { 351 createXalanTransformerFactory(); 352 } 353 if (_errorlistener != null) { 354 _xalanFactory.setErrorListener(_errorlistener); 355 } 356 if (_uriresolver != null) { 357 _xalanFactory.setURIResolver(_uriresolver); 358 } 359 return _xalanFactory.newTransformerHandler(); 360 } 361 362 /** 363 * Get a TransformerHandler object that can process SAX ContentHandler 364 * events based on a transformer specified by the stylesheet Source. 365 * Uses org.apache.xalan.processor.TransformerFactory. 366 */ 367 public TransformerHandler newTransformerHandler(Source src) 368 throws TransformerConfigurationException 369 { 370 if (_xalanFactory == null) { 371 createXalanTransformerFactory(); 372 } 373 if (_errorlistener != null) { 374 _xalanFactory.setErrorListener(_errorlistener); 375 } 376 if (_uriresolver != null) { 377 _xalanFactory.setURIResolver(_uriresolver); 378 } 379 return _xalanFactory.newTransformerHandler(src); 380 } 381 382 383 /** 384 * Get a TransformerHandler object that can process SAX ContentHandler 385 * events based on a transformer specified by the stylesheet Source. 386 * Uses org.apache.xalan.xsltc.trax.TransformerFactory. 387 */ 388 public TransformerHandler newTransformerHandler(Templates templates) 389 throws TransformerConfigurationException 390 { 391 if (_xsltcFactory == null) { 392 createXSLTCTransformerFactory(); 393 } 394 if (_errorlistener != null) { 395 _xsltcFactory.setErrorListener(_errorlistener); 396 } 397 if (_uriresolver != null) { 398 _xsltcFactory.setURIResolver(_uriresolver); 399 } 400 return _xsltcFactory.newTransformerHandler(templates); 401 } 402 403 404 /** 405 * Create an XMLFilter that uses the given source as the 406 * transformation instructions. Uses 407 * org.apache.xalan.xsltc.trax.TransformerFactory. 408 */ 409 public XMLFilter newXMLFilter(Source src) 410 throws TransformerConfigurationException { 411 if (_xsltcFactory == null) { 412 createXSLTCTransformerFactory(); 413 } 414 if (_errorlistener != null) { 415 _xsltcFactory.setErrorListener(_errorlistener); 416 } 417 if (_uriresolver != null) { 418 _xsltcFactory.setURIResolver(_uriresolver); 419 } 420 Templates templates = _xsltcFactory.newTemplates(src); 421 if (templates == null ) return null; 422 return newXMLFilter(templates); 423 } 424 425 /* 426 * Create an XMLFilter that uses the given source as the 427 * transformation instructions. Uses 428 * org.apache.xalan.xsltc.trax.TransformerFactory. 429 */ 430 public XMLFilter newXMLFilter(Templates templates) 431 throws TransformerConfigurationException { 432 try { 433 return new org.apache.xalan.xsltc.trax.TrAXFilter(templates); 434 } 435 catch(TransformerConfigurationException e1) { 436 if (_xsltcFactory == null) { 437 createXSLTCTransformerFactory(); 438 } 439 ErrorListener errorListener = _xsltcFactory.getErrorListener(); 440 if(errorListener != null) { 441 try { 442 errorListener.fatalError(e1); 443 return null; 444 } 445 catch( TransformerException e2) { 446 new TransformerConfigurationException(e2); 447 } 448 } 449 throw e1; 450 } 451 } 452 }