Java tutorial
/** * Copyright (c) 2016 NumberFour AG. * 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: * NumberFour AG - Initial API and implementation */ package eu.numberfour.n4js.ui.workingsets.internal; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jdt.ui.IContextMenuConstants; import org.eclipse.jdt.ui.actions.OpenProjectAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchCommandConstants; import org.eclipse.ui.IWorkbenchSite; import org.eclipse.ui.actions.ActionGroup; import org.eclipse.ui.actions.CloseResourceAction; import org.eclipse.ui.actions.CloseUnrelatedProjectsAction; import org.eclipse.ui.ide.IDEActionFactory; import eu.numberfour.n4js.ui.workingsets.WorkingSet; /** * Action group for closing and opening projects of a N4JS working set. */ public class N4JSProjectActionGroup extends ActionGroup { private static final int CLOSED_PROJECTS_SELECTED = 1; private static final int NON_PROJECT_SELECTED = 2; private final OpenProjectAction openAction; private final CloseResourceAction closeAction; private final CloseResourceAction closeUnrelatedAction; private final ISelectionChangedListener selectionChangedListener; private ISelectionProvider selectionProvider; private boolean enableOpenInContextMenu = true; /** * Creates a new {@code N4JSProjectActionGroup}. The group requires that the selection provided by the site's * selection provider is of type {@link IStructuredSelection}. * * @param part * the view part that owns this action group */ public N4JSProjectActionGroup(final IViewPart part) { this(part.getSite(), part.getSite().getSelectionProvider()); } /** * Creates a new {@code N4JSProjectActionGroup}. The group requires that the selection provided by the given * selection provider is of type {@link IStructuredSelection}. * * @param site * the site that will own the action group. * @param selectionProvider * the selection provider used instead of the page selection provider. */ public N4JSProjectActionGroup(final IWorkbenchSite site, final ISelectionProvider selectionProvider) { this.selectionProvider = selectionProvider; final ISelection selection = selectionProvider.getSelection(); closeAction = new CloseResourceAction(site); closeAction.setActionDefinitionId(IWorkbenchCommandConstants.PROJECT_CLOSE_PROJECT); closeUnrelatedAction = new CloseUnrelatedProjectsAction(site); closeUnrelatedAction.setActionDefinitionId(IWorkbenchCommandConstants.PROJECT_CLOSE_UNRELATED_PROJECTS); openAction = new OpenProjectAction(site); openAction.setActionDefinitionId(IWorkbenchCommandConstants.PROJECT_OPEN_PROJECT); if (selection instanceof IStructuredSelection) { final IStructuredSelection s = (IStructuredSelection) selection; openAction.selectionChanged(s); closeAction.selectionChanged(s); closeUnrelatedAction.selectionChanged(s); } selectionChangedListener = new ISelectionChangedListener() { @Override public void selectionChanged(final SelectionChangedEvent event) { final ISelection s = event.getSelection(); if (s instanceof IStructuredSelection) { performSelectionChanged((IStructuredSelection) s); } } }; selectionProvider.addSelectionChangedListener(selectionChangedListener); final IWorkspace workspace = ResourcesPlugin.getWorkspace(); workspace.addResourceChangeListener(openAction); workspace.addResourceChangeListener(closeAction); workspace.addResourceChangeListener(closeUnrelatedAction); } private void performSelectionChanged(final IStructuredSelection structuredSelection) { final Object[] array = structuredSelection.toArray(); final ArrayList<IProject> openProjects = new ArrayList<>(); final int selectionStatus = evaluateSelection(array, openProjects); final StructuredSelection sel = new StructuredSelection(openProjects); openAction.setEnabled(hasClosedProjectsInWorkspace()); enableOpenInContextMenu = (selectionStatus & CLOSED_PROJECTS_SELECTED) != 0 || (selectionStatus == 0 && array.length == 0 && hasClosedProjectsInWorkspace()); closeAction.selectionChanged(sel); closeUnrelatedAction.selectionChanged(sel); } private int evaluateSelection(final Object[] array, final List<IProject> allOpenProjects) { int status = 0; for (int i = 0; i < array.length; i++) { final Object curr = array[i]; if (curr instanceof IProject) { final IProject project = (IProject) curr; if (project.isOpen()) { allOpenProjects.add(project); } else { status |= CLOSED_PROJECTS_SELECTED; } } else { if (curr instanceof WorkingSet) { final int res = evaluateSelection(((WorkingSet) curr).getElements(), allOpenProjects); status |= res; } else { status |= NON_PROJECT_SELECTED; } } } return status; } private boolean hasClosedProjectsInWorkspace() { final IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); for (int i = 0; i < projects.length; i++) { if (!projects[i].isOpen()) return true; } return false; } @Override public void fillActionBars(final IActionBars actionBars) { super.fillActionBars(actionBars); actionBars.setGlobalActionHandler(IDEActionFactory.CLOSE_PROJECT.getId(), closeAction); actionBars.setGlobalActionHandler(IDEActionFactory.CLOSE_UNRELATED_PROJECTS.getId(), closeUnrelatedAction); actionBars.setGlobalActionHandler(IDEActionFactory.OPEN_PROJECT.getId(), openAction); } @Override public void fillContextMenu(final IMenuManager menu) { super.fillContextMenu(menu); if (openAction.isEnabled() && enableOpenInContextMenu) menu.appendToGroup(IContextMenuConstants.GROUP_BUILD, openAction); if (closeAction.isEnabled()) menu.appendToGroup(IContextMenuConstants.GROUP_BUILD, closeAction); if (closeUnrelatedAction.isEnabled() && areOnlyProjectsSelected(closeUnrelatedAction.getStructuredSelection())) menu.appendToGroup(IContextMenuConstants.GROUP_BUILD, closeUnrelatedAction); } /** * Returns the open project action contained in this project action group. * * @return returns the open project action */ public OpenProjectAction getOpenProjectAction() { return openAction; } private boolean areOnlyProjectsSelected(final IStructuredSelection selection) { if (selection.isEmpty()) return false; final Iterator<?> iter = selection.iterator(); while (iter.hasNext()) { final Object obj = iter.next(); if (obj instanceof IAdaptable) { if (((IAdaptable) obj).getAdapter(IProject.class) == null) { return false; } } } return true; } @Override public void dispose() { selectionProvider.removeSelectionChangedListener(selectionChangedListener); selectionProvider = null; final IWorkspace workspace = ResourcesPlugin.getWorkspace(); workspace.removeResourceChangeListener(openAction); workspace.removeResourceChangeListener(closeAction); workspace.removeResourceChangeListener(closeUnrelatedAction); super.dispose(); } }