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 }