// Copyright 2015 The Project Buendia Authors // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at: http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distrib- // uted under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES // OR CONDITIONS OF ANY KIND, either express or implied. See the License for // specific language governing permissions and limitations under the License. package org.openmrs.projectbuendia.webservices.rest; import org.openmrs.module.webservices.rest.web.response.IllegalPropertyException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; /** XML manipulation functions. */ public class XmlUtil { private static final DocumentBuilder documentBuilder; static { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); factory.setIgnoringComments(true); documentBuilder = factory.newDocumentBuilder(); } catch (ParserConfigurationException e) { throw new RuntimeException(e); } } /** Converts a NodeList to an Iterable of Elements. */ public static Iterable<Element> toElementIterable(NodeList nodeList) { List<Element> elements = new ArrayList<>(nodeList.getLength()); for (int i = 0; i < nodeList.getLength(); i++) { elements.add((Element) nodeList.item(i)); } return elements; } /** Removes a node from its tree. */ public static void removeNode(Node node) { node.getParentNode().removeChild(node); } /** * Given an element, returns all its direct child elements that have the * specified namespace and name. Use null to indicate the empty namespace. */ public static List<Element> getElementsNS( Element element, String namespaceURI, String localName) { List<Element> elements = new ArrayList<>(); for (Element candidate : getElements(element)) { if (namespaceURI.equals(candidate.getNamespaceURI()) && localName.equals(candidate.getLocalName())) { elements.add(candidate); } } return elements; } /** Returns all the direct child elements of the given element. */ public static List<Element> getElements(Element element) { List<Element> elements = new ArrayList<>(); for (Node node : toIterable(element.getChildNodes())) { if (node.getNodeType() == Node.ELEMENT_NODE) { elements.add((Element) node); } } return elements; } /** Converts a NodeList to an Iterable of Nodes. */ public static Iterable<Node> toIterable(NodeList nodeList) { List<Node> nodes = new ArrayList<>(nodeList.getLength()); for (int i = 0; i < nodeList.getLength(); i++) { nodes.add(nodeList.item(i)); } return nodes; } /** * Given an element, returns its direct child with the empty namespace * and the given name, failing unless there is one and only one match. */ public static Element getElementOrThrow(Element element, String name) { return getElementOrThrowNS(element, null, name); } /** * Given an element, returns its direct child with the given namespace * and name, failing unless there is one and only one match. * Use null to indicate the empty namespace. */ public static Element getElementOrThrowNS( Element element, String namespaceURI, String localName) { NodeList elements = element.getElementsByTagNameNS(namespaceURI, localName); if (elements.getLength() != 1) { throw new IllegalPropertyException("Element " + element.getNodeName() + " must have exactly one " + localName + " element"); } return (Element) elements.item(0); } /** Appends a new empty child element with the given namespace and name. */ public static Element appendElementNS(Element parent, String namespaceURI, String localName) { Element ret = parent.getOwnerDocument().createElementNS(namespaceURI, localName); parent.appendChild(ret); return ret; } /** Returns a namespace-aware DocumentBuilder. */ public static DocumentBuilder getDocumentBuilder() { return documentBuilder; } /** Parses the given XML string to produce a Document. */ public static Document parse(String xml) throws SAXException, IOException { return documentBuilder.parse(new InputSource(new StringReader(xml))); } }