001 /* 002 * Common usable utilities 003 * 004 * Copyright (c) 2006 Petr Hadraba <hadrabap@gmail.com> 005 * 006 * Author: Petr Hadraba 007 * 008 * -- 009 * 010 * XML Utilities 011 */ 012 013 package global.sandbox.xmlutilities; 014 015 import java.io.BufferedInputStream; 016 import java.io.BufferedOutputStream; 017 import java.io.BufferedReader; 018 import java.io.File; 019 import java.io.FileInputStream; 020 import java.io.FileNotFoundException; 021 import java.io.FileOutputStream; 022 import java.io.IOException; 023 import java.io.InputStream; 024 import java.io.OutputStream; 025 import java.io.StringReader; 026 import java.io.StringWriter; 027 import java.util.Map; 028 import java.util.Properties; 029 import java.util.logging.Level; 030 import java.util.logging.Logger; 031 import javax.xml.XMLConstants; 032 import javax.xml.namespace.NamespaceContext; 033 import javax.xml.parsers.DocumentBuilder; 034 import javax.xml.parsers.DocumentBuilderFactory; 035 import javax.xml.parsers.ParserConfigurationException; 036 import javax.xml.transform.Source; 037 import javax.xml.transform.Templates; 038 import javax.xml.transform.Transformer; 039 import javax.xml.transform.TransformerConfigurationException; 040 import javax.xml.transform.TransformerException; 041 import javax.xml.transform.TransformerFactory; 042 import javax.xml.transform.TransformerFactoryConfigurationError; 043 import javax.xml.transform.dom.DOMSource; 044 import javax.xml.transform.stream.StreamResult; 045 import javax.xml.validation.SchemaFactory; 046 import javax.xml.validation.Validator; 047 import javax.xml.xpath.XPath; 048 import javax.xml.xpath.XPathConstants; 049 import javax.xml.xpath.XPathExpressionException; 050 import javax.xml.xpath.XPathFactory; 051 import javax.xml.xpath.XPathFactoryConfigurationException; 052 import org.w3c.dom.Document; 053 import org.w3c.dom.Node; 054 import org.w3c.dom.NodeList; 055 import org.xml.sax.InputSource; 056 import org.xml.sax.SAXException; 057 058 /** 059 * This class provides simple XML utilities. 060 * 061 * @author Petr Hadraba 062 * 063 * @version 1.2 064 */ 065 public class XmlUtilities { 066 067 /** 068 * Name of internal logger. 069 */ 070 static final String XMLUTILITIES_LOGGER_NAME; 071 072 static { 073 XMLUTILITIES_LOGGER_NAME = XmlUtilities.class.getName(); 074 } 075 076 /** 077 * Internal logger. 078 */ 079 private static final Logger LOGGER = Logger.getLogger(XMLUTILITIES_LOGGER_NAME); 080 081 /** 082 * Stores schema factory. 083 */ 084 private final SchemaFactory schemaFactory; 085 086 /** 087 * Stores document builder factory. 088 */ 089 private final DocumentBuilderFactory documentBuilderFactory; 090 091 /** 092 * Stores document builder. 093 */ 094 private final DocumentBuilder documentBuilder; 095 096 /** 097 * Stores localTransformer factory. 098 */ 099 private final TransformerFactory transformerFactory; 100 101 /** 102 * Stores localTransformer. 103 */ 104 private final Transformer transformer; 105 106 /** 107 * Stores XPath factory. 108 */ 109 private final XPathFactory xpathFactory; 110 111 /** 112 * Stores XPath evaluator. 113 */ 114 private final XPath xpath; 115 116 /** 117 * Stores the default NamespaceContext. 118 */ 119 private final NamespaceContext defaultNamespaceContext; 120 121 /** 122 * Initializes XML Utilities. 123 * 124 * Creates new factories and new default instances. 125 * 126 * @throws XmlUtilitiesException on error 127 */ 128 public XmlUtilities() throws XmlUtilitiesException { 129 this(null, null, null, null, null, null, null, null); 130 } 131 132 /** 133 * Initializes XML Utilities. 134 * 135 * Creates new factories and new instances according to custom objects. 136 * 137 * @param documentBuilderFactory custom DocumentBuilderFactory 138 * @param documentBuilder custom DocumentBuilder 139 * @param schemaFactory custom SchemaFactory 140 * @param transformerFactory custom TransformerFactory 141 * @param transformer custom Transformer 142 * @param xpathFactory custom XPathFactory 143 * @param xpath custom XPath 144 * @param defaultNamespaceContext custom name spaces 145 * 146 * @throws XmlUtilitiesException on error 147 */ 148 public XmlUtilities( 149 final DocumentBuilderFactory documentBuilderFactory, 150 final DocumentBuilder documentBuilder, 151 final SchemaFactory schemaFactory, 152 final TransformerFactory transformerFactory, 153 final Transformer transformer, 154 final XPathFactory xpathFactory, 155 final XPath xpath, 156 final NamespaceContext defaultNamespaceContext) 157 throws XmlUtilitiesException { 158 try { 159 if (documentBuilderFactory == null) { 160 LOGGER.log(Level.FINEST, "Using default Name Space aware DocumentBuilderFactory."); 161 this.documentBuilderFactory = DocumentBuilderFactory.newInstance(); 162 this.documentBuilderFactory.setNamespaceAware(true); 163 } else { 164 LOGGER.log(Level.FINEST, "Using provided DocumentBuilderFactory."); 165 this.documentBuilderFactory = documentBuilderFactory; 166 } 167 168 if (documentBuilder == null) { 169 LOGGER.log(Level.FINEST, "Using default DocumentBuilder."); 170 this.documentBuilder = this.documentBuilderFactory.newDocumentBuilder(); 171 } else { 172 LOGGER.log(Level.FINEST, "Using provided DocumentBuilder."); 173 this.documentBuilder = documentBuilder; 174 } 175 176 if (schemaFactory == null) { 177 LOGGER.log(Level.FINEST, "Using default SchemaFactory."); 178 this.schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 179 } else { 180 LOGGER.log(Level.FINEST, "Using provided SchemaFactory."); 181 this.schemaFactory = schemaFactory; 182 } 183 184 if (transformerFactory == null) { 185 LOGGER.log(Level.FINEST, "Using default TransformerFactory."); 186 this.transformerFactory = TransformerFactory.newInstance(); 187 } else { 188 LOGGER.log(Level.FINEST, "Using provided TransformerFactory."); 189 this.transformerFactory = transformerFactory; 190 } 191 192 if (transformer == null) { 193 LOGGER.log(Level.FINEST, "Using default Transformer."); 194 this.transformer = this.transformerFactory.newTransformer(); 195 } else { 196 LOGGER.log(Level.FINEST, "Using provided Transformer."); 197 this.transformer = transformer; 198 } 199 200 if (xpathFactory == null) { 201 LOGGER.log(Level.FINEST, "Using default XPathFactory."); 202 this.xpathFactory = XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI); 203 } else { 204 LOGGER.log(Level.FINEST, "Using provided XPathFactory."); 205 this.xpathFactory = xpathFactory; 206 } 207 208 if (xpath == null) { 209 LOGGER.log(Level.FINEST, "Using default XPath."); 210 this.xpath = this.xpathFactory.newXPath(); 211 } else { 212 LOGGER.log(Level.FINEST, "Using provided XPath."); 213 this.xpath = xpath; 214 } 215 216 if (defaultNamespaceContext == null) { 217 LOGGER.log(Level.FINEST, "Using default NamespaceContextImpl."); 218 this.defaultNamespaceContext = NamespaceContextImpl.namespaceContextWithDefaults(); 219 } else { 220 LOGGER.log(Level.FINEST, "Using provided NamespaceContext."); 221 this.defaultNamespaceContext = defaultNamespaceContext; 222 } 223 } catch (ParserConfigurationException ex) { 224 final String message = "Failed to initialize XML Utilities."; 225 LOGGER.log(Level.SEVERE, message, ex); 226 throw new XmlUtilitiesException(message, ex); 227 } catch (TransformerFactoryConfigurationError ex) { 228 final String message = "Failed to initialize XML Utilities."; 229 LOGGER.log(Level.SEVERE, message, ex); 230 throw new XmlUtilitiesException(message, ex); 231 } catch (TransformerConfigurationException ex) { 232 final String message = "Failed to initialize XML Utilities."; 233 LOGGER.log(Level.SEVERE, message, ex); 234 throw new XmlUtilitiesException(message, ex); 235 } catch (XPathFactoryConfigurationException ex) { 236 final String message = "Failed to initialize XML Utilities."; 237 LOGGER.log(Level.SEVERE, message, ex); 238 throw new XmlUtilitiesException(message, ex); 239 } 240 } 241 242 /** 243 * Returns SchemaFactory object internally used by the XML Utilities. 244 * 245 * @return SchemaFactory object 246 */ 247 public SchemaFactory getSchemaFactory() { 248 return schemaFactory; 249 } 250 251 /** 252 * Returns DocumentBuilderFactory object internally used by the XML Utilities. 253 * 254 * @return DocumentBuilderFactory object 255 */ 256 public DocumentBuilderFactory getDocumentBuilderFactory() { 257 return documentBuilderFactory; 258 } 259 260 /** 261 * Returns DocumentBuilder object internally used by the XML Utilities. 262 * 263 * @return DocumentBuilder object 264 */ 265 public DocumentBuilder getDocumentBuilder() { 266 return documentBuilder; 267 } 268 269 /** 270 * Returns TransformerFactory object internally used by the XML Utilities. 271 * 272 * @return TransformerFactory object 273 */ 274 public TransformerFactory getTransformerFactory() { 275 return transformerFactory; 276 } 277 278 /** 279 * Returns Transformer object internally used by the XML Utilities. 280 * 281 * @return Transformer object 282 */ 283 public Transformer getTransformer() { 284 return transformer; 285 } 286 287 /** 288 * Returns XPathFactory object internally used by the XML Utilities. 289 * 290 * @return XPathFactory object 291 */ 292 public XPathFactory getXPathFactory() { 293 return xpathFactory; 294 } 295 296 /** 297 * Returns XPath object internally used by the XML Utilities. 298 * 299 * @return XPath object 300 */ 301 public XPath getXPath() { 302 return xpath; 303 } 304 305 /** 306 * Returns default NamespaceContext used by the XML Utilities. 307 * 308 * @return default NamespaceContenxt object 309 */ 310 public NamespaceContext getDefaultNamespaceContext() { 311 return defaultNamespaceContext; 312 } 313 314 /** 315 * Validates XML Document against XML Schema. 316 * 317 * @param xmlDocument document to validate 318 * @param xmlSchema XMLSchema 319 * 320 * @return {@code null} if successful, string with error otherwise 321 * 322 * @throws XmlUtilitiesException on error 323 */ 324 public String validateXmlUsingSchema(final Source xmlDocument, final Source xmlSchema) throws XmlUtilitiesException { 325 final Validator validator; 326 327 try { 328 validator = schemaFactory.newSchema(xmlSchema).newValidator(); 329 330 validator.validate(xmlDocument); 331 } catch (SAXException ex) { 332 return ex.getMessage(); 333 } catch (IOException ex) { 334 final String message = "Failed to validate XML Document against XML Schema."; 335 LOGGER.log(Level.SEVERE, message, ex); 336 throw new XmlUtilitiesException(message, ex); 337 } 338 339 return null; 340 } 341 342 /** 343 * Loads XML from file specified with file name. 344 * 345 * @param fileName file to load 346 * 347 * @return Document object 348 * 349 * @throws XmlUtilitiesException on error 350 */ 351 public Document loadDocumentFromFile(final String fileName) throws XmlUtilitiesException { 352 return loadDocumentFromFile(new File(fileName)); 353 } 354 355 /** 356 * Loads XML from file specified with file name. 357 * 358 * @param fileName file to load 359 * @param documentBuilder custom document builder 360 * 361 * @return Document object 362 * 363 * @throws XmlUtilitiesException on error 364 */ 365 public Document loadDocumentFromFile(final String fileName, final DocumentBuilder documentBuilder) throws XmlUtilitiesException { 366 return loadDocumentFromFile(new File(fileName), documentBuilder); 367 } 368 369 /** 370 * Loads XML from file specified with the File object. 371 * 372 * @param file file to load 373 * 374 * @return Document object 375 * 376 * @throws XmlUtilitiesException on error 377 */ 378 public Document loadDocumentFromFile(final File file) throws XmlUtilitiesException { 379 return loadDocumentFromFile(file, documentBuilder); 380 } 381 382 /** 383 * Loads XML from file specified with the file object. 384 * 385 * @param file file to load 386 * @param documentBuilder custom document builder 387 * 388 * @return Document object 389 * 390 * @throws XmlUtilitiesException on error 391 */ 392 public Document loadDocumentFromFile(final File file, final DocumentBuilder documentBuilder) throws XmlUtilitiesException { 393 final InputStream inputStream; 394 try { 395 inputStream = new FileInputStream(file); 396 } catch (FileNotFoundException ex) { 397 final String message = String.format("The specified file '%s' does not exist.", file); 398 LOGGER.log(Level.SEVERE, message, ex); 399 throw new XmlUtilitiesException(message, ex); 400 } 401 402 final Document document = loadDocumentFromStreamAndClose(inputStream, documentBuilder, true); 403 404 return document; 405 } 406 407 /** 408 * loads XML from specified input stream. The stream is not being closed. 409 * 410 * @param is input stream 411 * 412 * @return Document object 413 * 414 * @throws XmlUtilitiesException on error 415 */ 416 public Document loadDocumentFromStream(final InputStream is) throws XmlUtilitiesException { 417 return loadDocumentFromStream(is, documentBuilder); 418 } 419 420 /** 421 * Loads XML from specified input stream. The stream is not being closed. 422 * 423 * @param is input stream 424 * @param documentBuilder custom Document Builder 425 * 426 * @return Document object 427 * 428 * @throws XmlUtilitiesException on error 429 */ 430 public Document loadDocumentFromStream(final InputStream is, final DocumentBuilder documentBuilder) throws XmlUtilitiesException { 431 final BufferedInputStream bufferedInputStream = new BufferedInputStream(is); 432 433 try { 434 final Document document = documentBuilder.parse(bufferedInputStream); 435 436 return document; 437 } catch (IOException ex) { 438 final String message = "Failed to read data from stream."; 439 LOGGER.log(Level.SEVERE, message, ex); 440 throw new XmlUtilitiesException(message, ex); 441 } catch (SAXException ex) { 442 final String message = "Failed to parse XML from stream."; 443 LOGGER.log(Level.SEVERE, message, ex); 444 throw new XmlUtilitiesException(message, ex); 445 } 446 } 447 448 /** 449 * Loads XML from specified input stream and closes it if specified. 450 * 451 * @param is input stream 452 * @param close {@code true} to close input stream, {@code false} to leave it unclosed 453 * 454 * @return Document object 455 * 456 * @throws XmlUtilitiesException on error 457 */ 458 public Document loadDocumentFromStreamAndClose(final InputStream is, final boolean close) throws XmlUtilitiesException { 459 return loadDocumentFromStreamAndClose(is, documentBuilder, close); 460 } 461 462 /** 463 * Loads XML from specified input stream and closes it if specified. 464 * 465 * @param is input stream 466 * @param documentBuilder custom Document Builder 467 * @param close {@code true} to close input stream, {@code false} to leave it unclosed 468 * 469 * @return Document object 470 * 471 * @throws XmlUtilitiesException on error 472 */ 473 public Document loadDocumentFromStreamAndClose(final InputStream is, final DocumentBuilder documentBuilder, final boolean close) throws XmlUtilitiesException { 474 final BufferedInputStream bufferedInputStream = new BufferedInputStream(is); 475 476 Document document = null; 477 478 XmlUtilitiesException exception = null; 479 try { 480 try { 481 document = documentBuilder.parse(bufferedInputStream); 482 } catch (IOException ex) { 483 final String message = "Failed to read data from stream."; 484 LOGGER.log(Level.SEVERE, message, ex); 485 exception = new XmlUtilitiesException(message, ex); 486 } catch (SAXException ex) { 487 final String message = "Failed to parse XML from stream."; 488 LOGGER.log(Level.SEVERE, message, ex); 489 exception = new XmlUtilitiesException(message, ex); 490 } 491 } finally { 492 if (close) { 493 try { 494 bufferedInputStream.close(); 495 } catch (IOException ex) { 496 final String message = "Failed to close stream."; 497 if (exception != null) { 498 LOGGER.log(Level.WARNING, message, ex); 499 exception.addConsequent(ex); 500 } else { 501 LOGGER.log(Level.SEVERE, message, ex); 502 exception = new XmlUtilitiesException(message, ex); 503 } 504 } 505 } 506 507 if (exception != null) { 508 throw exception; 509 } 510 } 511 512 return document; 513 } 514 515 /** 516 * Loads document from ClassLoaders. The first of {@code ContextClassLoader}, {@code fallBackClazz#getClassLoader()} 517 * or {@code SystemClassLoader} is used whichever is find first. 518 * 519 * @param resource resource name to load from 520 * @param fallbackClazz ClassLoader to use if {@code ContextClassLoader} does not exist 521 * 522 * @return Document object 523 * 524 * @throws XmlUtilitiesException on error 525 */ 526 public Document loadDocumentFromClassLoader(final String resource, final Class<?> fallbackClazz) throws XmlUtilitiesException { 527 return loadDocumentFromClassLoader(resource, documentBuilder, fallbackClazz); 528 } 529 530 /** 531 * Loads document from ClassLoaders. The first of {@code ContextClassLoader}, {@code fallBackClazz#getClassLoader()} 532 * or {@code SystemClassLoader} is used whichever is find first. 533 * 534 * @param resource resource name to load from 535 * @param documentBuilder custom DocumentBuilder 536 * @param fallbackClazz ClassLoader to use if {@code ContextClassLoader} does not exist 537 * 538 * @return Document object 539 * 540 * @throws XmlUtilitiesException on error 541 */ 542 public Document loadDocumentFromClassLoader(final String resource, final DocumentBuilder documentBuilder, final Class<?> fallbackClazz) throws XmlUtilitiesException { 543 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 544 545 if (classLoader == null) { 546 if (fallbackClazz != null) { 547 LOGGER.log(Level.FINEST, "ContextClassLoader is null."); 548 LOGGER.log(Level.FINEST, "About to use ClassLoader from provided fallback Class."); 549 classLoader = fallbackClazz.getClassLoader(); 550 } 551 } 552 553 if (classLoader == null) { 554 classLoader = ClassLoader.getSystemClassLoader(); 555 if (classLoader != null) { 556 LOGGER.log(Level.FINEST, "About to use SystemClassLoader."); 557 } 558 } 559 560 if (classLoader == null) { 561 final String message = "Failed to retrieve ContextClassLoader, ClassLoader or SystemClassLoader."; 562 LOGGER.log(Level.SEVERE, message); 563 throw new XmlUtilitiesException(message); 564 } 565 566 InputStream is = classLoader.getResourceAsStream(resource); 567 568 if (is == null) { 569 final String message = String.format("The specified resource '%s' has not been found using ClassLoader %s.", resource, classLoader.toString()); 570 LOGGER.log(Level.SEVERE, message); 571 throw new XmlUtilitiesException(message); 572 } 573 574 return loadDocumentFromStreamAndClose(is, documentBuilder, true); 575 } 576 577 /** 578 * Loads Document from resource from given class. 579 * 580 * @param resource resource to load 581 * @param clazz class to use 582 * 583 * @return Document object 584 * 585 * @throws XmlUtilitiesException on error 586 */ 587 public Document loadDocumentFromResource(final String resource, final Class<?> clazz) throws XmlUtilitiesException { 588 return loadDocumentFromResource(resource, documentBuilder, clazz); 589 } 590 591 /** 592 * Loads Document from resource from given class. 593 * 594 * @param resource resource to load 595 * @param documentBuilder custom DocumentBuilder 596 * @param clazz class to use 597 * 598 * @return Document object 599 * 600 * @throws XmlUtilitiesException on error 601 */ 602 public Document loadDocumentFromResource(final String resource, final DocumentBuilder documentBuilder, final Class<?> clazz) throws XmlUtilitiesException { 603 InputStream is = clazz.getResourceAsStream(resource); 604 605 if (is == null) { 606 final String message = String.format("The resource '%s' not found.", resource); 607 LOGGER.log(Level.SEVERE, message); 608 throw new XmlUtilitiesException(message); 609 } 610 611 return loadDocumentFromStreamAndClose(is, documentBuilder, true); 612 } 613 614 /** 615 * Loads document from resource using specified ClassLoader. 616 * 617 * @param resource resource to load 618 * @param classLoader ClassLoader to use 619 * 620 * @return Document object 621 * 622 * @throws XmlUtilitiesException on error 623 */ 624 public Document loadDocumentFromResource(final String resource, final ClassLoader classLoader) throws XmlUtilitiesException { 625 return loadDocumentFromResource(resource, documentBuilder, classLoader); 626 } 627 628 /** 629 * Loads document from resource using specified ClassLoader. 630 * 631 * @param resource resource to load 632 * @param documentBuilder custom DocumentBuilder 633 * @param classLoader ClassLoader to use 634 * 635 * @return Document object 636 * 637 * @throws XmlUtilitiesException on error 638 */ 639 public Document loadDocumentFromResource(final String resource, final DocumentBuilder documentBuilder, final ClassLoader classLoader) throws XmlUtilitiesException { 640 InputStream is = classLoader.getResourceAsStream(resource); 641 642 if (is == null) { 643 final String message = String.format("The resource '%s' not found.", resource); 644 LOGGER.log(Level.SEVERE, message); 645 throw new XmlUtilitiesException(message); 646 } 647 648 return loadDocumentFromStreamAndClose(is, documentBuilder, true); 649 } 650 651 /** 652 * Loads document from String into the {@code Document}. 653 * 654 * @param source source XML 655 * 656 * @return resulting XML 657 * 658 * @throws XmlUtilitiesException on error 659 */ 660 public Document loadDocumentFromString(final String source) throws XmlUtilitiesException { 661 return loadDocumentFromString(source, documentBuilder); 662 } 663 664 /** 665 * Loads document from String into the {@code Document}. 666 * 667 * @param source source XML 668 * @param documentBuilder custom document builder 669 * 670 * @return resulting XML 671 * 672 * @throws XmlUtilitiesException on error 673 */ 674 public Document loadDocumentFromString(final String source, final DocumentBuilder documentBuilder) throws XmlUtilitiesException { 675 final StringReader sr = new StringReader(source); 676 final BufferedReader br = new BufferedReader(sr); 677 final InputSource is = new InputSource(br); 678 679 Document result = null; 680 681 XmlUtilitiesException exception = null; 682 try { 683 try { 684 result = documentBuilder.parse(is); 685 } catch (SAXException ex) { 686 final String message = "Failed to parse document from String."; 687 LOGGER.log(Level.SEVERE, message, ex); 688 exception = new XmlUtilitiesException(message, ex); 689 } catch (IOException ex) { 690 final String message = "Failed to parse document from String (I/O)."; 691 LOGGER.log(Level.SEVERE, message, ex); 692 exception = new XmlUtilitiesException(message, ex); 693 } 694 } finally { 695 try { 696 br.close(); 697 sr.close(); 698 } catch (IOException ex) { 699 final String message = "Failed to close()."; 700 if (exception != null) { 701 LOGGER.log(Level.WARNING, message, ex); 702 exception.addConsequent(ex); 703 } else { 704 LOGGER.log(Level.SEVERE, message, ex); 705 exception = new XmlUtilitiesException(message, ex); 706 } 707 } 708 709 if (exception != null) { 710 throw exception; 711 } 712 } 713 714 return result; 715 } 716 717 /** 718 * Converts XML Document into String. 719 * 720 * @param source Document to convert 721 * 722 * @return XML in the String 723 * 724 * @throws XmlUtilitiesException on error 725 */ 726 public String documentToString(final Document source) throws XmlUtilitiesException { 727 return sourceToString(XmlTools.documentToDomSource(source)); 728 } 729 730 /** 731 * Converts XML Document into String. 732 * 733 * @param source Document to convert 734 * @param outputFormat output format configuration 735 * 736 * @return XML in the String 737 * 738 * @throws XmlUtilitiesException on error 739 */ 740 public String documentToString(final Document source, final OutputFormat outputFormat) throws XmlUtilitiesException { 741 return sourceToString(XmlTools.documentToDomSource(source), outputFormat); 742 } 743 744 /** 745 * Converts XML Document into String. 746 * 747 * @param source Document to convert 748 * @param outputProperties output properties (see {@link OutputFormat OutputFormat}) 749 * 750 * @return XML in the String 751 * 752 * @throws XmlUtilitiesException on error 753 */ 754 public String documentToString(final Document source, final Properties outputProperties) throws XmlUtilitiesException { 755 return sourceToString(XmlTools.documentToDomSource(source), outputProperties); 756 } 757 758 /** 759 * Converts XML Source into String. 760 * 761 * @param source Document to convert 762 * 763 * @return XML in the String 764 * 765 * @throws XmlUtilitiesException on error 766 */ 767 public String sourceToString(final Source source) throws XmlUtilitiesException { 768 return sourceToString(source, (Properties) null); 769 } 770 771 /** 772 * Converts XML Source into String. 773 * 774 * @param source Document to convert 775 * @param outputFormat output format configuration 776 * 777 * @return XML in the String 778 * 779 * @throws XmlUtilitiesException on error 780 */ 781 public String sourceToString(final Source source, final OutputFormat outputFormat) throws XmlUtilitiesException { 782 Properties outputProperties = null; 783 if (outputFormat != null) { 784 outputProperties = outputFormat.toTransformerOutputProperties(); 785 } 786 return sourceToString(source, outputProperties); 787 } 788 789 /** 790 * Converts XML Source into String. 791 * 792 * @param source Document to convert 793 * @param outputProperties output properties (see {@link OutputFormat OutputFormat}) 794 * 795 * @return XML in the String 796 * 797 * @throws XmlUtilitiesException on error 798 */ 799 public String sourceToString(final Source source, final Properties outputProperties) throws XmlUtilitiesException { 800 final StringWriter stringWriter = new StringWriter(); 801 final StreamResult streamResult = new StreamResult(stringWriter); 802 803 transformer.setParameter("", ""); 804 transformer.clearParameters(); 805 transformer.setOutputProperties(null); 806 if (outputProperties != null) { 807 transformer.setOutputProperties(outputProperties); 808 } 809 try { 810 transformer.transform(source, streamResult); 811 } catch (TransformerException ex) { 812 final String message = "Failed to convert Source to String."; 813 LOGGER.log(Level.SEVERE, message, ex); 814 throw new XmlUtilitiesException(message, ex); 815 } 816 817 final String result = stringWriter.toString(); 818 819 try { 820 stringWriter.close(); 821 } catch (IOException ex) { 822 final String message = "Failed to close() StringWriter."; 823 LOGGER.log(Level.SEVERE, message, ex); 824 throw new XmlUtilitiesException(message, ex); 825 } 826 827 return result; 828 } 829 830 /** 831 * Evaluates specified XPath expression on specified context node. 832 * 833 * @param query XPath expression 834 * @param context context node 835 * 836 * @return {@link NodeList NodeList} or {@code null} if no matches 837 * 838 * @throws XmlUtilitiesException on error 839 */ 840 public NodeList evaluateXPath(final String query, final Node context) throws XmlUtilitiesException { 841 return evaluateXPath(query, context, (NamespaceContext) null); 842 } 843 844 /** 845 * Evaluates specified XPath expression on specified context node. 846 * 847 * @param query XPath expression 848 * @param context context node 849 * @param namespaces name space context 850 * 851 * @return {@link NodeList NodeList} or {@code null} if no matches 852 * 853 * @throws XmlUtilitiesException on error 854 */ 855 public NodeList evaluateXPath(final String query, final Node context, final NamespaceContext namespaces) throws XmlUtilitiesException { 856 xpath.reset(); 857 858 if (namespaces == null) { 859 xpath.setNamespaceContext(defaultNamespaceContext); 860 } else { 861 xpath.setNamespaceContext(namespaces); 862 } 863 864 try { 865 return (NodeList) xpath.evaluate(query, context, XPathConstants.NODESET); 866 } catch (XPathExpressionException ex) { 867 final String message = String.format("Failed to evaluate XPath '%s'.", query); 868 LOGGER.log(Level.SEVERE, message, ex); 869 throw new XmlUtilitiesException(message, ex); 870 } 871 } 872 873 /** 874 * Evaluates specified XPath expression on specified context node and returns results as 875 * {@link NodeListCollection NodeListCollection} of specified element types. This method never returns {@code null}. 876 * 877 * @param <E> type of element 878 * @param query XPath expression 879 * @param context context node 880 * @param elementType class type of element 881 * 882 * @return {@link NodeListCollection NodeListCollection} of element type or empty list if no matches. 883 * 884 * @throws XmlUtilitiesException on error 885 */ 886 @SuppressWarnings("unchecked") 887 public <E extends Node> NodeListCollection<E> evaluateXPath(final String query, final Node context, final Class<E> elementType) throws XmlUtilitiesException { 888 return evaluateXPath(query, context, null, elementType); 889 } 890 891 /** 892 * Evaluates specified XPath expression on specified context node and returns results as 893 * {@link NodeListCollection NodeListCollection} of specified element types. This method never returns {@code null}. 894 * 895 * @param <E> type of element 896 * @param query XPath expression 897 * @param context context node 898 * @param namespaces name space context 899 * @param elementType class type of element 900 * 901 * @return {@link NodeListCollection NodeListCollection} of element type or empty list if no matches. 902 * 903 * @throws XmlUtilitiesException on error 904 */ 905 @SuppressWarnings("unchecked") 906 public <E extends Node> NodeListCollection<E> evaluateXPath(final String query, final Node context, final NamespaceContext namespaces, final Class<E> elementType) 907 throws XmlUtilitiesException { 908 NodeList nodes = evaluateXPath(query, context, namespaces); 909 910 NodeListCollection<E> result = new NodeListCollection<E>(nodes, elementType); 911 912 return result; 913 } 914 915 /** 916 * Evaluates specified XPath expression and returns first Node if XPath has matches. 917 * 918 * @param query XPath expression 919 * @param context context node 920 * 921 * @return first node or {@code null} 922 * 923 * @throws XmlUtilitiesException on error 924 */ 925 public Node getFirstNodeForXPath(final String query, final Node context) throws XmlUtilitiesException { 926 return getFirstNodeForXPath(query, context, (NamespaceContext) null); 927 } 928 929 /** 930 * Evaluates specified XPath expression and returns first Node if XPath has matches. 931 * 932 * @param query XPath expression 933 * @param context context node 934 * @param namespaces name space context 935 * 936 * @return first node or {@code null} 937 * 938 * @throws XmlUtilitiesException on error 939 */ 940 public Node getFirstNodeForXPath(final String query, final Node context, final NamespaceContext namespaces) throws XmlUtilitiesException { 941 final NodeList nodes = evaluateXPath(query, context, namespaces); 942 943 if (nodes == null) { 944 return null; 945 } 946 947 if (nodes.getLength() > 0) { 948 return nodes.item(0); 949 } 950 951 return null; 952 } 953 954 /** 955 * Evaluates specified XPath expression and returns first Node as specified element type if XPath has matches. 956 * 957 * @param <E> type of element 958 * @param query XPath expression 959 * @param context context node 960 * @param elementType class type of element 961 * 962 * @return first node as specified type or {@code null} 963 * 964 * @throws XmlUtilitiesException on error 965 */ 966 public <E extends Node> E getFirstNodeForXPath(final String query, final Node context, final Class<E> elementType) throws XmlUtilitiesException { 967 return getFirstNodeForXPath(query, context, null, elementType); 968 } 969 970 /** 971 * Evaluates specified XPath expression and returns first Node as specified element type if XPath has matches. 972 * 973 * @param <E> type of element 974 * @param query XPath expression 975 * @param context context node 976 * @param namespaces name space context 977 * @param elementType class type of element 978 * 979 * @return first node as specified type or {@code null} 980 * 981 * @throws XmlUtilitiesException on error 982 */ 983 public <E extends Node> E getFirstNodeForXPath(final String query, final Node context, final NamespaceContext namespaces, final Class<E> elementType) 984 throws XmlUtilitiesException { 985 Node node = getFirstNodeForXPath(query, context, namespaces); 986 987 if (node == null) { 988 return null; 989 } 990 991 final E element; 992 try { 993 element = elementType.cast(node); 994 } catch (ClassCastException ex) { 995 final String message = String.format("Failed to cast node from %s to %s.", node.getClass(), elementType); 996 LOGGER.log(Level.SEVERE, message, ex); 997 throw new XmlUtilitiesException(message, ex); 998 } 999 1000 return element; 1001 } 1002 1003 /** 1004 * Transforms specified XML source using specified XSLT template. 1005 * 1006 * @param xsltTemplate template to use 1007 * @param document source XML document 1008 * @param parameters parameters to propagate to the localTransformer 1009 * 1010 * @return resulting XML in the String 1011 * 1012 * @throws XmlUtilitiesException on error 1013 */ 1014 public String transformToString(final Source xsltTemplate, final Source document, final Map<String, Object> parameters) throws XmlUtilitiesException { 1015 try { 1016 final Transformer localTransformer = transformerFactory.newTransformer(xsltTemplate); 1017 1018 if (parameters != null) { 1019 for (Map.Entry<String, Object> parameter : parameters.entrySet()) { 1020 localTransformer.setParameter(parameter.getKey(), parameter.getValue()); 1021 } 1022 } 1023 1024 final StringWriter sw = new StringWriter(); 1025 final StreamResult sr = new StreamResult(sw); 1026 1027 localTransformer.transform(document, sr); 1028 1029 final String result = sw.toString(); 1030 1031 try { 1032 sw.close(); 1033 } catch (IOException ex) { 1034 return null; 1035 } 1036 1037 return result; 1038 } catch (TransformerConfigurationException ex) { 1039 final String message = "Failed to transform Document using XSLT template and parameters."; 1040 LOGGER.log(Level.SEVERE, message, ex); 1041 throw new XmlUtilitiesException(message, ex); 1042 } catch (TransformerException ex) { 1043 final String message = "Failed to transform Document using XSLT template and parameters."; 1044 LOGGER.log(Level.SEVERE, message, ex); 1045 throw new XmlUtilitiesException(message, ex); 1046 } 1047 } 1048 1049 /** 1050 * Transforms specified XML source using specified XSLT (compiled) template. 1051 * 1052 * @param xsltTemplate template to use 1053 * @param document source XML document to transform 1054 * @param parameters parameters to propagate to the localTransformer 1055 * 1056 * @return resulting XML in the String 1057 * 1058 * @throws XmlUtilitiesException on error 1059 */ 1060 public String transformToString(final Templates xsltTemplate, final Source document, final Map<String, Object> parameters) throws XmlUtilitiesException { 1061 try { 1062 final Transformer localTransformer = xsltTemplate.newTransformer(); 1063 1064 if (parameters != null) { 1065 for (Map.Entry<String, Object> parameter : parameters.entrySet()) { 1066 localTransformer.setParameter(parameter.getKey(), parameter.getValue()); 1067 } 1068 } 1069 1070 final StringWriter sw = new StringWriter(); 1071 final StreamResult sr = new StreamResult(sw); 1072 1073 localTransformer.transform(document, sr); 1074 1075 final String result = sw.toString(); 1076 1077 try { 1078 sw.close(); 1079 } catch (IOException e) { 1080 return null; 1081 } 1082 1083 return result; 1084 } catch (TransformerConfigurationException ex) { 1085 final String message = "Failed to transform Document using XSLT template and parameters."; 1086 LOGGER.log(Level.SEVERE, message, ex); 1087 throw new XmlUtilitiesException(message, ex); 1088 } catch (TransformerException ex) { 1089 final String message = "Failed to transform Document using XSLT template and parameters."; 1090 LOGGER.log(Level.SEVERE, message, ex); 1091 throw new XmlUtilitiesException(message, ex); 1092 } 1093 } 1094 1095 /** 1096 * Transforms specified XML source using specified XSLT (compiled) template. 1097 * 1098 * @param xsltTemplate template to use 1099 * @param document source XML document to transform 1100 * 1101 * @return resulting XML in the String 1102 * 1103 * @throws XmlUtilitiesException on error 1104 */ 1105 public String transformToString(final Templates xsltTemplate, final Source document) throws XmlUtilitiesException { 1106 return transformToString(xsltTemplate, document, null); 1107 } 1108 1109 /** 1110 * Transforms specified XML document using specified XSLT template. 1111 * 1112 * @param xsltTemplate XSLT template 1113 * @param document source XML document 1114 * 1115 * @return resulting XML document in the String 1116 * 1117 * @throws XmlUtilitiesException on error 1118 */ 1119 public String transformToString(final Source xsltTemplate, final Source document) throws XmlUtilitiesException { 1120 return transformToString(xsltTemplate, document, null); 1121 } 1122 1123 /** 1124 * Transforms specified XML document using specified XSLT template. 1125 * 1126 * @param xsltTemplate XSLT template 1127 * @param document source XML document 1128 * 1129 * @return resulting XML document in the {@link Document Document} 1130 * 1131 * @throws XmlUtilitiesException on error 1132 */ 1133 public Document transformToDocument(final Source xsltTemplate, final Source document) throws XmlUtilitiesException { 1134 final XmlUtilities xmlUtils = new XmlUtilities(); 1135 1136 return XmlTools.loadDocumentFromString(transformToString(xsltTemplate, document, null), xmlUtils); 1137 } 1138 1139 /** 1140 * Transforms specified XML document using XSLT (compiled) template. 1141 * 1142 * @param xsltTemplate template to use 1143 * @param document document to transform 1144 * 1145 * @return resulting XML document in the {@link Document Document} 1146 * 1147 * @throws XmlUtilitiesException on error 1148 */ 1149 public Document transformToDocument(final Templates xsltTemplate, final Source document) throws XmlUtilitiesException { 1150 final XmlUtilities xmlUtils = new XmlUtilities(); 1151 1152 return XmlTools.loadDocumentFromString(transformToString(xsltTemplate, document, null), xmlUtils); 1153 } 1154 1155 /** 1156 * Transforms specified XML document using specified XSLT template. 1157 * 1158 * @param xsltTemplate XSLT template 1159 * @param document source XML document 1160 * @param parameters parameters for the template 1161 * 1162 * @return resulting XML document in the {@link Document Document} 1163 * 1164 * @throws XmlUtilitiesException on error 1165 */ 1166 public Document transformToDocument(final Source xsltTemplate, final Source document, final Map<String, Object> parameters) throws XmlUtilitiesException { 1167 final XmlUtilities xmlUtils = new XmlUtilities(); 1168 1169 return XmlTools.loadDocumentFromString(transformToString(xsltTemplate, document, parameters), xmlUtils); 1170 } 1171 1172 /** 1173 * Transforms specified XML using XSLT (compiled) template. 1174 * 1175 * @param xsltTemplate template to use 1176 * @param document XML document to transform 1177 * @param parameters parameters for the transformation 1178 * 1179 * @return resulting XML document in the {@link Document Document} 1180 * 1181 * @throws XmlUtilitiesException on error 1182 */ 1183 public Document transformToDocument(final Templates xsltTemplate, final Source document, final Map<String, Object> parameters) throws XmlUtilitiesException { 1184 final XmlUtilities xmlUtils = new XmlUtilities(); 1185 1186 return XmlTools.loadDocumentFromString(transformToString(xsltTemplate, document, parameters), xmlUtils); 1187 } 1188 1189 /** 1190 * Writes specified document into specified output stream. 1191 * 1192 * @param doc document 1193 * @param os output stream 1194 * 1195 * @throws XmlUtilitiesException on error 1196 */ 1197 public void writeDocumentToStream(final Document doc, final OutputStream os) throws XmlUtilitiesException { 1198 writeDocumentToStreamAndClose(doc, os, false, (Properties) null); 1199 } 1200 1201 /** 1202 * Writes specified document into specified stream and specified output format. 1203 * 1204 * @param doc document 1205 * @param os output stream 1206 * @param outputFormat output format 1207 * 1208 * @throws XmlUtilitiesException on error 1209 */ 1210 public void writeDocumentToStream(final Document doc, final OutputStream os, final OutputFormat outputFormat) throws XmlUtilitiesException { 1211 writeDocumentToStreamAndClose(doc, os, false, outputFormat); 1212 } 1213 1214 /** 1215 * Writes specified document into specified stream and specified output format properties. 1216 * 1217 * @param doc document 1218 * @param os output stream 1219 * @param outputProperties output format properties 1220 * 1221 * @throws XmlUtilitiesException on error 1222 */ 1223 public void writeDocumentToStream(final Document doc, final OutputStream os, final Properties outputProperties) throws XmlUtilitiesException { 1224 writeDocumentToStreamAndClose(doc, os, false, outputProperties); 1225 } 1226 1227 /** 1228 * Writes specified document into specified stream and specified {@link Transformer Transformer}. 1229 * 1230 * @param doc document 1231 * @param os output stream 1232 * @param transformer Transformer to use 1233 * 1234 * @throws XmlUtilitiesException on error 1235 */ 1236 public void writeDocumentToStream(final Document doc, final OutputStream os, final Transformer transformer) throws XmlUtilitiesException { 1237 writeDocumentToStreamAndClose(doc, os, false, transformer); 1238 } 1239 1240 /** 1241 * Writes specified document into specified output stream. 1242 * 1243 * @param doc document 1244 * @param os output stream 1245 * @param close tells if stream should be closed 1246 * 1247 * @throws XmlUtilitiesException on error 1248 */ 1249 public void writeDocumentToStreamAndClose(final Document doc, final OutputStream os, final boolean close) throws XmlUtilitiesException { 1250 writeDocumentToStreamAndClose(doc, os, close, (Properties) null); 1251 } 1252 1253 /** 1254 * Writes specified document into specified stream and specified output format. 1255 * 1256 * @param doc document 1257 * @param os output stream 1258 * @param close tells if stream should be closed 1259 * @param outputFormat output format 1260 * 1261 * @throws XmlUtilitiesException on error 1262 */ 1263 public void writeDocumentToStreamAndClose(final Document doc, final OutputStream os, final boolean close, final OutputFormat outputFormat) throws XmlUtilitiesException { 1264 Properties outputProperties = null; 1265 if (outputFormat != null) { 1266 outputProperties = outputFormat.toTransformerOutputProperties(); 1267 } 1268 writeDocumentToStreamAndClose(doc, os, close, outputProperties); 1269 } 1270 1271 /** 1272 * Writes specified document into specified stream and specified output format properties. 1273 * 1274 * @param doc document 1275 * @param os output stream 1276 * @param close tells if stream should be closed 1277 * @param outputProperties output format properties 1278 * 1279 * @throws XmlUtilitiesException on error 1280 */ 1281 public void writeDocumentToStreamAndClose(final Document doc, final OutputStream os, final boolean close, final Properties outputProperties) throws XmlUtilitiesException { 1282 DOMSource domSource = new DOMSource(doc); 1283 StreamResult streamResult = new StreamResult(os); 1284 1285 XmlUtilitiesException exception = null; 1286 try { 1287 try { 1288 transformer.setParameter("", ""); 1289 transformer.clearParameters(); 1290 transformer.setOutputProperties(null); 1291 if (outputProperties != null) { 1292 transformer.setOutputProperties(outputProperties); 1293 } 1294 transformer.transform(domSource, streamResult); 1295 } catch (TransformerException ex) { 1296 final String message = "Failed to write document to stream."; 1297 LOGGER.log(Level.SEVERE, message, ex); 1298 exception = new XmlUtilitiesException(message, ex); 1299 } 1300 } finally { 1301 if (close) { 1302 try { 1303 os.close(); 1304 } catch (IOException ex) { 1305 final String message = "Failed to close stream."; 1306 if (exception != null) { 1307 LOGGER.log(Level.WARNING, message, ex); 1308 exception.addConsequent(ex); 1309 } else { 1310 LOGGER.log(Level.SEVERE, message, ex); 1311 exception = new XmlUtilitiesException(message, ex); 1312 } 1313 } 1314 } 1315 1316 if (exception != null) { 1317 throw exception; 1318 } 1319 } 1320 } 1321 1322 /** 1323 * Writes specified document into specified stream and specified {@link Transformer Transformer}. 1324 * 1325 * @param doc document 1326 * @param os output stream 1327 * @param close tells if stream should be closed 1328 * @param transformer Transformer to use 1329 * 1330 * @throws XmlUtilitiesException on error 1331 */ 1332 public void writeDocumentToStreamAndClose(final Document doc, final OutputStream os, final boolean close, final Transformer transformer) throws XmlUtilitiesException { 1333 DOMSource domSource = new DOMSource(doc); 1334 StreamResult streamResult = new StreamResult(os); 1335 1336 XmlUtilitiesException exception = null; 1337 try { 1338 try { 1339 transformer.transform(domSource, streamResult); 1340 } catch (TransformerException ex) { 1341 final String message = "Failed to write document to stream."; 1342 LOGGER.log(Level.SEVERE, message, ex); 1343 exception = new XmlUtilitiesException(message, ex); 1344 } 1345 } finally { 1346 if (close) { 1347 try { 1348 os.close(); 1349 } catch (IOException ex) { 1350 final String message = "Failed to close stream."; 1351 if (exception != null) { 1352 LOGGER.log(Level.WARNING, message, ex); 1353 exception.addConsequent(ex); 1354 } else { 1355 LOGGER.log(Level.SEVERE, message, ex); 1356 exception = new XmlUtilitiesException(message, ex); 1357 } 1358 } 1359 } 1360 1361 if (exception != null) { 1362 throw exception; 1363 } 1364 } 1365 } 1366 1367 /** 1368 * Writes Document to stream using internal buffer and closes the stream. 1369 * 1370 * @param doc Document to write 1371 * @param os target stream 1372 * @param bufferSize specified buffer size, {@code null} for default 1373 * 1374 * @throws XmlUtilitiesException on error 1375 */ 1376 public void writeDocumentToBufferedStreamAndClose(final Document doc, final OutputStream os, final Integer bufferSize) throws XmlUtilitiesException { 1377 final OutputStream output; 1378 if (bufferSize == null) { 1379 LOGGER.log(Level.FINEST, "Using default buffer size."); 1380 output = new BufferedOutputStream(os); 1381 } else { 1382 LOGGER.log(Level.FINEST, "Using buffer size {0}.", bufferSize); 1383 output = new BufferedOutputStream(os, bufferSize); 1384 } 1385 writeDocumentToStreamAndClose(doc, output, true); 1386 } 1387 1388 /** 1389 * Writes Document to stream using internal buffer and closes the stream. 1390 * 1391 * @param doc Document to write 1392 * @param os target stream 1393 * @param bufferSize specified buffer size, {@code null} for default 1394 * @param outputFormat output format 1395 * 1396 * @throws XmlUtilitiesException on error 1397 */ 1398 public void writeDocumentToBufferedStreamAndClose(final Document doc, final OutputStream os, final Integer bufferSize, final OutputFormat outputFormat) 1399 throws XmlUtilitiesException { 1400 final OutputStream output; 1401 if (bufferSize == null) { 1402 LOGGER.log(Level.FINEST, "Using default buffer size."); 1403 output = new BufferedOutputStream(os); 1404 } else { 1405 LOGGER.log(Level.FINEST, "Using buffer size {0}.", bufferSize); 1406 output = new BufferedOutputStream(os, bufferSize); 1407 } 1408 writeDocumentToStreamAndClose(doc, output, true, outputFormat); 1409 } 1410 1411 /** 1412 * Writes Document to stream using internal buffer and closes the stream. 1413 * 1414 * @param doc Document to write 1415 * @param os target stream 1416 * @param bufferSize specified buffer size, {@code null} for default 1417 * @param outputProperties output format properties 1418 * 1419 * @throws XmlUtilitiesException on error 1420 */ 1421 public void writeDocumentToBufferedStreamAndClose(final Document doc, final OutputStream os, final Integer bufferSize, final Properties outputProperties) 1422 throws XmlUtilitiesException { 1423 final OutputStream output; 1424 if (bufferSize == null) { 1425 LOGGER.log(Level.FINEST, "Using default buffer size."); 1426 output = new BufferedOutputStream(os); 1427 } else { 1428 LOGGER.log(Level.FINEST, "Using buffer size {0}.", bufferSize); 1429 output = new BufferedOutputStream(os, bufferSize); 1430 } 1431 writeDocumentToStreamAndClose(doc, output, true, outputProperties); 1432 } 1433 1434 /** 1435 * Writes Document to stream using internal buffer and closes the stream. 1436 * 1437 * @param doc Document to write 1438 * @param os target stream 1439 * @param bufferSize specified buffer size, {@code null} for default 1440 * @param transformer transformer 1441 * 1442 * @throws XmlUtilitiesException on error 1443 */ 1444 public void writeDocumentToBufferedStreamAndClose(final Document doc, final OutputStream os, final Integer bufferSize, final Transformer transformer) 1445 throws XmlUtilitiesException { 1446 final OutputStream output; 1447 if (bufferSize == null) { 1448 LOGGER.log(Level.FINEST, "Using default buffer size."); 1449 output = new BufferedOutputStream(os); 1450 } else { 1451 LOGGER.log(Level.FINEST, "Using buffer size {0}.", bufferSize); 1452 output = new BufferedOutputStream(os, bufferSize); 1453 } 1454 writeDocumentToStreamAndClose(doc, output, true, transformer); 1455 } 1456 1457 /** 1458 * Writes Document to specified file. 1459 * 1460 * @param doc document 1461 * @param file target file 1462 * 1463 * @throws XmlUtilitiesException on error 1464 */ 1465 public void writeDocumentToFile(final Document doc, final String file) throws XmlUtilitiesException { 1466 writeDocumentToFile(doc, new File(file), (Integer) null); 1467 } 1468 1469 /** 1470 * Writes Document to specified file. 1471 * 1472 * @param doc document 1473 * @param file target file 1474 * @param outputFormat output format 1475 * 1476 * @throws XmlUtilitiesException on error 1477 */ 1478 public void writeDocumentToFile(final Document doc, final String file, final OutputFormat outputFormat) throws XmlUtilitiesException { 1479 writeDocumentToFile(doc, new File(file), null, outputFormat); 1480 } 1481 1482 /** 1483 * Writes Document to specified file. 1484 * 1485 * @param doc document 1486 * @param file target file 1487 * @param outputProperties output format properties 1488 * 1489 * @throws XmlUtilitiesException on error 1490 */ 1491 public void writeDocumentToFile(final Document doc, final String file, final Properties outputProperties) throws XmlUtilitiesException { 1492 writeDocumentToFile(doc, new File(file), null, outputProperties); 1493 } 1494 1495 /** 1496 * Writes Document to specified file. 1497 * 1498 * @param doc document 1499 * @param file target file 1500 * @param transformer transformer 1501 * 1502 * @throws XmlUtilitiesException on error 1503 */ 1504 public void writeDocumentToFile(final Document doc, final String file, final Transformer transformer) throws XmlUtilitiesException { 1505 writeDocumentToFile(doc, new File(file), null, transformer); 1506 } 1507 1508 /** 1509 * Writes Document to specified file using internal buffer. 1510 * 1511 * @param doc document 1512 * @param file target file 1513 * @param bufferSize buffer size or {@code null} for default 1514 * 1515 * @throws XmlUtilitiesException on error 1516 */ 1517 public void writeDocumentToFile(final Document doc, final String file, final Integer bufferSize) throws XmlUtilitiesException { 1518 writeDocumentToFile(doc, new File(file), bufferSize); 1519 } 1520 1521 /** 1522 * Writes Document to specified file using internal buffer. 1523 * 1524 * @param doc document 1525 * @param file target file 1526 * @param bufferSize buffer size or {@code null} for default 1527 * @param outputFormat output format 1528 * 1529 * @throws XmlUtilitiesException on error 1530 */ 1531 public void writeDocumentToFile(final Document doc, final String file, final Integer bufferSize, final OutputFormat outputFormat) throws XmlUtilitiesException { 1532 writeDocumentToFile(doc, new File(file), bufferSize, outputFormat); 1533 } 1534 1535 /** 1536 * Writes Document to specified file using internal buffer. 1537 * 1538 * @param doc document 1539 * @param file target file 1540 * @param bufferSize buffer size or {@code null} for default 1541 * @param outputProperties output format properties 1542 * 1543 * @throws XmlUtilitiesException on error 1544 */ 1545 public void writeDocumentToFile(final Document doc, final String file, final Integer bufferSize, final Properties outputProperties) throws XmlUtilitiesException { 1546 writeDocumentToFile(doc, new File(file), bufferSize, outputProperties); 1547 } 1548 1549 /** 1550 * Writes Document to specified file using internal buffer. 1551 * 1552 * @param doc document 1553 * @param file target file 1554 * @param bufferSize buffer size or {@code null} for default 1555 * @param transformer transformer 1556 * 1557 * @throws XmlUtilitiesException on error 1558 */ 1559 public void writeDocumentToFile(final Document doc, final String file, final Integer bufferSize, final Transformer transformer) throws XmlUtilitiesException { 1560 writeDocumentToFile(doc, new File(file), bufferSize, transformer); 1561 } 1562 1563 /** 1564 * Writes Document to specified file. 1565 * 1566 * @param doc document 1567 * @param file target file 1568 * 1569 * @throws XmlUtilitiesException on error 1570 */ 1571 public void writeDocumentToFile(final Document doc, final File file) throws XmlUtilitiesException { 1572 writeDocumentToFile(doc, file, (Integer) null); 1573 } 1574 1575 /** 1576 * Writes Document to specified file. 1577 * 1578 * @param doc document 1579 * @param file target file 1580 * @param outputFormat output format 1581 * 1582 * @throws XmlUtilitiesException on error 1583 */ 1584 public void writeDocumentToFile(final Document doc, final File file, final OutputFormat outputFormat) throws XmlUtilitiesException { 1585 writeDocumentToFile(doc, file, null, outputFormat); 1586 } 1587 1588 /** 1589 * Writes Document to specified file. 1590 * 1591 * @param doc document 1592 * @param file target file 1593 * @param outputProperties output format properties 1594 * 1595 * @throws XmlUtilitiesException on error 1596 */ 1597 public void writeDocumentToFile(final Document doc, final File file, final Properties outputProperties) throws XmlUtilitiesException { 1598 writeDocumentToFile(doc, file, null, outputProperties); 1599 } 1600 1601 /** 1602 * Writes Document to specified file. 1603 * 1604 * @param doc document 1605 * @param file target file 1606 * @param transformer transformer 1607 * 1608 * @throws XmlUtilitiesException on error 1609 */ 1610 public void writeDocumentToFile(final Document doc, final File file, final Transformer transformer) throws XmlUtilitiesException { 1611 writeDocumentToFile(doc, file, null, transformer); 1612 } 1613 1614 /** 1615 * Writes Document to specified file using internal buffer. 1616 * 1617 * @param doc document 1618 * @param file target file 1619 * @param bufferSize buffer size or {@code null} for default 1620 * 1621 * @throws XmlUtilitiesException on error 1622 */ 1623 public void writeDocumentToFile(final Document doc, final File file, final Integer bufferSize) throws XmlUtilitiesException { 1624 if (file == null) { 1625 throw new IllegalArgumentException("file can't be null."); 1626 } 1627 1628 final OutputStream os; 1629 try { 1630 os = new FileOutputStream(file); 1631 } catch (FileNotFoundException ex) { 1632 final String message = String.format("Failed to create output file '%s'.", file); 1633 LOGGER.log(Level.SEVERE, message, ex); 1634 throw new XmlUtilitiesException(message, ex); 1635 } 1636 writeDocumentToBufferedStreamAndClose(doc, os, bufferSize); 1637 } 1638 1639 /** 1640 * Writes Document to specified file using internal buffer. 1641 * 1642 * @param doc document 1643 * @param file target file 1644 * @param bufferSize buffer size or {@code null} for default 1645 * @param outputFormat output format 1646 * 1647 * @throws XmlUtilitiesException on error 1648 */ 1649 public void writeDocumentToFile(final Document doc, final File file, final Integer bufferSize, final OutputFormat outputFormat) throws XmlUtilitiesException { 1650 if (file == null) { 1651 throw new IllegalArgumentException("file can't be null."); 1652 } 1653 1654 final OutputStream os; 1655 try { 1656 os = new FileOutputStream(file); 1657 } catch (FileNotFoundException ex) { 1658 final String message = String.format("Failed to create output file '%s'.", file); 1659 LOGGER.log(Level.SEVERE, message, ex); 1660 throw new XmlUtilitiesException(message, ex); 1661 } 1662 writeDocumentToBufferedStreamAndClose(doc, os, bufferSize, outputFormat); 1663 } 1664 1665 /** 1666 * Writes Document to specified file using internal buffer. 1667 * 1668 * @param doc document 1669 * @param file target file 1670 * @param bufferSize buffer size or {@code null} for default 1671 * @param outputProperties output format properties 1672 * 1673 * @throws XmlUtilitiesException on error 1674 */ 1675 public void writeDocumentToFile(final Document doc, final File file, final Integer bufferSize, final Properties outputProperties) throws XmlUtilitiesException { 1676 if (file == null) { 1677 throw new IllegalArgumentException("file can't be null."); 1678 } 1679 1680 final OutputStream os; 1681 try { 1682 os = new FileOutputStream(file); 1683 } catch (FileNotFoundException ex) { 1684 final String message = String.format("Failed to create output file '%s'.", file); 1685 LOGGER.log(Level.SEVERE, message, ex); 1686 throw new XmlUtilitiesException(message, ex); 1687 } 1688 writeDocumentToBufferedStreamAndClose(doc, os, bufferSize, outputProperties); 1689 } 1690 1691 /** 1692 * Writes Document to specified file using internal buffer. 1693 * 1694 * @param doc document 1695 * @param file target file 1696 * @param bufferSize buffer size or {@code null} for default 1697 * @param transformer transformer 1698 * 1699 * @throws XmlUtilitiesException on error 1700 */ 1701 public void writeDocumentToFile(final Document doc, final File file, final Integer bufferSize, final Transformer transformer) throws XmlUtilitiesException { 1702 if (file == null) { 1703 throw new IllegalArgumentException("file can't be null."); 1704 } 1705 1706 final OutputStream os; 1707 try { 1708 os = new FileOutputStream(file); 1709 } catch (FileNotFoundException ex) { 1710 final String message = String.format("Failed to create output file '%s'.", file); 1711 LOGGER.log(Level.SEVERE, message, ex); 1712 throw new XmlUtilitiesException(message, ex); 1713 } 1714 writeDocumentToBufferedStreamAndClose(doc, os, bufferSize, transformer); 1715 } 1716 1717 /** 1718 * Disables logging of {@code XmlTools} and {@code XmlUtilities}. 1719 */ 1720 public static void disableLogging() { 1721 disableLogging0(); 1722 XmlTools.disableLogging0(); 1723 } 1724 1725 /** 1726 * Disables logging. 1727 */ 1728 static void disableLogging0() { 1729 setLoggingLevel0(Level.OFF); 1730 } 1731 1732 /** 1733 * Sets new logging level of {@code XmlTools} and {@code XmlUtilities}. 1734 * 1735 * @param newLevel level to set 1736 */ 1737 public static void setLoggingLevel(final Level newLevel) { 1738 setLoggingLevel0(newLevel); 1739 XmlTools.setLoggingLevel0(newLevel); 1740 } 1741 1742 /** 1743 * Sets new logging level. 1744 * 1745 * @param newLevel level to set 1746 */ 1747 static void setLoggingLevel0(final Level newLevel) { 1748 LOGGER.setLevel(newLevel); 1749 } 1750 1751 }