Coverage Summary for Class: XMLUtils (org.kitodo.production.helper)

Class Class, % Method, % Line, %
XMLUtils 100% (1/1) 16,7% (1/6) 13,3% (4/30)


 /*
  * (c) Kitodo. Key to digital objects e. V. <contact@kitodo.org>
  *
  * This file is part of the Kitodo project.
  *
  * It is licensed under GNU General Public License version 3 or later.
  *
  * For the full copyright and license information, please read the
  * GPL3-License.txt file that was distributed with this source code.
  */
 
 package org.kitodo.production.helper;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.NoSuchElementException;
 import java.util.Objects;
 
 import javax.xml.XMLConstants;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 /**
  * The class XMLUtils contains an omnium-gatherum of functions that work on XML.
  */
 public class XMLUtils {
 
     /**
      * Private constructor to hide the implicit public one.
      */
     private XMLUtils() {
 
     }
 
     /**
      * Converts an org.w3c.dom.Document to a
      * ByteArray for Downloading
      *
      * @param data
      *            The document to convert
      * @param indent
      *            No of spaces to use for indenting. Use “null” to disable
      * @return the XML data as byte[]
      * @throws TransformerException
      *             when it is not possible to create a Transformer instance or
      *             if an unrecoverable error occurs during the course of the
      *             transformation
      */
     public static byte[] documentToByteArray(Document data, Integer indent) throws TransformerException {
         ByteArrayOutputStream result = new ByteArrayOutputStream();
 
         Transformer transformer = TransformerFactory.newInstance().newTransformer();
         if (Objects.nonNull(indent)) {
             transformer.setOutputProperty(OutputKeys.INDENT, "yes");
             transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", indent.toString());
         }
         transformer.transform(new DOMSource(data), new StreamResult(result));
         return result.toByteArray();
     }
 
     /**
      * Returns the first child node from
      * a node, identified by its node name.
      *
      * @param data
      *            Document or Element whose children shall be examined
      * @param tagName
      *            name of the node to find
      * @return first child node with that node name
      * @throws NoSuchElementException
      *             if no child node with that name can be found
      */
     public static Element getFirstChildWithTagName(Node data, String tagName) {
         for (Node element = data.getFirstChild(); Objects.nonNull(element); element = element.getNextSibling()) {
             if (!(element instanceof Element)) {
                 continue;
             }
             if (element.getNodeName().equals(tagName)) {
                 return (Element) element;
             }
         }
         throw new NoSuchElementException(tagName);
     }
 
     /**
      * The function is a convenience method load a DOM Document object
      * from an input stream.
      *
      * @param data
      *            InputStream to read from
      * @return the DOM Document encoded in the input stream’s data
      * @throws SAXException
      *             if any parse errors occur
      * @throws IOException
      *             if any IO errors occur
      * @throws IOException
      *             if a DocumentBuilder cannot be created which satisfies the
      *             configuration requested—which never happens because we use
      *             the default configuration here and that is definitely
      *             supported, but in case - wrap it in IOException
      */
     public static Document load(InputStream data) throws SAXException, IOException {
         try {
             DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
             documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
             return documentBuilderFactory.newDocumentBuilder().parse(data);
         } catch (ParserConfigurationException e) {
             throw new IOException(e.getMessage(), e);
         }
     }
 
     /**
      * The function is a convenience method to obtain a new
      * instance of a DOM Document object.
      *
      * @return A new DOM Document
      * @throws IOException
      *             if a DocumentBuilder cannot be created which satisfies the
      *             configuration requested—which never happens because we use
      *             the default configuration here and that is definitely
      *             supported, but in case - wrap it in IOException
      */
     public static Document newDocument() throws IOException {
         try {
             DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
             documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
             return documentBuilderFactory.newDocumentBuilder().newDocument();
         } catch (ParserConfigurationException e) {
             throw new IOException(e.getMessage(), e);
         }
     }
 
     /**
      * Parse given String 'xmlString' and create Document from it.
      *
      * @param xmlString the String that will be parsed and converted to a Document
      * @return Document
      *          the Document created from the given String 'xmlString'
      * @throws ParserConfigurationException thrown when DocumentBuilder cannot be created
      * @throws IOException thrown when input stream cannot be parsed
      * @throws SAXException thrown when input stream cannot be parsed
      */
     public static Document parseXMLString(String xmlString) throws IOException, ParserConfigurationException,
             SAXException {
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         factory.setNamespaceAware(true);
         DocumentBuilder builder = factory.newDocumentBuilder();
         return builder.parse(new InputSource(new ByteArrayInputStream(xmlString.getBytes(StandardCharsets.UTF_8))));
     }
 
     /**
      * Compile given String "xpathString" and check whether it contains a valid XPath (e.g. if the syntax is correct)
      * Throws an exception if syntax is incorrect. Can be used to validate XPaths.
      *
      * @param xpathString String to be checked for correct XPath syntax
      * @throws XPathExpressionException if provided String does not contain valid XPath syntax
      */
     public static void validateXPathSyntax(String xpathString) throws XPathExpressionException {
         XPathFactory factory = XPathFactory.newInstance();
         XPath xpath = factory.newXPath();
         xpath.compile(xpathString);
     }
 }