/* * Copyright 2010 Outerthought bvba * * 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 * distributed 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 the specific language governing permissions and * limitations under the License. */ package org.lilyproject.util.xml; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.sax.TransformerHandler; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.lilyproject.util.io.IOUtils; import org.lilyproject.util.location.LocatedException; import org.lilyproject.util.location.LocatedRuntimeException; import org.lilyproject.util.location.LocationAttributes; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; /** * Utility methods for working with DOM documents. */ public class DocumentHelper { private DocumentHelper() { } public static Document parse(InputStream is) throws ParserConfigurationException, IOException, SAXException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); return factory.newDocumentBuilder().parse(is); } public static Document parse(File file) throws ParserConfigurationException, IOException, SAXException { InputStream is = null; try { is = new FileInputStream(file); return parse(is); } finally { IOUtils.closeQuietly(is); } } public static Element getElementChild(Element element, String name, boolean required) throws Exception { NodeList nodes = element.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (node instanceof Element && node.getLocalName().equals(name) && node.getNamespaceURI() == null) { return (Element)node; } } if (required) { throw new LocatedException("Missing element " + name + " in " + element.getLocalName(), LocationAttributes.getLocation(element)); } else { return null; } } public static Element[] getElementChildren(Element element) { List<Element> elements = new ArrayList<Element>(); NodeList nodes = element.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { if (nodes.item(i) instanceof Element) { elements.add((Element)nodes.item(i)); } } return elements.toArray(new Element[0]); } public static Element[] getElementChildren(Element element, String name) { Element[] elements = getElementChildren(element); List<Element> taggedElements = new ArrayList<Element>(); for (Element element1 : elements) { if (element1.getLocalName().equals(name) && element1.getNamespaceURI() == null) { taggedElements.add(element1); } } return taggedElements.toArray(new Element[0]); } public static String getAttribute(Element element, String name, boolean required) throws Exception { if (!element.hasAttribute(name)) { if (required) { throw new LocatedException("Missing attribute " + name + " on element " + element.getLocalName(), LocationAttributes.getLocation(element)); } else { return null; } } return element.getAttribute(name); } public static boolean getBooleanAttribute(Element element, String name, boolean defaultValue) throws Exception { String value = element.getAttribute(name); if (value.equals("")) { return defaultValue; } else { return value.equalsIgnoreCase("true"); } } public static Boolean getBooleanAttribute(Element element, String name, Boolean defaultValue) throws Exception { String value = element.getAttribute(name); if (value.equals("")) { return defaultValue; } else { return value.equalsIgnoreCase("true"); } } public static int getIntegerAttribute(Element element, String name) throws Exception { if (!element.hasAttribute(name)) { throw new LocatedException("Missing attribute " + name + " on element " + element.getLocalName(), LocationAttributes.getLocation(element)); } else { String value = element.getAttribute(name); try { return Integer.parseInt(value); } catch (NumberFormatException e) { throw new LocatedException("Invalid integer value " + value + " in attribute " + name, LocationAttributes.getLocation(element)); } } } public static int getIntegerAttribute(Element element, String name, int defaultValue) throws Exception { String value = element.getAttribute(name); if (value.equals("")) { return defaultValue; } else { try { return Integer.parseInt(value); } catch (NumberFormatException e) { throw new LocatedException("Invalid integer value " + value + " in attribute " + name, LocationAttributes.getLocation(element)); } } } public static boolean getBooleanElement(Element element, String name, boolean defaultValue) throws Exception { Element child = getElementChild(element, name, false); if (child == null) { return defaultValue; } return getElementText(child, true).equalsIgnoreCase("true"); } public static String getStringElement(Element element, String name, String defaultValue) throws Exception { Element child = getElementChild(element, name, false); if (child == null) { return defaultValue; } return getElementText(child, true); } public static int getIntegerElement(Element element, String name, int defaultValue) throws Exception { Element child = getElementChild(element, name, false); if (child == null) { return defaultValue; } String text = getElementText(child, true); try { return Integer.parseInt(text); } catch (NumberFormatException e) { throw new LocatedRuntimeException("Invalid integer value " + text + " in element " + name, LocationAttributes.getLocation(element)); } } public static String getElementText(Element element, boolean required) throws Exception { StringBuilder text = new StringBuilder(30); NodeList nodes = element.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (node instanceof Text) { text.append(node.getNodeValue()); } } if (required && text.length() == 0) { throw new LocatedException("Missing text content in element " + element.getLocalName(), LocationAttributes.getLocation(element)); } else if (text.length() == 0) { return null; } else { return text.toString(); } } public static Document parseDomWithLocationAttributes(File file) throws SAXException, ParserConfigurationException, TransformerConfigurationException, IOException { InputStream is = null; try { is = new FileInputStream(file); InputSource inputSource = new InputSource(is); inputSource.setSystemId(file.getCanonicalPath()); return parseDomWithLocationAttributes(inputSource); } finally { IOUtils.closeQuietly(is); } } public static Document parseDomWithLocationAttributes(InputSource inputSource) throws SAXException, ParserConfigurationException, TransformerConfigurationException, IOException { XMLReader xmlReader = LocalSAXParserFactory.newXmlReader(); TransformerHandler serializer = LocalTransformerFactory.get().newTransformerHandler(); DOMResult result = new DOMResult(); serializer.setResult(result); LocationAttributes.Pipe locationPipe = new LocationAttributes.Pipe(serializer); xmlReader.setContentHandler(locationPipe); xmlReader.parse(inputSource); return (Document)result.getNode(); } }