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