diff options
29 files changed, 1002 insertions, 510 deletions
diff --git a/org.eclipse.m2e.core.ui/plugin.properties b/org.eclipse.m2e.core.ui/plugin.properties index a3a5a5d8..6f61fac0 100644 --- a/org.eclipse.m2e.core.ui/plugin.properties +++ b/org.eclipse.m2e.core.ui/plugin.properties @@ -59,6 +59,7 @@ m2.editor.pom.name=Maven POM Editor m2.shortcut.addDependency=Add Maven Dependency m2.shortcut.addPlugin=Add Maven Plugin +m2.shortcut.updateProject=Update Project openpomaction.label = Open POM openpomaction.label2 = Open POM @@ -71,6 +72,7 @@ openprojectaction.label4 = Open Project Page command.opentype.description = Open Maven Type command.adddependency.description = Add Maven Dependency command.addplugin.description = Add Maven Plugin +command.updateproject.description = Update Maven Project configuration and dependencies keyword.label = maven page.installations.name = Installations page.usersettings.name = User Settings diff --git a/org.eclipse.m2e.core.ui/plugin.xml b/org.eclipse.m2e.core.ui/plugin.xml index 965e5522..89e96aee 100644 --- a/org.eclipse.m2e.core.ui/plugin.xml +++ b/org.eclipse.m2e.core.ui/plugin.xml @@ -125,6 +125,7 @@ objectClass="org.eclipse.core.resources.IProject" adaptable="true"> <action id="org.eclipse.m2e.updateProjectAction" + definitionId="org.eclipse.m2e.core.ui.command.updateProject" class="org.eclipse.m2e.core.ui.internal.actions.UpdateMavenProjectAction" label="%m2.popup.UpdateMavenProjectAction" style="push" @@ -260,6 +261,7 @@ adaptable="true" objectClass="org.eclipse.ui.IWorkingSet"> <action id="org.eclipse.m2e.updateConfigurationAction" + definitionId="org.eclipse.m2e.core.ui.command.updateProject" class="org.eclipse.m2e.core.ui.internal.actions.UpdateMavenProjectAction" label="%m2.popup.UpdateMavenProjectAction" style="push" @@ -368,8 +370,22 @@ id="org.eclipse.m2e.core.ui.command.addPlugin" name="%m2.shortcut.addPlugin"> </command> + <command + categoryId="org.eclipse.ui.category.window" + description="%command.updateproject.description" + id="org.eclipse.m2e.core.ui.command.updateProject" + name="%m2.shortcut.updateProject"> + </command> </extension> + <extension + point="org.eclipse.ui.handlers"> + <handler + class="org.eclipse.m2e.core.ui.internal.actions.UpdateMavenProjectCommandHandler" + commandId="org.eclipse.m2e.core.ui.command.updateProject"> + </handler> + </extension> + <extension point="org.eclipse.ui.keywords"> <keyword id="org.eclipse.m2e.core.maven" label="%keyword.label"/> </extension> @@ -508,6 +524,12 @@ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="Ctrl+Shift+P"> </key> + <key + commandId="org.eclipse.m2e.core.ui.command.updateProject" + contextId="org.eclipse.ui.contexts.window" + schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" + sequence="Alt+F5"> + </key> </extension> <extension point="org.eclipse.ui.propertyPages"> <page id="org.eclipse.m2e.core.MavenProjectPreferencePage" diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java index 48824ed9..339c4796 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java @@ -31,8 +31,12 @@ public class Messages extends NLS { public static String AddDependencyDialog_artifactId_label; + public static String AddDependencyDialog_artifactId_error; + public static String AddDependencyDialog_groupId_label; + public static String AddDependencyDialog_groupId_error; + public static String AddDependencyDialog_scope_label; public static String AddDependencyDialog_version_label; diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/MavenActionSupport.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/MavenActionSupport.java index 29868768..a2217a0c 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/MavenActionSupport.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/MavenActionSupport.java @@ -18,26 +18,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.m2e.core.embedder.ArtifactKey; import org.eclipse.m2e.core.embedder.ArtifactRef; -import org.eclipse.m2e.core.internal.IMavenConstants; import org.eclipse.m2e.core.project.IMavenProjectFacade; import org.eclipse.m2e.core.ui.internal.M2EUIPluginActivator; @@ -100,43 +93,7 @@ public abstract class MavenActionSupport implements IObjectActionDelegate { } protected IFile getPomFileFromPomEditorOrViewSelection() { - IFile file = null; - - //350136 we need to process the selection first! that's what is relevant for any popup menu action we have. - //the processing of active editor first might have been only relevant when we had the actions in main menu, but even - // then the popups were wrong.. - Object o = selection.iterator().next(); - - if(o instanceof IProject) { - file = ((IProject) o).getFile(IMavenConstants.POM_FILE_NAME); - } else if(o instanceof IFile) { - file = (IFile) o; - } - if(file != null) { - return file; - } - // - // If I am in the POM editor I want to get hold of the IFile that is currently in the buffer - // - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - - if(window != null) { - IWorkbenchPage page = window.getActivePage(); - if(page != null) { - IEditorPart editor = page.getActiveEditor(); - if(editor != null) { - IEditorInput input = editor.getEditorInput(); - if(input instanceof IFileEditorInput) { - IFileEditorInput fileInput = (IFileEditorInput) input; - file = fileInput.getFile(); - if(file.getName().equals(IMavenConstants.POM_FILE_NAME)) { - return file; - } - } - } - } - } - return null; + return SelectionUtil.getPomFileFromPomEditorOrViewSelection(selection); } } diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/MavenProjectActionSupport.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/MavenProjectActionSupport.java index 514c0273..1e328d0b 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/MavenProjectActionSupport.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/MavenProjectActionSupport.java @@ -11,53 +11,15 @@ package org.eclipse.m2e.core.ui.internal.actions; -import java.util.ArrayList; -import java.util.Iterator; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkbenchWindowActionDelegate; -import org.eclipse.ui.IWorkingSet; - -import org.eclipse.m2e.core.internal.IMavenConstants; public abstract class MavenProjectActionSupport extends MavenActionSupport implements IWorkbenchWindowActionDelegate { - private static final Logger log = LoggerFactory.getLogger(MavenProjectActionSupport.class); - protected IProject[] getProjects() { - ArrayList<IProject> projectList = new ArrayList<IProject>(); - if(selection != null) { - for(Iterator<?> it = selection.iterator(); it.hasNext();) { - Object o = it.next(); - if(o instanceof IProject) { - projectList.add((IProject) o); - } else if(o instanceof IWorkingSet) { - IWorkingSet workingSet = (IWorkingSet) o; - for(IAdaptable adaptable : workingSet.getElements()) { - IProject project = (IProject) adaptable.getAdapter(IProject.class); - try { - if(project != null && project.isAccessible() && project.hasNature(IMavenConstants.NATURE_ID)) { - projectList.add(project); - } - } catch(CoreException ex) { - log.error(ex.getMessage(), ex); - } - } - } - } - } - if(projectList.isEmpty()) { - return ResourcesPlugin.getWorkspace().getRoot().getProjects(); - } - return projectList.toArray(new IProject[projectList.size()]); + return SelectionUtil.getProjects(selection, true); } public void dispose() { diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/SelectionUtil.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/SelectionUtil.java index d845902f..e8711c3c 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/SelectionUtil.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/SelectionUtil.java @@ -27,6 +27,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IStorage; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; @@ -36,10 +37,14 @@ import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; +import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IStorageEditorInput; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.IWorkingSetManager; import org.eclipse.ui.PlatformUI; @@ -354,4 +359,94 @@ public class SelectionUtil { throw new CoreException(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, -1, // Messages.SelectionUtil_error_cannot_read, null)); } + + /** + * Finds the pom.xml from the given selection or the current active pom editor. + * + * @param selection + * @return the first pom.xml from the given selection or the current active pom editor. returns + * <code>null</null> if no pom was found. + * @since 1.4.0 + */ + public static IFile getPomFileFromPomEditorOrViewSelection(ISelection selection) { + IFile file = null; + + //350136 we need to process the selection first! that's what is relevant for any popup menu action we have. + //the processing of active editor first might have been only relevant when we had the actions in main menu, but even + // then the popups were wrong.. + if(selection instanceof IStructuredSelection) { + Object o = ((IStructuredSelection) selection).iterator().next(); + + if(o instanceof IProject) { + file = ((IProject) o).getFile(IMavenConstants.POM_FILE_NAME); + } else if(o instanceof IFile) { + file = (IFile) o; + } + if(file != null) { + return file; + } + } + // + // If I am in the POM editor I want to get hold of the IFile that is currently in the buffer + // + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + + if(window != null) { + IWorkbenchPage page = window.getActivePage(); + if(page != null) { + IEditorPart editor = page.getActiveEditor(); + if(editor != null) { + IEditorInput input = editor.getEditorInput(); + if(input instanceof IFileEditorInput) { + IFileEditorInput fileInput = (IFileEditorInput) input; + file = fileInput.getFile(); + if(file.getName().equals(IMavenConstants.POM_FILE_NAME)) { + return file; + } + } + } + } + } + return null; + } + + /** + * Returns all the Maven projects found in the given selection. If no projects are found in the selection and + * <code>includeAll</code> is true, all workspace projects are returned. + * + * @param selection + * @param includeAll flag to return all workspace projects if selection doesn't contain any Maven projects. + * @return an array of {@link IProject} containing all the Maven projects found in the given selection, or all the + * workspace projects if no Maven project was found and <code>includeAll</code> is true. + * @since 1.4.0 + */ + public static IProject[] getProjects(ISelection selection, boolean includeAll) { + ArrayList<IProject> projectList = new ArrayList<IProject>(); + if(selection instanceof IStructuredSelection) { + for(Iterator<?> it = ((IStructuredSelection) selection).iterator(); it.hasNext();) { + Object o = it.next(); + if(o instanceof IProject) { + projectList.add((IProject) o); + } else if(o instanceof IWorkingSet) { + IWorkingSet workingSet = (IWorkingSet) o; + for(IAdaptable adaptable : workingSet.getElements()) { + IProject project = (IProject) adaptable.getAdapter(IProject.class); + try { + if(project != null && project.isAccessible() && project.hasNature(IMavenConstants.NATURE_ID)) { + projectList.add(project); + } + } catch(CoreException ex) { + log.error(ex.getMessage(), ex); + } + } + } + } + } + + if(projectList.isEmpty() && includeAll) { + return ResourcesPlugin.getWorkspace().getRoot().getProjects(); + } + return projectList.toArray(new IProject[projectList.size()]); + } + } diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/UpdateMavenProjectAction.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/UpdateMavenProjectAction.java index ae1d8e97..471fb0f5 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/UpdateMavenProjectAction.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/UpdateMavenProjectAction.java @@ -12,12 +12,14 @@ package org.eclipse.m2e.core.ui.internal.actions; import org.eclipse.jface.action.IAction; -import org.eclipse.jface.window.Window; - -import org.eclipse.m2e.core.ui.internal.UpdateMavenProjectJob; -import org.eclipse.m2e.core.ui.internal.dialogs.UpdateMavenProjectsDialog; +/** + * UpdateMavenProjectAction + * + * @deprecated this action is deprecated in favor of {@link UpdateMavenProjectCommandHandler} + */ +@Deprecated public class UpdateMavenProjectAction extends MavenProjectActionSupport { public static final String ID = "org.eclipse.m2e.updateConfigurationAction"; //$NON-NLS-1$ @@ -26,11 +28,7 @@ public class UpdateMavenProjectAction extends MavenProjectActionSupport { } public void run(IAction action) { - UpdateMavenProjectsDialog dialog = new UpdateMavenProjectsDialog(getShell(), getProjects()); - if(dialog.open() == Window.OK) { - new UpdateMavenProjectJob(dialog.getSelectedProjects(), dialog.isOffline(), dialog.isForceUpdateDependencies(), - dialog.isUpdateConfiguration(), dialog.isCleanProjects(), dialog.isRefreshFromLocal()).schedule(); - } + UpdateMavenProjectCommandHandler.openUpdateProjectsDialog(getShell(), getProjects()); } } diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/UpdateMavenProjectCommandHandler.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/UpdateMavenProjectCommandHandler.java new file mode 100644 index 00000000..eba5b779 --- /dev/null +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/actions/UpdateMavenProjectCommandHandler.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2008-2013 Sonatype, Inc. and others + * 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 + * Red Hat, Inc. - transformed into a CommandHandler + *******************************************************************************/ + +package org.eclipse.m2e.core.ui.internal.actions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.handlers.HandlerUtil; + +import org.eclipse.m2e.core.internal.IMavenConstants; +import org.eclipse.m2e.core.ui.internal.UpdateMavenProjectJob; +import org.eclipse.m2e.core.ui.internal.dialogs.UpdateMavenProjectsDialog; + + +/** + * Handler for the Update Project command. This can then be bound to whatever key binding the user prefers (defaults to + * Alt+F5). + * + * @author Fred Bricon + * @since 1.4.0 + */ +public class UpdateMavenProjectCommandHandler extends AbstractHandler { + + private static final Logger log = LoggerFactory.getLogger(UpdateMavenProjectCommandHandler.class); + + public Object execute(final ExecutionEvent event) { + + ISelection selection = HandlerUtil.getCurrentSelection(event); + + Shell shell = HandlerUtil.getActiveWorkbenchWindow(event).getShell(); + + IProject[] projects = SelectionUtil.getProjects(selection, false); + + //If no projects in the current selection, look at the active editor + if(projects == null || projects.length == 0) { + projects = getProjectInActiveEditor(event); + } + + //If no projects found, select all projects in the workspace + if(projects == null || projects.length == 0) { + projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + } + + openUpdateProjectsDialog(shell, projects); + + return null; + } + + /** + * get the (maven) project in current active editor + */ + private IProject[] getProjectInActiveEditor(ExecutionEvent event) { + try { + IWorkbenchPart activePart = HandlerUtil.getActivePart(event); + if(activePart instanceof IEditorPart) { + IEditorPart editorPart = (IEditorPart) activePart; + if(editorPart.getEditorInput() instanceof IFileEditorInput) { + IFileEditorInput fileInput = (IFileEditorInput) editorPart.getEditorInput(); + IProject project = fileInput.getFile().getProject(); + if(project != null && project.isAccessible() && project.hasNature(IMavenConstants.NATURE_ID)) { + return new IProject[] {project}; + } + } + } + } catch(CoreException ex) { + log.error(ex.getMessage(), ex); + } + return null; + } + + /* package */static void openUpdateProjectsDialog(Shell shell, IProject[] projects) { + UpdateMavenProjectsDialog dialog = new UpdateMavenProjectsDialog(shell, projects); + if(dialog.open() == Window.OK) { + new UpdateMavenProjectJob(dialog.getSelectedProjects(), dialog.isOffline(), dialog.isForceUpdateDependencies(), + dialog.isUpdateConfiguration(), dialog.isCleanProjects(), dialog.isRefreshFromLocal()).schedule(); + } + } +} diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/dialogs/MavenRepositorySearchDialog.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/dialogs/MavenRepositorySearchDialog.java index 82c1a450..ae1c6cda 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/dialogs/MavenRepositorySearchDialog.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/dialogs/MavenRepositorySearchDialog.java @@ -17,6 +17,7 @@ import java.util.Set; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -44,6 +45,7 @@ import org.eclipse.m2e.core.embedder.ArtifactKey; import org.eclipse.m2e.core.internal.index.IIndex; import org.eclipse.m2e.core.internal.index.IndexedArtifact; import org.eclipse.m2e.core.internal.index.IndexedArtifactFile; +import org.eclipse.m2e.core.ui.internal.M2EUIPluginActivator; import org.eclipse.m2e.core.ui.internal.Messages; import org.eclipse.m2e.core.ui.internal.search.util.Packaging; import org.eclipse.m2e.core.ui.internal.util.M2EUIUtils; @@ -321,6 +323,7 @@ public class MavenRepositorySearchDialog extends AbstractMavenDialog { txtArtifactId.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { + updateStatus(validateArtifactEntries()); if(!ignoreTextChange) { computeResultFromField(valueOrNull(txtGroupId.getText()), valueOrNull(txtArtifactId.getText()), valueOrNull(txtVersion.getText())); @@ -331,6 +334,7 @@ public class MavenRepositorySearchDialog extends AbstractMavenDialog { txtGroupId.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { + updateStatus(validateArtifactEntries()); if(!ignoreTextChange) { computeResultFromField(valueOrNull(txtGroupId.getText()), valueOrNull(txtArtifactId.getText()), valueOrNull(txtVersion.getText())); @@ -347,15 +351,30 @@ public class MavenRepositorySearchDialog extends AbstractMavenDialog { } }); + updateStatus(validateArtifactEntries()); return composite; } + IStatus validateArtifactEntries() { + if(txtArtifactId.getText().isEmpty()) + return new Status(IStatus.ERROR, M2EUIPluginActivator.PLUGIN_ID, Messages.AddDependencyDialog_artifactId_error); + + if(txtGroupId.getText().isEmpty()) + return new Status(IStatus.ERROR, M2EUIPluginActivator.PLUGIN_ID, Messages.AddDependencyDialog_groupId_error); + + return new Status(IStatus.OK, M2EUIPluginActivator.PLUGIN_ID, "");//$NON-NLS-1$; + } + void okPressedDelegate() { okPressed(); } void updateStatusDelegate(IStatus status) { - updateStatus(status); + IStatus validationStatus = validateArtifactEntries(); + if(validationStatus.isOK()) + updateStatus(status); + else + updateStatus(validationStatus); } private String valueOrNull(String text) { diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties index 592d779f..cc7917f3 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties @@ -4,7 +4,9 @@ AddDependencyAction_error_msg=Can't add dependency to {0} AddDependencyAction_error_title=Add Dependency AddDependencyAction_searchDialog_title=Add Dependency AddDependencyDialog_artifactId_label=Artifact Id\: +AddDependencyDialog_artifactId_error=Artifact Id cannot be empty AddDependencyDialog_groupId_label=Group Id\: +AddDependencyDialog_groupId_error=Group Id cannot be empty AddDependencyDialog_scope_label=Scope\: AddDependencyDialog_version_label=Version\: AddPluginAction_searchDialog_title=Add Plugin @@ -223,7 +225,7 @@ MavenProjectWizardArchetypePage_error_no=No archetypes currently available. The MavenProjectWizardArchetypePage_error_read=Unable to read catalog factory. MavenProjectWizardArchetypePage_error_resolve=The archetype {0} could not be resolved. MavenProjectWizardArchetypePage_error_resolve2=Can't resolve Archetype {0} -MavenProjectWizardArchetypePage_lblCatalog=C&atalog\: +MavenProjectWizardArchetypePage_lblCatalog=Ca&talog\: MavenProjectWizardArchetypePage_lblFilter=&Filter\: MavenProjectWizardArchetypePage_task_downloading=Downloading Archetype MavenProjectWizardArchetypePage_task_indexing=indexing... diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenModuleWizard.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenModuleWizard.java index 67dac3a8..dc519f9f 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenModuleWizard.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenModuleWizard.java @@ -123,7 +123,9 @@ public class MavenModuleWizard extends AbstractMavenProjectWizard implements INe parentPage.addArchetypeSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { - archetypePage.setUsed(!parentPage.isSimpleProject()); + boolean isArchetype = !parentPage.isSimpleProject(); + archetypePage.setUsed(isArchetype); + parametersPage.setUsed(isArchetype); } }); diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenProjectWizardArchetypeParametersPage.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenProjectWizardArchetypeParametersPage.java index a638a9df..82346395 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenProjectWizardArchetypeParametersPage.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenProjectWizardArchetypeParametersPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008-2010 Sonatype, Inc. + * Copyright (c) 2008-2013 Sonatype, Inc. and others * 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 @@ -70,6 +70,7 @@ import org.eclipse.m2e.core.ui.internal.components.TextComboBoxCellEditor; * a project (thus the class name pun). */ public class MavenProjectWizardArchetypeParametersPage extends AbstractMavenWizardPage { + private static final Logger log = LoggerFactory.getLogger(MavenProjectWizardArchetypeParametersPage.class); public static final String DEFAULT_VERSION = "0.0.1-SNAPSHOT"; //$NON-NLS-1$ @@ -304,9 +305,11 @@ public class MavenProjectWizardArchetypeParametersPage extends AbstractMavenWiza * @see org.eclipse.jface.wizard.WizardPage#setPageComplete(boolean) */ void validate() { - String error = validateInput(); - setErrorMessage(error); - setPageComplete(error == null); + if(isVisible()) { + String error = validateInput(); + setErrorMessage(error); + setPageComplete(error == null); + } } private String validateInput() { @@ -539,16 +542,23 @@ public class MavenProjectWizardArchetypeParametersPage extends AbstractMavenWiza public void setVisible(boolean visible) { super.setVisible(visible); + boolean shouldValidate = false; + if(visible) { + + if(archetypeChanged && archetype != null) { + archetypeChanged = false; + loadArchetypeDescriptor(); + shouldValidate = true; + } + if(groupIdCombo.getText().length() == 0 && groupIdCombo.getItemCount() > 0) { groupIdCombo.setText(groupIdCombo.getItem(0)); packageCombo.setText(getDefaultJavaPackage()); packageCustomized = false; } - if(archetypeChanged && archetype != null) { - archetypeChanged = false; - loadArchetypeDescriptor(); + if(shouldValidate) { validate(); } @@ -642,4 +652,8 @@ public class MavenProjectWizardArchetypeParametersPage extends AbstractMavenWiza return pkg.toString(); } + + private boolean isVisible() { + return getControl() != null && getControl().isVisible(); + } } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/IMavenConstants.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/IMavenConstants.java index 8c417d89..4591b921 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/IMavenConstants.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/IMavenConstants.java @@ -89,6 +89,11 @@ public interface IMavenConstants { public static final String MARKER_ATTR_VERSION = "version";//$NON-NLS-1$ + /** + * @since 1.4.0 + */ + public static final String MARKER_ATTR_CLASSIFIER = "classifier";//$NON-NLS-1$ + public static final String EDITOR_HINT_PARENT_GROUP_ID = "parent_groupid";//$NON-NLS-1$ public static final String EDITOR_HINT_PARENT_VERSION = "parent_version";//$NON-NLS-1$ diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/builder/MavenBuilder.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/builder/MavenBuilder.java index 9faf9596..6562d046 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/builder/MavenBuilder.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/builder/MavenBuilder.java @@ -197,11 +197,22 @@ public class MavenBuilder extends IncrementalProjectBuilder implements DeltaProv /*package*/IMavenProjectFacade getProjectFacade(final IFile pomResource, final IProject project, final IProgressMonitor monitor) throws CoreException { + + // facade refresh should be forced whenever pom.xml has changed + // there is no delta info for full builds + // but these are usually forced from Project/Clean + // so assume pom did not change + boolean force = false; + IResourceDelta delta = getDelta(project); + if(delta != null) { + delta = delta.findMember(pomResource.getFullPath()); + force = delta != null && delta.getKind() == IResourceDelta.CHANGED; + } IMavenProjectFacade projectFacade = projectManager.create(getProject(), monitor); - if(delta == null || projectFacade == null || projectFacade.isStale()) { + if(force || projectFacade == null || projectFacade.isStale()) { projectManager.refresh(Collections.singleton(pomResource), monitor); projectFacade = projectManager.create(project, monitor); if(projectFacade == null) { diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExternalRuntime.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExternalRuntime.java index 3603d7fb..e539678f 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExternalRuntime.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExternalRuntime.java @@ -74,9 +74,14 @@ public class MavenExternalRuntime implements MavenRuntime { } private File getLauncherConfigurationFile() { - return new File(location, "bin/m2.conf"); //$NON-NLS-1$ + File m2Conf = new File(location, "bin/m2.conf"); + // Look for Tesla location + if(m2Conf.exists() == false) { + m2Conf = new File(location, "conf/m2.conf"); + } + return m2Conf; //$NON-NLS-1$ } - + public void createLauncherConfiguration(final IMavenLauncherConfiguration collector, IProgressMonitor monitor) throws CoreException { diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/markers/ArtifactNotFoundProblemInfo.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/markers/ArtifactNotFoundProblemInfo.java index 130d79ce..243c31aa 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/markers/ArtifactNotFoundProblemInfo.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/markers/ArtifactNotFoundProblemInfo.java @@ -11,10 +11,14 @@ package org.eclipse.m2e.core.internal.markers; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; import org.eclipse.osgi.util.NLS; import org.sonatype.aether.artifact.Artifact; +import org.eclipse.m2e.core.internal.IMavenConstants; + public class ArtifactNotFoundProblemInfo extends MavenProblemInfo { private final Artifact artifact; @@ -35,4 +39,19 @@ public class ArtifactNotFoundProblemInfo extends MavenProblemInfo { public Artifact getArtifact() { return this.artifact; } + + /** + * Adds the missing artifact groupId, artifactId, version and classifier as marker attributes. + * + * @since 1.4.0 + */ + public void processMarker(IMarker marker) throws CoreException { + super.processMarker(marker); + if(artifact != null) { + marker.setAttribute(IMavenConstants.MARKER_ATTR_GROUP_ID, artifact.getGroupId()); + marker.setAttribute(IMavenConstants.MARKER_ATTR_ARTIFACT_ID, artifact.getArtifactId()); + marker.setAttribute(IMavenConstants.MARKER_ATTR_VERSION, artifact.getVersion()); + marker.setAttribute(IMavenConstants.MARKER_ATTR_CLASSIFIER, artifact.getClassifier()); + } + } } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java index 2ee5e1ff..3d44b409 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java @@ -340,31 +340,46 @@ public class ProjectConfigurationManager implements IProjectConfigurationManager //project names to the errors encountered when updating them Map<String, IStatus> updateStatus = new HashMap<String, IStatus>(); - // refresh projects and update all dependencies - // this will ensure that project registry is up-to-date on GAV of all projects being updated - // TODO this sends multiple update events, rework using low-level registry update methods - for(IFile pom : pomFiles) { - if(monitor.isCanceled()) { - throw new OperationCanceledException(); - } - - IProject project = pom.getProject(); + List<IFile> pomsToRefresh = new ArrayList<IFile>(); - monitor.subTask(project.getName()); + // refresh from local filesystem + if(refreshFromLocal) { + for(IFile pom : pomFiles) { + if(monitor.isCanceled()) { + throw new OperationCanceledException(); + } - try { - if(refreshFromLocal) { + IProject project = pom.getProject(); + try { project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); + pomsToRefresh.add(pom); + } catch(CoreException ex) { + updateStatus.put(project.getName(), ex.getStatus()); } - projectManager.refresh(Collections.singleton(pom), new SubProgressMonitor(monitor, 1, - SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); + } + } else { + pomsToRefresh.addAll(pomFiles); + } + + // refresh projects and update all dependencies + // this will ensure that project registry is up-to-date on GAV of all projects being updated + // TODO this sends multiple update events, rework using low-level registry update methods + try { + projectManager.refresh(pomsToRefresh, new SubProgressMonitor(monitor, pomFiles.size())); + + for(IFile pom : pomsToRefresh) { + IProject project = pom.getProject(); IMavenProjectFacade facade = projectManager.getProject(project); if(facade != null) { // facade is null if pom.xml cannot be read projects.put(pom, facade); } updateStatus.put(project.getName(), Status.OK_STATUS); - } catch(CoreException ex) { + } + } catch(CoreException ex) { + // TODO per-project status + for(IFile pom : pomsToRefresh) { + IProject project = pom.getProject(); updateStatus.put(project.getName(), ex.getStatus()); } } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/WorkspaceStateWriter.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/WorkspaceStateWriter.java index cc3c1c1e..feffab14 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/WorkspaceStateWriter.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/WorkspaceStateWriter.java @@ -22,15 +22,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.QualifiedName; -import org.apache.maven.artifact.Artifact; +import org.apache.maven.project.MavenProject; +import org.eclipse.m2e.core.embedder.ArtifactKey; import org.eclipse.m2e.core.internal.project.registry.MavenProjectManager; import org.eclipse.m2e.core.project.IMavenProjectChangedListener; import org.eclipse.m2e.core.project.IMavenProjectFacade; @@ -41,6 +44,8 @@ import org.eclipse.m2e.core.project.MavenProjectChangedEvent; * Maintains map file of maven artifacts present in workspace. */ public class WorkspaceStateWriter implements IMavenProjectChangedListener { + private static QualifiedName PPROP_EXTENSION = new QualifiedName(WorkspaceStateWriter.class.getName(), "extension"); //$NON-NLS-1$ + private static final Logger log = LoggerFactory.getLogger(WorkspaceStateWriter.class); private MavenProjectManager projectManager; @@ -55,28 +60,47 @@ public class WorkspaceStateWriter implements IMavenProjectChangedListener { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); for(IMavenProjectFacade projectFacade : projectManager.getProjects()) { - if(!projectFacade.getProject().isAccessible()) { - log.debug("Project registry contains closed project {}", projectFacade.getProject()); + IProject project = projectFacade.getProject(); + if(!project.isAccessible()) { + log.debug("Project registry contains closed project {}", project); // this is actually a bug somewhere in registry refresh logic, closed projects should not be there continue; } try { - Artifact artifact = projectFacade.getMavenProject(monitor).getArtifact(); + ArtifactKey artifact = projectFacade.getArtifactKey(); IFile pomFile = projectFacade.getPom(); IPath location = pomFile.getLocation(); if(location != null) { File pom = location.toFile(); if(pom.canRead()) { - String key = artifact.getGroupId() + ":" + artifact.getArtifactId() + ":pom:" + artifact.getBaseVersion(); //$NON-NLS-1$ //$NON-NLS-2$ + String key = artifact.getGroupId() + ":" + artifact.getArtifactId() + ":pom:" + artifact.getVersion(); //$NON-NLS-1$ //$NON-NLS-2$ state.put(key, pom.getCanonicalPath()); } } IResource outputLocation = root.findMember(projectFacade.getOutputLocation()); - if(!"pom".equals(artifact.getType()) && outputLocation != null && outputLocation.exists()) { //$NON-NLS-1$ - String extension = artifact.getArtifactHandler().getExtension(); - String key = artifact.getGroupId() - + ":" + artifact.getArtifactId() + ":" + extension + ":" + artifact.getBaseVersion(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - state.put(key, outputLocation.getLocation().toFile().getCanonicalPath()); + if(!"pom".equals(projectFacade.getPackaging()) && outputLocation != null && outputLocation.exists()) { //$NON-NLS-1$ + // three cases to consider + // 1. facade has cached MavenProject instance, i.e. it was refreshed during this eclipse session + // 2. project has persistent PPROP_EXTENSION + // 3. neither cached MavenProject instance nor PPROP_EXTENSION are present + String extension; + MavenProject mavenProject = projectFacade.getMavenProject(); + if(mavenProject != null) { + extension = getAndPersistArtifactExtension(project, mavenProject); + } else { + extension = project.getPersistentProperty(PPROP_EXTENSION); + } + if(extension == null && mavenProject == null) { + // force loading of MavenProject + extension = getAndPersistArtifactExtension(project, projectFacade.getMavenProject(monitor)); + } + if(extension != null) { + String key = artifact.getGroupId() + + ":" + artifact.getArtifactId() + ":" + extension + ":" + artifact.getVersion(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + state.put(key, outputLocation.getLocation().toFile().getCanonicalPath()); + } else { + log.warn("Could not determine project {} main artifact extension.", project); + } } } catch(CoreException ex) { log.error("Error writing workspace state file", ex); @@ -93,4 +117,10 @@ public class WorkspaceStateWriter implements IMavenProjectChangedListener { log.error("Error writing workspace state file", ex); } } + + private String getAndPersistArtifactExtension(IProject project, MavenProject mavenProject) throws CoreException { + String extension = mavenProject.getArtifact().getArtifactHandler().getExtension(); + project.setPersistentProperty(PPROP_EXTENSION, extension); + return extension; + } } diff --git a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscovery.java b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscovery.java index c41b0178..3c59869c 100644 --- a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscovery.java +++ b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscovery.java @@ -62,9 +62,17 @@ public class MavenDiscovery { private static final Tag MAVEN_TAG = new Tag("maven", Messages.MavenDiscovery_Wizard_MavenTag); //$NON-NLS-1$ - public static final String DEFAULT_URL = "http://download.eclipse.org/technology/m2e/discovery/directory-1.4.xml"; //$NON-NLS-1$ + private static final String DEFAULT_BASEURL = "http://download.eclipse.org/technology/m2e/discovery/"; //$NON-NLS-1$ - public static final String PATH = System.getProperty("m2e.discovery.url", DEFAULT_URL); //$NON-NLS-1$ + private static final String DEFAULT_FILENAME = "directory-1.4.xml"; //$NON-NLS-1$ + + public static final String DEFAULT_URL = DEFAULT_BASEURL + DEFAULT_FILENAME; + + private static final String CONFIGURED_URL = System.getProperty("m2e.discovery.url"); //$NON-NLS-1$ + + private static final String BASEURL = System.getProperty("m2e.discovery.baseurl", DEFAULT_BASEURL); //$NON-NLS-1$ + + public static final String PATH; public static final String LIFECYCLE_PATH = "lifecycle/"; //$NON-NLS-1$ @@ -72,6 +80,10 @@ public class MavenDiscovery { public static final String PLUGINXML_EXT = ".pluginxml"; //$NON-NLS-1$ + static { + PATH = CONFIGURED_URL != null ? CONFIGURED_URL : BASEURL + DEFAULT_FILENAME; + } + @SuppressWarnings("unchecked") public static void launchWizard(Shell shell) { launchWizard(shell, Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST); diff --git a/org.eclipse.m2e.editor.xml/OSGI-INF/l10n/bundle.properties b/org.eclipse.m2e.editor.xml/OSGI-INF/l10n/bundle.properties index 842d65a7..eb4580ca 100644 --- a/org.eclipse.m2e.editor.xml/OSGI-INF/l10n/bundle.properties +++ b/org.eclipse.m2e.editor.xml/OSGI-INF/l10n/bundle.properties @@ -62,5 +62,7 @@ template.tools.description = Profile for tools.jar template.tools.name = tools.jar template.tools2.description = Path to the tools.jar template.tools2.name = tools.jar +template.m2e.profile.description = m2e activated profile +template.m2e.profile.name = m2e profile keyword.label = maven page.name = Templates diff --git a/org.eclipse.m2e.editor.xml/plugin.xml b/org.eclipse.m2e.editor.xml/plugin.xml index ff6d8f27..342284d5 100644 --- a/org.eclipse.m2e.editor.xml/plugin.xml +++ b/org.eclipse.m2e.editor.xml/plugin.xml @@ -180,7 +180,7 @@ <pattern><plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> - <version>3.0</version> + <version>3.1</version> <configuration> <!-- http://maven.apache.org/plugins/maven-compiler-plugin/ --> <source>${cursor}1.6</source> @@ -372,6 +372,24 @@ </profile></pattern> </template> + <template id="org.eclipse.m2e.editor.xml.templates.profile.m2e" + contextTypeId="org.eclipse.m2e.editor.xml.templates.contextType.profiles" + name="%template.m2e.profile.name" + description="%template.m2e.profile.description"> + <pattern><profile> + <id>m2e</id> + <!-- This profile is only activated when building in Eclipse with m2e --> + <activation> + <property> + <name>m2e.version</name> + </property> + </activation> + ${cursor} + </profile> + </pattern> + </template> + + <template id="org.eclipse.m2e.editor.xml.templates.systemPath.tools.jar" contextTypeId="org.eclipse.m2e.editor.xml.templates.contextType.systemPath" name="%template.tools2.name" diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/JavaProjectConversionParticipant.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/JavaProjectConversionParticipant.java index ca1e08a5..8f84cf0c 100644 --- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/JavaProjectConversionParticipant.java +++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/JavaProjectConversionParticipant.java @@ -11,11 +11,16 @@ package org.eclipse.m2e.jdt.internal; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,6 +30,7 @@ import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; +import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -34,11 +40,18 @@ import org.eclipse.jdt.core.JavaCore; import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.apache.maven.artifact.versioning.ComparableVersion; import org.apache.maven.model.Build; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; import org.apache.maven.model.Resource; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.internal.index.IIndex; +import org.eclipse.m2e.core.internal.index.IndexedArtifact; +import org.eclipse.m2e.core.internal.index.IndexedArtifactFile; +import org.eclipse.m2e.core.internal.index.SearchExpression; +import org.eclipse.m2e.core.internal.index.SourcedSearchExpression; import org.eclipse.m2e.core.project.conversion.AbstractProjectConversionParticipant; @@ -67,7 +80,7 @@ public class JavaProjectConversionParticipant extends AbstractProjectConversionP private static final String COMPILER_ARTIFACT_ID = "maven-compiler-plugin"; //$NON-NLS-1$ - private static final String DEFAULT_COMPILER_VERSION = "3.0"; //$NON-NLS-1$ + private static final String DEFAULT_COMPILER_VERSION = "3.1"; //$NON-NLS-1$ private static final String TARGET_KEY = "target"; //$NON-NLS-1$ @@ -358,8 +371,66 @@ public class JavaProjectConversionParticipant extends AbstractProjectConversionP } private String getCompilerVersion() { - //FIXME Workaround until we can get the version from JDT conversion preferences instead - //Useful for test purposes. - return System.getProperty("org.eclipse.m2e.jdt.conversion.compiler.version", DEFAULT_COMPILER_VERSION); + //For test purposes only, must not be considered API behavior. + String version = System.getProperty("org.eclipse.m2e.jdt.conversion.compiler.version");//$NON-NLS-1$ + if(version != null) { + return version; + } + return getMostRecentPluginVersion(COMPILER_GROUP_ID, COMPILER_ARTIFACT_ID, DEFAULT_COMPILER_VERSION); + } + + /** + * Returns the highest, non-snapshot plugin version between the given reference version and the versions found in the + * Nexus indexes. + */ + @SuppressWarnings("restriction") + //TODO extract as API when stabilized? + private String getMostRecentPluginVersion(String groupId, String artifactId, String referenceVersion) { + Assert.isNotNull(groupId, "groupId can not be null"); + Assert.isNotNull(artifactId, "artifactId can not be null"); + String version = referenceVersion; + String partialKey = artifactId + " : " + groupId; //$NON-NLS-1$ + try { + IIndex index = MavenPlugin.getIndexManager().getAllIndexes(); + SearchExpression a = new SourcedSearchExpression(artifactId); + + //For some reason, an exact search using : + //ISearchEngine searchEngine = M2EUIPluginActivator.getDefault().getSearchEngine(null) + //searchEngine.findVersions(groupId, artifactId, searchExpression, packaging) + // + //doesn't yield the expected results (the latest versions are not returned), so we rely on a fuzzier search + //and refine the results. + Map<String, IndexedArtifact> values = index.search(a, IIndex.SEARCH_PLUGIN); + if(!values.isEmpty()) { + SortedSet<ComparableVersion> versions = new TreeSet<ComparableVersion>(); + ComparableVersion referenceComparableVersion = referenceVersion == null ? null : new ComparableVersion( + referenceVersion); + + for(Map.Entry<String, IndexedArtifact> e : values.entrySet()) { + if(!(e.getKey().endsWith(partialKey))) { + continue; + } + for(IndexedArtifactFile f : e.getValue().getFiles()) { + if(groupId.equals(f.group) && artifactId.equals(f.artifact) && !f.version.contains("SNAPSHOT")) { + ComparableVersion v = new ComparableVersion(f.version); + if(referenceComparableVersion == null || v.compareTo(referenceComparableVersion) > 0) { + versions.add(v); + } + } + } + if(!versions.isEmpty()) { + List<String> sorted = new ArrayList<String>(versions.size()); + for(ComparableVersion v : versions) { + sorted.add(v.toString()); + } + Collections.reverse(sorted); + version = sorted.iterator().next(); + } + } + } + } catch(CoreException e) { + log.error("Can not retrieve latest version of " + partialKey, e); + } + return version; } } diff --git a/org.eclipse.m2e.launching/src/org/eclipse/m2e/actions/MavenLaunchConstants.java b/org.eclipse.m2e.launching/src/org/eclipse/m2e/actions/MavenLaunchConstants.java index 6dd33070..ad3d7547 100644 --- a/org.eclipse.m2e.launching/src/org/eclipse/m2e/actions/MavenLaunchConstants.java +++ b/org.eclipse.m2e.launching/src/org/eclipse/m2e/actions/MavenLaunchConstants.java @@ -20,6 +20,9 @@ public interface MavenLaunchConstants { // this should correspond with launchConfigurationType.id attribute in plugin.xml! public final String LAUNCH_CONFIGURATION_TYPE_ID = "org.eclipse.m2e.Maven2LaunchConfigurationType"; //$NON-NLS-1$ + /** + * @deprecated this constant is not used by m2e + */ public final String BUILDER_CONFIGURATION_TYPE_ID = "org.eclipse.m2e.Maven2BuilderConfigurationType"; //$NON-NLS-1$ // pom directory automatically became working directory for maven embedder launch @@ -27,12 +30,24 @@ public interface MavenLaunchConstants { public final String ATTR_GOALS = "M2_GOALS"; //$NON-NLS-1$ + /** + * @deprecated this constant is not used by m2e + */ public final String ATTR_GOALS_AUTO_BUILD = "M2_GOALS_AUTO_BUILD"; //$NON-NLS-1$ + /** + * @deprecated this constant is not used by m2e + */ public final String ATTR_GOALS_MANUAL_BUILD = "M2_GOALS_MANUAL_BUILD"; //$NON-NLS-1$ + /** + * @deprecated this constant is not used by m2e + */ public final String ATTR_GOALS_CLEAN = "M2_GOALS_CLEAN"; //$NON-NLS-1$ + /** + * @deprecated this constant is not used by m2e + */ public final String ATTR_GOALS_AFTER_CLEAN = "M2_GOALS_AFTER_CLEAN"; //$NON-NLS-1$ public final String ATTR_PROFILES = "M2_PROFILES"; //$NON-NLS-1$ diff --git a/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java index fbcb1a78..f3e489d8 100644 --- a/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java +++ b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java @@ -11,10 +11,9 @@ package org.eclipse.m2e.internal.launch; +import static org.eclipse.m2e.internal.launch.MavenLaunchUtils.quote; + import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -25,45 +24,27 @@ import org.slf4j.LoggerFactory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.debug.core.DebugEvent; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.IDebugEventSetListener; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; -import org.eclipse.debug.ui.RefreshTab; import org.eclipse.jdt.launching.IVMRunner; import org.eclipse.jdt.launching.JavaLaunchDelegate; -import org.eclipse.jdt.launching.VMRunnerConfiguration; import org.eclipse.jdt.launching.sourcelookup.containers.JavaSourceLookupParticipant; import org.eclipse.osgi.util.NLS; import org.eclipse.m2e.actions.MavenLaunchConstants; import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.m2e.core.embedder.IMavenConfiguration; -import org.eclipse.m2e.core.embedder.IMavenLauncherConfiguration; -import org.eclipse.m2e.core.embedder.MavenRuntime; -import org.eclipse.m2e.core.internal.MavenPluginActivator; +import org.eclipse.m2e.internal.launch.MavenRuntimeLaunchSupport.VMArguments; public class MavenLaunchDelegate extends JavaLaunchDelegate implements MavenLaunchConstants { - private static final Logger log = LoggerFactory.getLogger(MavenLaunchDelegate.class); + static final Logger log = LoggerFactory.getLogger(MavenLaunchDelegate.class); private static final String LAUNCHER_TYPE = "org.codehaus.classworlds.Launcher"; //$NON-NLS-1$ - private static final String LAUNCHER_TYPE3 = "org.codehaus.plexus.classworlds.launcher.Launcher"; // classworlds 2.0 //$NON-NLS-1$ - - private static final String LAUNCH_M2CONF_FILE = "org.eclipse.m2e.internal.launch.M2_CONF"; //$NON-NLS-1$ - - private MavenRuntime runtime; - - private MavenLauncherConfigurationHandler m2conf; - - private File confFile; + //classworlds 2.0 + private static final String LAUNCHER_TYPE3 = "org.codehaus.plexus.classworlds.launcher.Launcher"; //$NON-NLS-1$ private ILaunch launch; @@ -73,6 +54,8 @@ public class MavenLaunchDelegate extends JavaLaunchDelegate implements MavenLaun private String programArguments; + private MavenRuntimeLaunchSupport launchSupport; + public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { this.launch = launch; @@ -84,31 +67,7 @@ public class MavenLaunchDelegate extends JavaLaunchDelegate implements MavenLaun log.info(" mvn" + getProgramArguments(configuration)); //$NON-NLS-1$ try { - runtime = MavenLaunchUtils.getMavenRuntime(configuration); - - m2conf = new MavenLauncherConfigurationHandler(); - if(shouldResolveWorkspaceArtifacts(configuration)) { - m2conf.addArchiveEntry(MavenLaunchUtils.getCliResolver(runtime)); - } - MavenLaunchUtils.addUserComponents(configuration, m2conf); - runtime.createLauncherConfiguration(m2conf, monitor); - - File state = MavenPluginActivator.getDefault().getStateLocation().toFile(); - try { - File dir = new File(state, "launches"); //$NON-NLS-1$ - dir.mkdirs(); - confFile = File.createTempFile("m2conf", ".tmp", dir); //$NON-NLS-1$ //$NON-NLS-2$ - launch.setAttribute(LAUNCH_M2CONF_FILE, confFile.getCanonicalPath()); - OutputStream os = new FileOutputStream(confFile); - try { - m2conf.save(os); - } finally { - os.close(); - } - } catch(IOException e) { - throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, -1, - Messages.MavenLaunchDelegate_error_cannot_create_conf, e)); - } + this.launchSupport = MavenRuntimeLaunchSupport.create(configuration, launch, monitor); if(launch.getSourceLocator() instanceof MavenSourceLocator) { final MavenSourceLocator sourceLocator = (MavenSourceLocator) launch.getSourceLocator(); @@ -134,30 +93,15 @@ public class MavenLaunchDelegate extends JavaLaunchDelegate implements MavenLaun } public IVMRunner getVMRunner(final ILaunchConfiguration configuration, String mode) throws CoreException { - final IVMRunner runner = super.getVMRunner(configuration, mode); - - return new IVMRunner() { - public void run(VMRunnerConfiguration runnerConfiguration, ILaunch launch, IProgressMonitor monitor) - throws CoreException { - runner.run(runnerConfiguration, launch, monitor); - - IProcess[] processes = launch.getProcesses(); - if(processes != null && processes.length > 0) { - BackgroundResourceRefresher refresher = new BackgroundResourceRefresher(configuration, launch); - refresher.init(); - } else { - removeTempFiles(launch); - } - } - }; + return launchSupport.decorateVMRunner(super.getVMRunner(configuration, mode)); } - public String getMainTypeName(ILaunchConfiguration configuration) throws CoreException { - return runtime.getVersion().startsWith("3.0") ? LAUNCHER_TYPE3 : LAUNCHER_TYPE; //$NON-NLS-1$ + public String getMainTypeName(ILaunchConfiguration configuration) { + return launchSupport.getVersion().startsWith("3.0") ? LAUNCHER_TYPE3 : LAUNCHER_TYPE; //$NON-NLS-1$ } - public String[] getClasspath(ILaunchConfiguration configuration) throws CoreException { - List<String> cp = m2conf.getRealmEntries(IMavenLauncherConfiguration.LAUNCHER_REALM); + public String[] getClasspath(ILaunchConfiguration configuration) { + List<String> cp = launchSupport.getBootClasspath(); return cp.toArray(new String[cp.size()]); } @@ -180,53 +124,16 @@ public class MavenLaunchDelegate extends JavaLaunchDelegate implements MavenLaun } public String getVMArguments(ILaunchConfiguration configuration) throws CoreException { - /* - * <pre> - * %MAVEN_JAVA_EXE% %MAVEN_OPTS% - * -classpath %CLASSWORLDS_JAR% - * "-Dclassworlds.conf=%M2_HOME%\bin\m2.conf" - * "-Dmaven.home=%M2_HOME%" - * org.codehaus.classworlds.Launcher - * %MAVEN_CMD_LINE_ARGS% - * </pre> - */ - - StringBuffer sb = new StringBuffer(); - - // workspace artifact resolution - if(shouldResolveWorkspaceArtifacts(configuration)) { - File state = MavenPluginActivator.getDefault().getMavenProjectManager().getWorkspaceStateFile(); - sb.append(" -Dm2eclipse.workspace.state=").append(quote(state.getAbsolutePath())); //$NON-NLS-1$ - } - - // maven.home - String location = runtime.getLocation(); - if(location != null) { - sb.append(" -Dmaven.home=").append(quote(location)); //$NON-NLS-1$ - } - - // m2.conf - sb.append(" -Dclassworlds.conf=").append(quote(confFile.getAbsolutePath())); //$NON-NLS-1$ + VMArguments arguments = launchSupport.getVMArguments(); // user configured entries - sb.append(" ").append(super.getVMArguments(configuration)); //$NON-NLS-1$ + arguments.append(super.getVMArguments(configuration)); for(IMavenLaunchParticipant participant : participants) { - String vmArguments = participant.getVMArguments(configuration, launch, monitor); - if(vmArguments != null) { - sb.append(" ").append(vmArguments); - } + arguments.append(participant.getVMArguments(configuration, launch, monitor)); } - return sb.toString(); - } - - private String quote(String string) { - return string.indexOf(' ') > -1 ? "\"" + string + "\"" : string; //$NON-NLS-1$ //$NON-NLS-2$ - } - - private boolean shouldResolveWorkspaceArtifacts(ILaunchConfiguration configuration) throws CoreException { - return configuration.getAttribute(ATTR_WORKSPACE_RESOLUTION, false); + return arguments.toString(); } protected String getGoals(ILaunchConfiguration configuration) throws CoreException { @@ -344,73 +251,7 @@ public class MavenLaunchDelegate extends JavaLaunchDelegate implements MavenLaun } static void removeTempFiles(ILaunch launch) { - String m2confName = launch.getAttribute(LAUNCH_M2CONF_FILE); - if(m2confName != null) { - new File(m2confName).delete(); - } - } - - /** - * Refreshes resources as specified by a launch configuration, when an associated process terminates. Adapted from - * org.eclipse.ui.externaltools.internal.program.launchConfigurations.BackgroundResourceRefresher - */ - public static class BackgroundResourceRefresher implements IDebugEventSetListener { - final ILaunchConfiguration configuration; - - final IProcess process; - - final ILaunch launch; - - public BackgroundResourceRefresher(ILaunchConfiguration configuration, ILaunch launch) { - this.configuration = configuration; - this.process = launch.getProcesses()[0]; - this.launch = launch; - } - - /** - * If the process has already terminated, resource refreshing is done immediately in the current thread. Otherwise, - * refreshing is done when the process terminates. - */ - public void init() { - synchronized(process) { - if(process.isTerminated()) { - processResources(); - } else { - DebugPlugin.getDefault().addDebugEventListener(this); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[]) - */ - public void handleDebugEvents(DebugEvent[] events) { - for(int i = 0; i < events.length; i++ ) { - DebugEvent event = events[i]; - if(event.getSource() == process && event.getKind() == DebugEvent.TERMINATE) { - DebugPlugin.getDefault().removeDebugEventListener(this); - processResources(); - break; - } - } - } - - protected void processResources() { - removeTempFiles(launch); - - Job job = new Job(Messages.MavenLaunchDelegate_job_name) { - public IStatus run(IProgressMonitor monitor) { - try { - RefreshTab.refreshResources(configuration, monitor); - return Status.OK_STATUS; - } catch(CoreException e) { - log.error(e.getMessage(), e); - return e.getStatus(); - } - } - }; - job.schedule(); - } + MavenRuntimeLaunchSupport.removeTempFiles(launch); } private List<IMavenLaunchParticipant> getParticipants(ILaunchConfiguration configuration, ILaunch launch) diff --git a/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchUtils.java b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchUtils.java index 0418c7ac..44761cc1 100644 --- a/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchUtils.java +++ b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchUtils.java @@ -123,4 +123,26 @@ public class MavenLaunchUtils { } } } + + /** + * @since 1.4 + */ + public static String quote(String string) { + return string.indexOf(' ') > -1 ? "\"" + string + "\"" : string; //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * @since 1.4 + */ + public static String toPath(List<String> cp) { + StringBuilder sb = new StringBuilder(); + for(String cpe : cp) { + if(sb.length() > 0) { + sb.append(File.pathSeparator); + } + sb.append(cpe); + } + return sb.toString(); + } + } diff --git a/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenRuntimeLaunchSupport.java b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenRuntimeLaunchSupport.java new file mode 100644 index 00000000..b2f5fcbf --- /dev/null +++ b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenRuntimeLaunchSupport.java @@ -0,0 +1,277 @@ +/******************************************************************************* + * 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.internal.launch; + +import static org.eclipse.m2e.actions.MavenLaunchConstants.ATTR_WORKSPACE_RESOLUTION; +import static org.eclipse.m2e.actions.MavenLaunchConstants.PLUGIN_ID; +import static org.eclipse.m2e.internal.launch.MavenLaunchUtils.quote; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.ui.RefreshTab; +import org.eclipse.jdt.launching.IVMRunner; +import org.eclipse.jdt.launching.VMRunnerConfiguration; + +import org.eclipse.m2e.core.embedder.IMavenLauncherConfiguration; +import org.eclipse.m2e.core.embedder.MavenRuntime; +import org.eclipse.m2e.core.internal.MavenPluginActivator; +import org.eclipse.m2e.core.internal.project.WorkspaceStateWriter; + + +/** + * Helper class to configure and launch MavenRuntime instance. + * <p> + * Generates classworld configuration file, i.e. m2.conf. Generated classworld configuration file will include + * cliresolver for launch configuration that have workspace resolution enabled. + * <p> + * Sets the following conventional launch configuration attributes. + * <ul> + * <li>m2eclipse.workspace.state, full absolute path of m2e workspace state file. See {@link WorkspaceStateWriter} for + * details of the state file format. Only set if workspace dependency resolution is enabled for the launch + * configuration.</li> + * <li>maven.bootclasspath, maven runtime bootstrap classpath, normally only contains classworlds jar.</li> + * <li>maven.home, location of maven runtime, logical name is used for embedded and workspace runtimes</li> + * <li>classworlds.conf, location of classworlds configuration file, i.e. m2.conf</li> + * </ul> + * + * @since 1.4 + */ +public class MavenRuntimeLaunchSupport { + private static final String LAUNCH_M2CONF_FILE = "org.eclipse.m2e.internal.launch.M2_CONF"; //$NON-NLS-1$ + + private final MavenRuntime runtime; + + private final MavenLauncherConfigurationHandler cwconf; + + private final boolean resolveWorkspaceArtifacts; + + private final File cwconfFile; + + public static class VMArguments { + + private final StringBuilder properties = new StringBuilder(); + + public void append(String str) { + if(str != null) { + str = str.trim(); + } + if(str != null && str.length() > 0) { + if(properties.length() > 0) { + properties.append(' '); + } + properties.append(str); + } + } + + public void appendProperty(String key, String value) { + append("-D" + key + "=" + value); + } + + @Override + public String toString() { + return properties.toString(); + } + } + + private MavenRuntimeLaunchSupport(MavenRuntime runtime, MavenLauncherConfigurationHandler cwconf, File cwconfFile, + boolean resolveWorkspaceArtifacts) { + this.runtime = runtime; + this.cwconf = cwconf; + this.cwconfFile = cwconfFile; + this.resolveWorkspaceArtifacts = resolveWorkspaceArtifacts; + } + + public static MavenRuntimeLaunchSupport create(ILaunchConfiguration configuration, ILaunch launch, + IProgressMonitor monitor) throws CoreException { + MavenRuntime runtime = MavenLaunchUtils.getMavenRuntime(configuration); + + boolean resolveWorkspaceArtifacts = configuration.getAttribute(ATTR_WORKSPACE_RESOLUTION, false); + + MavenLauncherConfigurationHandler cwconf = new MavenLauncherConfigurationHandler(); + if(resolveWorkspaceArtifacts) { + cwconf.addArchiveEntry(MavenLaunchUtils.getCliResolver(runtime)); + } + MavenLaunchUtils.addUserComponents(configuration, cwconf); + runtime.createLauncherConfiguration(cwconf, monitor); + + File cwconfFile; + try { + File state = MavenLaunchPlugin.getDefault().getStateLocation().toFile(); + File dir = new File(state, "launches"); //$NON-NLS-1$ + dir.mkdirs(); + cwconfFile = File.createTempFile("m2conf", ".tmp", dir); //$NON-NLS-1$ //$NON-NLS-2$ + launch.setAttribute(LAUNCH_M2CONF_FILE, cwconfFile.getCanonicalPath()); + OutputStream os = new FileOutputStream(cwconfFile); + try { + cwconf.save(os); + } finally { + os.close(); + } + } catch(IOException e) { + throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, -1, + Messages.MavenLaunchDelegate_error_cannot_create_conf, e)); + } + + return new MavenRuntimeLaunchSupport(runtime, cwconf, cwconfFile, resolveWorkspaceArtifacts); + } + + public static void removeTempFiles(ILaunch launch) { + String m2confName = launch.getAttribute(LAUNCH_M2CONF_FILE); + if(m2confName != null) { + new File(m2confName).delete(); + } + } + + /** + * MAVEN_HOME or equivalent location of the Maven runtime. + */ + public String getLocation() { + return runtime.getLocation(); + } + + /** + * Location of classworld configuration file, i.e. m2.conf, of the Maven runtime. + */ + public File getClassworldConfFile() { + return cwconfFile; + } + + /** + * Bootstrap classpath of the Maven runtime, normally only contains classworlds jar. + */ + public List<String> getBootClasspath() { + return cwconf.getRealmEntries(IMavenLauncherConfiguration.LAUNCHER_REALM); + } + + public String getVersion() { + return runtime.getVersion(); + } + + public VMArguments getVMArguments() { + VMArguments properties = new VMArguments(); + + // workspace artifact resolution + if(resolveWorkspaceArtifacts) { + File state = MavenPluginActivator.getDefault().getMavenProjectManager().getWorkspaceStateFile(); + properties.appendProperty("m2eclipse.workspace.state", quote(state.getAbsolutePath())); //$NON-NLS-1$ + } + + // maven.home + String location = runtime.getLocation(); + if(location != null) { + properties.appendProperty("maven.home", quote(location)); //$NON-NLS-1$ + } + + // m2.conf + properties.appendProperty("classworlds.conf", quote(cwconfFile.getAbsolutePath())); //$NON-NLS-1$ + + // maven bootclasspath, i.e. classworlds jar. + // TODO only used by ITs, so consider making optional + properties.appendProperty("maven.bootclasspath", MavenLaunchUtils.toPath(getBootClasspath())); + + return properties; + } + + public IVMRunner decorateVMRunner(final IVMRunner runner) { + return new IVMRunner() { + public void run(VMRunnerConfiguration runnerConfiguration, ILaunch launch, IProgressMonitor monitor) + throws CoreException { + runner.run(runnerConfiguration, launch, monitor); + + IProcess[] processes = launch.getProcesses(); + if(processes != null && processes.length > 0) { + ILaunchConfiguration configuration = launch.getLaunchConfiguration(); + BackgroundResourceRefresher refresher = new BackgroundResourceRefresher(configuration, launch); + refresher.init(); + } else { + removeTempFiles(launch); + } + } + }; + } +} + + +/** + * Refreshes resources as specified by a launch configuration, when an associated process terminates. Adapted from + * org.eclipse.ui.externaltools.internal.program.launchConfigurations.BackgroundResourceRefresher + */ +class BackgroundResourceRefresher implements IDebugEventSetListener { + final ILaunchConfiguration configuration; + + final IProcess process; + + final ILaunch launch; + + public BackgroundResourceRefresher(ILaunchConfiguration configuration, ILaunch launch) { + this.configuration = configuration; + this.process = launch.getProcesses()[0]; + this.launch = launch; + } + + /** + * If the process has already terminated, resource refreshing is done immediately in the current thread. Otherwise, + * refreshing is done when the process terminates. + */ + public void init() { + synchronized(process) { + if(process.isTerminated()) { + processResources(); + } else { + DebugPlugin.getDefault().addDebugEventListener(this); + } + } + } + + public void handleDebugEvents(DebugEvent[] events) { + for(int i = 0; i < events.length; i++ ) { + DebugEvent event = events[i]; + if(event.getSource() == process && event.getKind() == DebugEvent.TERMINATE) { + DebugPlugin.getDefault().removeDebugEventListener(this); + processResources(); + break; + } + } + } + + protected void processResources() { + MavenLaunchDelegate.removeTempFiles(launch); + + Job job = new Job(Messages.MavenLaunchDelegate_job_name) { + public IStatus run(IProgressMonitor monitor) { + try { + RefreshTab.refreshResources(configuration, monitor); + return Status.OK_STATUS; + } catch(CoreException e) { + MavenLaunchDelegate.log.error(e.getMessage(), e); + return e.getStatus(); + } + } + }; + job.schedule(); + } +} diff --git a/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenLaunchConfigurationTabGroup.java b/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenLaunchConfigurationTabGroup.java index a1197898..9f9b30cd 100644 --- a/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenLaunchConfigurationTabGroup.java +++ b/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenLaunchConfigurationTabGroup.java @@ -30,7 +30,7 @@ public class MavenLaunchConfigurationTabGroup extends AbstractLaunchConfiguratio public void createTabs(ILaunchConfigurationDialog dialog, String mode) { List<ILaunchConfigurationTab> tabs = new ArrayList<ILaunchConfigurationTab>(); - tabs.add(new MavenLaunchMainTab(false)); + tabs.add(new MavenLaunchMainTab()); tabs.add(new MavenJRETab()); tabs.add(new RefreshTab()); tabs.add(new SourceLookupTab()); diff --git a/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenLaunchMainTab.java b/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenLaunchMainTab.java index b10205b5..69c2fa68 100644 --- a/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenLaunchMainTab.java +++ b/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenLaunchMainTab.java @@ -28,16 +28,11 @@ import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; import org.eclipse.debug.ui.StringVariableSelectionDialog; import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; @@ -61,14 +56,10 @@ import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.ContainerSelectionDialog; -import org.eclipse.ui.dialogs.PreferencesUtil; -import org.eclipse.ui.externaltools.internal.model.IExternalToolConstants; import org.eclipse.m2e.actions.MavenLaunchConstants; import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.m2e.core.embedder.IMavenConfiguration; -import org.eclipse.m2e.core.embedder.MavenRuntime; -import org.eclipse.m2e.core.embedder.MavenRuntimeManager; import org.eclipse.m2e.core.ui.internal.MavenImages; import org.eclipse.m2e.core.ui.internal.dialogs.MavenGoalSelectionDialog; import org.eclipse.m2e.core.ui.internal.dialogs.MavenPropertyDialog; @@ -88,8 +79,6 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement public static final String ID_EXTERNAL_TOOLS_LAUNCH_GROUP = "org.eclipse.ui.externaltools.launchGroup"; //$NON-NLS-1$ - private final boolean isBuilder; - protected Text pomDirNameText; protected Text goalsText; @@ -122,12 +111,11 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement private Button editPropButton; - ComboViewer runtimeComboViewer; - private Combo threadsCombo; - public MavenLaunchMainTab(boolean isBuilder) { - this.isBuilder = isBuilder; + private MavenRuntimeSelector runtimeSelector; + + public MavenLaunchMainTab() { } public Image getImage() { @@ -231,79 +219,25 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement // goals - if(isBuilder) { - Label autoBuildGoalsLabel = new Label(mainComposite, SWT.NONE); - GridData gd_autoBuildGoalsLabel = new GridData(); - gd_autoBuildGoalsLabel.verticalIndent = 7; - autoBuildGoalsLabel.setLayoutData(gd_autoBuildGoalsLabel); - autoBuildGoalsLabel.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_lblAutoBuildGoals); - goalsAutoBuildText = new Text(mainComposite, SWT.BORDER); - GridData gd_goalsAutoBuildText = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1); - gd_goalsAutoBuildText.verticalIndent = 7; - goalsAutoBuildText.setLayoutData(gd_goalsAutoBuildText); - goalsAutoBuildText.addModifyListener(modyfyingListener); - goalsAutoBuildText.addFocusListener(new GoalsFocusListener(goalsAutoBuildText)); - Button goalsAutoBuildButton = new Button(mainComposite, SWT.NONE); - GridData gd_goalsAutoBuildButton = new GridData(SWT.FILL, SWT.CENTER, false, false); - gd_goalsAutoBuildButton.verticalIndent = 7; - goalsAutoBuildButton.setLayoutData(gd_goalsAutoBuildButton); - goalsAutoBuildButton.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_btnAutoBuild); - goalsAutoBuildButton.addSelectionListener(new GoalSelectionAdapter(goalsAutoBuildText)); - - Label manualBuildGoalsLabel = new Label(mainComposite, SWT.NONE); - manualBuildGoalsLabel.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_lblManualGoals); - goalsManualBuildText = new Text(mainComposite, SWT.BORDER); - goalsManualBuildText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); - goalsManualBuildText.addModifyListener(modyfyingListener); - goalsManualBuildText.addFocusListener(new GoalsFocusListener(goalsManualBuildText)); - Button goalsManualBuildButton = new Button(mainComposite, SWT.NONE); - goalsManualBuildButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - goalsManualBuildButton.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_btnManualBuild); - goalsManualBuildButton.addSelectionListener(new GoalSelectionAdapter(goalsManualBuildText)); - - Label cleanBuildGoalsLabel = new Label(mainComposite, SWT.NONE); - cleanBuildGoalsLabel.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_lblCleanBuild); - goalsCleanText = new Text(mainComposite, SWT.BORDER); - goalsCleanText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); - goalsCleanText.addModifyListener(modyfyingListener); - goalsCleanText.addFocusListener(new GoalsFocusListener(goalsCleanText)); - Button goalsCleanButton = new Button(mainComposite, SWT.NONE); - goalsCleanButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - goalsCleanButton.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_btnCleanBuild); - goalsCleanButton.addSelectionListener(new GoalSelectionAdapter(goalsCleanText)); - - Label afterCleanGoalsLabel = new Label(mainComposite, SWT.NONE); - afterCleanGoalsLabel.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_lblAfterClean); - goalsAfterCleanText = new Text(mainComposite, SWT.BORDER); - goalsAfterCleanText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); - goalsAfterCleanText.addModifyListener(modyfyingListener); - goalsAfterCleanText.addFocusListener(new GoalsFocusListener(goalsAfterCleanText)); - Button goalsAfterCleanButton = new Button(mainComposite, SWT.NONE); - goalsAfterCleanButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - goalsAfterCleanButton.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_btnAfterClean); - goalsAfterCleanButton.addSelectionListener(new GoalSelectionAdapter(goalsAfterCleanText)); - - } else { - Label goalsLabel = new Label(mainComposite, SWT.NONE); - GridData gd_goalsLabel = new GridData(); - gd_goalsLabel.verticalIndent = 7; - goalsLabel.setLayoutData(gd_goalsLabel); - goalsLabel.setText(Messages.launchGoalsLabel); //$NON-NLS-1$ - goalsText = new Text(mainComposite, SWT.BORDER); - goalsText.setData("name", "goalsText"); //$NON-NLS-1$ //$NON-NLS-2$ - GridData gd_goalsText = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1); - gd_goalsText.verticalIndent = 7; - goalsText.setLayoutData(gd_goalsText); - goalsText.addModifyListener(modyfyingListener); - goalsText.addFocusListener(new GoalsFocusListener(goalsText)); - - Button selectGoalsButton = new Button(mainComposite, SWT.NONE); - GridData gd_selectGoalsButton = new GridData(SWT.FILL, SWT.CENTER, false, false); - gd_selectGoalsButton.verticalIndent = 7; - selectGoalsButton.setLayoutData(gd_selectGoalsButton); - selectGoalsButton.setText(Messages.launchGoals); //$NON-NLS-1$ - selectGoalsButton.addSelectionListener(new GoalSelectionAdapter(goalsText)); - } + Label goalsLabel = new Label(mainComposite, SWT.NONE); + GridData gd_goalsLabel = new GridData(); + gd_goalsLabel.verticalIndent = 7; + goalsLabel.setLayoutData(gd_goalsLabel); + goalsLabel.setText(Messages.launchGoalsLabel); //$NON-NLS-1$ + goalsText = new Text(mainComposite, SWT.BORDER); + goalsText.setData("name", "goalsText"); //$NON-NLS-1$ //$NON-NLS-2$ + GridData gd_goalsText = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1); + gd_goalsText.verticalIndent = 7; + goalsText.setLayoutData(gd_goalsText); + goalsText.addModifyListener(modyfyingListener); + goalsText.addFocusListener(new GoalsFocusListener(goalsText)); + + Button selectGoalsButton = new Button(mainComposite, SWT.NONE); + GridData gd_selectGoalsButton = new GridData(SWT.FILL, SWT.CENTER, false, false); + gd_selectGoalsButton.verticalIndent = 7; + selectGoalsButton.setLayoutData(gd_selectGoalsButton); + selectGoalsButton.setText(Messages.launchGoals); //$NON-NLS-1$ + selectGoalsButton.addSelectionListener(new GoalSelectionAdapter(goalsText)); Label profilesLabel = new Label(mainComposite, SWT.NONE); profilesLabel.setText(Messages.launchProfilesLabel); //$NON-NLS-1$ @@ -315,9 +249,7 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement new Label(mainComposite, SWT.NONE); offlineButton = new Button(mainComposite, SWT.CHECK); - offlineButton.setToolTipText("-o"); //$NON-NLS-1$ - GridData gd_offlineButton = new GridData(); - offlineButton.setLayoutData(gd_offlineButton); + offlineButton.setToolTipText("-o"); offlineButton.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_btnOffline); offlineButton.addSelectionListener(modyfyingListener); @@ -333,7 +265,6 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement debugOutputButton = new Button(mainComposite, SWT.CHECK); debugOutputButton.setToolTipText("-X -e"); //$NON-NLS-1$ debugOutputButton.addSelectionListener(modyfyingListener); - debugOutputButton.setLayoutData(new GridData()); debugOutputButton.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_btnDebugOutput); skipTestsButton = new Button(mainComposite, SWT.CHECK); @@ -371,7 +302,6 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement gridLayout.marginHeight = 0; composite.setLayout(gridLayout); threadsCombo = new Combo(composite, SWT.BORDER | SWT.READ_ONLY | SWT.SINGLE); - threadsCombo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); for(int i = 1; i <= processors; i++ ) { threadsCombo.add(Integer.toString(i)); } @@ -379,10 +309,11 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement threadsCombo.addSelectionListener(modyfyingListener); Label threadsLabel = new Label(composite, SWT.NONE); - threadsLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); threadsLabel.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_lblThreads); threadsLabel.setToolTipText("--threads"); //$NON-NLS-1$ } + new Label(mainComposite, SWT.NONE); + new Label(mainComposite, SWT.NONE); TableViewer tableViewer = new TableViewer(mainComposite, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI); tableViewer.addDoubleClickListener(new IDoubleClickListener() { @@ -460,64 +391,15 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement }); removePropButton.setEnabled(false); - { - Composite composite = new Composite(mainComposite, SWT.NONE); - composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 4, 1)); - GridLayout gridLayout = new GridLayout(2, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - composite.setLayout(gridLayout); - - Label mavenRuntimeLabel = new Label(composite, SWT.NONE); - mavenRuntimeLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); - mavenRuntimeLabel.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_lblRuntime); - - runtimeComboViewer = new ComboViewer(composite, SWT.BORDER | SWT.READ_ONLY); - runtimeComboViewer.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - runtimeComboViewer.setContentProvider(new IStructuredContentProvider() { - - public Object[] getElements(Object input) { - return ((List<?>) input).toArray(); - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - public void dispose() { - } - - }); - - runtimeComboViewer.addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - entriesChanged(); - } - }); - - MavenRuntimeManager runtimeManager = MavenPlugin.getMavenRuntimeManager(); - runtimeComboViewer.setInput(runtimeManager.getMavenRuntimes()); - runtimeComboViewer.setSelection(new StructuredSelection(runtimeManager.getDefaultRuntime())); - } - - Button configureRuntimesButton = new Button(mainComposite, SWT.NONE); - GridData gd_configureRuntimesButton = new GridData(SWT.FILL, SWT.CENTER, false, false); - configureRuntimesButton.setLayoutData(gd_configureRuntimesButton); - configureRuntimesButton.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_btnConfigure); - configureRuntimesButton.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - PreferencesUtil.createPreferenceDialogOn(getShell(), - "org.eclipse.m2e.core.preferences.MavenInstallationsPreferencePage", null, null).open(); //$NON-NLS-1$ - MavenRuntimeManager runtimeManager = MavenPlugin.getMavenRuntimeManager(); - runtimeComboViewer.setInput(runtimeManager.getMavenRuntimes()); - runtimeComboViewer.setSelection(new StructuredSelection(runtimeManager.getDefaultRuntime())); + runtimeSelector = new MavenRuntimeSelector(mainComposite); + runtimeSelector.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 5, 1)); + runtimeSelector.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + entriesChanged(); } }); - if(isBuilder) { - goalsAutoBuildText.setFocus(); - } else { - goalsText.setFocus(); - } + goalsText.setFocus(); } protected Shell getShell() { @@ -579,24 +461,13 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement public void initializeFrom(ILaunchConfiguration configuration) { String pomDirName = getAttribute(configuration, ATTR_POM_DIR, ""); //$NON-NLS-1$ - if(isBuilder && pomDirName.length() == 0) { - pomDirName = "${workspace_loc:/" + configuration.getFile().getProject().getName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ - } this.pomDirNameText.setText(pomDirName); - if(isBuilder) { - this.goalsAutoBuildText.setText(getAttribute(configuration, ATTR_GOALS_AUTO_BUILD, "install")); //$NON-NLS-1$ - this.goalsManualBuildText.setText(getAttribute(configuration, ATTR_GOALS_MANUAL_BUILD, "install")); //$NON-NLS-1$ - this.goalsCleanText.setText(getAttribute(configuration, ATTR_GOALS_CLEAN, "clean")); //$NON-NLS-1$ - this.goalsAfterCleanText.setText(getAttribute(configuration, ATTR_GOALS_AFTER_CLEAN, "install")); //$NON-NLS-1$ - } else { - this.goalsText.setText(getAttribute(configuration, ATTR_GOALS, "")); //$NON-NLS-1$ - } + this.goalsText.setText(getAttribute(configuration, ATTR_GOALS, "")); //$NON-NLS-1$ this.profilesText.setText(getAttribute(configuration, ATTR_PROFILES, "")); //$NON-NLS-1$ try { - MavenRuntimeManager runtimeManager = MavenPlugin.getMavenRuntimeManager(); IMavenConfiguration mavenConfiguration = MavenPlugin.getMavenConfiguration(); this.offlineButton.setSelection(getAttribute(configuration, ATTR_OFFLINE, mavenConfiguration.isOffline())); @@ -609,12 +480,9 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement this.enableWorkspaceResolution.setSelection(getAttribute(configuration, ATTR_WORKSPACE_RESOLUTION, false)); this.threadsCombo.select(getAttribute(configuration, ATTR_THREADS, 1) - 1); - String location = getAttribute(configuration, ATTR_RUNTIME, ""); //$NON-NLS-1$ - MavenRuntime runtime = runtimeManager.getRuntime(location); - if(runtime != null) { - this.runtimeComboViewer.setSelection(new StructuredSelection(runtime)); - } - propsTable.removeAll(); + this.runtimeSelector.initializeFrom(configuration); + + this.propsTable.removeAll(); @SuppressWarnings("unchecked") List<String> properties = configuration.getAttribute(ATTR_PROPERTIES, Collections.EMPTY_LIST); @@ -670,30 +538,7 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement public void performApply(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(ATTR_POM_DIR, this.pomDirNameText.getText()); - if(isBuilder) { - configuration.setAttribute(ATTR_GOALS_AUTO_BUILD, goalsAutoBuildText.getText()); - configuration.setAttribute(ATTR_GOALS_MANUAL_BUILD, this.goalsManualBuildText.getText()); - configuration.setAttribute(ATTR_GOALS_CLEAN, this.goalsCleanText.getText()); - configuration.setAttribute(ATTR_GOALS_AFTER_CLEAN, this.goalsAfterCleanText.getText()); - - StringBuffer sb = new StringBuffer(); - if(goalsAfterCleanText.getText().trim().length() > 0) { - sb.append(IExternalToolConstants.BUILD_TYPE_FULL).append(','); - } - if(goalsManualBuildText.getText().trim().length() > 0) { - sb.append(IExternalToolConstants.BUILD_TYPE_INCREMENTAL).append(','); - } - if(goalsAutoBuildText.getText().trim().length() > 0) { - sb.append(IExternalToolConstants.BUILD_TYPE_AUTO).append(','); - } - if(goalsCleanText.getText().trim().length() > 0) { - sb.append(IExternalToolConstants.BUILD_TYPE_CLEAN); - } - configuration.setAttribute(IExternalToolConstants.ATTR_RUN_BUILD_KINDS, sb.toString()); - - } else { - configuration.setAttribute(ATTR_GOALS, this.goalsText.getText()); - } + configuration.setAttribute(ATTR_GOALS, this.goalsText.getText()); configuration.setAttribute(ATTR_PROFILES, this.profilesText.getText()); @@ -704,9 +549,7 @@ public class MavenLaunchMainTab extends AbstractLaunchConfigurationTab implement configuration.setAttribute(ATTR_WORKSPACE_RESOLUTION, this.enableWorkspaceResolution.getSelection()); configuration.setAttribute(ATTR_DEBUG_OUTPUT, this.debugOutputButton.getSelection()); - IStructuredSelection selection = (IStructuredSelection) runtimeComboViewer.getSelection(); - MavenRuntime runtime = (MavenRuntime) selection.getFirstElement(); - configuration.setAttribute(ATTR_RUNTIME, runtime.getLocation()); + runtimeSelector.performApply(configuration); configuration.setAttribute(ATTR_THREADS, threadsCombo.getSelectionIndex() + 1); diff --git a/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenRuntimeSelector.java b/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenRuntimeSelector.java new file mode 100644 index 00000000..8e218495 --- /dev/null +++ b/org.eclipse.m2e.launching/src/org/eclipse/m2e/ui/internal/launch/MavenRuntimeSelector.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 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.ui.internal.launch; + +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.dialogs.PreferencesUtil; + +import org.eclipse.m2e.actions.MavenLaunchConstants; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.embedder.MavenRuntime; +import org.eclipse.m2e.core.embedder.MavenRuntimeManager; + + +/** + * @since 1.4 + */ +public class MavenRuntimeSelector extends Composite { + + ComboViewer runtimeComboViewer; + + private MavenRuntimeManager runtimeManager; + + public MavenRuntimeSelector(final Composite mainComposite) { + super(mainComposite, SWT.NONE); + + GridLayout gridLayout = new GridLayout(3, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + setLayout(gridLayout); + + Label mavenRuntimeLabel = new Label(this, SWT.NONE); + mavenRuntimeLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + mavenRuntimeLabel.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_lblRuntime); + + runtimeComboViewer = new ComboViewer(this, SWT.BORDER | SWT.READ_ONLY); + runtimeComboViewer.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + runtimeComboViewer.setContentProvider(new IStructuredContentProvider() { + + public Object[] getElements(Object input) { + return ((List<?>) input).toArray(); + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public void dispose() { + } + + }); + + try { + runtimeManager = MavenPlugin.getMavenRuntimeManager(); + runtimeComboViewer.setInput(runtimeManager.getMavenRuntimes()); + runtimeComboViewer.setSelection(new StructuredSelection(runtimeManager.getDefaultRuntime())); + } catch(NullPointerException e) { + // ignore, this only happens inside windowbuilder + } + + Button configureRuntimesButton = new Button(this, SWT.NONE); + configureRuntimesButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + configureRuntimesButton.setText(org.eclipse.m2e.internal.launch.Messages.MavenLaunchMainTab_btnConfigure); + configureRuntimesButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + PreferencesUtil.createPreferenceDialogOn(mainComposite.getShell(), + "org.eclipse.m2e.core.preferences.MavenInstallationsPreferencePage", null, null).open(); //$NON-NLS-1$ + MavenRuntimeManager runtimeManager = MavenPlugin.getMavenRuntimeManager(); + runtimeComboViewer.setInput(runtimeManager.getMavenRuntimes()); + runtimeComboViewer.setSelection(new StructuredSelection(runtimeManager.getDefaultRuntime())); + } + }); + } + + public void setSelectRuntime(MavenRuntime runtime) { + this.runtimeComboViewer.setSelection(new StructuredSelection(runtime)); + } + + public MavenRuntime getSelectedRuntime() { + IStructuredSelection selection = (IStructuredSelection) runtimeComboViewer.getSelection(); + return (MavenRuntime) selection.getFirstElement(); + } + + public void addSelectionChangedListener(ISelectionChangedListener listener) { + runtimeComboViewer.addSelectionChangedListener(listener); + } + + public void initializeFrom(ILaunchConfiguration configuration) { + String location = ""; + try { + location = configuration.getAttribute(MavenLaunchConstants.ATTR_RUNTIME, ""); //$NON-NLS-1$ + } catch(CoreException ex) { + // TODO log + } + MavenRuntime runtime = runtimeManager.getRuntime(location); + if(runtime != null) { + setSelectRuntime(runtime); + } + } + + public void performApply(ILaunchConfigurationWorkingCopy configuration) { + MavenRuntime runtime = getSelectedRuntime(); + configuration.setAttribute(MavenLaunchConstants.ATTR_RUNTIME, runtime.getLocation()); + } +} |