blob: 28c9d270395bb31d730dc72baa5d7dd5b725f5fb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2010 Sonatype, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sonatype, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.m2e.scm;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.osgi.util.NLS;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.Profile;
import org.apache.maven.model.Scm;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.embedder.IMaven;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.internal.Messages;
import org.eclipse.m2e.core.project.AbstractProjectScanner;
/**
* Maven project scanner using dependency list
*
* @author Eugene Kuleshov
*/
public class MavenProjectPomScanner<T> extends AbstractProjectScanner<MavenProjectScmInfo> {
private static final Logger log = LoggerFactory.getLogger(MavenProjectPomScanner.class);
private final boolean developer;
private final Dependency[] dependencies;
private IMaven maven;
public MavenProjectPomScanner(boolean developer, Dependency[] dependencies) {
this.developer = developer;
this.dependencies = dependencies;
this.maven = MavenPlugin.getMaven();
}
public String getDescription() {
if(dependencies.length == 1) {
Dependency d = dependencies[0];
return d.getGroupId()
+ ":" + d.getArtifactId() + ":" + d.getVersion() + (d.getClassifier() == null ? "" : ":" + d.getClassifier()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
return "" + dependencies.length + " projects"; //$NON-NLS-1$
}
public void run(IProgressMonitor monitor) throws InterruptedException {
for(int i = 0; i < dependencies.length; i++ ) {
if(monitor.isCanceled()) {
throw new InterruptedException();
}
Dependency d = dependencies[i];
try {
Model model = resolveModel(d.getGroupId(), d.getArtifactId(), d.getVersion(), monitor);
if(model == null) {
String msg = "Can't resolve " + d.getArtifactId();
Exception error = new Exception(msg);
log.error(msg, error);
addError(error);
continue;
}
Scm scm = resolveScm(model, monitor);
if(scm == null) {
String msg = "No SCM info for " + d.getArtifactId();
Exception error = new Exception(msg);
log.error(msg, error);
addError(error);
continue;
}
String tag = scm.getTag();
log.info(d.getArtifactId());
log.info("Connection: " + scm.getConnection());
log.info(" dev: " + scm.getDeveloperConnection());
log.info(" url: " + scm.getUrl());
log.info(" tag: " + tag);
String connection;
if(developer) {
connection = scm.getDeveloperConnection();
if(connection == null) {
String msg = d.getArtifactId() + " doesn't specify developer SCM connection";
Exception error = new Exception(msg);
log.error(msg, error);
addError(error);
continue;
}
} else {
connection = scm.getConnection();
if(connection == null) {
String msg = d.getArtifactId() + " doesn't specify SCM connection";
Exception error = new Exception(msg);
log.error(msg, error);
addError(error);
continue;
}
}
// connection: scm:svn:https://svn.apache.org/repos/asf/incubator/wicket/branches/wicket-1.2.x/wicket
// dev: scm:svn:https://svn.apache.org/repos/asf/incubator/wicket/branches/wicket-1.2.x/wicket
// url: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.2.x/wicket
// tag: HEAD
// TODO add an option to select all modules/projects and optimize scan
if(connection.endsWith("/")) { //$NON-NLS-1$
connection = connection.substring(0, connection.length() - 1);
}
int n = connection.lastIndexOf("/"); //$NON-NLS-1$
String label = (n == -1 ? connection : connection.substring(n)) + "/" + IMavenConstants.POM_FILE_NAME; //$NON-NLS-1$
addProject(new MavenProjectScmInfo(label, model, null, tag, connection, connection));
} catch(Exception ex) {
addError(ex);
String msg = "Error reading " + d.getArtifactId();
log.error(msg, ex);
}
}
}
private Scm resolveScm(Model model, IProgressMonitor monitor) throws ArtifactResolutionException,
ArtifactNotFoundException, XmlPullParserException, IOException, CoreException {
Scm scm = model.getScm();
if(scm != null) {
return scm;
}
Parent parent = model.getParent();
if(parent == null) {
return null;
}
Model parentModel = resolveModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), monitor);
if(parentModel == null) {
return null;
}
Scm parentScm = resolveScm(parentModel, monitor);
if(parentScm == null) {
return null;
}
Set<String> modules = new HashSet<String>(parentModel.getModules());
List<Profile> parentModelProfiles = parentModel.getProfiles();
for(Profile profile : parentModelProfiles) {
modules.addAll(profile.getModules());
}
// heuristics for matching module names to artifactId
String artifactId = model.getArtifactId();
for(String module : modules) {
if(module.equals(artifactId) || module.endsWith("/" + artifactId)) { //$NON-NLS-1$
if(parentScm.getConnection() != null) {
parentScm.setConnection(parentScm.getConnection() + "/" + module); //$NON-NLS-1$
}
if(parentScm.getDeveloperConnection() != null) {
parentScm.setDeveloperConnection(parentScm.getDeveloperConnection() + "/" + module); //$NON-NLS-1$
}
return parentScm;
}
}
// XXX read modules from profiles
return parentScm;
}
private Model resolveModel(String groupId, String artifactId, String version, IProgressMonitor monitor)
throws CoreException {
monitor.subTask(NLS.bind(Messages.MavenProjectPomScanner_task_resolving,
new Object[] {groupId, artifactId, version}));
List<ArtifactRepository> repositories = maven.getArtifactRepositories();
Artifact artifact = maven.resolve(groupId, artifactId, version, "pom", null, repositories, monitor); //$NON-NLS-1$
File file = artifact.getFile();
if(file == null) {
return null;
}
// XXX this fail on reading extensions
// MavenProject project = embedder.readProject(file);
monitor.subTask(NLS.bind(Messages.MavenProjectPomScanner_23, new Object[] {groupId, artifactId, version}));
return maven.readModel(file);
}
}