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