1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package ca.uhn.hl7v2.util;
27
28 import java.io.*;
29
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.w3c.dom.DOMConfiguration;
33 import org.w3c.dom.DOMErrorHandler;
34 import org.w3c.dom.DOMImplementation;
35 import org.w3c.dom.Document;
36 import org.w3c.dom.bootstrap.DOMImplementationRegistry;
37 import org.w3c.dom.ls.DOMImplementationLS;
38 import org.w3c.dom.ls.LSInput;
39 import org.w3c.dom.ls.LSOutput;
40 import org.w3c.dom.ls.LSResourceResolver;
41 import org.w3c.dom.ls.LSSerializer;
42 import org.xml.sax.InputSource;
43 import org.xml.sax.SAXException;
44
45 import javax.xml.parsers.DocumentBuilder;
46 import javax.xml.parsers.DocumentBuilderFactory;
47 import javax.xml.parsers.ParserConfigurationException;
48
49 public class XMLUtils {
50 private static final Logger ourLog = LoggerFactory.getLogger(XMLUtils.class);
51
52 private static DOMImplementation IMPL;
53
54 @SuppressWarnings("unchecked")
55 public synchronized static <T> T getDOMImpl() {
56 if (IMPL == null) {
57 try {
58 DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
59 IMPL = registry.getDOMImplementation("LS 3.0");
60 } catch (Exception e) {
61 throw new RuntimeException(e);
62 }
63 }
64 return (T) IMPL;
65 }
66
67 @SuppressWarnings("unchecked")
68 public static Document parse(String s) {
69 return parseDocument(new InputSource(new StringReader(s)), false);
70 }
71
72 public static Document parse(String s, boolean validateIfSchema) {
73 return parseDocument(new InputSource(new StringReader(s)), validateIfSchema);
74 }
75
76 public static Document parse(InputStream s, boolean validateIfSchema) {
77 return parseDocument(new InputSource(s), validateIfSchema);
78 }
79
80 public static Document parseDocument(InputSource theInputSource, boolean theValidating) {
81 DocumentBuilder builder;
82 try {
83 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
84 docBuilderFactory.setNamespaceAware(true);
85 docBuilderFactory.setXIncludeAware(false);
86 docBuilderFactory.setExpandEntityReferences(false);
87 docBuilderFactory.setValidating(theValidating);
88 try {
89 docBuilderFactory.setFeature(
90 "http://apache.org/xml/features/disallow-doctype-decl", false);
91 docBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
92 docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
93 docBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
94 docBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
95 } catch (Exception e) {
96 ourLog.warn("Failed to set feature on XML parser: " + e.toString());
97 }
98
99 builder = docBuilderFactory.newDocumentBuilder();
100 } catch (ParserConfigurationException e) {
101 throw new RuntimeException(e);
102 }
103
104 try {
105 return builder.parse(theInputSource);
106 } catch (SAXException | IOException e) {
107 throw new RuntimeException(e);
108 }
109 }
110
111
112 public static void validate(Document d, String schema, DOMErrorHandler handler) {
113 DOMConfiguration config = d.getDomConfig();
114 config.setParameter("schema-type", "http://www.w3.org/2001/XMLSchema");
115 config.setParameter("validate", true);
116 config.setParameter("schema-location", schema);
117 config.setParameter("resource-resolver", new ClasspathResourceResolver());
118 config.setParameter("error-handler", handler);
119 d.normalizeDocument();
120 }
121
122 public static String serialize(Document document, boolean prettyPrint) {
123 DOMImplementationLS impl = getDOMImpl();
124 LSSerializer serializer = impl.createLSSerializer();
125
126 DOMConfiguration config = serializer.getDomConfig();
127 if (prettyPrint && config.canSetParameter("format-pretty-print", Boolean.TRUE)) {
128 config.setParameter("format-pretty-print", true);
129 }
130 config.setParameter("xml-declaration", true);
131 LSOutput output = impl.createLSOutput();
132 output.setEncoding("UTF-8");
133 Writer writer = new StringWriter();
134 output.setCharacterStream(writer);
135 serializer.write(document, output);
136 return writer.toString();
137 }
138
139 public static Document emptyDocument(String title) {
140 DOMImplementation impl = getDOMImpl();
141 return impl.createDocument("urn:hl7-org:v2xml", title, null);
142 }
143
144
145
146
147
148 private static class ClasspathResourceResolver implements LSResourceResolver {
149 private final DOMImplementationLS impl;
150
151 ClasspathResourceResolver() {
152 impl = getDOMImpl();
153 }
154
155 public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId,
156 String baseURI) {
157 LSInput lsInput = impl.createLSInput();
158 InputStream is = getClass().getResourceAsStream("/" + systemId);
159 if (is == null)
160 return null;
161 lsInput.setByteStream(is);
162 return lsInput;
163 }
164 }
165
166 }