diff options
Diffstat (limited to 'org.eclipse.m2e.core/src/org/eclipse/m2e/core/project')
30 files changed, 2984 insertions, 0 deletions
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/AbstractProjectScanner.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/AbstractProjectScanner.java new file mode 100644 index 00000000..c996a869 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/AbstractProjectScanner.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * 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.core.project; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; + + +/** + * Project Scanner + * + * @author Eugene Kuleshov + */ +public abstract class AbstractProjectScanner<T extends MavenProjectInfo> { + + private final List<T> projects = new ArrayList<T>(); + private final List<Throwable> errors = new ArrayList<Throwable>(); + + /** + * Returns <code>List</code> of {@link MavenProjectInfo} + */ + public List<T> getProjects() { + return projects; + } + + /** + * Returns <code>List</code> of <code>Exception</code> + */ + public List<Throwable> getErrors() { + return this.errors; + } + + protected void addProject(T mavenProjectInfo) { + projects.add(mavenProjectInfo); + } + + protected void addError(Throwable exception) { + errors.add(exception); + } + + public abstract String getDescription(); + + public abstract void run(IProgressMonitor monitor) throws InterruptedException; +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenMarkerManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenMarkerManager.java new file mode 100644 index 00000000..a96622ba --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenMarkerManager.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * 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.core.project; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; + +import org.apache.maven.execution.MavenExecutionResult; + +/** + * IMavenMarkerManager + * + * @author Fred Bricon + */ +public interface IMavenMarkerManager { + + /** + * Add markers to a pom file from a MavenExecutionResult. + * @param pomFile the pom file to attach markers to. + * @param result containing messages to be addedd as markers + */ + public void addMarkers(IResource pomFile, String type, MavenExecutionResult result); + + /** + * Add a Maven marker to a resource + * @param resource : the IResource to attach the marker to. + * @param message : the marker's message. + * @param lineNumber : the resource line to attach the marker to. + * @param severity : the severity of the marker. + */ + public IMarker addMarker(IResource resource, String type, String message, int lineNumber, int severity); + + /** + * Delete all Maven markers of the specified type from an IResource + */ + public void deleteMarkers(IResource resource, String type) throws CoreException; + + /** + * Transform an exception into an error marker on an IResource + */ + public void addErrorMarkers(IResource resource, String type, Exception ex); + + public void addEditorHintMarkers(IResource pom, String type); +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectChangedListener.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectChangedListener.java new file mode 100644 index 00000000..f37ec18d --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectChangedListener.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * 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.core.project; + +import org.eclipse.core.runtime.IProgressMonitor; + +public interface IMavenProjectChangedListener { + /** + * This method is called while holding workspace lock. + */ + public void mavenProjectChanged(MavenProjectChangedEvent[] events, IProgressMonitor monitor); +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectFacade.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectFacade.java new file mode 100644 index 00000000..ded501aa --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectFacade.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * 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.core.project; + +import java.io.File; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; + +import org.apache.maven.lifecycle.MavenExecutionPlan; +import org.apache.maven.project.MavenProject; + +import org.eclipse.m2e.core.embedder.ArtifactKey; +import org.eclipse.m2e.core.embedder.ArtifactRef; +import org.eclipse.m2e.core.embedder.ArtifactRepositoryRef; +import org.eclipse.m2e.core.internal.project.ProjectConfigurationManager; +import org.eclipse.m2e.core.project.configurator.ILifecycleMapping; + +/** + * IMavenProjectFacade + * + * @noimplement This interface is not intended to be implemented by clients. + * + * @author Igor Fedorenko + */ +public interface IMavenProjectFacade { + + /** + * Returns project relative paths of resource directories + */ + IPath[] getResourceLocations(); + + /** + * Returns project relative paths of test resource directories + */ + IPath[] getTestResourceLocations(); + + IPath[] getCompileSourceLocations(); + + IPath[] getTestCompileSourceLocations(); + + /** + * Returns project resource for given file system location or null the location is outside of project. + * + * @param resourceLocation absolute file system location + * @return IPath the full, absolute workspace path resourceLocation + */ + IPath getProjectRelativePath(String resourceLocation); + + /** + * Returns the full, absolute path of this project maven build output directory relative to the workspace or null if + * maven build output directory cannot be determined or outside of the workspace. + */ + IPath getOutputLocation(); + + /** + * Returns the full, absolute path of this project maven build test output directory relative to the workspace or null + * if maven build output directory cannot be determined or outside of the workspace. + */ + IPath getTestOutputLocation(); + + IPath getFullPath(); + + /** + * Lazy load and cache MavenProject instance + */ + MavenProject getMavenProject(IProgressMonitor monitor) throws CoreException; + + /** + * Returns cached MavenProject instance associated with this facade or null, + * if the cache has not been populated yet. + */ + MavenProject getMavenProject(); + + /** + * Lazy load and cache build execution plan + */ + MavenExecutionPlan getExecutionPlan(IProgressMonitor monitor) throws CoreException; + + String getPackaging(); + + IProject getProject(); + + IFile getPom(); + + File getPomFile(); + + /** + * Returns the full, absolute path of the given file relative to the workspace. Returns null if the file does not + * exist or is not a member of this project. + */ + IPath getFullPath(File file); + + /** + * Visits trough Maven project artifacts and modules + * + * @param visitor a project visitor used to visit Maven project + * @param flags flags to specify visiting behavior. See {@link IMavenProjectVisitor#LOAD}, + * {@link IMavenProjectVisitor#NESTED_MODULES}. + */ + void accept(IMavenProjectVisitor visitor, int flags) throws CoreException; + + void accept(IMavenProjectVisitor2 visitor, int flags, IProgressMonitor monitor) throws CoreException; + + List<String> getMavenProjectModules(); + + Set<ArtifactRef> getMavenProjectArtifacts(); + + ResolverConfiguration getResolverConfiguration(); + + /** + * @return true if maven project needs to be re-read from disk + */ + boolean isStale(); + + ArtifactKey getArtifactKey(); + + /** + * Associates the value with the key in session (i.e. transient) context. + * Intended as a mechanism to cache state derived from MavenProject. + * Session properties are cleared when MavenProject is re-read from disk. + * + * @see #getSessionProperty(String) + */ + public void setSessionProperty(String key, Object value); + + /** + * @return the value associated with the key in session context or null + * if the key is not associated with any value. + * + * @see #setSessionProperty(String, Object) + */ + public Object getSessionProperty(String key); + + public Set<ArtifactRepositoryRef> getArtifactRepositoryRefs(); + + public Set<ArtifactRepositoryRef> getPluginArtifactRepositoryRefs(); + + public ILifecycleMapping getLifecycleMapping(IProgressMonitor monitor) throws CoreException; + + /** + * Returns true if the project configuration is valid. This flag is set by + * {@link ProjectConfigurationManager#validateProjectConfiguration(IMavenProjectFacade, IProgressMonitor)}. Returns + * false if the project configuration has not been validated yet. + */ + boolean hasValidConfiguration(); + + void setHasValidConfiguration(boolean hasValidConfiguration); +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectImportResult.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectImportResult.java new file mode 100644 index 00000000..218e5a4d --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectImportResult.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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.core.project; + +import org.eclipse.core.resources.IProject; + +/** + * Holds IProject that was created during project import + * + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IMavenProjectImportResult { + + /** + * @return MavenProjectInfo maven project import request + */ + MavenProjectInfo getMavenProjectInfo(); + + /** + * @return IProject imported project or <code>null</code> if the project could not be imported. + */ + IProject getProject(); +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectVisitor.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectVisitor.java new file mode 100644 index 00000000..71a5e400 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectVisitor.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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.core.project; + +import org.eclipse.core.runtime.CoreException; + +/** + * This interface is implemented by clients that visit MavenProject tree. + */ +public interface IMavenProjectVisitor { + + public static int NONE = 0; + + public static int LOAD = 1 << 0; + + /** + * Visit Maven project or project module + * + * @param projectFacade a facade for visited Maven project + * @return true if nested artifacts and modules should be visited + */ + public boolean visit(IMavenProjectFacade projectFacade) throws CoreException; + + /** + * Visit Maven project dependency/artifact + * + * @param projectFacade a facade for visited Maven project + * @param artifact an artifact for project dependency + */ +// public void visit(IMavenProjectFacade projectFacade, Artifact artifact); + +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectVisitor2.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectVisitor2.java new file mode 100644 index 00000000..5effc055 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IMavenProjectVisitor2.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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.core.project; + +import org.apache.maven.artifact.Artifact; + +/** + * IMavenProjectVisitor2 + * + * @author Igor Fedorenko + */ +public interface IMavenProjectVisitor2 extends IMavenProjectVisitor { + + /** + * @param mavenProjectFacade + * @param artifact + */ + void visit(IMavenProjectFacade mavenProjectFacade, Artifact artifact); + +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IProjectConfigurationManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IProjectConfigurationManager.java new file mode 100644 index 00000000..a36aa966 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IProjectConfigurationManager.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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.core.project; + +import java.util.Collection; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.jobs.ISchedulingRule; + +import org.apache.maven.archetype.catalog.Archetype; +import org.apache.maven.model.Model; + +import org.eclipse.m2e.core.project.configurator.ILifecycleMapping; + + +public interface IProjectConfigurationManager { + + ISchedulingRule getRule(); + + List<IMavenProjectImportResult> importProjects(Collection<MavenProjectInfo> projects, // + ProjectImportConfiguration configuration, IProgressMonitor monitor) throws CoreException; + + void createSimpleProject(IProject project, IPath location, Model model, String[] folders, + ProjectImportConfiguration configuration, IProgressMonitor monitor) throws CoreException; + + void createArchetypeProject(IProject project, IPath location, Archetype archetype, // + String groupId, String artifactId, String version, String javaPackage, Properties properties, // + ProjectImportConfiguration configuration, IProgressMonitor monitor) throws CoreException; + + Set<MavenProjectInfo> collectProjects(Collection<MavenProjectInfo> projects); + + void enableMavenNature(IProject project, ResolverConfiguration configuration, IProgressMonitor monitor) + throws CoreException; + + void disableMavenNature(IProject project, IProgressMonitor monitor) throws CoreException; + + void updateProjectConfiguration(IProject project, ResolverConfiguration configuration, IProgressMonitor monitor) + throws CoreException; + + ILifecycleMapping getLifecycleMapping(IMavenProjectFacade projectFacade, IProgressMonitor monitor) + throws CoreException; + + /** + * Validates that the project configuration is valid. It does not actually (re)configure the project, but it validates + * that the project configure action will not fail for obvious reasons like missing lifecycle mapping, missing project + * configuration, etc. + * + * @return true if the configuration is valid + */ + boolean validateProjectConfiguration(IMavenProjectFacade projectFacade, IProgressMonitor monitor); +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/LocalProjectScanner.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/LocalProjectScanner.java new file mode 100644 index 00000000..b397910e --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/LocalProjectScanner.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * 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.core.project; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; + +import org.apache.maven.model.Model; +import org.apache.maven.model.Profile; + +import org.eclipse.m2e.core.core.IMavenConstants; +import org.eclipse.m2e.core.core.MavenConsole; +import org.eclipse.m2e.core.embedder.MavenModelManager; +import org.eclipse.m2e.core.internal.Messages; + + +/** + * @author Eugene Kuleshov + */ +public class LocalProjectScanner extends AbstractProjectScanner<MavenProjectInfo> { + private final File workspaceRoot; + private final List<String> folders; + private final boolean basedirRemameRequired; + + private Set<File> scannedFolders = new HashSet<File>(); + private final MavenConsole console; + private final MavenModelManager modelManager; + + public LocalProjectScanner(File workspaceRoot, String folder, boolean needsRename, MavenModelManager modelManager, + MavenConsole console) { + this(workspaceRoot, Collections.singletonList(folder), needsRename, modelManager, console); + } + + public LocalProjectScanner(File workspaceRoot, List<String> folders, boolean basedirRemameRequired, + MavenModelManager modelManager, MavenConsole console) { + this.workspaceRoot = workspaceRoot; + this.folders = folders; + this.basedirRemameRequired = basedirRemameRequired; + this.modelManager = modelManager; + this.console = console; + } + + public void run(IProgressMonitor monitor) throws InterruptedException { + monitor.beginTask(Messages.LocalProjectScanner_task_scanning, IProgressMonitor.UNKNOWN); + try { + for(String folderName : folders) { + try { + File folder = new File(folderName).getCanonicalFile(); + scanFolder(folder, new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN)); + } catch(IOException ex) { + addError(ex); + } + } + } finally { + monitor.done(); + } + } + + private void scanFolder(File baseDir, IProgressMonitor monitor) throws InterruptedException { + if(monitor.isCanceled()) { + throw new InterruptedException(); + } + + monitor.subTask(baseDir.toString()); + monitor.worked(1); + + // Don't scan the .metadata folder + if(!baseDir.exists() || !baseDir.isDirectory() || IMavenConstants.METADATA_FOLDER.equals(baseDir.getName())) { + return; + } + + MavenProjectInfo projectInfo = readMavenProjectInfo(baseDir, "", null); //$NON-NLS-1$ + if(projectInfo != null) { + addProject(projectInfo); + return; // don't scan subfolders of the Maven project + } + + File[] files = baseDir.listFiles(); + for(int i = 0; i < files.length; i++ ) { + File file; + try { + file = files[i].getCanonicalFile(); + if(file.isDirectory()) { + scanFolder(file, monitor); + } + } catch(IOException ex) { + addError(ex); + } + } + } + + private MavenProjectInfo readMavenProjectInfo(File baseDir, String modulePath, MavenProjectInfo parentInfo) { + try { + baseDir = baseDir.getCanonicalFile(); + + File pomFile = new File(baseDir, IMavenConstants.POM_FILE_NAME); + if(!pomFile.exists()) { + return null; + } + + Model model = modelManager.readMavenModel(pomFile); + + if (!scannedFolders.add(baseDir)) { + return null; // we already know this project + } + + String pomName = modulePath + "/" + IMavenConstants.POM_FILE_NAME; //$NON-NLS-1$ + + MavenProjectInfo projectInfo = newMavenProjectInfo(pomName, pomFile, model, parentInfo); + projectInfo.setBasedirRename(getBasedirRename(projectInfo)); + + Map<String, Set<String>> modules = new LinkedHashMap<String, Set<String>>(); + for(String module : model.getModules()) { + modules.put(module, new HashSet<String>()); + } + + for(Profile profile : model.getProfiles()) { + for(String module : profile.getModules()) { + Set<String> profiles = modules.get(module); + if(profiles == null) { + profiles = new HashSet<String>(); + modules.put(module, profiles); + } + profiles.add(profile.getId()); + } + } + + for(Map.Entry<String, Set<String>> e : modules.entrySet()) { + String module = e.getKey(); + Set<String> profiles = e.getValue(); + + File moduleBaseDir = new File(baseDir, module); + MavenProjectInfo moduleInfo = readMavenProjectInfo(moduleBaseDir, module, projectInfo); + if(moduleInfo != null) { + moduleInfo.addProfiles(profiles); + projectInfo.add(moduleInfo); + } + } + + return projectInfo; + + } catch(CoreException ex) { + addError(ex); + console.logError("Unable to read model " + baseDir.getAbsolutePath()); + } catch(IOException ex) { + addError(ex); + console.logError("Unable to read model " + baseDir.getAbsolutePath()); + } + + return null; + } + + protected MavenProjectInfo newMavenProjectInfo(String label, File pomFile, Model model, MavenProjectInfo parent) { + return new MavenProjectInfo(label, pomFile, model, parent); + } + + public String getDescription() { + return folders.toString(); + } + + private int getBasedirRename(MavenProjectInfo mavenProjectInfo) throws IOException { + File cannonical = mavenProjectInfo.getPomFile().getParentFile().getParentFile().getCanonicalFile(); + if (basedirRemameRequired && cannonical.equals(workspaceRoot.getCanonicalFile())) { + return MavenProjectInfo.RENAME_REQUIRED; + } + return MavenProjectInfo.RENAME_NO; + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectChangedEvent.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectChangedEvent.java new file mode 100644 index 00000000..e0d775ef --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectChangedEvent.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * 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.core.project; + +import org.eclipse.core.resources.IFile; + +public class MavenProjectChangedEvent { + + private final IFile source; + + private final int kind; + + private final int flags; + + public static final int KIND_ADDED = 1; + + public static final int KIND_REMOVED = 2; + + public static final int KIND_CHANGED = 3; + + public static final int FLAG_NONE = 0; + + public static final int FLAG_DEPENDENCIES = 1; + + public static final int FLAG_DEPENDENCY_SOURCES = 2; + + public static final int FLAG_ENTRY_SOURCES = 3; + + private final IMavenProjectFacade oldMavenProject; + + private final IMavenProjectFacade mavenProject; + + public MavenProjectChangedEvent(IFile source, int kind, int flags, IMavenProjectFacade oldMavenProject, IMavenProjectFacade mavenProject) { + this.source = source; + this.kind = kind; + this.flags = flags; + this.oldMavenProject = oldMavenProject; + this.mavenProject = mavenProject; + } + + public int getKind() { + return kind; + } + + public int getFlags() { + return flags; + } + + public IMavenProjectFacade getMavenProject() { + return mavenProject; + } + + public IMavenProjectFacade getOldMavenProject() { + return oldMavenProject; + } + + public IFile getSource() { + return source; + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectInfo.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectInfo.java new file mode 100644 index 00000000..64088a15 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectInfo.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * 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.core.project; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.maven.model.Model; + +import org.eclipse.m2e.core.core.MavenLogger; + + +/** + * @author Eugene Kuleshov + */ +public class MavenProjectInfo { + + /** + * Project basedir must NOT be renamed on filesystem. + */ + public static final int RENAME_NO = 0; + + /** + * Project basedir MUST be ranamed to match workspace project name. + */ + public static final int RENAME_REQUIRED = 2; + + private final String label; + + private File pomFile; + + private Model model; + + private final MavenProjectInfo parent; + + /** + * Map of MavenProjectInfo + */ + private final Map<String, MavenProjectInfo> projects = new LinkedHashMap<String, MavenProjectInfo>(); + + private final Set<String> profiles = new HashSet<String>(); + + private int basedirRename = RENAME_NO; + + public MavenProjectInfo(String label, File pomFile, Model model, MavenProjectInfo parent) { + this.label = label; + this.pomFile = pomFile; + this.model = model; + this.parent = parent; + } + + public void setPomFile(File pomFile) { + File oldDir = this.pomFile.getParentFile(); + File newDir = pomFile.getParentFile(); + + for(MavenProjectInfo projectInfo : projects.values()) { + File childPom = projectInfo.getPomFile(); + if(isSubDir(oldDir, childPom.getParentFile())) { + String oldPath = oldDir.getAbsolutePath(); + String path = childPom.getAbsolutePath().substring(oldPath.length()); + projectInfo.setPomFile(new File(newDir, path)); + } + } + + this.pomFile = pomFile; + } + + /** @deprecated use set/get BasedirRename */ + public void setNeedsRename(boolean needsRename) { + setBasedirRename(needsRename? RENAME_REQUIRED: RENAME_NO); + } + + /** @deprecated use set/get BasedirRenamePolicy */ + public boolean isNeedsRename() { + return getBasedirRename() == RENAME_REQUIRED; + } + + /** + * See {@link #RENAME_NO}, {@link #RENAME_REQUIRED} + */ + public void setBasedirRename(int basedirRename) { + this.basedirRename = basedirRename; + } + + /** + * See {@link #RENAME_NO}, {@link #RENAME_REQUIRED} + */ + public int getBasedirRename() { + return basedirRename; + } + + private boolean isSubDir(File parentDir, File subDir) { + if(parentDir.equals(subDir)) { + return true; + } + + if(subDir.getParentFile()!=null) { + return isSubDir(parentDir, subDir.getParentFile()); + } + + return false; + } + + public void add(MavenProjectInfo info) { + String key; + try { + if(info.getPomFile() == null) { + // Is this possible? + key = info.getLabel(); + } else { + key = info.getPomFile().getCanonicalPath(); + } + } catch(IOException ex) { + throw new RuntimeException(ex); + } + MavenProjectInfo i = projects.get(key); + if(i==null) { + projects.put(key, info); + } else { + MavenLogger.log("Project info " + this + " already has a child project info with key '" + key + "'"); //$NON-NLS-3$ + for(Iterator<String> it = info.getProfiles().iterator(); it.hasNext();) { + i.addProfile(it.next()); + } + } + } + + public void addProfile(String profileId) { + if(profileId!=null) { + this.profiles.add(profileId); + } + } + + public void addProfiles(Collection<String> profiles) { + this.profiles.addAll(profiles); + } + + public String getLabel() { + return this.label; + } + + public File getPomFile() { + return this.pomFile; + } + + public Model getModel() { + return this.model; + } + + public void setModel(Model model) { + this.model = model; + } + + public Collection<MavenProjectInfo> getProjects() { + return this.projects.values(); + } + + public MavenProjectInfo getParent() { + return this.parent; + } + + public Set<String> getProfiles() { + return this.profiles; + } + + public boolean equals(Object obj) { + if(obj instanceof MavenProjectInfo) { + MavenProjectInfo info = (MavenProjectInfo) obj; + if(pomFile == null) { + return info.getPomFile() == null; + } + return pomFile.equals(info.getPomFile()); + } + return false; + } + + public int hashCode() { + return pomFile==null ? 0 : pomFile.hashCode(); + } + + public String toString() { + return "'" + label + "'" + (pomFile == null ? "" : " " + pomFile.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectManager.java new file mode 100644 index 00000000..303d30a7 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectManager.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * 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.core.project; + +import java.io.File; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; + +import org.apache.maven.artifact.repository.MavenArtifactRepository; +import org.apache.maven.execution.MavenExecutionRequest; + +import org.eclipse.m2e.core.core.IMavenConstants; +import org.eclipse.m2e.core.internal.project.registry.ProjectRegistryManager; +import org.eclipse.m2e.core.internal.project.registry.ProjectRegistryRefreshJob; + + +/** + * This class keeps track of all Maven projects present in the workspace and provides mapping between Maven artifacts + * and Workspace projects. + */ +public class MavenProjectManager { + + public static final String STATE_FILENAME = "workspacestate.properties"; //$NON-NLS-1$ + + private final ProjectRegistryManager manager; + + private final ProjectRegistryRefreshJob mavenBackgroundJob; + + private final File workspaceStateFile; + + public MavenProjectManager(ProjectRegistryManager manager, ProjectRegistryRefreshJob mavenBackgroundJob, File stateLocation) { + this.manager = manager; + this.mavenBackgroundJob = mavenBackgroundJob; + this.workspaceStateFile = new File(stateLocation, STATE_FILENAME); + } + + // Maven projects + + /** + * Performs requested Maven project update asynchronously, using background + * job. This method returns immediately. + */ + public void refresh(MavenUpdateRequest request) { + mavenBackgroundJob.refresh(request); + } + + /** + * Performs requested Maven project update synchronously. In other words, this method + * does not return until all affected projects have been updated and + * corresponding MavenProjectChangeEvent's broadcast. + * + * This method acquires a lock on the workspace's root. + */ + public void refresh(MavenUpdateRequest request, IProgressMonitor monitor) throws CoreException { + manager.refresh(request, monitor); + } + + public void addMavenProjectChangedListener(IMavenProjectChangedListener listener) { + manager.addMavenProjectChangedListener(listener); + } + + public void removeMavenProjectChangedListener(IMavenProjectChangedListener listener) { + manager.removeMavenProjectChangedListener(listener); + } + + /** + * Returns MavenProjectFacade corresponding to the pom. This method first looks in the project cache, then attempts to + * load the pom if the pom is not found in the cache. In the latter case, workspace resolution is assumed to be + * enabled for the pom but the pom will not be added to the cache. + */ + public IMavenProjectFacade create(IFile pom, boolean load, IProgressMonitor monitor) { + return manager.create(pom, load, monitor); + } + + public IMavenProjectFacade create(IProject project, IProgressMonitor monitor) { + return manager.create(project, monitor); + } + + public ResolverConfiguration getResolverConfiguration(IProject project) { + IMavenProjectFacade projectFacade = create(project, new NullProgressMonitor()); + if(projectFacade!=null) { + return projectFacade.getResolverConfiguration(); + } + return manager.readResolverConfiguration(project); + } + + public boolean setResolverConfiguration(IProject project, ResolverConfiguration configuration) { + return manager.setResolverConfiguration(project, configuration); + } + + /** + * @return MavenProjectFacade[] all maven projects which exist under workspace root + */ + public IMavenProjectFacade[] getProjects() { + return manager.getProjects(); + } + + /** + * @return IMavenProjectFacade cached IMavenProjectFacade corresponding + * to the project or null if there is no cache entry for the project. + */ + public IMavenProjectFacade getProject(IProject project) { + return manager.getProject(project); + } + + public IMavenProjectFacade getMavenProject(String groupId, String artifactId, String version) { + return manager.getMavenProject(groupId, artifactId, version); + } + + public File getWorkspaceStateFile() { + return workspaceStateFile; + } + + /** + * Request full maven build for a project. + * + * This call only has effect for projects that have maven nature and + * Maven builder configured. + * + * This call does not trigger the build. Instead next time Maven builder + * processes the project it will use goals to execute during clean + * build regardless of the build type requested. + * + * The main purpose of this call is to allow coordination between multiple + * builders configured for the same project. + */ + public void requestFullMavenBuild(IProject project) throws CoreException { + project.setSessionProperty(IMavenConstants.FULL_MAVEN_BUILD, Boolean.TRUE); + } + + /** + * PROVISIONAL + */ + public MavenExecutionRequest createExecutionRequest(IFile pom, ResolverConfiguration resolverConfiguration, IProgressMonitor monitor) throws CoreException { + return manager.createExecutionRequest(pom, resolverConfiguration, monitor); + } + + /** + * PROVISIONAL + */ + public MavenExecutionRequest createExecutionRequest(IMavenProjectFacade project, IProgressMonitor monitor) throws CoreException { + return manager.createExecutionRequest(project.getPom(), project.getResolverConfiguration(), monitor); + } + + /** + * Local repository implementation that checks artifacts in workspace first. + * + * PROVISIONAL + */ + public MavenArtifactRepository getWorkspaceLocalRepository() throws CoreException { + return manager.getWorkspaceLocalRepository(); + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectPomScanner.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectPomScanner.java new file mode 100644 index 00000000..fe73112f --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectPomScanner.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * 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.core.project; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +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.core.IMavenConstants; +import org.eclipse.m2e.core.core.MavenConsole; +import org.eclipse.m2e.core.core.MavenLogger; +import org.eclipse.m2e.core.embedder.IMaven; +import org.eclipse.m2e.core.embedder.MavenModelManager; +import org.eclipse.m2e.core.internal.Messages; + +/** + * Maven project scanner using dependency list + * + * @author Eugene Kuleshov + */ +public class MavenProjectPomScanner<T> extends AbstractProjectScanner<MavenProjectScmInfo> { + + private final boolean developer; + + private final Dependency[] dependencies; + + private MavenConsole console; + + private IMaven maven; + + public MavenProjectPomScanner(boolean developer, Dependency[] dependencies, // + MavenModelManager modelManager, MavenConsole console) { + this.developer = developer; + this.dependencies = dependencies; + this.console = console; + this.maven = MavenPlugin.getDefault().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(); + console.logError(msg); + addError(new Exception(msg)); + continue; + } + + Scm scm = resolveScm(model, monitor); + if(scm==null) { + String msg = "No SCM info for " + d.getArtifactId(); + console.logError(msg); + addError(new Exception(msg)); + continue; + } + + String tag = scm.getTag(); + + console.logMessage(d.getArtifactId()); + console.logMessage("Connection: " + scm.getConnection()); + console.logMessage(" dev: " + scm.getDeveloperConnection()); + console.logMessage(" url: " + scm.getUrl()); + console.logMessage(" tag: " + tag); + + String connection; + if(developer) { + connection = scm.getDeveloperConnection(); + if(connection==null) { + String msg = d.getArtifactId() + " doesn't specify developer SCM connection"; + console.logError(msg); + addError(new Exception(msg)); + continue; + } + } else { + connection = scm.getConnection(); + if(connection==null) { + String msg = d.getArtifactId() + " doesn't specify SCM connection"; + console.logError(msg); + addError(new Exception(msg)); + 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(); + console.logError(msg); + MavenLogger.log(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); + } + + +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectScmInfo.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectScmInfo.java new file mode 100644 index 00000000..fc810dfa --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectScmInfo.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * 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.core.project; + +import java.io.File; + +import org.apache.maven.model.Model; + + +/** + * @author Eugene Kuleshov + */ +public class MavenProjectScmInfo extends MavenProjectInfo { + + private final String folderUrl; + private final String repositoryUrl; + private final String revision; + private final String branch; + + private String username; + private String password; + + private File sslCertificate; + private String sslCertificatePassphrase; + + public MavenProjectScmInfo(String label, Model model, MavenProjectInfo parent, // + String revision, String folderUrl, String repositoryUrl) { + this(label, model, parent, null, revision, folderUrl, repositoryUrl); + } + + public MavenProjectScmInfo(String label, Model model, MavenProjectInfo parent, // + String branch, String revision, String folderUrl, String repositoryUrl) { + super(label, null, model, parent); + this.revision = revision; + this.folderUrl = folderUrl; + this.repositoryUrl = repositoryUrl; + this.branch = branch; + } + + public String getBranch() { + return this.branch; + } + + public String getRevision() { + return this.revision; + } + + public String getFolderUrl() { + return folderUrl; + } + + public String getRepositoryUrl() { + return repositoryUrl; + } + + public boolean equals(Object obj) { + if(obj instanceof MavenProjectScmInfo) { + MavenProjectScmInfo info = (MavenProjectScmInfo) obj; + return folderUrl.equals(info.getFolderUrl()); + } + return false; + } + + public int hashCode() { + return folderUrl.hashCode(); + } + + public String toString() { + return getLabel() + " " + folderUrl; //$NON-NLS-1$ + } + + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + + public void setSSLCertificate(File certificate) { + this.sslCertificate = certificate; + } + public File getSSLCertificate() { + return sslCertificate; + } + + public String getSSLCertificatePassphrase() { + return sslCertificatePassphrase; + } + public void setSSLCertificatePassphrase(String passphrase) { + this.sslCertificatePassphrase = passphrase; + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectUtils.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectUtils.java new file mode 100644 index 00000000..cbcf60e6 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenProjectUtils.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * 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.core.project; + +import java.io.File; +import java.util.LinkedHashSet; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +import org.apache.maven.model.Resource; + +/** + * Collection of helper methods to map between MavenProject and IResource. + * + * @author igor + */ +public class MavenProjectUtils { + + private MavenProjectUtils() { + } + + /** + * Returns project resource for given filesystem location or null the location is outside of project. + * + * @param resourceLocation absolute filesystem location + * @return IPath the full, absolute workspace path resourceLocation + */ + public static IPath getProjectRelativePath(IProject project, String resourceLocation) { + if(resourceLocation == null) { + return null; + } + IPath projectLocation = project.getLocation(); + IPath directory = Path.fromOSString(resourceLocation); // this is an absolute path! + if(projectLocation == null || !projectLocation.isPrefixOf(directory)) { + return null; + } + + return directory.removeFirstSegments(projectLocation.segmentCount()).makeRelative().setDevice(null); + } + + public static IPath[] getResourceLocations(IProject project, List<Resource> resources) { + LinkedHashSet<IPath> locations = new LinkedHashSet<IPath>(); + for(Resource resource : resources) { + locations.add(getProjectRelativePath(project, resource.getDirectory())); + } + return locations.toArray(new IPath[locations.size()]); + } + + public static IPath[] getSourceLocations(IProject project, List<String> roots) { + LinkedHashSet<IPath> locations = new LinkedHashSet<IPath>(); + for(String root : roots) { + IPath path = getProjectRelativePath(project, root); + if(path != null) { + locations.add(path); + } + } + return locations.toArray(new IPath[locations.size()]); + } + + /** + * Returns the full, absolute path of the given file relative to the workspace. Returns null if the file does not + * exist or is not a member of this project. + */ + public static IPath getFullPath(IProject project, File file) { + if (project == null || file == null) { + return null; + } + + IPath projectPath = project.getLocation(); + if(projectPath == null) { + return null; + } + + IPath filePath = new Path(file.getAbsolutePath()); + if (!projectPath.isPrefixOf(filePath)) { + return null; + } + IResource resource = project.findMember(filePath.removeFirstSegments(projectPath.segmentCount())); + if (resource == null) { + return null; + } + return resource.getFullPath(); + } + +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenUpdateRequest.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenUpdateRequest.java new file mode 100644 index 00000000..8f936f24 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/MavenUpdateRequest.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * 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.core.project; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; + +import org.eclipse.m2e.core.core.IMavenConstants; + +/** + * Maven project update request + * + * @author Eugene Kuleshov + */ +public class MavenUpdateRequest { + private boolean offline = false; + private boolean updateSnapshots = false; + private boolean force = true; + + /** + * Set of {@link IFile} + */ + private final Set<IFile> pomFiles = new LinkedHashSet<IFile>(); + + public MavenUpdateRequest(boolean offline, boolean updateSnapshots) { + this.offline = offline; + this.updateSnapshots = updateSnapshots; + } + + public MavenUpdateRequest(IProject project, boolean offline, boolean updateSnapshots) { + this(offline, updateSnapshots); + addPomFile(project); + } + + public MavenUpdateRequest(IProject[] projects, boolean offline, boolean updateSnapshots) { + this(offline, updateSnapshots); + + for(int i = 0; i < projects.length; i++ ) { + addPomFile(projects[i]); + } + } + + public boolean isOffline() { + return this.offline; + } + + public boolean isUpdateSnapshots() { + return this.updateSnapshots; + } + + public void addPomFiles(Set<IFile> pomFiles) { + for (IFile pomFile : pomFiles) { + addPomFile(pomFile); + } + } + + public void addPomFile(IFile pomFile) { + pomFiles.add(pomFile); + } + + public void addPomFile(IProject project) { + pomFiles.add(project.getFile(IMavenConstants.POM_FILE_NAME)); + + } + + public void removePomFile(IFile pomFile) { + pomFiles.remove(pomFile); + } + + /** + * Returns Set of {@link IFile} + */ + public Set<IFile> getPomFiles() { + return this.pomFiles; + } + + public boolean isEmpty() { + return this.pomFiles.isEmpty(); + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public String toString() { + StringBuilder sb = new StringBuilder("["); //$NON-NLS-1$ + String sep = ""; //$NON-NLS-1$ + for(IFile pomFile : pomFiles) { + sb.append(sep); + sb.append(pomFile.getFullPath()); + sep = ", "; //$NON-NLS-1$ + } + sb.append("]"); //$NON-NLS-1$ + + if(offline) { + sb.append(" offline"); //$NON-NLS-1$ + } + if(updateSnapshots) { + sb.append(" updateSnapshots"); //$NON-NLS-1$ + } + if(force) { + sb.append(" force"); //$NON-NLS-1$ + } + + return sb.toString(); + } + +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ProjectImportConfiguration.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ProjectImportConfiguration.java new file mode 100644 index 00000000..e8f8b8bf --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ProjectImportConfiguration.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * 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.core.project; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.IWorkingSet; + +import org.apache.maven.model.Model; + +import org.eclipse.m2e.core.core.IMavenConstants; +import org.eclipse.m2e.core.core.Messages; + + +/** + * Project import configuration bean. + */ +public class ProjectImportConfiguration { + + private static final String GROUP_ID = "\\[groupId\\]"; //$NON-NLS-1$ + + private static final String ARTIFACT_ID = "\\[artifactId\\]"; //$NON-NLS-1$ + + private static final String VERSION = "\\[version\\]"; //$NON-NLS-1$ + + /** resolver configuration bean */ + private ResolverConfiguration resolverConfiguration; + + /** the project name template */ + private String projectNameTemplate = ""; //$NON-NLS-1$ + + private IWorkingSet[] workingSets; + + /** Creates a new configuration. */ + public ProjectImportConfiguration(ResolverConfiguration resolverConfiguration) { + this.resolverConfiguration = resolverConfiguration; + } + + /** Creates a new configuration. */ + public ProjectImportConfiguration() { + this(new ResolverConfiguration()); + } + + /** Returns the resolver configuration bean. */ + public ResolverConfiguration getResolverConfiguration() { + return resolverConfiguration; + } + + /** Sets the project name template. */ + public void setProjectNameTemplate(String projectNameTemplate) { + this.projectNameTemplate = projectNameTemplate; + } + + /** Returns the project name template. */ + public String getProjectNameTemplate() { + return projectNameTemplate; + } + + /** @deprecated UI aspects will be refactored out of core import logic */ + public void setWorkingSet(IWorkingSet workingSet) { + this.workingSets = workingSet == null ? null : new IWorkingSet[]{workingSet}; + } + + /** @deprecated UI aspects will be refactored out of core import logic */ + public void setWorkingSets(IWorkingSet[] workingSets) { + this.workingSets = workingSets; + } + + /** @deprecated UI aspects will be refactored out of core import logic */ + public IWorkingSet[] getWorkingSets() { + return this.workingSets; + } + + /** + * Calculates the project name for the given model. + * + * @deprecated This method does not take into account MavenProjectInfo.basedirRename + */ + public String getProjectName(Model model) { + // XXX should use resolved MavenProject or Model + if(projectNameTemplate.length() == 0) { + return model.getArtifactId(); + } + + String artifactId = model.getArtifactId(); + String groupId = model.getGroupId(); + if(groupId == null && model.getParent() != null) { + groupId = model.getParent().getGroupId(); + } + String version = model.getVersion(); + if(version == null && model.getParent() != null) { + version = model.getParent().getVersion(); + } + + // XXX needs MavenProjectManager update to resolve groupId and version + return projectNameTemplate.replaceAll(GROUP_ID, groupId).replaceAll(ARTIFACT_ID, artifactId).replaceAll(VERSION, + version == null ? "" : version); //$NON-NLS-1$ + } + + /** + * @deprecated This method does not take into account MavenProjectInfo.basedirRename. + * Use IMavenProjectImportResult#getProject instead + */ + public IProject getProject(IWorkspaceRoot root, Model model) { + return root.getProject(getProjectName(model)); + } + + /** + * @deprecated business logic does not belong to a value object + */ + public IStatus validateProjectName(Model model) { + String projectName = getProjectName(model); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + + // check if the project name is valid + IStatus nameStatus = workspace.validateName(projectName, IResource.PROJECT); + if(!nameStatus.isOK()) { + return nameStatus; + } + + // check if project already exists + if(workspace.getRoot().getProject(projectName).exists()) { + return new Status( IStatus.ERROR, IMavenConstants.PLUGIN_ID, 0, Messages.getString("wizard.project.page.project.validator.projectExists",projectName), null); //$NON-NLS-1$ + } + + return Status.OK_STATUS; + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java new file mode 100644 index 00000000..8271bd19 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.core.project; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Resolver configuration holder. + * + * TODO need a better name, this configures all aspects of maven project in eclipse, + * not just dependency resolution. + * + * @author Eugene Kuleshov + */ +public class ResolverConfiguration implements Serializable { + private static final long serialVersionUID = 1258510761534886581L; + + private boolean resolveWorkspaceProjects = true; + + private String activeProfiles = ""; //$NON-NLS-1$ + + public boolean shouldResolveWorkspaceProjects() { + return this.resolveWorkspaceProjects; + } + + public String getActiveProfiles() { + return this.activeProfiles; + } + + public List<String> getActiveProfileList() { + if (activeProfiles.trim().length() > 0) { + return Arrays.asList(activeProfiles.split("[,\\s\\|]")); //$NON-NLS-1$ + } + return new ArrayList<String>(); + } + + public void setResolveWorkspaceProjects(boolean resolveWorkspaceProjects) { + this.resolveWorkspaceProjects = resolveWorkspaceProjects; + } + + public void setActiveProfiles(String activeProfiles) { + this.activeProfiles = activeProfiles; + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/AbstractBuildParticipant.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/AbstractBuildParticipant.java new file mode 100644 index 00000000..ebc79a35 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/AbstractBuildParticipant.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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.core.project.configurator; + +import java.util.Set; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +import org.apache.maven.execution.MavenSession; + +import org.sonatype.plexus.build.incremental.BuildContext; + +import org.eclipse.m2e.core.internal.builder.InternalBuildParticipant; +import org.eclipse.m2e.core.project.IMavenProjectFacade; + + +/** + * AbstractMavenBuildParticipant + * + * @author igor + */ +public abstract class AbstractBuildParticipant extends InternalBuildParticipant { + + /** + * This method is called during workspace full or incremental build. + */ + public abstract Set<IProject> build(int kind, IProgressMonitor monitor) throws Exception; + + public boolean callOnEmptyDelta() { + return false; + } + + /** + * This method is called during workspace clean build. + */ + @SuppressWarnings("unused") + public void clean(IProgressMonitor monitor) throws CoreException { + // default implementation does nothing + } + + protected IMavenProjectFacade getMavenProjectFacade() { + return super.getMavenProjectFacade(); + } + + protected IResourceDelta getDelta(IProject project) { + return super.getDelta(project); + } + + protected MavenSession getSession() { + return super.getSession(); + } + + protected BuildContext getBuildContext() { + return super.getBuildContext(); + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/AbstractLifecycleMapping.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/AbstractLifecycleMapping.java new file mode 100644 index 00000000..e64db998 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/AbstractLifecycleMapping.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * 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.core.project.configurator; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.ICommand; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; + +import org.apache.maven.lifecycle.MavenExecutionPlan; +import org.apache.maven.plugin.MojoExecution; + +import org.eclipse.m2e.core.core.IMavenConstants; +import org.eclipse.m2e.core.project.IMavenProjectFacade; + + +/** + * AbstractLifecycleMapping + * + * @author igor + */ +public abstract class AbstractLifecycleMapping implements ILifecycleMapping { + + private String name; + + private String id; + + private boolean showConfigurators; + + /** + * Calls #configure method of all registered project configurators + */ + public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException { + addMavenBuilder(request.getProject(), monitor); + + for(AbstractProjectConfigurator configurator : getProjectConfigurators(request.getMavenProjectFacade(), monitor)) { + if(monitor.isCanceled()) { + throw new OperationCanceledException(); + } + configurator.configure(request, monitor); + } + } + + public void unconfigure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException { + for(AbstractProjectConfigurator configurator : getProjectConfigurators(request.getMavenProjectFacade(), monitor)) { + if(monitor.isCanceled()) { + throw new OperationCanceledException(); + } + configurator.unconfigure(request, monitor); + } + } + + protected static void addMavenBuilder(IProject project, IProgressMonitor monitor) throws CoreException { + IProjectDescription description = project.getDescription(); + + // ensure Maven builder is always the last one + ICommand mavenBuilder = null; + ArrayList<ICommand> newSpec = new ArrayList<ICommand>(); + for(ICommand command : description.getBuildSpec()) { + if(IMavenConstants.BUILDER_ID.equals(command.getBuilderName())) { + mavenBuilder = command; + } else { + newSpec.add(command); + } + } + if(mavenBuilder == null) { + mavenBuilder = description.newCommand(); + mavenBuilder.setBuilderName(IMavenConstants.BUILDER_ID); + } + newSpec.add(mavenBuilder); + description.setBuildSpec(newSpec.toArray(new ICommand[newSpec.size()])); + + project.setDescription(description, monitor); + } + + /** + * @return Returns the name. + */ + public String getName() { + return this.name; + } + + /** + * @param name The name to set. + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return Returns the id. + */ + public String getId() { + return this.id; + } + + /** + * @param id The id to set. + */ + public void setId(String id) { + this.id = id; + } + + /** + * @param show Set whether the project configurators should show. Default is true. + */ + public void setShowConfigurators(boolean show) { + this.showConfigurators = show; + } + + /** + * Returns whether the project configurators will be shown in the UI. Default is true. + */ + public boolean showConfigurators() { + return this.showConfigurators; + } + + protected List<AbstractBuildParticipant> getBuildParticipants(IMavenProjectFacade facade, + List<AbstractProjectConfigurator> configurators, IProgressMonitor monitor) throws CoreException { + List<AbstractBuildParticipant> participants = new ArrayList<AbstractBuildParticipant>(); + + for(MojoExecution execution : facade.getExecutionPlan(monitor).getMojoExecutions()) { + for(AbstractProjectConfigurator configurator : configurators) { + if(configurator.isSupportedExecution(execution)) { + AbstractBuildParticipant participant = configurator.getBuildParticipant(execution); + if(participant != null) { + participants.add(participant); + } + } + } + } + + return participants; + } + + public List<MojoExecution> getNotCoveredMojoExecutions(IMavenProjectFacade mavenProjectFacade, + IProgressMonitor monitor) throws CoreException { + List<MojoExecution> result = new ArrayList<MojoExecution>(); + + List<AbstractProjectConfigurator> projectConfigurators = getProjectConfigurators(mavenProjectFacade, monitor); + MavenExecutionPlan mavenExecutionPlan = mavenProjectFacade.getExecutionPlan(monitor); + List<MojoExecution> allMojoExecutions = mavenExecutionPlan.getMojoExecutions(); + for(MojoExecution mojoExecution : allMojoExecutions) { + if(!isInterestingPhase(mojoExecution.getLifecyclePhase())) { + continue; + } + boolean isCovered = false; + for(AbstractProjectConfigurator configurator : projectConfigurators) { + if(configurator.isSupportedExecution(mojoExecution)) { + isCovered = true; + break; + } + } + if(!isCovered) { + result.add(mojoExecution); + } + } + return result; + } + + public List<AbstractBuildParticipant> getBuildParticipants(IMavenProjectFacade facade, IProgressMonitor monitor) + throws CoreException { + List<AbstractProjectConfigurator> configurators = getProjectConfigurators(facade, monitor); + + return getBuildParticipants(facade, configurators, monitor); + } + + private static final String[] INTERESTING_PHASES = {"validate", // + "initialize", // + "generate-sources", // + "process-sources", // + "generate-resources", // + "process-resources", // + "compile", // + "process-classes", // + "generate-test-sources", // + "process-test-sources", // + "generate-test-resources", // + "process-test-resources", // + "test-compile", // + "process-test-classes", // + // "test", // + // "prepare-package", // + // "package", // + //"pre-integration-test", // + // "integration-test", // + // "post-integration-test", // + // "verify", // + // "install", // + // "deploy", // + }; + + public boolean isInterestingPhase(String phase) { + for(String interestingPhase : INTERESTING_PHASES) { + if(interestingPhase.equals(phase)) { + return true; + } + } + return false; + } + + public abstract List<AbstractProjectConfigurator> getProjectConfigurators(IMavenProjectFacade mavenProjectFacade, + IProgressMonitor monitor) throws CoreException; + +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/AbstractProjectConfigurator.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/AbstractProjectConfigurator.java new file mode 100644 index 00000000..d6d51c76 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/AbstractProjectConfigurator.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * 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.core.project.configurator; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.PluginExecution; +import org.apache.maven.plugin.MojoExecution; + +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.core.IMavenConstants; +import org.eclipse.m2e.core.core.MavenConsole; +import org.eclipse.m2e.core.core.MavenLogger; +import org.eclipse.m2e.core.embedder.IMaven; +import org.eclipse.m2e.core.embedder.IMavenConfiguration; +import org.eclipse.m2e.core.internal.Messages; +import org.eclipse.m2e.core.project.IMavenMarkerManager; +import org.eclipse.m2e.core.project.IMavenProjectChangedListener; +import org.eclipse.m2e.core.project.MavenProjectChangedEvent; +import org.eclipse.m2e.core.project.MavenProjectManager; + + +/** + * Used to configure maven projects. + * + * @author Igor Fedorenko + */ +public abstract class AbstractProjectConfigurator implements IExecutableExtension, IMavenProjectChangedListener { + + public static final String ATTR_ID = "id"; //$NON-NLS-1$ + + public static final String ATTR_PRIORITY = "priority"; //$NON-NLS-1$ + + public static final String ATTR_NAME = "name"; //$NON-NLS-1$ + + public static final String ATTR_CLASS = "class"; //$NON-NLS-1$ + + private int priority; + + private String id; + + private String name; + + /** + * List of maven plugin goal patterns for which this project configurator is enabled automatically. Can be null, in + * which case the project configurator can only be enabled explicitly in pom.xml. + */ + protected List<PluginExecutionFilter> pluginExecutionFilters; + + protected MavenProjectManager projectManager; + + protected IMavenConfiguration mavenConfiguration; + + protected IMavenMarkerManager markerManager; + + protected MavenConsole console; + + protected IMaven maven = MavenPlugin.getDefault().getMaven(); + + public void setProjectManager(MavenProjectManager projectManager) { + this.projectManager = projectManager; + } + + public void setMavenConfiguration(IMavenConfiguration mavenConfiguration) { + this.mavenConfiguration = mavenConfiguration; + } + + public void setMarkerManager(IMavenMarkerManager markerManager) { + this.markerManager = markerManager; + } + + public void setConsole(MavenConsole console) { + this.console = console; + } + + /** + * Configures Eclipse project passed in ProjectConfigurationRequest, using information from Maven project and other + * configuration request parameters + * <p> + * <i>Should be implemented by subclass</i> + * + * @param request a project configuration request + * @param monitor a progress monitor + */ + public abstract void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException; + + /** + * Removes Maven specific configuration from the project passed in ProjectConfigurationRequest + * + * @param request a project un-configuration request + * @param monitor a progress monitor + */ + @SuppressWarnings("unused") + public void unconfigure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException { + } + + /** + * Updates project configuration according project changes. + * <p> + * <i>Can be overwritten by subclass</i> + * + * @param event a project change event + * @param monitor a progress monitor + */ + @SuppressWarnings("unused") + public void mavenProjectChanged(MavenProjectChangedEvent event, IProgressMonitor monitor) throws CoreException { + } + + // IMavenProjectChangedListener + + public final void mavenProjectChanged(MavenProjectChangedEvent[] events, IProgressMonitor monitor) { + for(int i = 0; i < events.length; i++ ) { + try { + mavenProjectChanged(events[i], monitor); + } catch(CoreException ex) { + MavenLogger.log(ex); + } + } + } + + public int getPriority() { + return priority; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + // IExecutableExtension + public void setInitializationData(IConfigurationElement config, String propertyName, Object data) { + this.id = config.getAttribute(ATTR_ID); + this.name = config.getAttribute(ATTR_NAME); + String priorityString = config.getAttribute(ATTR_PRIORITY); + try { + priority = Integer.parseInt(priorityString); + } catch(Exception ex) { + priority = Integer.MAX_VALUE; + } + + IConfigurationElement[] mojos = config.getChildren("mojo"); //$NON-NLS-1$ + if(mojos != null && mojos.length > 0) { + pluginExecutionFilters = new ArrayList<PluginExecutionFilter>(); + for(IConfigurationElement mojo : mojos) { + String groupId = mojo.getAttribute("groupId"); //$NON-NLS-1$ + String artifactId = mojo.getAttribute("artifactId"); //$NON-NLS-1$ + String versionRange = mojo.getAttribute("versionRange"); //$NON-NLS-1$ + String goals = mojo.getAttribute("goals"); //$NON-NLS-1$ + addPluginExecutionFilter(groupId, artifactId, versionRange, goals); + } + } + } + + protected void addPluginExecutionFilter(String groupId, String artifactId, String versionRange, String goals) { + addPluginExecutionFilter(new PluginExecutionFilter(groupId, artifactId, versionRange, goals)); + } + + public void addPluginExecutionFilter(PluginExecutionFilter filter) { + // TODO validate + if(pluginExecutionFilters == null) { + pluginExecutionFilters = new ArrayList<PluginExecutionFilter>(); + } + pluginExecutionFilters.add(filter); + } + + // TODO move to a helper + public static void addNature(IProject project, String natureId, IProgressMonitor monitor) throws CoreException { + if(!project.hasNature(natureId)) { + IProjectDescription description = project.getDescription(); + String[] prevNatures = description.getNatureIds(); + String[] newNatures = new String[prevNatures.length + 1]; + System.arraycopy(prevNatures, 0, newNatures, 1, prevNatures.length); + newNatures[0] = natureId; + description.setNatureIds(newNatures); + project.setDescription(description, monitor); + } + } + + @Deprecated + protected <T> T getParameterValue(MavenSession session, MojoExecution execution, String parameter, Class<T> asType) + throws CoreException { + return maven.getMojoParameterValue(session, execution, parameter, asType); + } + + protected <T> T getParameterValue(String parameter, Class<T> asType, MavenSession session, MojoExecution mojoExecution) + throws CoreException { + PluginExecution execution = new PluginExecution(); + execution.setConfiguration(mojoExecution.getConfiguration()); + return maven.getMojoParameterValue(parameter, asType, session, mojoExecution.getPlugin(), execution, + mojoExecution.getGoal()); + } + + protected void assertHasNature(IProject project, String natureId) throws CoreException { + if(project.getNature(natureId) == null) { + throw new CoreException(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, -1, + Messages.AbstractProjectConfigurator_error_missing_nature + natureId, null)); + } + } + + @Override + public String toString() { + return id + ":" + name + "(" + priority + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + public AbstractBuildParticipant getBuildParticipant(MojoExecution execution) { + return null; + } + + public boolean isSupportedExecution(MojoExecution mojoExecution) { + if(pluginExecutionFilters == null) { + return false; + } + for(PluginExecutionFilter key : pluginExecutionFilters) { + if(key.match(mojoExecution)) { + return true; + } + } + return false; + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/CustomizableLifecycleMapping.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/CustomizableLifecycleMapping.java new file mode 100644 index 00000000..762ffd04 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/CustomizableLifecycleMapping.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2008 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.core.project.configurator; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.m2e.core.project.IMavenProjectFacade; + + +/** + * @author igor + */ +public class CustomizableLifecycleMapping extends AbstractLifecycleMapping { + public static final String EXTENSION_ID = "customizable"; //$NON-NLS-1$ + + private List<AbstractProjectConfigurator> configurators = new ArrayList<AbstractProjectConfigurator>(); + + @SuppressWarnings("unused") + public List<AbstractProjectConfigurator> getProjectConfigurators(IMavenProjectFacade facade, IProgressMonitor monitor) + throws CoreException { + return configurators; + } + + public void addConfigurator(AbstractProjectConfigurator configurator) { + this.configurators.add(configurator); + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/DefaultLifecycleMapping.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/DefaultLifecycleMapping.java new file mode 100644 index 00000000..3f5c2f00 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/DefaultLifecycleMapping.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2008 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.core.project.configurator; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +import org.apache.maven.lifecycle.MavenExecutionPlan; +import org.apache.maven.plugin.MojoExecution; + +import org.eclipse.m2e.core.internal.lifecycle.LifecycleMappingFactory; +import org.eclipse.m2e.core.project.IMavenProjectFacade; + + +/** + * DefaultLifecycleMapping + * + * @author igor + */ +public class DefaultLifecycleMapping extends CustomizableLifecycleMapping { + + private static class MojoExecutionKey { + private final MojoExecution execution; + + public MojoExecutionKey(MojoExecution execution) { + this.execution = execution; + } + + public MojoExecution getMojoExecution() { + return execution; + } + + public int hashCode() { + int hash = execution.getGroupId().hashCode(); + hash = 17 * hash + execution.getArtifactId().hashCode(); + hash = 17 * hash + execution.getVersion().hashCode(); + hash = 17 * execution.getGoal().hashCode(); + return hash; + } + + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if(!(obj instanceof MojoExecutionKey)) { + return false; + } + + MojoExecutionKey other = (MojoExecutionKey) obj; + + return execution.getGroupId().equals(other.execution.getGroupId()) + && execution.getArtifactId().equals(other.execution.getArtifactId()) + && execution.getVersion().equals(other.execution.getVersion()) + && execution.getGoal().equals(other.execution.getGoal()); + } + } + + public List<AbstractProjectConfigurator> getProjectConfigurators(IMavenProjectFacade facade, IProgressMonitor monitor) + throws CoreException { + + List<AbstractProjectConfigurator> configurators = super.getProjectConfigurators(facade, monitor); + + Map<MojoExecutionKey, AbstractProjectConfigurator> executions = new LinkedHashMap<MojoExecutionKey, AbstractProjectConfigurator>(); + + MavenExecutionPlan executionPlan = facade.getExecutionPlan(monitor); + execution: for(MojoExecution execution : executionPlan.getMojoExecutions()) { + MojoExecutionKey key = new MojoExecutionKey(execution); + for(AbstractProjectConfigurator configurator : configurators) { + if(configurator.isSupportedExecution(execution)) { + executions.put(key, configurator); + continue execution; + } + } + executions.put(key, null); + } + + for(Map.Entry<MojoExecutionKey, AbstractProjectConfigurator> entry : executions.entrySet()) { + MojoExecutionKey key = entry.getKey(); + if(entry.getValue() == null) { + // make sure to reuse the same instance of project configurator + for(AbstractProjectConfigurator configurator : executions.values()) { + if(configurator != null && configurator.isSupportedExecution(key.getMojoExecution())) { + entry.setValue(configurator); + break; + } + } + } + if(entry.getValue() == null) { + AbstractProjectConfigurator configurator = LifecycleMappingFactory.createProjectConfiguratorFor(key + .getMojoExecution()); + if(configurator != null) { + entry.setValue(configurator); + } + } + } + + ArrayList<AbstractProjectConfigurator> result = new ArrayList<AbstractProjectConfigurator>(); + + for(AbstractProjectConfigurator configurator : executions.values()) { + if(configurator != null && !result.contains(configurator)) { + result.add(configurator); + } + } + + return result; + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/ILifecycleMapping.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/ILifecycleMapping.java new file mode 100644 index 00000000..80ece0df --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/ILifecycleMapping.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.core.project.configurator; + +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +import org.apache.maven.plugin.MojoExecution; + +import org.eclipse.m2e.core.project.IMavenProjectFacade; + +/** + * LifecycleMapping + * + * @author igor + */ +public interface ILifecycleMapping { + String getId(); + + String getName(); + + /** + * Configure Eclipse workspace project according to Maven build project configuration. + */ + void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException; + + /** + * Undo any Eclipse project configuration done during previous call(s) to {@link #configure(ProjectConfigurationRequest, IProgressMonitor)} + */ + void unconfigure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException; + + /** + * Returns list of AbstractBuildParticipant that need to be executed during + * Eclipse workspace build. List can be empty but cannot be null. + */ + List<AbstractBuildParticipant> getBuildParticipants(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException; + + /** TODO does this belong here? */ + List<AbstractProjectConfigurator> getProjectConfigurators(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException; + + List<MojoExecution> getNotCoveredMojoExecutions(IMavenProjectFacade mavenProjectFacade, IProgressMonitor monitor) + throws CoreException; + + boolean isInterestingPhase(String phase); +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/MavenProjectConfigurator.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/MavenProjectConfigurator.java new file mode 100644 index 00000000..204fcb98 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/MavenProjectConfigurator.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * 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.core.project.configurator; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; + +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.model.Build; +import org.apache.maven.model.Plugin; +import org.apache.maven.project.MavenProject; + +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.core.MavenLogger; +import org.eclipse.m2e.core.embedder.IMaven; +import org.eclipse.m2e.core.project.ResolverConfiguration; + + +/** + * Generic project configurator that using Maven plugins + * + * @author Eugene Kuleshov + * @see AbstractProjectConfigurator + */ +public class MavenProjectConfigurator extends AbstractProjectConfigurator { + + String pluginKey; + + List<String> goals; + + public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) { + if(pluginKey == null || goals == null) { + return; + } + + MavenProject mavenProject = request.getMavenProject(); + Build build = mavenProject.getBuild(); + if(build != null) { + Map<String, Plugin> pluginMap = build.getPluginsAsMap(); + Plugin mavenPlugin = pluginMap.get(pluginKey); + if(mavenPlugin != null) { + IFile pomFile = request.getPom(); + ResolverConfiguration resolverConfiguration = request.getResolverConfiguration(); + // MavenPlugin plugin = MavenPlugin.getDefault(); + try { + IMaven maven = MavenPlugin.getDefault().getMaven(); + MavenExecutionRequest executionRequest = projectManager.createExecutionRequest(pomFile, resolverConfiguration, monitor); + executionRequest.setGoals(goals); + maven.execute(executionRequest, monitor); + } catch(Exception ex) { + String msg = ex.getMessage() == null ? ex.toString() : ex.getMessage(); + console.logError(msg); + MavenLogger.log(msg, ex); + } + + try { + request.getProject().refreshLocal(IResource.DEPTH_INFINITE, monitor); + } catch(CoreException ex) { + IStatus status = ex.getStatus(); + String msg = status.getMessage(); + Throwable t = status.getException(); + console.logError(msg + (t == null ? "" : "; " + t.toString())); //$NON-NLS-1$ //$NON-NLS-2$ + MavenLogger.log(ex); + } + } + } + } + + public String getPluginKey() { + return this.pluginKey; + } + + public List<String> getGoals() { + return this.goals; + } + + // IExecutableExtension + + @Override + public void setInitializationData(IConfigurationElement config, String propertyName, Object data) { + super.setInitializationData(config, propertyName, data); + + Pattern pattern = Pattern.compile("(.+?)\\:(.+?)\\|(.+)"); //$NON-NLS-1$ + String params = (String) data; + if(params != null) { + Matcher matcher = pattern.matcher(params); + if(matcher.find() && matcher.groupCount() == 3) { + pluginKey = matcher.group(1) + ":" + matcher.group(2); //$NON-NLS-1$ + goals = Arrays.asList(matcher.group(3).split("\\|")); //$NON-NLS-1$ + return; + } + } + MavenLogger.log("Unable to parse configuration for project configurator " + getId() + "; " + data, null); //$NON-NLS-2$ + } + + @Override + public String toString() { + return super.toString() + " " + pluginKey + goals; //$NON-NLS-1$ + } + +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/MavenResourcesProjectConfigurator.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/MavenResourcesProjectConfigurator.java new file mode 100644 index 00000000..87c013fe --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/MavenResourcesProjectConfigurator.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ + +package org.eclipse.m2e.core.project.configurator; + +import org.eclipse.m2e.core.internal.project.MojoExecutionProjectConfigurator; + +/** + * Project configurator for maven-resources-plugin + */ +public class MavenResourcesProjectConfigurator extends MojoExecutionProjectConfigurator { + public MavenResourcesProjectConfigurator() { + super(true /*runOnIncremental*/); + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/MojoExecutionBuildParticipant.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/MojoExecutionBuildParticipant.java new file mode 100644 index 00000000..f0852f35 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/MojoExecutionBuildParticipant.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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.core.project.configurator; + +import java.util.Set; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.IProgressMonitor; + +import org.apache.maven.plugin.MojoExecution; + +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.embedder.IMaven; + + +/** + * MojoExecutionBuildParticipant + * + * @author igor + */ +public class MojoExecutionBuildParticipant extends AbstractBuildParticipant { + + private final MojoExecution execution; + private final boolean runOnIncremental; + + public MojoExecutionBuildParticipant(MojoExecution execution, boolean runOnIncremental) { + this.execution = execution; + this.runOnIncremental = runOnIncremental; + } + + public Set<IProject> build(int kind, IProgressMonitor monitor) throws Exception { + if(appliesToBuildKind(kind)) { + IMaven maven = MavenPlugin.getDefault().getMaven(); + + maven.execute(getSession(), getMojoExecution(), monitor); + } + return null; + } + + public boolean appliesToBuildKind(int kind) { + if(IncrementalProjectBuilder.FULL_BUILD == kind || IncrementalProjectBuilder.CLEAN_BUILD == kind) { + return true; + } + return runOnIncremental; + } + + public MojoExecution getMojoExecution() { + return execution; + } + +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/NoopLifecycleMapping.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/NoopLifecycleMapping.java new file mode 100644 index 00000000..9273aa71 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/NoopLifecycleMapping.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * 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.core.project.configurator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.m2e.core.project.IMavenProjectFacade; + +/** + * NoopLifecycleMapping + * + * @author igor + */ +public class NoopLifecycleMapping extends AbstractLifecycleMapping { + + public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException { + // do nothing + } + + public List<AbstractBuildParticipant> getBuildParticipants(IMavenProjectFacade facade, IProgressMonitor monitor) + throws CoreException { + return new ArrayList<AbstractBuildParticipant>(); + } + + public List<AbstractProjectConfigurator> getProjectConfigurators(IMavenProjectFacade facade, IProgressMonitor monitor) + throws CoreException { + return new ArrayList<AbstractProjectConfigurator>(); + } + + public void unconfigure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException { + // do nothing + } + + public List<String> getPotentialMojoExecutionsForBuildKind(IMavenProjectFacade facade, int kind, IProgressMonitor progressMonitor) { + return Collections.emptyList(); + } + + public boolean isInterestingPhase(String phase) { + return false; + } +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/PluginExecutionFilter.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/PluginExecutionFilter.java new file mode 100644 index 00000000..18f8b260 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/PluginExecutionFilter.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * 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.core.project.configurator; + +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; +import org.apache.maven.plugin.MojoExecution; + + +public final class PluginExecutionFilter { + + private final String groupId; + + private final String artifactId; + + private final String versionRange; + + private final Set<String> goals; + + private final VersionRange parsedVersionRange; + + public PluginExecutionFilter(String groupId, String artifactId, String versionRange, String goals) { + this.groupId = groupId; + this.artifactId = artifactId; + this.versionRange = versionRange; + this.goals = new LinkedHashSet<String>(Arrays.asList(goals.split(","))); //$NON-NLS-1$; + try { + this.parsedVersionRange = VersionRange.createFromVersionSpec(versionRange); + } catch(InvalidVersionSpecificationException e) { + throw new IllegalArgumentException("Can't parse version range", e); + } + } + + public String getVersionRange() { + return this.versionRange; + } + + public String getGroupId() { + return this.groupId; + } + + public String getArtifactId() { + return this.artifactId; + } + + public Set<String> getGoals() { + return this.goals; + } + + /** + * @return true if mojoExecution matches this key or false otherwise + */ + public boolean match(MojoExecution mojoExecution) { + if(!groupId.equals(mojoExecution.getGroupId()) || !artifactId.equals(mojoExecution.getArtifactId())) { + return false; + } + + DefaultArtifactVersion version = new DefaultArtifactVersion(mojoExecution.getVersion()); + + if(!parsedVersionRange.containsVersion(version)) { + return false; + } + + return goals.contains(mojoExecution.getGoal()); + } + +} diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/ProjectConfigurationRequest.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/ProjectConfigurationRequest.java new file mode 100644 index 00000000..f6f08f49 --- /dev/null +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/configurator/ProjectConfigurationRequest.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * 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.core.project.configurator; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.project.MavenProject; + +import org.eclipse.m2e.core.project.IMavenProjectFacade; +import org.eclipse.m2e.core.project.ResolverConfiguration; + +/** + * ProjectConfigurationRequest + * + * @author igor + */ +public class ProjectConfigurationRequest { + private final boolean updateSources; + private final IMavenProjectFacade facade; + private final MavenProject mavenProject; + private final MavenSession mavenSession; + + public ProjectConfigurationRequest(IMavenProjectFacade facade, MavenProject mavenProject, MavenSession mavenSession, boolean updateSources) { + this.facade = facade; + this.mavenSession = mavenSession; + this.updateSources = updateSources; + this.mavenProject = mavenProject; + } + + public IProject getProject() { + return facade.getProject(); + } + + public ResolverConfiguration getResolverConfiguration() { + return facade.getResolverConfiguration(); + } + + public boolean isProjectConfigure() { + return updateSources; + } + + public boolean isProjectImport() { + return !updateSources; + } + + public MavenProject getMavenProject() { + return mavenProject; + } + + public MavenSession getMavenSession() { + return mavenSession; + } + + public IFile getPom() { + return facade.getPom(); + } + + public IMavenProjectFacade getMavenProjectFacade() { + return facade; + } +} |