1 29 30 package com.caucho.xsl; 31 32 import com.caucho.java.LineMap; 33 import com.caucho.util.L10N; 34 import com.caucho.vfs.Encoding; 35 import com.caucho.vfs.IOExceptionWrapper; 36 import com.caucho.vfs.Path; 37 import com.caucho.vfs.Vfs; 38 import com.caucho.vfs.WriteStream; 39 import com.caucho.xml.*; 40 import com.caucho.xpath.XPathFun; 41 42 import org.w3c.dom.Document ; 43 import org.w3c.dom.Node ; 44 import org.xml.sax.ContentHandler ; 45 import org.xml.sax.InputSource ; 46 import org.xml.sax.SAXException ; 47 import org.xml.sax.XMLReader ; 48 import org.xml.sax.ext.LexicalHandler ; 49 50 import javax.xml.transform.ErrorListener ; 51 import javax.xml.transform.OutputKeys ; 52 import javax.xml.transform.Result ; 53 import javax.xml.transform.Source ; 54 import javax.xml.transform.TransformerException ; 55 import javax.xml.transform.URIResolver ; 56 import javax.xml.transform.dom.DOMResult ; 57 import javax.xml.transform.dom.DOMSource ; 58 import javax.xml.transform.sax.SAXResult ; 59 import javax.xml.transform.sax.SAXSource ; 60 import javax.xml.transform.stream.StreamResult ; 61 import javax.xml.transform.stream.StreamSource ; 62 import java.io.IOException ; 63 import java.io.InputStream ; 64 import java.io.OutputStream ; 65 import java.io.OutputStreamWriter ; 66 import java.io.Writer ; 67 import java.util.ArrayList ; 68 import java.util.HashMap ; 69 import java.util.Properties ; 70 71 public class TransformerImpl extends javax.xml.transform.Transformer { 72 protected static L10N L = new L10N(TransformerImpl.class); 73 74 public final static String LINE_MAP = "caucho.line-map"; 75 public final static String CACHE_DEPENDS = "caucho.cache.depends"; 76 public final static String GENERATE_LOCATION = "caucho.generate.location"; 77 78 protected StylesheetImpl _stylesheet; 79 protected HashMap <String ,Object > _properties = new HashMap <String ,Object >(); 80 protected HashMap <String ,Object > _parameters; 81 82 private URIResolver _uriResolver; 83 private ErrorListener _errorListener; 84 85 private Properties _output; 86 87 protected LineMap _lineMap; 88 89 protected ArrayList <Path> _cacheDepends = new ArrayList <Path>(); 90 91 protected TransformerImpl(StylesheetImpl stylesheet) 92 { 93 _stylesheet = stylesheet; 94 _uriResolver = stylesheet.getURIResolver(); 95 } 96 97 100 public URIResolver getURIResolver() 101 { 102 return _uriResolver; 103 } 104 105 108 public void setURIResolver(URIResolver uriResolver) 109 { 110 _uriResolver = uriResolver; 111 } 112 113 116 public ErrorListener getErrorListener() 117 { 118 return _errorListener; 119 } 120 121 124 public void setErrorListener(ErrorListener errorListener) 125 { 126 _errorListener = errorListener; 127 } 128 129 public boolean getFeature(String name) 130 { 131 if (name.equals(DOMResult.FEATURE)) 132 return true; 133 else if (name.equals(DOMSource.FEATURE)) 134 return true; 135 else if (name.equals(StreamSource.FEATURE)) 136 return true; 137 else if (name.equals(StreamResult.FEATURE)) 138 return true; 139 else if (name.equals(SAXSource.FEATURE)) 140 return true; 141 else if (name.equals(SAXResult.FEATURE)) 142 return true; 143 else 144 return false; 145 } 146 147 public void setFeature(String name, boolean enable) 148 { 149 if (name.equals(GENERATE_LOCATION)) 150 _stylesheet.setGenerateLocation(enable); 151 } 152 153 public StylesheetImpl getStylesheet() 154 { 155 return _stylesheet; 156 } 157 158 public Object getProperty(String name) 159 { 160 Object property = _properties.get(name); 161 162 if (property != null) 163 return property; 164 165 if (name.equals(CACHE_DEPENDS)) 166 return _cacheDepends; 167 else if (name.equals(LINE_MAP)) 168 return _lineMap; 169 else 170 return _stylesheet.getProperty(name); 171 } 172 173 public void setProperty(String name, Object value) 174 { 175 _properties.put(name, value); 176 } 177 178 185 public void setParameter(String name, Object value) 186 { 187 if (_parameters == null) 188 _parameters = new HashMap <String ,Object >(); 189 190 _parameters.put(name, value); 191 } 192 193 198 public Properties getOutputProperties() 199 { 200 if (_output == null) 201 _output = (Properties ) _stylesheet.getOutputProperties().clone(); 202 203 return (Properties ) _output.clone(); 204 } 205 206 211 public void setOutputProperties(Properties properties) 212 { 213 _output = properties; 214 } 215 216 222 public void setOutputProperty(String name, String value) 223 { 224 if (_output == null) 225 _output = (Properties ) _stylesheet.getOutputProperties().clone(); 226 227 _output.put(name, value); 228 } 229 230 235 public String getOutputProperty(String name) 236 { 237 if (_output == null) 238 _output = (Properties ) _stylesheet.getOutputProperties().clone(); 239 240 return (String ) _output.get(name); 241 } 242 243 250 public Object getParameter(String name) 251 { 252 if (_parameters == null) 253 return null; 254 else 255 return _parameters.get(name); 256 } 257 258 261 public void clearParameters() 262 { 263 if (_parameters != null) 264 _parameters.clear(); 265 266 if (_cacheDepends != null) 267 _cacheDepends.clear(); 268 } 269 270 276 public void addFunction(String name, XPathFun fun) 277 { 278 _stylesheet.addFunction(name, fun); 279 } 280 281 287 public void transform(Source source, Result result) 288 throws TransformerException 289 { 290 try { 291 Node node = parseDocument(source); 292 293 if (result instanceof StreamResult ) { 294 StreamResult stream = (StreamResult ) result; 295 296 if (stream.getOutputStream() != null) 297 transform(node, stream.getOutputStream(), null, result.getSystemId()); 298 else if (stream.getWriter() != null) { 299 Writer writer = stream.getWriter(); 300 WriteStream os = Vfs.openWrite(writer); 301 302 if (writer instanceof OutputStreamWriter ) { 303 String javaEncoding = ((OutputStreamWriter ) writer).getEncoding(); 304 String mimeEncoding = Encoding.getMimeName(javaEncoding); 305 transform(node, os, mimeEncoding, result.getSystemId()); 306 } 307 else 308 transform(node, os, null, result.getSystemId()); 309 310 os.flush(); 311 os.free(); 312 } 313 else { 314 WriteStream os = Vfs.lookup(result.getSystemId()).openWrite(); 315 316 try { 317 transform(node, os, null, result.getSystemId()); 318 } finally { 319 os.close(); 320 } 321 } 322 } 323 else if (result instanceof DOMResult ) { 324 DOMResult domResult = (DOMResult ) result; 325 326 Node resultNode = domResult.getNode(); 327 328 domResult.setNode(transform(node, resultNode)); 329 } 330 else if (result instanceof SAXResult ) { 331 SAXResult sax = (SAXResult ) result; 332 333 transform(node, sax.getHandler(), sax.getLexicalHandler()); 334 } 335 else 336 throw new TransformerException (String.valueOf(result)); 337 } catch (TransformerException e) { 338 throw e; 339 } catch (Exception e) { 340 throw new TransformerExceptionWrapper(e); 341 } 342 } 343 344 public void transform(Node node, OutputStream os) 345 throws TransformerException 346 { 347 if (os instanceof WriteStream) { 348 String encoding = ((WriteStream) os).getEncoding(); 349 if (encoding == null) 350 encoding = "ISO-8859-1"; 351 352 transform(node, os, encoding, null); 353 } 354 else 355 transform(node, os, null, null); 356 } 357 363 public void transform(Node node, OutputStream os, 364 String encoding, String systemId) 365 throws TransformerException 366 { 367 if (node == null) 368 throw new IllegalArgumentException ("can't transform null node"); 369 370 try { 371 _lineMap = null; 372 Properties output = getOutputProperties(); 373 374 WriteStream ws; 375 376 if (os instanceof WriteStream) 377 ws = (WriteStream) os; 378 else { 379 ws = Vfs.openWrite(os); 380 381 if (systemId != null) 382 ws.setPath(Vfs.lookup(systemId)); 383 else if (node instanceof QNode) { 384 String baseURI = ((QNode) node).getBaseURI(); 385 386 if (baseURI != null) 387 ws.setPath(Vfs.lookup(baseURI)); 388 } 389 } 390 391 XmlPrinter out = new XmlPrinter(ws); 392 393 String method = (String ) output.get(OutputKeys.METHOD); 394 out.setMethod(method); 395 if (encoding == null) 396 encoding = (String ) output.get(OutputKeys.ENCODING); 397 if (encoding == null && ! (os instanceof WriteStream) && 398 ! "html".equals(method)) 399 encoding = "UTF-8"; 400 if (encoding != null) 401 out.setEncoding(encoding); 402 out.setMimeType((String ) output.get(OutputKeys.MEDIA_TYPE)); 403 String omit = (String ) output.get(OutputKeys.OMIT_XML_DECLARATION); 404 405 if (omit == null || omit.equals("false") || omit.equals("no")) 406 out.setPrintDeclaration(true); 407 408 out.setStandalone((String ) output.get(OutputKeys.STANDALONE)); 409 out.setSystemId((String ) output.get(OutputKeys.DOCTYPE_SYSTEM)); 410 out.setPublicId((String ) output.get(OutputKeys.DOCTYPE_PUBLIC)); 411 412 String indent = (String ) output.get(OutputKeys.INDENT); 413 if (indent != null) 414 out.setPretty(indent.equals("true") || indent.equals("yes")); 415 416 String jsp = (String ) output.get("caucho.jsp"); 417 if (jsp != null) 418 out.setJSP(jsp.equals("true") || jsp.equals("yes")); 419 420 out.setVersion((String ) output.get(OutputKeys.VERSION)); 421 422 String includeContentType = (String ) output.get("include-content-type"); 423 if (includeContentType != null) 424 out.setIncludeContentType(includeContentType.equals("true") || 425 includeContentType.equals("yes")); 426 427 if (! _stylesheet.getGenerateLocation()) { 428 } 429 else if (node instanceof CauchoNode) { 430 String filename = ((CauchoNode) node).getFilename(); 431 if (filename != null) 432 out.setLineMap(filename); 433 else 434 out.setLineMap("anonymous.xsl"); 435 } 436 else 437 out.setLineMap("anonymous.xsl"); 438 439 _stylesheet.transform(node, out, this); 441 _lineMap = out.getLineMap(); 443 if (os != ws) { 444 ws.flush(); 445 ws.free(); 446 } 447 } catch (TransformerException e) { 448 throw e; 449 } catch (Exception e) { 450 throw new TransformerExceptionWrapper(e); 451 } 452 } 453 454 458 public Node transform(Node sourceNode, Node destNode) 459 throws SAXException , IOException 460 { 461 _lineMap = null; 462 463 if (destNode == null) 464 destNode = Xml.createDocument(); 465 466 DOMBuilder out = new DOMBuilder(); 467 out.init(destNode); 468 469 try { 470 out.startDocument(); 471 _stylesheet.transform(sourceNode, out, this); 472 } catch (Exception e) { 474 throw new IOExceptionWrapper(e); 475 } 476 477 return destNode; 478 } 479 480 483 public void transform(Node sourceNode, 484 ContentHandler contentHandler, 485 LexicalHandler lexicalHandler) 486 throws SAXException , IOException , TransformerException 487 { 488 if (contentHandler == null) 489 throw new IllegalArgumentException (L.l("null content handler")); 490 491 _lineMap = null; 492 493 SAXBuilder out = new SAXBuilder(); 494 out.setContentHandler(contentHandler); 495 496 out.startDocument(); 497 _stylesheet.transform(sourceNode, out, this); 498 } 500 501 508 protected Node parseDocument(Source source) 509 throws IOException , SAXException , TransformerException 510 { 511 if (source instanceof StreamSource ) { 512 StreamSource stream = (StreamSource ) source; 513 514 InputSource in = new InputSource (); 515 in.setSystemId(stream.getSystemId()); 516 in.setByteStream(stream.getInputStream()); 517 in.setCharacterStream(stream.getReader()); 518 519 XmlParser parser = Xml.create(); 520 521 Node node = parser.parseDocument(in); 522 523 parser.free(); 524 525 return node; 526 527 } 529 else if (source instanceof DOMSource ){ 530 Node node = ((DOMSource ) source).getNode(); 531 532 return node != null ? node : new QDocument(); 533 } 534 else if (source instanceof StringSource) { 535 String string = ((StringSource) source).getString(); 536 537 if (string != null) 538 return parseStringDocument(string, source.getSystemId()); 539 else 540 return new QDocument(); 541 } 542 else if (source instanceof SAXSource ) { 543 SAXSource saxSource = (SAXSource ) source; 544 545 XMLReader reader = saxSource.getXMLReader(); 546 547 if (reader == null) 548 return new QDocument(); 549 550 InputSource inputSource = saxSource.getInputSource(); 551 552 Document doc = new QDocument(); 553 DOMBuilder builder = new DOMBuilder(); 554 builder.init(doc); 555 reader.setContentHandler(builder); 556 557 reader.parse(inputSource); 558 559 return doc; 560 } 561 562 else 563 throw new TransformerException (L.l("unknown source {0}", source)); 564 } 565 566 574 protected Node parseDocument(InputStream is, String systemId) 575 throws IOException , SAXException 576 { 577 XmlParser parser = Xml.create(); 578 579 Node node = parser.parseDocument(is); 580 581 parser.free(); 582 583 return node; 584 } 585 586 593 protected Node parseDocument(String url) 594 throws IOException , SAXException 595 { 596 XmlParser parser = Xml.create(); 597 598 Node node = parser.parseDocument(url); 599 600 parser.free(); 601 602 return node; 603 } 604 605 613 protected Node parseStringDocument(String source, String systemId) 614 throws IOException , SAXException 615 { 616 XmlParser parser = Xml.create(); 617 618 Node node = parser.parseDocumentString(source); 619 620 parser.free(); 621 622 return node; 623 } 624 625 public void addCacheDepend(Path path) 626 { 627 _cacheDepends.add(path); 628 } 629 630 protected void addCacheDepend(String path) 631 { 632 _cacheDepends.add(Vfs.lookup(path)); 633 } 634 635 public ArrayList <Path> getCacheDepends() 636 { 637 return _cacheDepends; 638 } 639 } 640 | Popular Tags |