com.dslplatform.json.XmlConverter Maven / Gradle / Ivy
package com.dslplatform.json;
import org.w3c.dom.*;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.*;
public abstract class XmlConverter {
static final JsonReader.ReadObject Reader = new JsonReader.ReadObject() {
@Nullable
@Override
public Element read(JsonReader reader) throws IOException {
return reader.wasNull() ? null : deserialize(reader);
}
};
static final JsonWriter.WriteObject Writer = new JsonWriter.WriteObject() {
@Override
public void write(JsonWriter writer, @Nullable Element value) {
serializeNullable(value, writer);
}
};
private static final DocumentBuilder documentBuilder;
static {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
try {
documentBuilder = dbFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
}
}
public static void serializeNullable(@Nullable final Element value, final JsonWriter sw) {
if (value == null)
sw.writeNull();
else
serialize(value, sw);
}
public static void serialize(final Element value, final JsonWriter sw) {
Document document = value.getOwnerDocument();
DOMImplementationLS domImplLS = (DOMImplementationLS) document.getImplementation();
LSSerializer serializer = domImplLS.createLSSerializer();
LSOutput lsOutput = domImplLS.createLSOutput();
lsOutput.setEncoding("UTF-8");
StringWriter writer = new StringWriter();
lsOutput.setCharacterStream(writer);
serializer.write(document, lsOutput);
StringConverter.serialize(writer.toString(), sw);
}
public static Element deserialize(final JsonReader reader) throws IOException {
if (reader.last() == '"') {
try {
InputSource source = new InputSource(new StringReader(reader.readString()));
return documentBuilder.parse(source).getDocumentElement();
} catch (SAXException ex) {
throw reader.newParseErrorAt("Invalid XML value", 0, ex);
}
} else {
final Map map = ObjectConverter.deserializeMap(reader);
return mapToXml(map);
}
}
public static Element mapToXml(final Map map) throws IOException {
final Set xmlRootElementNames = map.keySet();
if (xmlRootElementNames.size() > 1) {
throw ParsingException.create("Invalid XML. Expecting root element", true);
}
final String rootName = xmlRootElementNames.iterator().next();
final Document document = createDocument();
final Element rootElement = document.createElement(rootName);
document.appendChild(rootElement);
buildXmlFromHashMap(document, rootElement, map.get(rootName));
return rootElement;
}
private static synchronized Document createDocument() {
try {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
final DocumentBuilder builder = factory.newDocumentBuilder();
return builder.newDocument();
} catch (ParserConfigurationException e) {
throw new ConfigurationException(e);
}
}
private static final String TEXT_NODE_TAG = "#text";
private static final String COMMENT_NODE_TAG = "#comment";
private static final String CDATA_NODE_TAG = "#cdata-section";
@SuppressWarnings("unchecked")
private static void buildXmlFromHashMap(
final Document doc,
final Element subtreeRootElement,
@Nullable final Object elementContent) {
if (elementContent instanceof HashMap) {
final HashMap elementContentMap = (HashMap) elementContent;
for (final Map.Entry childEntry : elementContentMap.entrySet()) {
final String key = childEntry.getKey();
if (key.startsWith("@")) {
subtreeRootElement.setAttribute(key.substring(1), childEntry.getValue().toString());
} else if (key.startsWith("#")) {
if (key.equals(TEXT_NODE_TAG)) {
if (childEntry.getValue() instanceof List) {
buildTextNodeList(doc, subtreeRootElement, (List) childEntry.getValue());
} else {
final Node textNode = doc.createTextNode(childEntry.getValue().toString());
subtreeRootElement.appendChild(textNode);
}
} else if (key.equals(CDATA_NODE_TAG)) {
if (childEntry.getValue() instanceof List) {
buildCDataList(doc, subtreeRootElement, (List) childEntry.getValue());
} else {
final Node cDataNode = doc.createCDATASection(childEntry.getValue().toString());
subtreeRootElement.appendChild(cDataNode);
}
} else if (key.equals(COMMENT_NODE_TAG)) {
if (childEntry.getValue() instanceof List) {
buildCommentList(doc, subtreeRootElement, (List) childEntry.getValue());
} else {
final Node commentNode = doc.createComment(childEntry.getValue().toString());
subtreeRootElement.appendChild(commentNode);
}
} //else if (key.equals(WHITESPACE_NODE_TAG)
// || key.equals(SIGNIFICANT_WHITESPACE_NODE_TAG)) {
// Ignore
//} else {
/*
* All other nodes whose name starts with a '#' are invalid XML
* nodes, and thus ignored:
*/
//}
} else {
final Element newElement = doc.createElement(key);
subtreeRootElement.appendChild(newElement);
buildXmlFromHashMap(doc, newElement, childEntry.getValue());
}
}
} else if (elementContent instanceof List) {
buildXmlFromJsonArray(doc, subtreeRootElement, (List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy