-package org.simantics.scl.data.xml;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.io.StringReader;\r
-import java.io.StringWriter;\r
-import java.net.URL;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.LinkedHashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.jdom2.Document;\r
-import org.jdom2.Element;\r
-import org.jdom2.IllegalAddException;\r
-import org.jdom2.JDOMException;\r
-import org.jdom2.Namespace;\r
-import org.jdom2.filter.Filters;\r
-import org.jdom2.input.SAXBuilder;\r
-import org.jdom2.input.sax.XMLReaderJDOMFactory;\r
-import org.jdom2.input.sax.XMLReaderXSDFactory;\r
-import org.jdom2.output.Format;\r
-import org.jdom2.output.XMLOutputter;\r
-import org.jdom2.xpath.XPathExpression;\r
-import org.jdom2.xpath.XPathFactory;\r
-import org.simantics.scl.runtime.function.Function;\r
-import org.simantics.scl.runtime.function.FunctionImpl1;\r
-import org.simantics.scl.runtime.reporting.SCLReporting;\r
-\r
-public class JDomHelper {\r
- private static final SAXBuilder BUILDER = new SAXBuilder();\r
- private static final XMLOutputter OUTPUTTER = new XMLOutputter(Format.getPrettyFormat());\r
- private static final XPathFactory XPATH_FACTORY = XPathFactory.instance(); \r
- \r
- private static final int XPATH_CACHE_MAX = 50;\r
- \r
- private static final Map<String,XPathExpression<Element>> XPATH_CACHE = Collections.synchronizedMap(\r
- new LinkedHashMap<String,XPathExpression<Element>>(XPATH_CACHE_MAX) {\r
- private static final long serialVersionUID = 2546245625L;\r
- \r
- @Override\r
- protected boolean removeEldestEntry(Map.Entry<String,XPathExpression<Element>> eldest) {\r
- return size() > XPATH_CACHE_MAX;\r
- }\r
- });\r
-\r
- public static Document parseString(String xmlDocument) throws JDOMException, IOException {\r
- return BUILDER.build(new StringReader(xmlDocument));\r
- }\r
- \r
- public static Document parseFile(String xmlFileName) throws JDOMException, IOException {\r
- return BUILDER.build(new File(xmlFileName));\r
- }\r
- \r
- public static String outputString(Document document) throws IOException {\r
- StringWriter writer = new StringWriter();\r
- OUTPUTTER.output(document, writer);\r
- return writer.toString();\r
- }\r
- \r
- private static XPathExpression<Element> getXPathExpression(String xPathText) {\r
- XPathExpression<Element> expression = XPATH_CACHE.get(xPathText);\r
- if(expression == null) {\r
- expression = XPATH_FACTORY.compile(xPathText, Filters.element());\r
- XPATH_CACHE.put(xPathText, expression);\r
- }\r
- return expression;\r
- }\r
- \r
- public static List<Element> elementsByXPath(Element element, String xPathText) {\r
- XPathExpression<Element> expr = getXPathExpression(xPathText);\r
- return expr.evaluate(element);\r
- }\r
- \r
- public static void addNamedChild(Element parent, String name, Element child) {\r
- child.setName(name);\r
- try {\r
- parent.addContent(child);\r
- } catch(IllegalAddException e) {\r
- SCLReporting.printError("Failed to set the parent of an element " + name + ":");\r
- SCLReporting.printError(" " + e.getMessage());\r
- }\r
- }\r
- \r
- public static void setNamespace(Document document, String namespace) {\r
- setElementNamespace(document.getRootElement(), namespace);\r
- }\r
- \r
- public static void setElementNamespace(Element element, String namespace) {\r
- Namespace ns = Namespace.getNamespace(namespace);\r
- setNamespaceRecursively(element, ns);\r
- } \r
-\r
- private static void setNamespaceRecursively(Element element, Namespace ns) {\r
- element.setNamespace(ns);\r
- for(Element child : element.getChildren())\r
- if(child.getNamespace() == Namespace.NO_NAMESPACE)\r
- setNamespaceRecursively(child, ns);\r
- }\r
- \r
- public static void clearNamespace(Document document) {\r
- clearElementNamespace(document.getRootElement());\r
- }\r
- \r
- public static void clearElementNamespace(Element element) {\r
- element.setNamespace(null);\r
- for (Element child : element.getChildren())\r
- clearElementNamespace(child);\r
- }\r
- \r
- public static Function parseStringWithSchemaFile(String xsdFile) throws JDOMException {\r
- XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(new File(xsdFile));\r
- SAXBuilder builder = new SAXBuilder(factory);\r
- return parseStringWithBuilder(builder);\r
- }\r
- \r
- public static Function parseStringWithSchemaURL(URL xsd) throws JDOMException {\r
- XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(xsd);\r
- SAXBuilder builder = new SAXBuilder(factory);\r
- return parseStringWithBuilder(builder);\r
- }\r
- \r
- public static Function parseFileWithSchemaFile(String xsdFile) throws JDOMException {\r
- XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(new File(xsdFile));\r
- SAXBuilder builder = new SAXBuilder(factory);\r
- return parseFileWithBuilder(builder);\r
- }\r
- \r
- public static Function parseFileWithSchemaURL(URL xsd) throws JDOMException {\r
- XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(xsd);\r
- SAXBuilder builder = new SAXBuilder(factory);\r
- return parseFileWithBuilder(builder);\r
- }\r
- \r
- private static Function parseStringWithBuilder(final SAXBuilder builder) {\r
- return new FunctionImpl1<String, Document>() {\r
- @Override\r
- public Document apply(String xml) {\r
- try {\r
- return builder.build(new StringReader(xml));\r
- }\r
- catch (JDOMException | IOException e) {\r
- throw new RuntimeException(e);\r
- }\r
- };\r
- };\r
- }\r
- \r
- private static Function parseFileWithBuilder(final SAXBuilder builder) {\r
- return new FunctionImpl1<String, Document>() {\r
- @Override\r
- public Document apply(String xml) {\r
- try {\r
- return builder.build(new File(xml));\r
- }\r
- catch (JDOMException | IOException e) {\r
- throw new RuntimeException(e);\r
- }\r
- };\r
- };\r
- }\r
- \r
- public static void sortChildrenWith(final Function comparator, Element element) {\r
- element.sortChildren(new Comparator() {\r
- @Override\r
- public int compare(Object o1, Object o2) {\r
- return (Integer)comparator.apply(o1, o2);\r
- }\r
- });\r
- }\r
-}\r
+package org.simantics.scl.data.xml;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import org.jdom2.CDATA;
+import org.jdom2.Content;
+import org.jdom2.Content.CType;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.IllegalAddException;
+import org.jdom2.JDOMException;
+import org.jdom2.Namespace;
+import org.jdom2.filter.Filters;
+import org.jdom2.input.SAXBuilder;
+import org.jdom2.input.sax.XMLReaderJDOMFactory;
+import org.jdom2.input.sax.XMLReaderXSDFactory;
+import org.jdom2.output.Format;
+import org.jdom2.output.XMLOutputter;
+import org.jdom2.xpath.XPathExpression;
+import org.jdom2.xpath.XPathFactory;
+import org.simantics.scl.runtime.function.Function;
+import org.simantics.scl.runtime.function.FunctionImpl1;
+import org.simantics.scl.runtime.reporting.SCLReporting;
+
+public class JDomHelper {
+ private static final SAXBuilder BUILDER = new SAXBuilder();
+ private static final XMLOutputter OUTPUTTER = new XMLOutputter(Format.getPrettyFormat());
+ private static final XPathFactory XPATH_FACTORY = XPathFactory.instance();
+
+ private static final int XPATH_CACHE_MAX = 50;
+
+ private static final Map<String,XPathExpression<Element>> XPATH_CACHE = Collections.synchronizedMap(
+ new LinkedHashMap<String,XPathExpression<Element>>(XPATH_CACHE_MAX) {
+ private static final long serialVersionUID = 2546245625L;
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<String,XPathExpression<Element>> eldest) {
+ return size() > XPATH_CACHE_MAX;
+ }
+ });
+
+ public static Document parseString(String xmlDocument) throws JDOMException, IOException {
+ return BUILDER.build(new StringReader(xmlDocument));
+ }
+
+ public static Document parseFile(String xmlFileName) throws JDOMException, IOException {
+ return BUILDER.build(new File(xmlFileName));
+ }
+
+ public static String outputString(Document document) throws IOException {
+ StringWriter writer = new StringWriter();
+ OUTPUTTER.output(document, writer);
+ return writer.toString();
+ }
+
+ private static XPathExpression<Element> getXPathExpression(String xPathText) {
+ XPathExpression<Element> expression = XPATH_CACHE.get(xPathText);
+ if(expression == null) {
+ expression = XPATH_FACTORY.compile(xPathText, Filters.element());
+ XPATH_CACHE.put(xPathText, expression);
+ }
+ return expression;
+ }
+
+ public static List<Element> elementsByXPath(Element element, String xPathText) {
+ XPathExpression<Element> expr = getXPathExpression(xPathText);
+ return expr.evaluate(element);
+ }
+
+ public static void addNamedChild(Element parent, String name, Element child) {
+ child.setName(name);
+ try {
+ parent.addContent(child);
+ } catch(IllegalAddException e) {
+ SCLReporting.printError("Failed to set the parent of an element " + name + ":");
+ SCLReporting.printError(" " + e.getMessage());
+ }
+ }
+
+ public static void setNamespace(Document document, String namespace) {
+ setElementNamespace(document.getRootElement(), namespace);
+ }
+
+ public static void setElementNamespace(Element element, String namespace) {
+ Namespace ns = Namespace.getNamespace(namespace);
+ setNamespaceRecursively(element, ns);
+ }
+
+ private static void setNamespaceRecursively(Element element, Namespace ns) {
+ element.setNamespace(ns);
+ for(Element child : element.getChildren())
+ if(child.getNamespace() == Namespace.NO_NAMESPACE)
+ setNamespaceRecursively(child, ns);
+ }
+
+ public static void clearNamespace(Document document) {
+ clearElementNamespace(document.getRootElement());
+ }
+
+ public static void clearElementNamespace(Element element) {
+ element.setNamespace(null);
+ for (Element child : element.getChildren())
+ clearElementNamespace(child);
+ }
+
+ public static Function parseStringWithSchemaFile(String xsdFile) throws JDOMException {
+ XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(new File(xsdFile));
+ SAXBuilder builder = new SAXBuilder(factory);
+ return parseStringWithBuilder(builder);
+ }
+
+ public static Function parseStringWithSchemaURL(URL xsd) throws JDOMException {
+ XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(xsd);
+ SAXBuilder builder = new SAXBuilder(factory);
+ return parseStringWithBuilder(builder);
+ }
+
+ public static Function parseFileWithSchemaFile(String xsdFile) throws JDOMException {
+ XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(new File(xsdFile));
+ SAXBuilder builder = new SAXBuilder(factory);
+ return parseFileWithBuilder(builder);
+ }
+
+ public static Function parseFileWithSchemaURL(URL xsd) throws JDOMException {
+ XMLReaderJDOMFactory factory = new XMLReaderXSDFactory(xsd);
+ SAXBuilder builder = new SAXBuilder(factory);
+ return parseFileWithBuilder(builder);
+ }
+
+ private static Function parseStringWithBuilder(final SAXBuilder builder) {
+ return new FunctionImpl1<String, Document>() {
+ @Override
+ public Document apply(String xml) {
+ try {
+ return builder.build(new StringReader(xml));
+ }
+ catch (JDOMException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ };
+ };
+ }
+
+ private static Function parseFileWithBuilder(final SAXBuilder builder) {
+ return new FunctionImpl1<String, Document>() {
+ @Override
+ public Document apply(String xml) {
+ try {
+ return builder.build(new File(xml));
+ }
+ catch (JDOMException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ };
+ };
+ }
+
+ public static void sortChildrenWith(final Function comparator, Element element) {
+ element.sortChildren(new Comparator() {
+ @Override
+ public int compare(Object o1, Object o2) {
+ return (Integer)comparator.apply(o1, o2);
+ }
+ });
+ }
+
+ public static void addCDATA(Element element, String cdata) {
+ element.addContent(new CDATA(cdata));
+ }
+
+ public static List<String> getCDATAs(Element element) {
+ ArrayList<String> result = new ArrayList<>();
+ for(Content c : element.getContent()) {
+ if(CType.CDATA.equals(c.getCType())) result.add(c.getValue());
+ }
+ return result;
+ }
+
+}