package org.jfrog.build.extractor.maven.reader; import com.google.common.collect.Maps; import com.google.common.io.Files; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.nio.charset.Charset; import java.util.List; import java.util.Map; /** * Read a Maven project recursively. * * @author Tomer Cohen */ public class ProjectReader { private final File rootPom; /** * Constructor, gets the file which represents the location of the <b>root</b> pom of the Maven project. * * @param rootPom The root pom of the Maven project. */ public ProjectReader(File rootPom) { this.rootPom = rootPom; } /** * Read the project starting with the root pom. This method returns a {@link java.util.HashMap} that has {@link * ModuleName} as its key, and the location of its corresponding pom file which was used to construct the {@link * ModuleName} * * @return A map of {@link ModuleName} and the file that was used to build it. * @throws IOException Thrown in case of an error occurring while reading the pom. */ public Map<ModuleName, File> read() throws IOException { Map<ModuleName, File> result = Maps.newHashMap(); readRecursive(result, rootPom); return result; } /** * Read the modules recursively and populate the {@link ModuleName} and file map according to the modules. */ private void readRecursive(Map<ModuleName, File> modules, File current) throws IOException { if (!current.exists()) { throw new IllegalArgumentException("Root pom file: " + current.getAbsolutePath() + " does not exist"); } Model model = readModel(current); String groupId = model.getGroupId(); if (StringUtils.isBlank(groupId)) { groupId = model.getParent().getGroupId(); } modules.put(new ModuleName(groupId, model.getArtifactId()), current); List<String> children = model.getModules(); for (String child : children) { if (!child.endsWith("pom.xml")) { child += "/pom.xml"; } File childPom = new File(current.getParentFile().getAbsolutePath(), child); readRecursive(modules, childPom); } } /** * @return Construct a Maven {@link Model} from the pom. */ private Model readModel(File pom) throws IOException { MavenXpp3Reader reader = new MavenXpp3Reader(); StringReader stringReader = null; try { stringReader = new StringReader(Files.toString(pom, Charset.forName("UTF-8"))); return reader.read(stringReader); } catch (XmlPullParserException e) { throw new IOException(e); } finally { IOUtils.closeQuietly(stringReader); } } }