Java tutorial
/* * 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(); } }