/******************************************************************************
* 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;
}
}