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