/******************************************************************************* * Copyright (c) 2008-2010 Sonatype, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Sonatype, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.m2e.core.ui.internal.actions; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; 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.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; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; 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.PlatformUI; import org.codehaus.plexus.util.IOUtil; import org.apache.maven.artifact.Artifact; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.project.MavenProject; import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.m2e.core.embedder.ArtifactKey; import org.eclipse.m2e.core.embedder.ICallable; import org.eclipse.m2e.core.embedder.IMaven; import org.eclipse.m2e.core.embedder.IMavenExecutionContext; import org.eclipse.m2e.core.internal.IMavenConstants; import org.eclipse.m2e.core.project.IMavenProjectFacade; import org.eclipse.m2e.core.project.IMavenProjectRegistry; import org.eclipse.m2e.core.ui.internal.Messages; import org.eclipse.m2e.core.ui.internal.WorkingSets; import org.eclipse.m2e.core.ui.internal.util.Util; import org.eclipse.m2e.core.ui.internal.util.Util.FileStoreEditorInputStub; /** * Helper methods to deal with workspace resources passed as navigator selection to actions and wizards. */ public class SelectionUtil { private static final Logger log = LoggerFactory.getLogger(SelectionUtil.class); public static final int UNSUPPORTED = 0; public static final int PROJECT_WITH_NATURE = 1; public static final int PROJECT_WITHOUT_NATURE = 2; public static final int POM_FILE = 4; public static final int JAR_FILE = 8; public static final int WORKING_SET = 16; /** Checks which type the given selection belongs to. */ public static int getSelectionType(IStructuredSelection selection) { int type = UNSUPPORTED; if(selection != null) { for(Iterator<?> it = selection.iterator(); it.hasNext();) { int elementType = getElementType(it.next()); if(elementType == UNSUPPORTED) { return UNSUPPORTED; } type |= elementType; } } return type; } /** Checks which type the given element belongs to. */ public static int getElementType(Object element) { IProject project = getType(element, IProject.class); if(project != null) { try { if(project.hasNature(IMavenConstants.NATURE_ID)) { return PROJECT_WITH_NATURE; } return PROJECT_WITHOUT_NATURE; } catch(CoreException e) { // ignored } } IFile file = getType(element, IFile.class); if(file != null) { if(IMavenConstants.POM_FILE_NAME.equals(file.getFullPath().lastSegment())) { return POM_FILE; } } ArtifactKey artifactKey = getType(element, ArtifactKey.class); if(artifactKey != null) { return JAR_FILE; } IWorkingSet workingSet = getType(element, IWorkingSet.class); if(workingSet != null) { return WORKING_SET; } return UNSUPPORTED; } /** * Checks if the object belongs to a given type and returns it or a suitable adapter. */ @SuppressWarnings("unchecked") public static <T> T getType(Object element, Class<T> type) { if(element == null) { return null; } if(type.isInstance(element)) { return (T) element; } if(element instanceof IAdaptable) { T adapter = (T) ((IAdaptable) element).getAdapter(type); if(adapter != null) { return adapter; } } return (T) Platform.getAdapterManager().getAdapter(element, type); } public static IPath getSelectedLocation(IStructuredSelection selection) { Object element = selection == null ? null : selection.getFirstElement(); IPath path = getType(element, IPath.class); if(path != null) { return path; } IResource resource = getType(element, IResource.class); if(resource != null) { return resource.getLocation(); } // IPackageFragmentRoot fragment = getType(element, IResource.class); // if(fragment != null) { // IJavaProject javaProject = fragment.getJavaProject(); // if(javaProject != null) { // IResource resource = getType(javaProject, IResource.class); // if(resource != null) { // return resource.getProject().getProject().getLocation(); // } // } // } return null; } public static IWorkingSet getSelectedWorkingSet(IStructuredSelection selection) { Object element = selection == null ? null : selection.getFirstElement(); if(element == null) { return null; } IWorkingSet workingSet = getType(element, IWorkingSet.class); if(workingSet != null) { return workingSet; } IResource resource = getType(element, IResource.class); if(resource != null) { return WorkingSets.getAssignedWorkingSet(resource.getProject()); } return null; // IResource resource = getType(element, IResource.class); // if(resource != null) { // return getWorkingSet(resource); // } // IPackageFragmentRoot fragment = getType(element, IPackageFragmentRoot.class); // if(fragment != null) { // IJavaProject javaProject = fragment.getJavaProject(); // if(javaProject != null) { // IResource resource = getType(javaProject, IResource.class); // if(resource != null) { // return getWorkingSet(resource.getProject()); // } // } // } } public static ArtifactKey getArtifactKey(Object element) throws CoreException { if(element instanceof Artifact) { return new ArtifactKey(((Artifact) element)); } else if(element instanceof org.eclipse.aether.graph.DependencyNode) { org.eclipse.aether.artifact.Artifact artifact = ((org.eclipse.aether.graph.DependencyNode) element) .getDependency().getArtifact(); return new ArtifactKey(artifact); //getArtifactKey() used only in a handful of actions, to my knowledge none of these are currently available on //model.edit.Dependency instances. // } else if(element instanceof Dependency) { // Dependency dependency = (Dependency) element; // String groupId = dependency.getGroupId(); // String artifactId = dependency.getArtifactId(); // String version = dependency.getVersion(); // // if(version == null) { // //mkleint: this looks scary // IEditorPart editor = getActiveEditor(); // if(editor!=null) { // MavenProject mavenProject = getMavenProject(editor.getEditorInput(), null); // if(mavenProject!=null) { // Artifact a = mavenProject.getArtifactMap().get(groupId + ":" + artifactId); //$NON-NLS-1$ // version = a.getBaseVersion(); // } // } // } // return new ArtifactKey(dependency.getGroupId(), dependency.getArtifactId(), version, null); } return SelectionUtil.getType(element, ArtifactKey.class); } public static MavenProject getMavenProject(IEditorInput editorInput, IProgressMonitor monitor) throws CoreException { if(editorInput instanceof IFileEditorInput) { IFile pomFile = ((IFileEditorInput) editorInput).getFile(); IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry(); IMavenProjectFacade facade = projectManager.create(pomFile, true, monitor); if(facade != null) { return facade.getMavenProject(monitor); } } else if(editorInput instanceof IStorageEditorInput) { IStorageEditorInput storageInput = (IStorageEditorInput) editorInput; IStorage storage = storageInput.getStorage(); IPath path = storage.getFullPath(); if(path == null || !new File(path.toOSString()).exists()) { File tempPomFile = null; InputStream is = null; OutputStream os = null; try { tempPomFile = File.createTempFile("maven-pom", ".pom"); //$NON-NLS-1$ //$NON-NLS-2$ os = new FileOutputStream(tempPomFile); is = storage.getContents(); IOUtil.copy(is, os); return readMavenProject(tempPomFile, monitor); } catch(IOException ex) { log.error("Can't close stream", ex); //$NON-NLS-1$ } finally { IOUtil.close(is); IOUtil.close(os); if(tempPomFile != null) { tempPomFile.delete(); } } } else { return readMavenProject(path.toFile(), monitor); } } else if(editorInput.getClass().getName().endsWith("FileStoreEditorInput")) { //$NON-NLS-1$ return readMavenProject(new File(Util.proxy(editorInput, FileStoreEditorInputStub.class).getURI().getPath()), monitor); } return null; } private static MavenProject readMavenProject(final File pomFile, IProgressMonitor monitor) throws CoreException { if(monitor == null) { monitor = new NullProgressMonitor(); } final IMaven maven = MavenPlugin.getMaven(); IMavenExecutionContext context = maven.createExecutionContext(); MavenExecutionRequest request = context.getExecutionRequest(); request.setOffline(false); request.setUpdateSnapshots(false); request.setRecursive(false); MavenExecutionResult result = context.execute(new ICallable<MavenExecutionResult>() { public MavenExecutionResult call(IMavenExecutionContext context, IProgressMonitor monitor) throws CoreException { return maven.readMavenProject(pomFile, context.newProjectBuildingRequest()); } }, monitor); MavenProject project = result.getProject(); if(project != null) { return project; } if(result.hasExceptions()) { List<IStatus> statuses = new ArrayList<IStatus>(); List<Throwable> exceptions = result.getExceptions(); for(Throwable e : exceptions) { statuses.add(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, -1, e.getMessage(), e)); } throw new CoreException(new MultiStatus(IMavenConstants.PLUGIN_ID, IStatus.ERROR, // statuses.toArray(new IStatus[statuses.size()]), Messages.SelectionUtil_error_cannot_read, null)); } 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) { safeAdd((IProject) o, projectList); } else if(o instanceof IWorkingSet) { IWorkingSet workingSet = (IWorkingSet) o; for(IAdaptable adaptable : workingSet.getElements()) { IProject project = (IProject) adaptable.getAdapter(IProject.class); safeAdd(project, projectList); } } else if(o instanceof IResource) { safeAdd(((IResource) o).getProject(), projectList); } else if(o instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) o; IProject project = (IProject) adaptable.getAdapter(IProject.class); safeAdd(project, projectList); } } } if(projectList.isEmpty() && includeAll) { return ResourcesPlugin.getWorkspace().getRoot().getProjects(); } return projectList.toArray(new IProject[projectList.size()]); } private static void safeAdd(IProject project, List<IProject> projectList) { try { if(project != null && project.isAccessible() && project.hasNature(IMavenConstants.NATURE_ID) && !projectList.contains(project)) { projectList.add(project); } } catch(CoreException ex) { log.error(ex.getMessage(), ex); } } }