/opup/src/old/java/com/atlassian/labs/opup/PomScanner.java
Java | 314 lines | 248 code | 60 blank | 6 comment | 38 complexity | 261dac0d3bed0ecb72d2644dfdc5ecd0 MD5 | raw file
Possible License(s): BSD-3-Clause
- package com.atlassian.labs.opup;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Set;
- 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.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.versioning.ArtifactVersion;
- import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.w3c.dom.NodeList;
- import org.xml.sax.SAXException;
- public class PomScanner
- {
- public static Iterable<File> pomFiles(File base)
- {
- ArrayList<File> poms = new ArrayList<File>();
- recurse(poms, base);
- return poms;
- }
- private static void recurse(Collection<? super File> poms, File dir)
- {
- File p = new File(dir, "pom.xml");
- if (p.isFile())
- {
- poms.add(p);
- for (File f : dir.listFiles())
- {
- if (f.isDirectory())
- {
- recurse(poms, f);
- }
- }
- }
- }
- private final Set<String> defined = new HashSet<String>();
- private final DocumentBuilder docBuilder;
- private final XPath xpath;
- private final Map<String, Collection<String>> versions = new HashMap<String, Collection<String>>();
- private final Map<String, Collection<String>> properties = new HashMap<String, Collection<String>>();
- private final Set<String> requirements = new HashSet<String>();
- public PomScanner() throws ParserConfigurationException
- {
- docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
- xpath = XPathFactory.newInstance().newXPath();
- }
- private static <K, V> void add(Map<K, Collection<V>> m, K k, V v)
- {
- Collection<V> c = m.get(k);
- if (c == null)
- {
- c = new HashSet<V>();
- m.put(k, c);
- }
- c.add(v);
- }
- void addVersion(String groupAndArtifact, String version)
- {
- add(versions, groupAndArtifact, version);
- }
- void addProperty(String name, String value)
- {
- add(properties, name, value);
- }
- public void process(InputStream in) throws SAXException, IOException, XPathExpressionException
- {
- Document d = docBuilder.parse(in);
- /* This pom's artifact */
- String pomGroupId = (String) xpath.evaluate("project/groupId", d, XPathConstants.STRING);
- String pomArtifactId = (String) xpath.evaluate("project/artifactId", d, XPathConstants.STRING);
- if (pomGroupId.isEmpty())
- {
- pomGroupId = (String) xpath.evaluate("project/parent/groupId", d, XPathConstants.STRING);
- }
- String pomCoords = pomGroupId + ":" + pomArtifactId;
- defined.add(pomCoords);
- /* Any dependency versions defined */
- XPathExpression expr = xpath.compile("//dependency[groupId and artifactId]");
- NodeList nl = (NodeList) expr.evaluate(d, XPathConstants.NODESET);
- for (int i = 0; i < nl.getLength(); i++)
- {
- Element e = (Element) nl.item(i);
- String groupId = (String) xpath.evaluate("groupId", e, XPathConstants.STRING);
- String artifactId = (String) xpath.evaluate("artifactId", e, XPathConstants.STRING);
- String version = (String) xpath.evaluate("version", e, XPathConstants.STRING);
- String type = (String) xpath.evaluate("type", e, XPathConstants.STRING);
- String scope = (String) xpath.evaluate("scope", e, XPathConstants.STRING);
- String coords = groupId + ":" + artifactId;
- if (!type.isEmpty() && !type.equals("jar"))
- {
- coords += ":" + type;
- }
- // Don't want to upgrade provided dependencies
- if (scope == null || !scope.equals("provided"))
- {
- requirements.add(coords);
- }
- if (!version.isEmpty())
- {
- addVersion(groupId + ":" + artifactId, version);
- }
- }
- /* Properties */
- nl = (NodeList) xpath.evaluate("project/properties/*", d, XPathConstants.NODESET);
- for (int i = 0; i < nl.getLength(); i++)
- {
- Element e = (Element) nl.item(i);
- addProperty(e.getTagName(), (String) xpath.evaluate(".", e, XPathConstants.STRING));
- }
- nl = (NodeList) xpath.evaluate("project/profiles/profile/properties/*", d, XPathConstants.NODESET);
- for (int i = 0; i < nl.getLength(); i++)
- {
- Element e = (Element) nl.item(i);
- addProperty(e.getTagName(), (String) xpath.evaluate(".", e, XPathConstants.STRING));
- }
- }
- public Collection<? extends String> getDefinedArtifacts()
- {
- return defined;
- }
- static String groupAndArtifact(String coords)
- {
- String s = coords;
- int sc = s.indexOf(':', s.indexOf(':') + 1);
- if (sc >= 0)
- {
- s = s.substring(0, sc);
- }
- return s;
- }
- private Collection<ArtifactVersion> toVersions(Collection<String> vs)
- {
- Collection<ArtifactVersion> artifactVersions = new ArrayList<ArtifactVersion>();
- for (String s : vs)
- {
- artifactVersions.add(new DefaultArtifactVersion(s));
- }
- return artifactVersions;
- }
- Map<String, ArtifactVersion> currentVersions = new HashMap<String, ArtifactVersion>();
- Map<String, ArtifactVersion> currentProperties = new HashMap<String, ArtifactVersion>();
- public Map<String, ArtifactVersion> getCurrentVersions()
- {
- return currentVersions;
- }
- public Map<String, ArtifactVersion> getCurrentProperties()
- {
- return currentProperties;
- }
- public void findCurrent(ReportTarget report)
- {
- Set<String> external = new HashSet<String>(requirements);
- /* We don't want anything we already have */
- Iterator<String> i = external.iterator();
- while (i.hasNext())
- {
- String s = groupAndArtifact(i.next());
- if (defined.contains(s))
- {
- i.remove();
- }
- }
- for (String s : external)
- {
- Collection<String> v = versions.get(groupAndArtifact(s));
- if (v.size() != 1)
- {
- report.multipleVersions(s, toVersions(v));
- }
- else if (v.iterator().next().startsWith("$"))
- {
- String expr = v.iterator().next();
- String propname = propNameFromExpression(expr);
- if (propname != null)
- {
- /* Don't try to upgrade internal dependencies */
- if (propname.equals("project.version"))
- {
- continue;
- }
- Collection<String> values = properties.get(propname);
- if (values == null)
- {
- throw new RuntimeException("No value for: " + propname);
- }
- else if (values.size() != 1)
- {
- report.multipleValues(propname, toVersions(values));
- }
- else
- {
- ArtifactVersion current = new DefaultArtifactVersion(values.iterator().next());
- currentVersions.put(s, current);
- currentProperties.put(propname, current);
- }
- }
- else
- {
- throw new RuntimeException("Bad expression: " + expr);
- }
- }
- else
- {
- currentVersions.put(s, new DefaultArtifactVersion(v.iterator().next()));
- }
- }
- }
- public String getPropertyForArtifactVersion(String artifact)
- {
- Collection<String> v = versions.get(groupAndArtifact(artifact));
- if (v.size() == 1 && v.iterator().next().startsWith("$"))
- {
- String expr = v.iterator().next();
- String prop = propNameFromExpression(expr);
- if (prop == null)
- {
- throw new RuntimeException("Bad expression: " + expr);
- }
- return prop;
- }
- else
- {
- return null;
- }
- }
- private static final Pattern SINGLE_PROPERTY_EXPRESSION = Pattern.compile("\\$\\{([-\\._a-zA-Z0-9]+)\\}");
- public String propNameFromExpression(String expr)
- {
- Matcher m = SINGLE_PROPERTY_EXPRESSION.matcher(expr);
- if (m.matches())
- {
- return m.group(1);
- }
- else
- {
- return null;
- }
- }
- }