View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 2001-2004 The Apache Software Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  /*
21   * $Id: TransformerHandlerImpl.java,v 1.2.4.1 2005/09/15 06:25:12 pvedula Exp $
22   */
23  
24  package com.sun.org.apache.xalan.internal.xsltc.trax;
25  
26  import javax.xml.transform.Result;
27  import javax.xml.transform.Transformer;
28  import javax.xml.transform.TransformerException;
29  import javax.xml.transform.sax.TransformerHandler;
30  import javax.xml.transform.dom.DOMResult;
31  
32  import com.sun.org.apache.xalan.internal.xsltc.StripFilter;
33  import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
34  import com.sun.org.apache.xalan.internal.xsltc.dom.DOMWSFilter;
35  import com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl;
36  import com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager;
37  import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
38  import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
39  import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
40  
41  import org.xml.sax.Attributes;
42  import org.xml.sax.ContentHandler;
43  import org.xml.sax.DTDHandler;
44  import org.xml.sax.Locator;
45  import org.xml.sax.SAXException;
46  import org.xml.sax.ext.DeclHandler;
47  import org.xml.sax.ext.LexicalHandler;
48  import org.xml.sax.helpers.DefaultHandler;
49  
50  /**
51   * Implementation of a JAXP1.1 TransformerHandler
52   * @author Morten Jorgensen
53   */
54  public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
55  
56      private TransformerImpl  _transformer;
57      private AbstractTranslet _translet = null;
58      private String           _systemId;
59      private SAXImpl          _dom = null;
60      private ContentHandler   _handler = null;
61      private LexicalHandler   _lexHandler = null;
62      private DTDHandler       _dtdHandler = null;
63      private DeclHandler      _declHandler = null;
64      private Result           _result = null;
65      private Locator          _locator = null;
66  
67      private boolean          _done = false; // Set in endDocument()
68  
69      /**
70       * A flag indicating whether this transformer handler implements the
71       * identity transform.
72       */
73      private boolean _isIdentity = false;
74  
75      /**
76       * Cosntructor - pass in reference to a TransformerImpl object
77       */
78      public TransformerHandlerImpl(TransformerImpl transformer) {
79          // Save the reference to the transformer
80          _transformer = transformer;
81  
82          if (transformer.isIdentity()) {
83              // Set initial handler to the empty handler
84              _handler = new DefaultHandler();
85              _isIdentity = true;
86          }
87          else {
88              // Get a reference to the translet wrapped inside the transformer
89              _translet = _transformer.getTranslet();
90          }
91      }
92  
93      /**
94       * Implements javax.xml.transform.sax.TransformerHandler.getSystemId()
95       * Get the base ID (URI or system ID) from where relative URLs will be
96       * resolved.
97       * @return The systemID that was set with setSystemId(String id)
98       */
99      @Override
100     public String getSystemId() {
101         return _systemId;
102     }
103 
104     /**
105      * Implements javax.xml.transform.sax.TransformerHandler.setSystemId()
106      * Get the base ID (URI or system ID) from where relative URLs will be
107      * resolved.
108      * @param id Base URI for this stylesheet
109      */
110     @Override
111     public void setSystemId(String id) {
112         _systemId = id;
113     }
114 
115     /**
116      * Implements javax.xml.transform.sax.TransformerHandler.getTransformer()
117      * Get the Transformer associated with this handler, which is needed in
118      * order to set parameters and output properties.
119      * @return The Transformer object
120      */
121     @Override
122     public Transformer getTransformer() {
123         return _transformer;
124     }
125 
126     /**
127      * Implements javax.xml.transform.sax.TransformerHandler.setResult()
128      * Enables the user of the TransformerHandler to set the to set the Result
129      * for the transformation.
130      * @param result A Result instance, should not be null
131      * @throws IllegalArgumentException if result is invalid for some reason
132      */
133     @Override
134     public void setResult(Result result) throws IllegalArgumentException {
135         _result = result;
136 
137     if (null == result) {
138        ErrorMsg err = new ErrorMsg(ErrorMsg.ER_RESULT_NULL);
139        throw new IllegalArgumentException(err.toString()); //"result should not be null");
140     }
141 
142         if (_isIdentity) {
143             try {
144                 // Connect this object with output system directly
145                 SerializationHandler outputHandler =
146                     _transformer.getOutputHandler(result);
147                 _transformer.transferOutputProperties(outputHandler);
148 
149                 _handler = outputHandler;
150                 _lexHandler = outputHandler;
151             }
152             catch (TransformerException e) {
153                 _result = null;
154             }
155         }
156         else if (_done) {
157             // Run the transformation now, if not already done
158             try {
159                 _transformer.setDOM(_dom);
160                 _transformer.transform(null, _result);
161             }
162             catch (TransformerException e) {
163                 // What the hell are we supposed to do with this???
164                 throw new IllegalArgumentException(e.getMessage());
165             }
166         }
167     }
168 
169     /**
170      * Implements org.xml.sax.ContentHandler.characters()
171      * Receive notification of character data.
172      */
173     @Override
174     public void characters(char[] ch, int start, int length)
175         throws SAXException
176     {
177         _handler.characters(ch, start, length);
178     }
179 
180     /**
181      * Implements org.xml.sax.ContentHandler.startDocument()
182      * Receive notification of the beginning of a document.
183      */
184     @Override
185     public void startDocument() throws SAXException {
186         // Make sure setResult() was called before the first SAX event
187         if (_result == null) {
188             ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_SET_RESULT_ERR);
189             throw new SAXException(err.toString());
190         }
191 
192         if (!_isIdentity) {
193             boolean hasIdCall = (_translet != null) ? _translet.hasIdCall() : false;
194             XSLTCDTMManager dtmManager = null;
195 
196             // Create an internal DOM (not W3C) and get SAX2 input handler
197             try {
198                 dtmManager = _transformer.getTransformerFactory()
199                                          .createNewDTMManagerInstance();
200             } catch (Exception e) {
201                 throw new SAXException(e);
202             }
203 
204             DTMWSFilter wsFilter;
205             if (_translet != null && _translet instanceof StripFilter) {
206                 wsFilter = new DOMWSFilter(_translet);
207             } else {
208                 wsFilter = null;
209             }
210 
211             // Construct the DTM using the SAX events that come through
212             _dom = (SAXImpl)dtmManager.getDTM(null, false, wsFilter, true,
213                                               false, hasIdCall);
214 
215             _handler = _dom.getBuilder();
216             _lexHandler = (LexicalHandler) _handler;
217             _dtdHandler = (DTDHandler) _handler;
218             _declHandler = (DeclHandler) _handler;
219 
220 
221             // Set document URI
222             _dom.setDocumentURI(_systemId);
223 
224             if (_locator != null) {
225                 _handler.setDocumentLocator(_locator);
226             }
227         }
228 
229         // Proxy call
230         _handler.startDocument();
231     }
232 
233     /**
234      * Implements org.xml.sax.ContentHandler.endDocument()
235      * Receive notification of the end of a document.
236      */
237     @Override
238     public void endDocument() throws SAXException {
239         // Signal to the DOMBuilder that the document is complete
240         _handler.endDocument();
241 
242         if (!_isIdentity) {
243             // Run the transformation now if we have a reference to a Result object
244             if (_result != null) {
245                 try {
246                     _transformer.setDOM(_dom);
247                     _transformer.transform(null, _result);
248                 }
249                 catch (TransformerException e) {
250                     throw new SAXException(e);
251                 }
252             }
253             // Signal that the internal DOM is built (see 'setResult()').
254             _done = true;
255 
256             // Set this DOM as the transformer's DOM
257             _transformer.setDOM(_dom);
258         }
259         if (_isIdentity && _result instanceof DOMResult) {
260             ((DOMResult)_result).setNode(_transformer.getTransletOutputHandlerFactory().getNode());
261         }
262     }
263 
264     /**
265      * Implements org.xml.sax.ContentHandler.startElement()
266      * Receive notification of the beginning of an element.
267      */
268     @Override
269     public void startElement(String uri, String localName,
270                              String qname, Attributes attributes)
271         throws SAXException
272     {
273         _handler.startElement(uri, localName, qname, attributes);
274     }
275 
276     /**
277      * Implements org.xml.sax.ContentHandler.endElement()
278      * Receive notification of the end of an element.
279      */
280     @Override
281     public void endElement(String namespaceURI, String localName, String qname)
282         throws SAXException
283     {
284         _handler.endElement(namespaceURI, localName, qname);
285     }
286 
287     /**
288      * Implements org.xml.sax.ContentHandler.processingInstruction()
289      * Receive notification of a processing instruction.
290      */
291     @Override
292     public void processingInstruction(String target, String data)
293         throws SAXException
294     {
295         _handler.processingInstruction(target, data);
296     }
297 
298     /**
299      * Implements org.xml.sax.ext.LexicalHandler.startCDATA()
300      */
301     @Override
302     public void startCDATA() throws SAXException {
303         if (_lexHandler != null) {
304             _lexHandler.startCDATA();
305         }
306     }
307 
308     /**
309      * Implements org.xml.sax.ext.LexicalHandler.endCDATA()
310      */
311     @Override
312     public void endCDATA() throws SAXException {
313         if (_lexHandler != null) {
314             _lexHandler.endCDATA();
315         }
316     }
317 
318     /**
319      * Implements org.xml.sax.ext.LexicalHandler.comment()
320      * Receieve notification of a comment
321      */
322     @Override
323     public void comment(char[] ch, int start, int length)
324         throws SAXException
325     {
326         if (_lexHandler != null) {
327             _lexHandler.comment(ch, start, length);
328         }
329     }
330 
331     /**
332      * Implements org.xml.sax.ContentHandler.ignorableWhitespace()
333      * Receive notification of ignorable whitespace in element
334      * content. Similar to characters(char[], int, int).
335      */
336     @Override
337     public void ignorableWhitespace(char[] ch, int start, int length)
338         throws SAXException
339     {
340         _handler.ignorableWhitespace(ch, start, length);
341     }
342 
343     /**
344      * Implements org.xml.sax.ContentHandler.setDocumentLocator()
345      * Receive an object for locating the origin of SAX document events.
346      */
347     @Override
348     public void setDocumentLocator(Locator locator) {
349         _locator = locator;
350 
351         if (_handler != null) {
352             _handler.setDocumentLocator(locator);
353         }
354     }
355 
356     /**
357      * Implements org.xml.sax.ContentHandler.skippedEntity()
358      * Receive notification of a skipped entity.
359      */
360     @Override
361     public void skippedEntity(String name) throws SAXException {
362         _handler.skippedEntity(name);
363     }
364 
365     /**
366      * Implements org.xml.sax.ContentHandler.startPrefixMapping()
367      * Begin the scope of a prefix-URI Namespace mapping.
368      */
369     @Override
370     public void startPrefixMapping(String prefix, String uri)
371         throws SAXException {
372         _handler.startPrefixMapping(prefix, uri);
373     }
374 
375     /**
376      * Implements org.xml.sax.ContentHandler.endPrefixMapping()
377      * End the scope of a prefix-URI Namespace mapping.
378      */
379     @Override
380     public void endPrefixMapping(String prefix) throws SAXException {
381         _handler.endPrefixMapping(prefix);
382     }
383 
384     /**
385      * Implements org.xml.sax.ext.LexicalHandler.startDTD()
386      */
387     @Override
388     public void startDTD(String name, String publicId, String systemId)
389         throws SAXException
390     {
391         if (_lexHandler != null) {
392             _lexHandler.startDTD(name, publicId, systemId);
393         }
394     }
395 
396     /**
397      * Implements org.xml.sax.ext.LexicalHandler.endDTD()
398      */
399     @Override
400     public void endDTD() throws SAXException {
401         if (_lexHandler != null) {
402             _lexHandler.endDTD();
403         }
404     }
405 
406     /**
407      * Implements org.xml.sax.ext.LexicalHandler.startEntity()
408      */
409     @Override
410     public void startEntity(String name) throws SAXException {
411         if (_lexHandler != null) {
412             _lexHandler.startEntity(name);
413         }
414     }
415 
416     /**
417      * Implements org.xml.sax.ext.LexicalHandler.endEntity()
418      */
419     @Override
420     public void endEntity(String name) throws SAXException {
421         if (_lexHandler != null) {
422             _lexHandler.endEntity(name);
423         }
424     }
425 
426     /**
427      * Implements org.xml.sax.DTDHandler.unparsedEntityDecl()
428      */
429     @Override
430     public void unparsedEntityDecl(String name, String publicId,
431         String systemId, String notationName) throws SAXException
432     {
433         if (_dtdHandler != null) {
434             _dtdHandler.unparsedEntityDecl(name, publicId, systemId,
435                                            notationName);
436         }
437     }
438 
439     /**
440      * Implements org.xml.sax.DTDHandler.notationDecl()
441      */
442     @Override
443     public void notationDecl(String name, String publicId, String systemId)
444         throws SAXException
445     {
446         if (_dtdHandler != null) {
447             _dtdHandler.notationDecl(name, publicId, systemId);
448         }
449     }
450 
451     /**
452      * Implements org.xml.sax.ext.DeclHandler.attributeDecl()
453      */
454     @Override
455     public void attributeDecl(String eName, String aName, String type,
456         String valueDefault, String value) throws SAXException
457     {
458         if (_declHandler != null) {
459             _declHandler.attributeDecl(eName, aName, type, valueDefault, value);
460         }
461     }
462 
463     /**
464      * Implements org.xml.sax.ext.DeclHandler.elementDecl()
465      */
466     @Override
467     public void elementDecl(String name, String model)
468         throws SAXException
469     {
470         if (_declHandler != null) {
471             _declHandler.elementDecl(name, model);
472         }
473     }
474 
475     /**
476      * Implements org.xml.sax.ext.DeclHandler.externalEntityDecl()
477      */
478     @Override
479     public void externalEntityDecl(String name, String publicId, String systemId)
480         throws SAXException
481     {
482         if (_declHandler != null) {
483             _declHandler.externalEntityDecl(name, publicId, systemId);
484         }
485     }
486 
487     /**
488      * Implements org.xml.sax.ext.DeclHandler.externalEntityDecl()
489      */
490     @Override
491     public void internalEntityDecl(String name, String value)
492         throws SAXException
493     {
494         if (_declHandler != null) {
495             _declHandler.internalEntityDecl(name, value);
496         }
497     }
498 
499 
500    /** Implementation of the reset() method
501     *
502     */
503    public void reset() {
504        _systemId = null;
505        _dom = null;
506        _handler = null;
507        _lexHandler = null;
508        _dtdHandler = null;
509        _declHandler = null;
510        _result = null;
511        _locator = null;
512    }
513 }