org.automagic.deps.doctor.Utils.java Source code

Java tutorial

Introduction

Here is the source code for org.automagic.deps.doctor.Utils.java

Source

/*
 * Copyright 2015 Jose Carrizo
 * Licensed under the Apache License, Version 2.0 
 * See accompanying file LICENSE or get a copy at http://www.apache.org/licenses/LICENSE-2.0
 */
package org.automagic.deps.doctor;

import static org.apache.commons.lang3.StringUtils.contains;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.maven.artifact.Artifact;
import org.automagic.deps.doctor.editor.PomWriter;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.google.common.base.Optional;

public class Utils {

    private static final ThreadLocal<DocumentBuilder> DOC_BUILDER = new ThreadLocal<>();
    private static final ThreadLocal<XPathFactory> XPATH_FACTORY = new ThreadLocal<>();
    private static final Pattern INDENT_PATTERN = Pattern.compile("[ ](?=[ ]*<)");

    static {
        synchronized (Utils.class) {
            try {
                XPATH_FACTORY.set(XPathFactory.newInstance());
                DOC_BUILDER.set(DocumentBuilderFactory.newInstance().newDocumentBuilder());
            } catch (ParserConfigurationException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static Optional<Node> getDependencyNode(Artifact artifact, Document document, String parent) {

        String xpath = String.format(
                "%s/dependency[./groupId[text()[normalize-space(.) = '%s']] and ./artifactId[text()[normalize-space(.) = '%s']]]",
                parent, artifact.getGroupId(), artifact.getArtifactId());
        return getNode(xpath, document);
    }

    public static Optional<Node> getNode(String xpath, Document document) {
        return getNode(xpath, (Node) document);
    }

    public static Optional<Node> getNode(String xpath, Node parent) {
        try {
            XPath xPath = XPATH_FACTORY.get().newXPath();
            XPathExpression expression = xPath.compile(xpath);
            Node node = (Node) expression.evaluate(parent, XPathConstants.NODE);
            if (node == null) {
                return Optional.absent();
            }
            return Optional.of(node);
        } catch (XPathExpressionException e) {
            throw new RuntimeException(e);
        }
    }

    public static Document getDocument(File file) {
        try (InputStream inputStream = new FileInputStream(file)) {
            Document document = DOC_BUILDER.get().parse(inputStream);
            return document;
        } catch (SAXException | IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Node prettyFormat(Node node, int indentSize, boolean indentWithTabs) {

        if (indentSize < 1) {
            throw new IllegalArgumentException("Indentation size must be greater or equal to 1");
        }

        try {
            Source xmlInput = new DOMSource(node);

            StringWriter stringWriter = new StringWriter();
            StreamResult xmlOutput = new StreamResult(stringWriter);

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            transformerFactory.setAttribute("indent-number", indentSize);
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.transform(xmlInput, xmlOutput);

            String result = xmlOutput.getWriter().toString();

            if (indentWithTabs) {
                StringBuilder sb = new StringBuilder(result);
                Matcher matcher = INDENT_PATTERN.matcher(result);
                while (matcher.find()) {
                    sb.setCharAt(matcher.start(), '\t');
                }
                result = sb.toString();
            }

            Document parse = DOC_BUILDER.get().parse(new ByteArrayInputStream(result.getBytes()));
            Node importNode = node.getOwnerDocument().importNode(parse.getDocumentElement(), true);

            return importNode;

        } catch (TransformerException | SAXException | IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Optional<Node> getPluginComment(String parent, Artifact artifact, Document document) {

        Optional<Node> dependencyNode = getDependencyNode(artifact, document, parent);

        if (!dependencyNode.isPresent()) {
            return Optional.absent();
        }

        if (dependencyNode.get().hasChildNodes()) {
            NodeList childNodes = dependencyNode.get().getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node node = childNodes.item(i);
                if (Node.COMMENT_NODE == node.getNodeType()
                        && contains(node.getNodeValue(), PomWriter.AUTO_COMMENT)) {
                    return Optional.of(node);
                }
            }
        }

        return Optional.absent();
    }

}