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 }