package ca.uhn.fhir.tinder.util;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.Writer;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMErrorHandler;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSParser;
import org.w3c.dom.ls.LSResourceResolver;
import org.w3c.dom.ls.LSSerializer;
public class XMLUtils {
private static DOMImplementation IMPL;
@SuppressWarnings("unchecked")
public synchronized static <T> T getDOMImpl() {
if (IMPL == null) {
try {
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
IMPL = registry.getDOMImplementation("LS 3.0");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return (T) IMPL;
}
@SuppressWarnings("unchecked")
public static <T> T getDOMImplUncached() {
try {
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
return (T) registry.getDOMImplementation("LS 3.0");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Document parse(String s) {
return parse(s, false);
}
public static Document parse(String s, boolean validateIfSchema) {
DOMImplementationLS impl = getDOMImpl();
LSInput input = impl.createLSInput();
input.setStringData(s);
return parse(input, validateIfSchema);
}
public static Document parse(InputStream s, boolean validateIfSchema) {
DOMImplementationLS impl = getDOMImpl();
LSInput input = impl.createLSInput();
input.setByteStream(s);
return parse(input, validateIfSchema);
}
private static Document parse(LSInput input, boolean validateIfSchema) {
DOMImplementationLS impl = getDOMImpl();
LSParser parser = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
DOMConfiguration config = parser.getDomConfig();
config.setParameter("element-content-whitespace", false);
config.setParameter("namespaces", true);
config.setParameter("validate-if-schema", validateIfSchema);
return parser.parse(input);
}
public static void validate(Document d, String schema, DOMErrorHandler handler) {
DOMConfiguration config = d.getDomConfig();
config.setParameter("schema-type", "http://www.w3.org/2001/XMLSchema");
config.setParameter("validate", true);
config.setParameter("schema-location", schema);
config.setParameter("resource-resolver", new ClasspathResourceResolver());
config.setParameter("error-handler", handler);
d.normalizeDocument();
}
public static String serialize(Document document, boolean prettyPrint) {
DOMImplementationLS impl = getDOMImpl();
LSSerializer serializer = impl.createLSSerializer();
// document.normalizeDocument();
DOMConfiguration config = serializer.getDomConfig();
if (prettyPrint && config.canSetParameter("format-pretty-print", Boolean.TRUE)) {
config.setParameter("format-pretty-print", true);
}
config.setParameter("xml-declaration", true);
LSOutput output = impl.createLSOutput();
output.setEncoding("UTF-8");
Writer writer = new StringWriter();
output.setCharacterStream(writer);
serializer.write(document, output);
return writer.toString();
}
public static Document emptyDocument(String title) {
DOMImplementation impl = getDOMImpl();
Document doc = impl.createDocument("urn:hl7-org:v2xml", title, null);
return doc;
}
/**
* This is an implementation of LSResourceResolver that can resolve XML schemas from the
* classpath
*/
private static class ClasspathResourceResolver implements LSResourceResolver {
private DOMImplementationLS impl;
ClasspathResourceResolver() {
impl = getDOMImpl();
}
public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId,
String baseURI) {
LSInput lsInput = impl.createLSInput();
InputStream is = getClass().getResourceAsStream("/" + systemId);
if (is == null)
return null;
lsInput.setByteStream(is);
return lsInput;
}
}
}