|
@@ -0,0 +1,250 @@
|
|
|
+package org.maxkey.pretty.impl;
|
|
|
+
|
|
|
+import java.io.OutputStream;
|
|
|
+import java.io.StringReader;
|
|
|
+import java.io.StringWriter;
|
|
|
+import java.io.Writer;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import javax.xml.parsers.DocumentBuilder;
|
|
|
+import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
+import javax.xml.transform.OutputKeys;
|
|
|
+import javax.xml.transform.Transformer;
|
|
|
+import javax.xml.transform.TransformerConfigurationException;
|
|
|
+import javax.xml.transform.TransformerException;
|
|
|
+import javax.xml.transform.TransformerFactory;
|
|
|
+import javax.xml.transform.dom.DOMSource;
|
|
|
+import javax.xml.transform.stream.StreamResult;
|
|
|
+
|
|
|
+import org.w3c.dom.DOMConfiguration;
|
|
|
+import org.w3c.dom.DOMImplementation;
|
|
|
+import org.w3c.dom.Document;
|
|
|
+import org.w3c.dom.Element;
|
|
|
+import org.w3c.dom.Node;
|
|
|
+import org.w3c.dom.ls.DOMImplementationLS;
|
|
|
+import org.w3c.dom.ls.LSOutput;
|
|
|
+import org.w3c.dom.ls.LSSerializer;
|
|
|
+import org.w3c.dom.ls.LSSerializerFilter;
|
|
|
+import org.xml.sax.InputSource;
|
|
|
+
|
|
|
+import net.shibboleth.utilities.java.support.collection.LazyMap;
|
|
|
+
|
|
|
+public class XMLHelper {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * A string which contains the valid delimiters for the XML Schema 'list' type. These are: space, newline, carriage
|
|
|
+ * return, and tab.
|
|
|
+ */
|
|
|
+ public static final String LIST_DELIMITERS = " \n\r\t";
|
|
|
+
|
|
|
+ /** DOM configuration parameters used by LSSerializer in pretty print format output. */
|
|
|
+ private static Map<String, Object> prettyPrintParams;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Converts a Node into a String using the DOM, level 3, Load/Save serializer.
|
|
|
+ *
|
|
|
+ * @param node the node to be written to a string
|
|
|
+ *
|
|
|
+ * @return the string representation of the node
|
|
|
+ */
|
|
|
+ public static String nodeToString(Node node) {
|
|
|
+ StringWriter writer = new StringWriter();
|
|
|
+ writeNode(node, writer);
|
|
|
+ return writer.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Pretty prints the XML node.
|
|
|
+ *
|
|
|
+ * @param node xml node to print
|
|
|
+ *
|
|
|
+ * @return pretty-printed xml
|
|
|
+ */
|
|
|
+ public static String prettyPrintXML(Node node) {
|
|
|
+ StringWriter writer = new StringWriter();
|
|
|
+ writeNode(node, writer, getPrettyPrintParams());
|
|
|
+ return writer.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String prettyPrintXML(String xmlString){
|
|
|
+ try{
|
|
|
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
|
|
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
|
|
+ Document document = documentBuilder.parse(new InputSource(new StringReader(xmlString)));
|
|
|
+ return prettyPrintXML(document);
|
|
|
+ }catch(Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Create the parameters set used in pretty print formatting of an LSSerializer.
|
|
|
+ *
|
|
|
+ * @return the params map
|
|
|
+ */
|
|
|
+ private static Map<String, Object> getPrettyPrintParams() {
|
|
|
+ if (prettyPrintParams == null) {
|
|
|
+ prettyPrintParams = new LazyMap<String, Object>();
|
|
|
+ prettyPrintParams.put("format-pretty-print", Boolean.TRUE);
|
|
|
+ }
|
|
|
+ return prettyPrintParams;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Writes a Node out to a Writer using the DOM, level 3, Load/Save serializer. The written content is encoded using
|
|
|
+ * the encoding specified in the writer configuration.
|
|
|
+ *
|
|
|
+ * @param node the node to write out
|
|
|
+ * @param output the writer to write the XML to
|
|
|
+ */
|
|
|
+ public static void writeNode(Node node, Writer output) {
|
|
|
+ writeNode(node, output, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Writes a Node out to a Writer using the DOM, level 3, Load/Save serializer. The written content is encoded using
|
|
|
+ * the encoding specified in the writer configuration.
|
|
|
+ *
|
|
|
+ * @param node the node to write out
|
|
|
+ * @param output the writer to write the XML to
|
|
|
+ * @param serializerParams parameters to pass to the {@link DOMConfiguration} of the serializer
|
|
|
+ * instance, obtained via {@link LSSerializer#getDomConfig()}. May be null.
|
|
|
+ */
|
|
|
+ public static void writeNode(Node node, Writer output, Map<String, Object> serializerParams) {
|
|
|
+ DOMImplementationLS domImplLS = getLSDOMImpl(node);
|
|
|
+
|
|
|
+ LSSerializer serializer = getLSSerializer(domImplLS, serializerParams);
|
|
|
+
|
|
|
+ LSOutput serializerOut = domImplLS.createLSOutput();
|
|
|
+ serializerOut.setCharacterStream(output);
|
|
|
+
|
|
|
+ serializer.write(node, serializerOut);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Writes a Node out to an OutputStream using the DOM, level 3, Load/Save serializer. The written content
|
|
|
+ * is encoded using the encoding specified in the output stream configuration.
|
|
|
+ *
|
|
|
+ * @param node the node to write out
|
|
|
+ * @param output the output stream to write the XML to
|
|
|
+ */
|
|
|
+ public static void writeNode(Node node, OutputStream output) {
|
|
|
+ writeNode(node, output, null);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Writes a Node out to an OutputStream using the DOM, level 3, Load/Save serializer. The written content
|
|
|
+ * is encoded using the encoding specified in the output stream configuration.
|
|
|
+ *
|
|
|
+ * @param node the node to write out
|
|
|
+ * @param output the output stream to write the XML to
|
|
|
+ * @param serializerParams parameters to pass to the {@link DOMConfiguration} of the serializer
|
|
|
+ * instance, obtained via {@link LSSerializer#getDomConfig()}. May be null.
|
|
|
+ */
|
|
|
+ public static void writeNode(Node node, OutputStream output, Map<String, Object> serializerParams) {
|
|
|
+ DOMImplementationLS domImplLS = getLSDOMImpl(node);
|
|
|
+
|
|
|
+ LSSerializer serializer = getLSSerializer(domImplLS, serializerParams);
|
|
|
+
|
|
|
+ LSOutput serializerOut = domImplLS.createLSOutput();
|
|
|
+ serializerOut.setByteStream(output);
|
|
|
+
|
|
|
+ serializer.write(node, serializerOut);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Obtain a the DOM, level 3, Load/Save serializer {@link LSSerializer} instance from the
|
|
|
+ * given {@link DOMImplementationLS} instance.
|
|
|
+ *
|
|
|
+ * <p>
|
|
|
+ * The serializer instance will be configured with the parameters passed as the <code>serializerParams</code>
|
|
|
+ * argument. It will also be configured with an {@link LSSerializerFilter} that shows all nodes to the filter,
|
|
|
+ * and accepts all nodes shown.
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param domImplLS the DOM Level 3 Load/Save implementation to use
|
|
|
+ * @param serializerParams parameters to pass to the {@link DOMConfiguration} of the serializer
|
|
|
+ * instance, obtained via {@link LSSerializer#getDomConfig()}. May be null.
|
|
|
+ *
|
|
|
+ * @return a new LSSerializer instance
|
|
|
+ */
|
|
|
+ public static LSSerializer getLSSerializer(DOMImplementationLS domImplLS, Map<String, Object> serializerParams) {
|
|
|
+ LSSerializer serializer = domImplLS.createLSSerializer();
|
|
|
+
|
|
|
+ serializer.setFilter(new LSSerializerFilter() {
|
|
|
+
|
|
|
+ public short acceptNode(Node arg0) {
|
|
|
+ return FILTER_ACCEPT;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getWhatToShow() {
|
|
|
+ return SHOW_ALL;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ if (serializerParams != null) {
|
|
|
+ DOMConfiguration serializerDOMConfig = serializer.getDomConfig();
|
|
|
+ for (String key : serializerParams.keySet()) {
|
|
|
+ serializerDOMConfig.setParameter(key, serializerParams.get(key));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return serializer;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get the DOM Level 3 Load/Save {@link DOMImplementationLS} for the given node.
|
|
|
+ *
|
|
|
+ * @param node the node to evaluate
|
|
|
+ * @return the DOMImplementationLS for the given node
|
|
|
+ */
|
|
|
+ public static DOMImplementationLS getLSDOMImpl(Node node) {
|
|
|
+ DOMImplementation domImpl;
|
|
|
+ if (node instanceof Document) {
|
|
|
+ domImpl = ((Document) node).getImplementation();
|
|
|
+ } else {
|
|
|
+ domImpl = node.getOwnerDocument().getImplementation();
|
|
|
+ }
|
|
|
+
|
|
|
+ DOMImplementationLS domImplLS = (DOMImplementationLS) domImpl.getFeature("LS", "3.0");
|
|
|
+ return domImplLS;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String transformer(Element element) {
|
|
|
+
|
|
|
+ String xmlString = null;
|
|
|
+ try {
|
|
|
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
|
|
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
|
|
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
|
|
|
+ StreamResult result = new StreamResult(new StringWriter());
|
|
|
+ DOMSource source = new DOMSource(element);
|
|
|
+
|
|
|
+ transformer.transform(source, result);
|
|
|
+ xmlString = result.getWriter().toString();
|
|
|
+
|
|
|
+ } catch (TransformerConfigurationException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (TransformerException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return xmlString;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String transformer(String xmlString){
|
|
|
+ try{
|
|
|
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
|
|
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
|
|
+ Document document = documentBuilder.parse(new InputSource(new StringReader(xmlString)));
|
|
|
+ return transformer(document.getDocumentElement());
|
|
|
+ }catch(Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|