View Javadoc
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  
16  import static java.lang.String.format;
17  
18  import java.io.IOException;
19  import java.io.OutputStreamWriter;
20  import java.io.StringReader;
21  import java.util.List;
22  import javax.xml.stream.XMLInputFactory;
23  import javax.xml.stream.XMLStreamException;
24  import javax.xml.stream.XMLStreamReader;
25  
26  import com.google.common.base.Strings;
27  import com.google.common.collect.Iterables;
28  import org.eclipse.aether.graph.Dependency;
29  import org.eclipse.aether.util.artifact.JavaScopes;
30  import org.jdom2.Content;
31  import org.jdom2.Content.CType;
32  import org.jdom2.Document;
33  import org.jdom2.Element;
34  import org.jdom2.JDOMException;
35  import org.jdom2.Namespace;
36  import org.jdom2.Text;
37  import org.jdom2.filter.Filters;
38  import org.jdom2.input.StAXStreamBuilder;
39  import org.jdom2.output.Format;
40  import org.jdom2.output.LineSeparator;
41  import org.jdom2.output.XMLOutputter;
42  import org.jdom2.xpath.XPathExpression;
43  import org.jdom2.xpath.XPathFactory;
44  
45  final class PomUtil {
46  
47      private final String pomText;
48      private final Document pomDocument;
49  
50      PomUtil(String pomText) throws XMLStreamException, JDOMException {
51          this.pomText = pomText;
52  
53          final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
54          final XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(new StringReader(pomText));
55          final StAXStreamBuilder builder = new StAXStreamBuilder();
56          this.pomDocument = builder.build(reader);
57      }
58  
59      void writePom(OutputStreamWriter writer) throws IOException {
60          // this is a hack because jdom2 has the annoying habit of removing a newline between
61          // a leading comment and the root element.
62          if (pomDocument.getContentSize() > 1
63                  && pomDocument.getContent(0).getCType() == CType.Comment
64                  && pomDocument.getContent(1).getCType() == CType.Element) {
65              this.pomDocument.addContent(1, new Text("\n"));
66          }
67  
68          XMLOutputter xml = new XMLOutputter();
69          xml.setFormat(Format.getPrettyFormat()
70                  .setLineSeparator(LineSeparator.SYSTEM));
71          xml.output(pomDocument, writer);
72      }
73  
74      void removeDependency(Dependency dependency) {
75          Namespace pomNs = Namespace.getNamespace("pom", pomDocument.getRootElement().getNamespaceURI());
76          XPathFactory xpathFactory = XPathFactory.instance();
77          final var artifact = dependency.getArtifact();
78          String xpathExpression;
79  
80          if (Strings.emptyToNull(artifact.getClassifier()) == null) {
81              xpathExpression =
82                      format("//pom:dependencies/pom:dependency[pom:artifactId[text() = '%s'] and pom:groupId[text() = '%s'] and not(pom:classifier) ]",
83                              artifact.getArtifactId(), artifact.getGroupId());
84          } else {
85              xpathExpression =
86                      format("//pom:dependencies/pom:dependency[pom:artifactId[text() = '%s'] and pom:groupId[text() = '%s'] and pom:classifier[text() = '%s']]",
87                              artifact.getArtifactId(), artifact.getGroupId(), artifact.getClassifier());
88          }
89  
90          XPathExpression<Content> dependencies = xpathFactory.compile(xpathExpression, Filters.content(), null, pomNs);
91          List<Content> contents = dependencies.evaluate(pomDocument.getRootElement());
92          for (Content content : contents) {
93              content.getParentElement().removeContent(content);
94          }
95      }
96  
97      void addDependency(Dependency dependency) {
98          Namespace pomNs = Namespace.getNamespace("pom", pomDocument.getRootElement().getNamespaceURI());
99          XPathFactory xpathFactory = XPathFactory.instance();
100 
101         XPathExpression<Content> dependencies = xpathFactory.compile("/pom:project/pom:dependencies", Filters.content(), null, pomNs);
102         Content content = Iterables.getOnlyElement(dependencies.evaluate(pomDocument.getRootElement()));
103 
104         Namespace newNs = pomDocument.getRootElement().getNamespace();
105 
106         Element dependencyElement = new Element("dependency", newNs);
107         dependencyElement.addContent(new Element("groupId", newNs).addContent(dependency.getArtifact().getGroupId()));
108         dependencyElement.addContent(new Element("artifactId", newNs).addContent(dependency.getArtifact().getArtifactId()));
109         dependencyElement.addContent(new Element("version", newNs).addContent(dependency.getArtifact().getVersion()));
110 
111         String scope = dependency.getScope();
112         if (Strings.emptyToNull(scope) != null && !JavaScopes.COMPILE.equals(scope)) {
113             dependencyElement.addContent(new Element("scope", newNs).addContent(scope));
114         }
115 
116         if (dependency.isOptional()) {
117             dependencyElement.addContent(new Element("optional", newNs).addContent("true"));
118         }
119 
120         ((Element) content).addContent(dependencyElement);
121     }
122 }