/****************************************************************************** * Copyright (c) 2006, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0 * is available at http://www.opensource.org/licenses/apache2.0.php. * You may elect to redistribute this code under either of these licenses. * * Contributors: * VMware Inc. *****************************************************************************/ package org.eclipse.gemini.blueprint.test.provisioning.internal; import java.io.File; import java.io.FileFilter; import java.io.FileNotFoundException; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.xml.DefaultDocumentLoader; import org.springframework.beans.factory.xml.DocumentLoader; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.util.xml.DomUtils; import org.springframework.util.xml.XmlValidationModeDetector; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.InputSource; /** * Find a packaged maven artifact starting in some root directory of a maven * project. * * Poor approximation as doesn't check groupId. Could probably be done better * using some maven API.... but I can't find any good doc. * * @author Adrian Colyer */ public class MavenPackagedArtifactFinder { /** logger */ private static final Log log = LogFactory.getLog(MavenPackagedArtifactFinder.class); private static final String POM_XML = "pom.xml"; private static final String TARGET = "target"; private static final String GROUP_ID_ELEM = "groupId"; private final String artifactName; private final String groupId; public MavenPackagedArtifactFinder(String groupId, String artifactId, String version, String type) { this.groupId = groupId; this.artifactName = artifactId + "-" + version + "." + type; } File findPackagedArtifact(File startingDirectory) throws IOException { if (!isMavenProjectDirectory(startingDirectory)) { throw new IllegalStateException(startingDirectory + " does not contain a pom.xml file"); } File rootMavenProjectDir = findRootMavenProjectDir(startingDirectory.getCanonicalFile()); if (log.isTraceEnabled()) log.trace("Starting local artifact search from " + rootMavenProjectDir.getAbsolutePath()); File found = findInDirectoryTree(artifactName, rootMavenProjectDir); if (found == null) { throw new FileNotFoundException("Cannot find the artifact <" + artifactName + "> with groupId <" + groupId + ">"); } return found; } /** * Check whether the folder is a maven dir. * * @param dir * @return */ private boolean isMavenProjectDirectory(File dir) { return (dir.isDirectory() && new File(dir, POM_XML).exists()); } /** * Returns the <tt>groupId</tt> setting in a <tt>pom.xml</tt> file. * * @return a <tt>pom.xml</tt> <tt>groupId</tt>. */ String getGroupIdFromPom(Resource pomXml) { try { DocumentLoader docLoader = new DefaultDocumentLoader(); Document document = docLoader.loadDocument(new InputSource(pomXml.getInputStream()), null, null, XmlValidationModeDetector.VALIDATION_NONE, false); String groupId = DomUtils.getChildElementValueByTagName(document.getDocumentElement(), GROUP_ID_ELEM); // no groupId specified, try the parent definition if (groupId == null) { if (log.isTraceEnabled()) log.trace("No groupId defined; checking for the parent definition"); Element parent = DomUtils.getChildElementByTagName(document.getDocumentElement(), "parent"); if (parent != null) return DomUtils.getChildElementValueByTagName(parent, GROUP_ID_ELEM); } else { return groupId; } } catch (Exception ex) { throw (RuntimeException) new RuntimeException(new ParserConfigurationException("error parsing resource=" + pomXml).initCause(ex)); } throw new IllegalArgumentException("no groupId or parent/groupId defined by resource [" + pomXml.getDescription() + "]"); } private File findRootMavenProjectDir(File dir) { File lastFoundMavenProjectDir = dir; File parentDir = dir.getParentFile(); while (parentDir != null && isMavenProjectDirectory(parentDir)) { lastFoundMavenProjectDir = parentDir; parentDir = parentDir.getParentFile(); } return lastFoundMavenProjectDir; } private File findInDirectoryTree(String fileName, File root) { boolean trace = log.isTraceEnabled(); File targetDir = new File(root, TARGET); if (targetDir.exists()) { File artifact = new File(targetDir, fileName); // found artifact if (artifact.exists()) { if (trace) log.trace("Found artifact at " + artifact.getAbsolutePath() + "; checking the pom.xml groupId..."); // check the groupId inside the parent pom // (happens late to allow filtering to occur) File pomXml = new File(root, POM_XML); String groupId = getGroupIdFromPom(new FileSystemResource(pomXml)); if (trace) log.trace("Pom [" + pomXml.getAbsolutePath() + "] has groupId [" + groupId + "]"); if (this.groupId.equals(groupId)) return artifact; } } File[] children = root.listFiles(new FileFilter() { public boolean accept(File pathname) { if (!isMavenProjectDirectory(pathname)) { return false; } if (pathname.getName().equals(TARGET)) { return false; } if (pathname.getName().equals("src")) { return false; } if (pathname.getName().equals(".svn")) { return false; } return true; } }); for (int i = 0; i < children.length; i++) { File found = findInDirectoryTree(fileName, children[i]); if (found != null) { return found; } } return null; } }