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 public String getSystemId() {
100 return _systemId;
101 }
102
103 /**
104 * Implements javax.xml.transform.sax.TransformerHandler.setSystemId()
105 * Get the base ID (URI or system ID) from where relative URLs will be
106 * resolved.
107 * @param id Base URI for this stylesheet
108 */
109 public void setSystemId(String id) {
110 _systemId = id;
111 }
112
113 /**
114 * Implements javax.xml.transform.sax.TransformerHandler.getTransformer()
115 * Get the Transformer associated with this handler, which is needed in
116 * order to set parameters and output properties.
117 * @return The Transformer object
118 */
119 public Transformer getTransformer() {
120 return _transformer;
121 }
122
123 /**
124 * Implements javax.xml.transform.sax.TransformerHandler.setResult()
125 * Enables the user of the TransformerHandler to set the to set the Result
126 * for the transformation.
127 * @param result A Result instance, should not be null
128 * @throws IllegalArgumentException if result is invalid for some reason
129 */
130 public void setResult(Result result) throws IllegalArgumentException {
131 _result = result;
132
133 if (null == result) {
134 ErrorMsg err = new ErrorMsg(ErrorMsg.ER_RESULT_NULL);
135 throw new IllegalArgumentException(err.toString()); //"result should not be null");
136 }
137
138 if (_isIdentity) {
139 try {
140 // Connect this object with output system directly
141 SerializationHandler outputHandler =
142 _transformer.getOutputHandler(result);
143 _transformer.transferOutputProperties(outputHandler);
144
145 _handler = outputHandler;
146 _lexHandler = outputHandler;
147 }
148 catch (TransformerException e) {
149 _result = null;
150 }
151 }
152 else if (_done) {
153 // Run the transformation now, if not already done
154 try {
155 _transformer.setDOM(_dom);
156 _transformer.transform(null, _result);
157 }
158 catch (TransformerException e) {
159 // What the hell are we supposed to do with this???
160 throw new IllegalArgumentException(e.getMessage());
161 }
162 }
163 }
164
165 /**
166 * Implements org.xml.sax.ContentHandler.characters()
167 * Receive notification of character data.
168 */
169 public void characters(char[] ch, int start, int length)
170 throws SAXException
171 {
172 _handler.characters(ch, start, length);
173 }
174
175 /**
176 * Implements org.xml.sax.ContentHandler.startDocument()
177 * Receive notification of the beginning of a document.
178 */
179 public void startDocument() throws SAXException {
180 // Make sure setResult() was called before the first SAX event
181 if (_result == null) {
182 ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_SET_RESULT_ERR);
183 throw new SAXException(err.toString());
184 }
185
186 if (!_isIdentity) {
187 boolean hasIdCall = (_translet != null) ? _translet.hasIdCall() : false;
188 XSLTCDTMManager dtmManager = null;
189
190 // Create an internal DOM (not W3C) and get SAX2 input handler
191 try {
192 dtmManager =
193 (XSLTCDTMManager)_transformer.getTransformerFactory()
194 .getDTMManagerClass()
195 .newInstance();
196 } catch (Exception e) {
197 throw new SAXException(e);
198 }
199
200 DTMWSFilter wsFilter;
201 if (_translet != null && _translet instanceof StripFilter) {
202 wsFilter = new DOMWSFilter(_translet);
203 } else {
204 wsFilter = null;
205 }
206
207 // Construct the DTM using the SAX events that come through
208 _dom = (SAXImpl)dtmManager.getDTM(null, false, wsFilter, true,
209 false, hasIdCall);
210
211 _handler = _dom.getBuilder();
212 _lexHandler = (LexicalHandler) _handler;
213 _dtdHandler = (DTDHandler) _handler;
214 _declHandler = (DeclHandler) _handler;
215
216
217 // Set document URI
218 _dom.setDocumentURI(_systemId);
219
220 if (_locator != null) {
221 _handler.setDocumentLocator(_locator);
222 }
223 }
224
225 // Proxy call
226 _handler.startDocument();
227 }
228
229 /**
230 * Implements org.xml.sax.ContentHandler.endDocument()
231 * Receive notification of the end of a document.
232 */
233 public void endDocument() throws SAXException {
234 // Signal to the DOMBuilder that the document is complete
235 _handler.endDocument();
236
237 if (!_isIdentity) {
238 // Run the transformation now if we have a reference to a Result object
239 if (_result != null) {
240 try {
241 _transformer.setDOM(_dom);
242 _transformer.transform(null, _result);
243 }
244 catch (TransformerException e) {
245 throw new SAXException(e);
246 }
247 }
248 // Signal that the internal DOM is built (see 'setResult()').
249 _done = true;
250
251 // Set this DOM as the transformer's DOM
252 _transformer.setDOM(_dom);
253 }
254 if (_isIdentity && _result instanceof DOMResult) {
255 ((DOMResult)_result).setNode(_transformer.getTransletOutputHandlerFactory().getNode());
256 }
257 }
258
259 /**
260 * Implements org.xml.sax.ContentHandler.startElement()
261 * Receive notification of the beginning of an element.
262 */
263 public void startElement(String uri, String localName,
264 String qname, Attributes attributes)
265 throws SAXException
266 {
267 _handler.startElement(uri, localName, qname, attributes);
268 }
269
270 /**
271 * Implements org.xml.sax.ContentHandler.endElement()
272 * Receive notification of the end of an element.
273 */
274 public void endElement(String namespaceURI, String localName, String qname)
275 throws SAXException
276 {
277 _handler.endElement(namespaceURI, localName, qname);
278 }
279
280 /**
281 * Implements org.xml.sax.ContentHandler.processingInstruction()
282 * Receive notification of a processing instruction.
283 */
284 public void processingInstruction(String target, String data)
285 throws SAXException
286 {
287 _handler.processingInstruction(target, data);
288 }
289
290 /**
291 * Implements org.xml.sax.ext.LexicalHandler.startCDATA()
292 */
293 public void startCDATA() throws SAXException {
294 if (_lexHandler != null) {
295 _lexHandler.startCDATA();
296 }
297 }
298
299 /**
300 * Implements org.xml.sax.ext.LexicalHandler.endCDATA()
301 */
302 public void endCDATA() throws SAXException {
303 if (_lexHandler != null) {
304 _lexHandler.endCDATA();
305 }
306 }
307
308 /**
309 * Implements org.xml.sax.ext.LexicalHandler.comment()
310 * Receieve notification of a comment
311 */
312 public void comment(char[] ch, int start, int length)
313 throws SAXException
314 {
315 if (_lexHandler != null) {
316 _lexHandler.comment(ch, start, length);
317 }
318 }
319
320 /**
321 * Implements org.xml.sax.ContentHandler.ignorableWhitespace()
322 * Receive notification of ignorable whitespace in element
323 * content. Similar to characters(char[], int, int).
324 */
325 public void ignorableWhitespace(char[] ch, int start, int length)
326 throws SAXException
327 {
328 _handler.ignorableWhitespace(ch, start, length);
329 }
330
331 /**
332 * Implements org.xml.sax.ContentHandler.setDocumentLocator()
333 * Receive an object for locating the origin of SAX document events.
334 */
335 public void setDocumentLocator(Locator locator) {
336 _locator = locator;
337
338 if (_handler != null) {
339 _handler.setDocumentLocator(locator);
340 }
341 }
342
343 /**
344 * Implements org.xml.sax.ContentHandler.skippedEntity()
345 * Receive notification of a skipped entity.
346 */
347 public void skippedEntity(String name) throws SAXException {
348 _handler.skippedEntity(name);
349 }
350
351 /**
352 * Implements org.xml.sax.ContentHandler.startPrefixMapping()
353 * Begin the scope of a prefix-URI Namespace mapping.
354 */
355 public void startPrefixMapping(String prefix, String uri)
356 throws SAXException {
357 _handler.startPrefixMapping(prefix, uri);
358 }
359
360 /**
361 * Implements org.xml.sax.ContentHandler.endPrefixMapping()
362 * End the scope of a prefix-URI Namespace mapping.
363 */
364 public void endPrefixMapping(String prefix) throws SAXException {
365 _handler.endPrefixMapping(prefix);
366 }
367
368 /**
369 * Implements org.xml.sax.ext.LexicalHandler.startDTD()
370 */
371 public void startDTD(String name, String publicId, String systemId)
372 throws SAXException
373 {
374 if (_lexHandler != null) {
375 _lexHandler.startDTD(name, publicId, systemId);
376 }
377 }
378
379 /**
380 * Implements org.xml.sax.ext.LexicalHandler.endDTD()
381 */
382 public void endDTD() throws SAXException {
383 if (_lexHandler != null) {
384 _lexHandler.endDTD();
385 }
386 }
387
388 /**
389 * Implements org.xml.sax.ext.LexicalHandler.startEntity()
390 */
391 public void startEntity(String name) throws SAXException {
392 if (_lexHandler != null) {
393 _lexHandler.startEntity(name);
394 }
395 }
396
397 /**
398 * Implements org.xml.sax.ext.LexicalHandler.endEntity()
399 */
400 public void endEntity(String name) throws SAXException {
401 if (_lexHandler != null) {
402 _lexHandler.endEntity(name);
403 }
404 }
405
406 /**
407 * Implements org.xml.sax.DTDHandler.unparsedEntityDecl()
408 */
409 public void unparsedEntityDecl(String name, String publicId,
410 String systemId, String notationName) throws SAXException
411 {
412 if (_dtdHandler != null) {
413 _dtdHandler.unparsedEntityDecl(name, publicId, systemId,
414 notationName);
415 }
416 }
417
418 /**
419 * Implements org.xml.sax.DTDHandler.notationDecl()
420 */
421 public void notationDecl(String name, String publicId, String systemId)
422 throws SAXException
423 {
424 if (_dtdHandler != null) {
425 _dtdHandler.notationDecl(name, publicId, systemId);
426 }
427 }
428
429 /**
430 * Implements org.xml.sax.ext.DeclHandler.attributeDecl()
431 */
432 public void attributeDecl(String eName, String aName, String type,
433 String valueDefault, String value) throws SAXException
434 {
435 if (_declHandler != null) {
436 _declHandler.attributeDecl(eName, aName, type, valueDefault, value);
437 }
438 }
439
440 /**
441 * Implements org.xml.sax.ext.DeclHandler.elementDecl()
442 */
443 public void elementDecl(String name, String model)
444 throws SAXException
445 {
446 if (_declHandler != null) {
447 _declHandler.elementDecl(name, model);
448 }
449 }
450
451 /**
452 * Implements org.xml.sax.ext.DeclHandler.externalEntityDecl()
453 */
454 public void externalEntityDecl(String name, String publicId, String systemId)
455 throws SAXException
456 {
457 if (_declHandler != null) {
458 _declHandler.externalEntityDecl(name, publicId, systemId);
459 }
460 }
461
462 /**
463 * Implements org.xml.sax.ext.DeclHandler.externalEntityDecl()
464 */
465 public void internalEntityDecl(String name, String value)
466 throws SAXException
467 {
468 if (_declHandler != null) {
469 _declHandler.internalEntityDecl(name, value);
470 }
471 }
472
473
474 /** Implementation of the reset() method
475 *
476 */
477 public void reset() {
478 _systemId = null;
479 _dom = null;
480 _handler = null;
481 _lexHandler = null;
482 _dtdHandler = null;
483 _declHandler = null;
484 _result = null;
485 _locator = null;
486 }
487 }