Coverage Report - org.webslinger.xml.XmlUtil
 
Classes in this File Line Coverage Branch Coverage Complexity
XmlUtil
27%
45/165
23%
9/39
0
XmlUtil$NodeProcessor
N/A
N/A
0
 
 1  
 package org.webslinger.xml;
 2  
 
 3  
 import java.io.ByteArrayInputStream;
 4  
 import java.io.InputStream;
 5  
 import java.io.IOException;
 6  
 import java.io.OutputStream;
 7  
 import java.io.StringWriter;
 8  
 import java.io.Writer;
 9  
 import java.util.Collection;
 10  
 import java.util.LinkedList;
 11  
 import java.util.HashMap;
 12  
 import java.util.Queue;
 13  
 import java.util.concurrent.LinkedBlockingQueue;
 14  
 import javax.xml.parsers.DocumentBuilder;
 15  
 import javax.xml.parsers.DocumentBuilderFactory;
 16  
 import javax.xml.parsers.ParserConfigurationException;
 17  
 import javax.xml.transform.Result;
 18  
 import javax.xml.transform.Transformer;
 19  
 import javax.xml.transform.TransformerConfigurationException;
 20  
 import javax.xml.transform.TransformerException;
 21  
 import javax.xml.transform.TransformerFactory;
 22  
 import javax.xml.transform.dom.DOMSource;
 23  
 import javax.xml.transform.stream.StreamResult;
 24  
 import javax.xml.xpath.XPathConstants;
 25  
 import javax.xml.xpath.XPathExpressionException;
 26  
 import javax.xml.xpath.XPathFactory;
 27  
 
 28  
 import org.xml.sax.SAXException;
 29  
 import org.xml.sax.SAXParseException;
 30  
 
 31  
 import org.w3c.dom.Document;
 32  
 import org.w3c.dom.Element;
 33  
 import org.w3c.dom.Node;
 34  
 import org.w3c.dom.NodeList;
 35  
 import org.w3c.dom.Text;
 36  
 
 37  
 import org.webslinger.io.IOUtil;
 38  
 
 39  0
 public class XmlUtil {
 40  
     private static final Queue<Transformer> writeTransformers;
 41  
     private static final Queue<DocumentBuilder> readBuilders;
 42  
 
 43  
     static {
 44  
         try {
 45  1
             readBuilders = createPool(getDocumentBuilderFactory(), 20);
 46  1
             writeTransformers = createPool(getTransformerFactory(), 20);
 47  1
             for (Transformer transformer: writeTransformers) {
 48  20
                 transformer.setOutputProperty("indent", "yes");
 49  
             }
 50  0
         } catch (RuntimeException e) {
 51  0
             throw e;
 52  0
         } catch (Exception e) {
 53  0
             throw (InternalError) new InternalError("loading queues").initCause(e);
 54  1
         }
 55  1
     }
 56  
 
 57  
     public static Queue<DocumentBuilder> createPool(DocumentBuilderFactory factory, int size) throws ParserConfigurationException {
 58  3
         LinkedBlockingQueue<DocumentBuilder> queue = new LinkedBlockingQueue<DocumentBuilder>(size);
 59  63
         while (size > 0) {
 60  60
             queue.add(factory.newDocumentBuilder());
 61  60
             size--;
 62  
         }
 63  3
         return queue;
 64  
     }
 65  
 
 66  
     public static Queue<Transformer> createPool(TransformerFactory factory, int size) throws TransformerConfigurationException {
 67  1
         LinkedBlockingQueue<Transformer> queue = new LinkedBlockingQueue<Transformer>(size);
 68  21
         while (size > 0) {
 69  20
             queue.add(factory.newTransformer());
 70  20
             size--;
 71  
         }
 72  1
         return queue;
 73  
     }
 74  
 
 75  
     public static TransformerFactory getTransformerFactory() {
 76  1
         return TransformerFactory.newInstance();
 77  
     }
 78  
 
 79  
     public static Transformer newTransformer() throws TransformerConfigurationException {
 80  0
         return getTransformerFactory().newTransformer();
 81  
     }
 82  
 
 83  
     public static DocumentBuilderFactory getDocumentBuilderFactory() {
 84  41
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 85  41
         factory.setCoalescing(true);
 86  41
         factory.setExpandEntityReferences(true);
 87  41
         return factory;
 88  
     }
 89  
 
 90  
     public static NodeList getNodes(Node root, String xpath) throws XPathExpressionException {
 91  0
         return (NodeList) XPathFactory.newInstance().newXPath().evaluate(xpath, root, XPathConstants.NODESET);
 92  
     }
 93  
 
 94  
     public static Node getNode(Node root, String xpath) throws XPathExpressionException {
 95  0
         return (Node) XPathFactory.newInstance().newXPath().evaluate(xpath, root, XPathConstants.NODE);
 96  
     }
 97  
 
 98  
     public static void setNodes(Node root, String xpath, String value) throws XPathExpressionException {
 99  0
         NodeList list = getNodes(root, xpath);
 100  0
         for (int i = 0; i < list.getLength(); i++) {
 101  0
             list.item(i).setTextContent(value);
 102  
         }
 103  0
     }
 104  
 
 105  
     public static void fixupNodes(Node root, String xpath, NodeProcessor processor) throws XPathExpressionException {
 106  0
         NodeList list = getNodes(root, xpath);
 107  0
         for (int i = 0; i < list.getLength(); i++) {
 108  0
             processor.process(list.item(i));
 109  
         }
 110  0
     }
 111  
 
 112  
     public static void removeNodes(Node root, String xpath) throws XPathExpressionException {
 113  0
         NodeList list = getNodes(root, xpath);
 114  0
         for (int i = 0; i < list.getLength(); i++) {
 115  0
             Node child = list.item(i);
 116  0
             child.getParentNode().removeChild(child);
 117  
         }
 118  0
     }
 119  
 
 120  
     public static String getNodeValue(Node root, String xpath) throws XPathExpressionException {
 121  0
         return getNodeSubText(getNode(root, xpath));
 122  
     }
 123  
 
 124  
     public static Document newDocument() throws ParserConfigurationException {
 125  2
         DocumentBuilder builder = readBuilders.poll();
 126  
         try {
 127  2
             return builder.newDocument();
 128  
         } finally {
 129  2
             readBuilders.offer(builder);
 130  
         }
 131  
     }
 132  
 
 133  
     public static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
 134  40
         return getDocumentBuilderFactory().newDocumentBuilder();
 135  
     }
 136  
 
 137  
     public static Document read(String content) throws IOException, ParserConfigurationException, SAXException {
 138  0
         return read(readBuilders, new ByteArrayInputStream(IOUtil.getBytes(content)));
 139  
     }
 140  
 
 141  
     public static Document read(Queue<DocumentBuilder> queue, String content) throws IOException, ParserConfigurationException, SAXException {
 142  0
         return read(queue, new ByteArrayInputStream(IOUtil.getBytes(content)));
 143  
     }
 144  
 
 145  
     public static Document read(InputStream in) throws IOException, ParserConfigurationException, SAXException {
 146  40
         return read(readBuilders, in);
 147  
     }
 148  
 
 149  
     public static Document read(Queue<DocumentBuilder> queue, InputStream in) throws IOException, ParserConfigurationException, SAXException {
 150  40
         DocumentBuilder builder = queue.poll();
 151  
         try {
 152  40
             return getDocumentBuilder().parse(in);
 153  
         } finally {
 154  40
             queue.offer(builder);
 155  40
             in.close();
 156  
         }
 157  
     }
 158  
 
 159  
     public static void write(Document doc, OutputStream out) throws IOException, TransformerException {
 160  0
         write(writeTransformers, doc, out);
 161  0
     }
 162  
 
 163  
     public static void write(Queue<Transformer> queue, Document doc, OutputStream out) throws IOException, TransformerException {
 164  
         try {
 165  0
             write(queue, doc, new StreamResult(out));
 166  
         } finally {
 167  0
             out.close();
 168  0
         }
 169  0
     }
 170  
 
 171  
     public static void write(Element element, OutputStream out) throws IOException, TransformerException {
 172  0
         write(writeTransformers, element, out);
 173  0
     }
 174  
 
 175  
     public static void write(Queue<Transformer> queue, Element element, OutputStream out) throws IOException, TransformerException {
 176  
         try {
 177  0
             write(queue, element, new StreamResult(out));
 178  
         } finally {
 179  0
             out.close();
 180  0
         }
 181  0
     }
 182  
 
 183  
     public static void write(Document doc, Writer writer) throws IOException, TransformerException {
 184  0
         write(writeTransformers, doc, writer);
 185  0
     }
 186  
 
 187  
     public static void write(Queue<Transformer> queue, Document doc, Writer writer) throws IOException, TransformerException {
 188  
         try {
 189  0
             write(queue, doc, new StreamResult(writer));
 190  
         } finally {
 191  0
             writer.close();
 192  0
         }
 193  0
     }
 194  
 
 195  
     public static void write(Element element, Writer writer) throws IOException, TransformerException {
 196  0
         write(writeTransformers, element, writer);
 197  0
     }
 198  
 
 199  
     public static void write(Queue<Transformer> queue, Element element, Writer writer) throws IOException, TransformerException {
 200  
         try {
 201  0
             write(queue, element, new StreamResult(writer));
 202  
         } finally {
 203  0
             writer.close();
 204  0
         }
 205  0
     }
 206  
 
 207  
     public static String write(Document doc) throws IOException, TransformerException {
 208  0
         return write(writeTransformers, doc);
 209  
     }
 210  
 
 211  
     public static String write(Queue<Transformer> queue, Document doc) throws IOException, TransformerException {
 212  0
         StringWriter writer = new StringWriter();
 213  0
         write(queue, doc, writer);
 214  0
         return writer.toString();
 215  
     }
 216  
 
 217  
     public static String write(Element element) throws IOException, TransformerException {
 218  0
         return write(writeTransformers, element);
 219  
     }
 220  
 
 221  
     public static String write(Queue<Transformer> queue, Element element) throws IOException, TransformerException {
 222  0
         StringWriter writer = new StringWriter();
 223  0
         write(queue, element, writer);
 224  0
         return writer.toString();
 225  
     }
 226  
 
 227  
     public static void write(Document doc, Result result) throws TransformerException {
 228  0
         write(doc.getDocumentElement(), result);
 229  0
     }
 230  
 
 231  
     public static void write(Queue<Transformer> queue, Document doc, Result result) throws TransformerException {
 232  0
         write(queue, doc.getDocumentElement(), result);
 233  0
     }
 234  
 
 235  
     public static void write(Element element, Result result) throws TransformerException {
 236  0
         write(writeTransformers, element, result);
 237  0
     }
 238  
 
 239  
     public static void write(Queue<Transformer> queue, Element element, Result result) throws TransformerException {
 240  0
         DOMSource source = new DOMSource(element);
 241  0
         Transformer transformer = queue.element();
 242  
         try {
 243  0
             transformer.transform(source, result);
 244  
         } finally {
 245  0
             queue.offer(transformer);
 246  0
         }
 247  0
     }
 248  
 
 249  
     public static String getAttribute(Element element, String attrName, String def) {
 250  0
         String value = element != null ? element.getAttribute(attrName) : null;
 251  0
         return value != null ? value : def;
 252  
     }
 253  
 
 254  
     public static Element getFirstElement(Node node) {
 255  0
         if (node == null) return null;
 256  0
         Node ptr = node.getFirstChild();
 257  0
         while (ptr != null) {
 258  0
             if (ptr instanceof Element) return (Element) ptr;
 259  0
             ptr = ptr.getNextSibling();
 260  
         }
 261  0
         return null;
 262  
     }
 263  
 
 264  
     public static Element getNextElement(Node node) {
 265  0
         if (node == null) return null;
 266  0
         Node ptr = node.getNextSibling();
 267  0
         while (ptr != null) {
 268  0
             if (ptr instanceof Element) return (Element) ptr;
 269  0
             ptr = ptr.getNextSibling();
 270  
         }
 271  0
         return null;
 272  
     }
 273  
 
 274  
     public static Element getFirstElementNamed(Node node, String name) {
 275  0
         if (node == null) return null;
 276  0
         Node ptr = node.getFirstChild();
 277  0
         while (ptr != null) {
 278  0
             if (!(ptr instanceof Element)) continue;
 279  0
             if (node.getNodeName().equals(name)) return (Element) ptr;
 280  0
             ptr = ptr.getNextSibling();
 281  
         }
 282  0
         return null;
 283  
     }
 284  
 
 285  
     public static Collection<Element> getElementsNamed(Node node, String name) {
 286  167
         LinkedList<Element> elements = new LinkedList<Element>();
 287  167
         if (node == null) return elements;
 288  167
         Node ptr = node.getFirstChild();
 289  554
         while (ptr != null) {
 290  387
             if (ptr instanceof Element && ptr.getNodeName().equals(name)) elements.add((Element) ptr);
 291  387
             ptr = ptr.getNextSibling();
 292  
         }
 293  167
         return elements;
 294  
     }
 295  
 
 296  
     public static String getNodeSubText(Node node) {
 297  235
         if (node == null) return null;
 298  235
         if (node instanceof Text) return node.getNodeValue();
 299  235
         StringBuilder sb = new StringBuilder();
 300  235
         Node ptr = node.getFirstChild();
 301  470
         while (ptr != null) {
 302  235
             if (ptr instanceof Text) sb.append(ptr.getNodeValue());
 303  235
             ptr = ptr.getNextSibling();
 304  
         }
 305  235
         return sb.toString();
 306  
     }
 307  
 
 308  
     public static Object parse(Element element) {
 309  0
         if (element == null) return null;
 310  0
         String nodeName = element.getNodeName();
 311  0
         if ("true".equals(nodeName)) return Boolean.TRUE;
 312  0
         if ("false".equals(nodeName)) return Boolean.FALSE;
 313  0
         if ("integer".equals(nodeName)) return new Integer(element.getNodeValue());
 314  0
         if ("float".equals(nodeName)) return new Float(element.getNodeValue());
 315  0
         if ("long".equals(nodeName)) return new Long(element.getNodeValue());
 316  0
         if ("double".equals(nodeName)) return new Double(element.getNodeValue());
 317  0
         if ("string".equals(nodeName)) return getNodeSubText(element);
 318  0
         if ("map".equals(nodeName)) {
 319  0
             HashMap<String, Object> value = new HashMap<String, Object>();
 320  0
             Node ptr = element.getFirstChild();
 321  0
             while (ptr != null) {
 322  0
                 ptr = ptr.getNextSibling();
 323  0
                 if (!(ptr instanceof Element)) continue;
 324  0
                 if (ptr.getNodeName().equals("entry")) {
 325  0
                     Element subE = (Element) ptr;
 326  0
                     String key = subE.getAttribute("key");
 327  0
                     value.put(key, parse(getFirstElement(ptr)));
 328  0
                 }
 329  
             }
 330  0
             return value;
 331  
         }
 332  0
         if ("list".equals(nodeName)) {
 333  0
             LinkedList<Object> value = new LinkedList<Object> ();
 334  0
             Node ptr = element.getFirstChild();
 335  0
             while (ptr != null) {
 336  0
                 ptr = ptr.getNextSibling();
 337  0
                 if (!(ptr instanceof Element)) continue;
 338  0
                 value.add(parse((Element) ptr));
 339  
             }
 340  0
             return value;
 341  
         }
 342  0
         throw new IllegalArgumentException("unknown element: " + element);
 343  
     }
 344  
 
 345  0
     public interface NodeProcessor {
 346  
         void process(Node node);
 347  
     }
 348  
 }
 349