PomUtil.java

  1. /*
  2.  * Licensed under the Apache License, Version 2.0 (the "License");
  3.  * you may not use this file except in compliance with the License.
  4.  * You may obtain a copy of the License at
  5.  *
  6.  * http://www.apache.org/licenses/LICENSE-2.0
  7.  *
  8.  * Unless required by applicable law or agreed to in writing, software
  9.  * distributed under the License is distributed on an "AS IS" BASIS,
  10.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11.  * See the License for the specific language governing permissions and
  12.  * limitations under the License.
  13.  */

  14. package org.basepom.inline.mojo;

  15. import static java.lang.String.format;

  16. import java.io.IOException;
  17. import java.io.StringReader;
  18. import java.io.Writer;
  19. import java.util.List;
  20. import javax.xml.stream.XMLInputFactory;
  21. import javax.xml.stream.XMLStreamException;
  22. import javax.xml.stream.XMLStreamReader;

  23. import com.google.common.base.Strings;
  24. import com.google.common.collect.Iterables;
  25. import org.eclipse.aether.graph.Dependency;
  26. import org.eclipse.aether.util.artifact.JavaScopes;
  27. import org.jdom2.Content;
  28. import org.jdom2.Content.CType;
  29. import org.jdom2.Document;
  30. import org.jdom2.Element;
  31. import org.jdom2.JDOMException;
  32. import org.jdom2.Namespace;
  33. import org.jdom2.Text;
  34. import org.jdom2.filter.Filters;
  35. import org.jdom2.input.StAXStreamBuilder;
  36. import org.jdom2.output.Format;
  37. import org.jdom2.output.LineSeparator;
  38. import org.jdom2.output.XMLOutputter;
  39. import org.jdom2.xpath.XPathExpression;
  40. import org.jdom2.xpath.XPathFactory;

  41. final class PomUtil {

  42.     private final Document pomDocument;

  43.     PomUtil(String pomText) throws XMLStreamException, JDOMException {
  44.         final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
  45.         final XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(new StringReader(pomText));
  46.         final StAXStreamBuilder builder = new StAXStreamBuilder();
  47.         this.pomDocument = builder.build(reader);
  48.     }

  49.     void writePom(Writer writer) throws IOException {
  50.         // this is a hack because jdom2 has the annoying habit of removing a newline between
  51.         // a leading comment and the root element.
  52.         if (pomDocument.getContentSize() > 1
  53.                 && pomDocument.getContent(0).getCType() == CType.Comment
  54.                 && pomDocument.getContent(1).getCType() == CType.Element) {
  55.             this.pomDocument.addContent(1, new Text("\n"));
  56.         }

  57.         XMLOutputter xml = new XMLOutputter();
  58.         xml.setFormat(Format.getPrettyFormat()
  59.                 .setLineSeparator(LineSeparator.SYSTEM));
  60.         xml.output(pomDocument, writer);
  61.         writer.flush();
  62.     }

  63.     void removeDependency(Dependency dependency) {
  64.         Namespace pomNs = Namespace.getNamespace("pom", pomDocument.getRootElement().getNamespaceURI());
  65.         XPathFactory xpathFactory = XPathFactory.instance();
  66.         final var artifact = dependency.getArtifact();
  67.         String xpathExpression;

  68.         if (Strings.emptyToNull(artifact.getClassifier()) == null) {
  69.             xpathExpression =
  70.                     format("//pom:dependencies/pom:dependency[pom:artifactId[text() = '%s'] and pom:groupId[text() = '%s'] and not(pom:classifier) ]",
  71.                             artifact.getArtifactId(), artifact.getGroupId());
  72.         } else {
  73.             xpathExpression =
  74.                     format("//pom:dependencies/pom:dependency[pom:artifactId[text() = '%s'] and pom:groupId[text() = '%s'] and pom:classifier[text() = '%s']]",
  75.                             artifact.getArtifactId(), artifact.getGroupId(), artifact.getClassifier());
  76.         }

  77.         XPathExpression<Content> dependencies = xpathFactory.compile(xpathExpression, Filters.content(), null, pomNs);
  78.         List<Content> contents = dependencies.evaluate(pomDocument.getRootElement());
  79.         for (Content content : contents) {
  80.             content.getParentElement().removeContent(content);
  81.         }
  82.     }

  83.     void addDependency(Dependency dependency) {
  84.         Namespace pomNs = Namespace.getNamespace("pom", pomDocument.getRootElement().getNamespaceURI());
  85.         XPathFactory xpathFactory = XPathFactory.instance();

  86.         XPathExpression<Content> dependencies = xpathFactory.compile("/pom:project/pom:dependencies", Filters.content(), null, pomNs);
  87.         Content content = Iterables.getOnlyElement(dependencies.evaluate(pomDocument.getRootElement()));

  88.         Namespace newNs = pomDocument.getRootElement().getNamespace();

  89.         Element dependencyElement = new Element("dependency", newNs);
  90.         dependencyElement.addContent(new Element("groupId", newNs).addContent(dependency.getArtifact().getGroupId()));
  91.         dependencyElement.addContent(new Element("artifactId", newNs).addContent(dependency.getArtifact().getArtifactId()));
  92.         dependencyElement.addContent(new Element("version", newNs).addContent(dependency.getArtifact().getVersion()));

  93.         String scope = dependency.getScope();
  94.         if (Strings.emptyToNull(scope) != null && !JavaScopes.COMPILE.equals(scope)) {
  95.             dependencyElement.addContent(new Element("scope", newNs).addContent(scope));
  96.         }

  97.         if (dependency.isOptional()) {
  98.             dependencyElement.addContent(new Element("optional", newNs).addContent("true"));
  99.         }

  100.         ((Element) content).addContent(dependencyElement);
  101.     }
  102. }