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