Coverage Report - org.kuali.rice.core.util.xml.XmlHelper
 
Classes in this File Line Coverage Branch Coverage Complexity
XmlHelper
0%
0/96
0%
0/40
3.071
 
 1  
 /*
 2  
  * Copyright 2005-2007 The Kuali Foundation
 3  
  *
 4  
  *
 5  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  * http://www.opensource.org/licenses/ecl2.php
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.kuali.rice.core.util.xml;
 18  
 
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.apache.commons.logging.Log;
 21  
 import org.apache.commons.logging.LogFactory;
 22  
 import org.jdom.Document;
 23  
 import org.jdom.Element;
 24  
 import org.jdom.JDOMException;
 25  
 import org.jdom.Namespace;
 26  
 import org.jdom.input.DOMBuilder;
 27  
 import org.jdom.input.SAXBuilder;
 28  
 import org.w3c.dom.Node;
 29  
 import org.w3c.dom.NodeList;
 30  
 import org.xml.sax.InputSource;
 31  
 import org.xml.sax.SAXException;
 32  
 
 33  
 import javax.xml.parsers.DocumentBuilder;
 34  
 import javax.xml.parsers.DocumentBuilderFactory;
 35  
 import javax.xml.parsers.ParserConfigurationException;
 36  
 import javax.xml.transform.*;
 37  
 import javax.xml.transform.dom.DOMResult;
 38  
 import javax.xml.transform.stream.StreamSource;
 39  
 import javax.xml.xpath.XPath;
 40  
 import javax.xml.xpath.XPathConstants;
 41  
 import javax.xml.xpath.XPathExpressionException;
 42  
 import java.io.*;
 43  
 import java.lang.reflect.Method;
 44  
 import java.util.ArrayList;
 45  
 import java.util.Collection;
 46  
 
 47  
 
 48  
 /**
 49  
  * Provides a set of utilities for XML-related operations on org.jdom & org.w3c
 50  
  * xml Objects.
 51  
  *
 52  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 53  
  */
 54  
 public final class XmlHelper {
 55  0
     private static final Log LOG = LogFactory.getLog(XmlHelper.class);
 56  
 
 57  0
     private XmlHelper() {
 58  0
         throw new UnsupportedOperationException("do not call");
 59  
     }
 60  
 
 61  
     /**
 62  
      * Creates jdom Document from a Reader.  Does not close the reader.
 63  
      *
 64  
      * @param xmlStream the reader representing the xmlstream
 65  
      * @return jdom document
 66  
      */
 67  
     public static org.jdom.Document buildJDocument(Reader xmlStream) {
 68  
         // use SAX Builder
 69  
         // don't verify for speed reasons
 70  0
         final SAXBuilder builder = new SAXBuilder(false);
 71  
         try {
 72  0
             return builder.build(xmlStream);
 73  0
         } catch (IOException e) {
 74  0
             throw new XmlException("Invalid xml string. ", e);
 75  0
         } catch (JDOMException e) {
 76  0
             throw new XmlException("Invalid xml string. ", e);
 77  
         }
 78  
     }
 79  
 
 80  
     /**
 81  
      * Creates jdom Document from a w3c Document.  Does not close the reader.
 82  
      *
 83  
      * @param document the w3c document
 84  
      * @return jdom document
 85  
      */
 86  
     public static org.jdom.Document buildJDocument(org.w3c.dom.Document document) {
 87  0
         return new DOMBuilder().build(document);
 88  
     }
 89  
 
 90  
     /**
 91  
      * Find all Elements in document of a particular name
 92  
      *
 93  
      * @param root the starting Element to scan
 94  
      * @param elementName name of the Element to scan for
 95  
      * @return collection of the Elements found.
 96  
      *         returns an empty collection if none are found.
 97  
      */
 98  
     public static Collection<Element> findElements(Element root, String elementName) {
 99  0
         Collection<Element> elementList = new ArrayList<Element>();
 100  
 
 101  0
         if (root == null) {
 102  0
             return elementList;
 103  
         }
 104  
 
 105  0
         XmlHelper.findElements(root, elementName, elementList);
 106  
 
 107  0
         return elementList;
 108  
     }
 109  
 
 110  
     public static void appendXml(Node parentNode, String xml) throws SAXException, IOException, ParserConfigurationException {
 111  0
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 112  0
         factory.setValidating(false);
 113  0
         org.w3c.dom.Document xmlDocument = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
 114  0
         org.w3c.dom.Element xmlDocumentElement = xmlDocument.getDocumentElement();
 115  0
         Node importedNode = parentNode.getOwnerDocument().importNode(xmlDocumentElement, true);
 116  0
         parentNode.appendChild(importedNode);
 117  0
     }
 118  
 
 119  
     public static org.w3c.dom.Document readXml(String xml) throws TransformerException {
 120  0
         Source source = new StreamSource(new BufferedReader(new StringReader(xml)));
 121  0
         DOMResult result = new DOMResult();
 122  0
         Transformer transformer = TransformerFactory.newInstance().newTransformer();
 123  0
         transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
 124  0
         transformer.transform(source, result);
 125  0
         return (org.w3c.dom.Document) result.getNode();
 126  
     }
 127  
 
 128  
     public static void propagateNamespace(Element element, Namespace namespace) {
 129  0
         element.setNamespace(namespace);
 130  0
         for (Object childElement : element.getChildren()) {
 131  0
             propagateNamespace((Element) childElement, namespace);
 132  
         }
 133  0
     }
 134  
 
 135  
     public static org.w3c.dom.Document trimXml(InputStream input) throws SAXException, IOException, ParserConfigurationException {
 136  0
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 137  0
         factory.setIgnoringElementContentWhitespace(true);
 138  0
         DocumentBuilder builder = factory.newDocumentBuilder();
 139  0
         org.w3c.dom.Document oldDocument = builder.parse(input);
 140  0
         org.w3c.dom.Element naviElement = oldDocument.getDocumentElement();
 141  0
         trimElement(naviElement);
 142  0
         return oldDocument;
 143  
     }
 144  
 
 145  
     public static Document trimSAXXml(InputStream input) throws JDOMException, SAXException, IOException, ParserConfigurationException {
 146  0
         SAXBuilder builder = new SAXBuilder(false);
 147  0
         Document oldDocument = builder.build(input);
 148  0
         Element naviElement = oldDocument.getRootElement();
 149  0
         trimSAXElement(naviElement);
 150  0
         return oldDocument;
 151  
     }
 152  
 
 153  
     /**
 154  
      * Convenience method that performs an xpath evaluation to determine whether the expression
 155  
      * evaluates to true (a node exists).
 156  
      * This is method exists only to disambiguate the cases of determining the *presence* of a node
 157  
      * and determining the *boolean value of the node as converted from a string*, as the syntaxes
 158  
      * are very similar and could be misleading.
 159  
      *
 160  
      * @param xpath      the XPath object
 161  
      * @param expression the XPath expression
 162  
      * @param object     the object on which to evaluate the expression as required by the XPath API, typically a Node
 163  
      * @return whether the result of the expression evaluation, which is whether or not a node was present
 164  
      * @throws XPathExpressionException if the expression fails
 165  
      */
 166  
     public static boolean pathExists(XPath xpath, String expression, Object object) throws XPathExpressionException {
 167  0
         return ((Boolean) xpath.evaluate(expression, object, XPathConstants.BOOLEAN)).booleanValue();
 168  
     }
 169  
 
 170  
     public static org.w3c.dom.Element propertiesToXml(org.w3c.dom.Document doc, Object o, String elementName) throws Exception {
 171  0
         Class<?> c = o.getClass();
 172  0
         org.w3c.dom.Element wrapper = doc.createElement(elementName);
 173  0
         Method[] methods = c.getMethods();
 174  0
         for (Method method : methods) {
 175  0
             String name = method.getName();
 176  0
             if ("getClass".equals(name)) {
 177  0
                 continue;
 178  
             }
 179  0
             if (!name.startsWith("get") || method.getParameterTypes().length > 0) {
 180  0
                 continue;
 181  
             }
 182  0
             name = name.substring("get".length());
 183  0
             name = StringUtils.uncapitalize(name);
 184  
             try {
 185  0
                 Object result = method.invoke(o);
 186  
                 final String value;
 187  0
                 if (result == null) {
 188  0
                     LOG.debug("value of " + name + " method on object " + o.getClass() + " is null");
 189  0
                     value = "";
 190  
                 } else {
 191  0
                     value = result.toString();
 192  
                 }
 193  0
                 org.w3c.dom.Element fieldE = doc.createElement(name);
 194  0
                 fieldE.appendChild(doc.createTextNode(value));
 195  0
                 wrapper.appendChild(fieldE);
 196  0
             } catch (Exception e) {
 197  0
                 throw new XmlException("Error accessing method '" + method.getName() + "' of instance of " + c, e);
 198  0
             }
 199  
         }
 200  0
         return wrapper;
 201  
     }
 202  
 
 203  
     /**
 204  
      * This function is tail-recursive and just adds the root to the list if it
 205  
      * matches and checks the children.
 206  
      *
 207  
      * @param root the root element to search under
 208  
      * @param elementName the element name to find
 209  
      * @param list a list of found element
 210  
      */
 211  
     private static void findElements(Element root, String elementName, Collection<Element> list) {
 212  0
         if (root != null) {
 213  0
             if (root.getName().equals(elementName)) {
 214  0
                 list.add(root);
 215  
             }
 216  
 
 217  0
             for (Object item : root.getChildren()) {
 218  0
                 if (item != null) {
 219  0
                     XmlHelper.findElements((Element) item, elementName, list);
 220  
                 }
 221  
             }
 222  
         }
 223  0
     }
 224  
 
 225  
     private static void trimElement(Node node) throws SAXException, IOException, ParserConfigurationException {
 226  
 
 227  0
         if (node.hasChildNodes()) {
 228  0
             NodeList children = node.getChildNodes();
 229  0
             for (int i = 0; i < children.getLength(); i++) {
 230  0
                 Node child = children.item(i);
 231  0
                 if (child != null) {
 232  0
                     trimElement(child);
 233  
                 }
 234  
             }
 235  0
         } else {
 236  0
             if (node.getNodeType() == Node.TEXT_NODE) {
 237  0
                 String text = node.getNodeValue();
 238  0
                 text = StringUtils.isEmpty(text) ? "" : text.trim();
 239  0
                 node.setNodeValue(text);
 240  
             }
 241  
         }
 242  0
     }
 243  
 
 244  
     private static void trimSAXElement(Element element) throws SAXException, IOException, ParserConfigurationException {
 245  
 
 246  0
         if (!element.getChildren().isEmpty()) {
 247  0
             for (Object child : element.getChildren()) {
 248  0
                 if (child != null) {
 249  0
                     trimSAXElement((Element) child);
 250  
                 }
 251  
             }
 252  
         } else {
 253  0
             String text = element.getTextTrim();
 254  0
             if (StringUtils.isEmpty(text)) {
 255  0
                 text = "";
 256  
             }
 257  0
             element.setText(text);
 258  
         }
 259  0
     }
 260  
 }