]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.data/src/org/simantics/scl/data/xml/JDomHelper.java
897af542a055c6f03f9d87a0439ac78a31c3b2d3
[simantics/platform.git] / bundles / org.simantics.scl.data / src / org / simantics / scl / data / xml / JDomHelper.java
1 package org.simantics.scl.data.xml;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.StringReader;
6 import java.io.StringWriter;
7 import java.net.URL;
8 import java.util.Collections;
9 import java.util.Comparator;
10 import java.util.LinkedHashMap;
11 import java.util.List;
12 import java.util.Map;
13
14 import org.jdom2.Document;
15 import org.jdom2.Element;
16 import org.jdom2.IllegalAddException;
17 import org.jdom2.JDOMException;
18 import org.jdom2.Namespace;
19 import org.jdom2.filter.Filters;
20 import org.jdom2.input.SAXBuilder;
21 import org.jdom2.input.sax.XMLReaderJDOMFactory;
22 import org.jdom2.input.sax.XMLReaderXSDFactory;
23 import org.jdom2.output.Format;
24 import org.jdom2.output.XMLOutputter;
25 import org.jdom2.xpath.XPathExpression;
26 import org.jdom2.xpath.XPathFactory;
27 import org.simantics.scl.runtime.function.Function;
28 import org.simantics.scl.runtime.function.FunctionImpl1;
29 import org.simantics.scl.runtime.reporting.SCLReporting;
30
31 public class JDomHelper {
32     private static final SAXBuilder BUILDER = new SAXBuilder();
33     private static final XMLOutputter OUTPUTTER = new XMLOutputter(Format.getPrettyFormat());
34     private static final XPathFactory XPATH_FACTORY = XPathFactory.instance(); 
35     
36     private static final int XPATH_CACHE_MAX = 50;
37     
38     private static final Map<String,XPathExpression<Element>> XPATH_CACHE = Collections.synchronizedMap(
39             new LinkedHashMap<String,XPathExpression<Element>>(XPATH_CACHE_MAX) {
40                 private static final long serialVersionUID = 2546245625L;
41      
42                 @Override
43                 protected boolean removeEldestEntry(Map.Entry<String,XPathExpression<Element>> eldest) {
44                     return size() > XPATH_CACHE_MAX;
45                 }
46             });
47
48     public static Document parseString(String xmlDocument) throws JDOMException, IOException {
49         return BUILDER.build(new StringReader(xmlDocument));
50     }
51     
52     public static Document parseFile(String xmlFileName) throws JDOMException, IOException {
53         return BUILDER.build(new File(xmlFileName));
54     }
55     
56     public static String outputString(Document document) throws IOException {
57         StringWriter writer = new StringWriter();
58         OUTPUTTER.output(document, writer);
59         return writer.toString();
60     }
61     
62     private static XPathExpression<Element> getXPathExpression(String xPathText) {
63         XPathExpression<Element> expression = XPATH_CACHE.get(xPathText);
64         if(expression == null) {
65             expression = XPATH_FACTORY.compile(xPathText, Filters.element());
66             XPATH_CACHE.put(xPathText, expression);
67         }
68         return expression;
69     }
70     
71     public static List<Element> elementsByXPath(Element element, String xPathText) {
72         XPathExpression<Element> expr = getXPathExpression(xPathText);
73         return expr.evaluate(element);
74     }
75     
76     public static void addNamedChild(Element parent, String name, Element child) {
77         child.setName(name);
78         try {
79             parent.addContent(child);
80         } catch(IllegalAddException e) {
81             SCLReporting.printError("Failed to set the parent of an element " + name + ":");
82             SCLReporting.printError("    " + e.getMessage());
83         }
84     }
85     
86     public static void setNamespace(Document document, String namespace) {
87         setElementNamespace(document.getRootElement(), namespace);
88     }
89     
90     public static void setElementNamespace(Element element, String namespace) {
91         Namespace ns = Namespace.getNamespace(namespace);
92         setNamespaceRecursively(element, ns);
93     }   
94
95         private static void setNamespaceRecursively(Element element, Namespace ns) {
96                 element.setNamespace(ns);
97                 for(Element child : element.getChildren())
98                         if(child.getNamespace() == Namespace.NO_NAMESPACE)
99                                 setNamespaceRecursively(child, ns);
100         }
101         
102         public static void clearNamespace(Document document) {
103                 clearElementNamespace(document.getRootElement());
104         }
105         
106         public static void clearElementNamespace(Element element) {
107                 element.setNamespace(null);
108                 for (Element child : element.getChildren())
109                         clearElementNamespace(child);
110         }
111         
112         public static Function parseStringWithSchemaFile(String xsdFile) throws JDOMException {
113                 XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(new File(xsdFile));
114                 SAXBuilder builder = new SAXBuilder(factory);
115                 return parseStringWithBuilder(builder);
116         }
117         
118         public static Function parseStringWithSchemaURL(URL xsd) throws JDOMException {
119                 XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(xsd);
120                 SAXBuilder builder = new SAXBuilder(factory);
121                 return parseStringWithBuilder(builder);
122         }
123         
124         public static Function parseFileWithSchemaFile(String xsdFile) throws JDOMException {
125                 XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(new File(xsdFile));
126                 SAXBuilder builder = new SAXBuilder(factory);
127                 return parseFileWithBuilder(builder);
128         }
129         
130         public static Function parseFileWithSchemaURL(URL xsd) throws JDOMException {
131                 XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(xsd);
132                 SAXBuilder builder = new SAXBuilder(factory);
133                 return parseFileWithBuilder(builder);
134         }
135         
136         private static Function parseStringWithBuilder(final SAXBuilder builder) {
137                 return new FunctionImpl1<String, Document>() {
138                         @Override
139                         public Document apply(String xml) {
140                                 try {
141                                         return builder.build(new StringReader(xml));
142                                 }
143                                 catch (JDOMException | IOException e) {
144                                         throw new RuntimeException(e);
145                                 }
146                         };
147                 };
148         }
149         
150         private static Function parseFileWithBuilder(final SAXBuilder builder) {
151                 return new FunctionImpl1<String, Document>() {
152                         @Override
153                         public Document apply(String xml) {
154                                 try {
155                                         return builder.build(new File(xml));
156                                 }
157                                 catch (JDOMException | IOException e) {
158                                         throw new RuntimeException(e);
159                                 }
160                         };
161                 };
162         }
163         
164         public static void sortChildrenWith(final Function comparator, Element element) {
165             element.sortChildren(new Comparator() {
166             @Override
167             public int compare(Object o1, Object o2) {
168                 return (Integer)comparator.apply(o1, o2);
169             }
170             });
171         }
172 }