All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.crabshue.commons.xml.XmlPrintUtils Maven / Gradle / Ivy

package com.crabshue.commons.xml;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;

import com.crabshue.commons.exceptions.SystemException;
import com.crabshue.commons.xml.exceptions.XmlErrorType;
import com.crabshue.commons.xml.inputsource.InputSourceBuilder;
import com.crabshue.commons.xml.processinginstructions.ProcessingInstructionsConstants;

/**
 * Utility class for printing XML documents.
 *
 */
public class XmlPrintUtils {

    /**
     * Converts a DOM document, into a set of string lines, preserving or not the XML declaration processing instruction.
     *
     * @param doc the source document to convert
     * @return the string collection representation of a document.
     */
    public static Collection stringify(final Document doc) {
        return stringify(doc, Options.defaultOptions());
    }

    /**
     * Converts a DOM document, into a set of string lines, preserving or not the XML declaration processing instruction.
     *
     * @param doc     the source document to convert
     * @param options
     * @return the string collection representation of a document.
     */
    public static Collection stringify(final Document doc, final XmlPrintUtils.Options options) {
        StringWriter sw = new StringWriter();

        try {
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer = tf.newTransformer();
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, options.isOmitXmlDeclaration() ? "yes" : "no");
            transformer.setOutputProperty(OutputKeys.METHOD, options.getOutputMethod());
            transformer.setOutputProperty(OutputKeys.INDENT, options.isIndent() ? "yes" : "no");
            transformer.setOutputProperty(OutputKeys.ENCODING, options.getEncoding());
            transformer.transform(new DOMSource(doc), new StreamResult(sw));
        } catch (Exception ex) {
            throw new SystemException(XmlErrorType.ERROR_MODIFYING_XML, "Error converting to String", ex);
        }

        Collection lines = Arrays.asList(StringUtils.split(sw.toString(), "\n"));
        return XmlPrintUtils.isolateProcessingInstructions(lines);
    }

    /**
     * Prettify a collection of {@link String lines} (representing an XML).
     *
     * @param lines the collection of lines.
     * @return the prettified lines.
     */
    public static Collection prettyPrint(final Collection lines) {
        Collection ret;
        final Document document = XmlDocumentBuilder.of(InputSourceBuilder.newInputSource(lines)).build();

        ret = XmlPrintUtils.stringify(document, new Options().omitXmlDeclaration(false));
        ret = isolateProcessingInstructions(ret);
        return ret;
    }

    /**
     * Modify a set of {@link String lines}, to put the xml processing instructions on individual lines.
     *
     * @param lines the lines.
     * @return the prettified lines.
     */
    public static Collection isolateProcessingInstructions(final Collection lines) {
        Collection ret = new ArrayList<>();

        Pattern pattern = Pattern.compile(ProcessingInstructionsConstants.PROCESSING_INSTRUCTION_REGEXP);
        for (String line : lines) {
            Matcher matcher = pattern.matcher(line);
            if (matcher.find()) {
                String s = line.replaceAll(ProcessingInstructionsConstants.PROCESSING_INSTRUCTION_REGEXP, "\n$0\n");
                ret.addAll(Arrays.asList(StringUtils.split(s, "\n")));
            } else {
                ret.add(line);
            }

        }
        return ret;
    }

    /**
     * Stringify options
     */
    public static class Options {

        private boolean omitXmlDeclaration = false;
        private String outputMethod = "xml";
        private String encoding = "UTF-8";
        private boolean indent = true;

        public static Options defaultOptions() {
            return new Options();
        }

        public boolean isOmitXmlDeclaration() {
            return omitXmlDeclaration;
        }

        public Options omitXmlDeclaration(final boolean omitXmlDeclaration) {
            this.omitXmlDeclaration = omitXmlDeclaration;
            return this;
        }

        public String getOutputMethod() {
            return outputMethod;
        }

        public Options outputMethod(final String outputMethod) {
            this.outputMethod = outputMethod;
            return this;
        }

        public String getEncoding() {
            return encoding;
        }

        public Options encoding(final String encoding) {
            this.encoding = encoding;
            return this;
        }

        public boolean isIndent() {
            return indent;
        }

        public Options indent(final boolean indent) {
            this.indent = indent;
            return this;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy