| /******************************************************************************* |
| * Copyright (c) 2002, 2018 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.core.tools.resources; |
| |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IContainer; |
| import java.util.*; |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.tools.ErrorUtil; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.ui.*; |
| |
| /** |
| * This action pops-up a <code>MessageDialog</code> showing the number of |
| * resources (and their child resources) currently selected. |
| */ |
| public class CountResourcesAction implements IWorkbenchWindowActionDelegate { |
| |
| /** A reference to the window where this action will work in.*/ |
| private IWorkbenchWindow window; |
| |
| /** |
| * Executes this action, popping up a <code>MessageDialog</code> showing the |
| * number of resources (and their child resources) currently selected. |
| * |
| * @param action the action proxy that handles the presentation portion of the |
| * action |
| * @see org.eclipse.jface.action.Action#run() |
| */ |
| @Override |
| public void run(IAction action) { |
| List<IResource> resources = getSelectedResources(); |
| try { |
| int count = countResources(resources); |
| showResourcesCount(resources, count); |
| } catch (CoreException ce) { |
| ErrorUtil.logException(ce, "Error counting resources."); //$NON-NLS-1$ |
| ErrorUtil.showErrorMessage(ce.toString(), "Error counting resources"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Returns a list of resources currently selected. If no resource is currently |
| * selected, returns a list containing the workspace root. |
| * |
| * @return a list of resources |
| */ |
| @SuppressWarnings("rawtypes") |
| private List<IResource> getSelectedResources() { |
| |
| List<IResource> resources = new LinkedList<>(); |
| |
| ISelectionService selectionService = window.getSelectionService(); |
| ISelection selection = selectionService.getSelection(); |
| |
| if (selection instanceof IStructuredSelection) { |
| IStructuredSelection structuredSelection = (IStructuredSelection) selection; |
| for (Iterator elements = structuredSelection.iterator(); elements.hasNext();) { |
| IResource resource = convertToResource(elements.next()); |
| if (resource != null) |
| resources.add(resource); |
| } |
| eliminateRedundancies(resources); |
| } |
| |
| // if no resources were selected, add the workspace root to the list |
| if (resources.size() == 0) |
| resources.add(ResourcesPlugin.getWorkspace().getRoot()); |
| |
| return resources; |
| } |
| |
| /** |
| * Pops-up a <code>MessageDialog</code> showing the number of resources (and |
| * their child resources) currently selected. |
| * |
| * @param resources a list containing all resources used as a starting point in |
| * the search |
| * @param count the number of resources found |
| */ |
| |
| private void showResourcesCount(List<IResource> resources, int count) { |
| StringBuilder message = new StringBuilder(); |
| message.append("Number of resources visited: "); //$NON-NLS-1$ |
| message.append(count); |
| message.append("\nStarting point(s): \n"); //$NON-NLS-1$ |
| for (IResource resource : resources) { |
| message.append('\t'); |
| message.append(resource.getFullPath()); |
| message.append('\n'); |
| } |
| MessageDialog.openInformation(window.getShell(), "Resource counting", message.toString()); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Helper method that converts an object to the <code>IResource</code> |
| * interface. The conversion is a bare cast operation (if the object is instance |
| * of <code>IResource</code>, or an adaptation (if the object is instance of |
| * <code>IAdaptable</code>). |
| * |
| * @param object the object to be cast to <code>IResource</code> |
| * @return a reference to an IResource corresponding to the object provided, or |
| * null if it is not possible to convert the provided object to |
| * <code>IResource</code>. |
| */ |
| private IResource convertToResource(Object object) { |
| |
| if (object instanceof IResource) |
| return (IResource) object; |
| |
| if (object instanceof IAdaptable) { |
| IAdaptable adaptable = (IAdaptable) object; |
| return adaptable.getAdapter(IResource.class); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Counts the number of resources (and its sub-resources) in the list of |
| * resources provided. |
| * |
| * @param resources a <code>List</code> object containing resource objects |
| * @return the number of resources found |
| * @throws CoreException if a visited resource does not exist |
| * @see IResource#accept(org.eclipse.core.resources.IResourceVisitor) |
| */ |
| private int countResources(List<IResource> resources) throws CoreException { |
| |
| ResourceCounterVisitor counter = new ResourceCounterVisitor(); |
| |
| for (IResource resource : resources) |
| resource.accept(counter, IResource.DEPTH_INFINITE, IContainer.INCLUDE_PHANTOMS | IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN); |
| |
| return counter.count; |
| } |
| |
| /** |
| * A helper class that implements <code>IResourceVisitor</code>. Visits each |
| * resource in a resource hierarchy, counting them. |
| */ |
| class ResourceCounterVisitor implements IResourceVisitor { |
| protected int count; |
| |
| /** |
| * @see org.eclipse.core.resources.IResourceVisitor#visit(org.eclipse.core.resources.IResource) |
| */ |
| @Override |
| public boolean visit(IResource resource) { |
| count++; |
| return true; |
| } |
| } |
| |
| /** |
| * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose() |
| */ |
| @Override |
| public void dispose() { |
| // do nothing |
| } |
| |
| /** |
| * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) |
| */ |
| @Override |
| public void selectionChanged(IAction action, ISelection selection) { |
| // do nothing |
| } |
| |
| /** |
| * Initializes this action delegate with the workbench window it will work in. |
| * |
| * @param workbenchWindow the window that provides the context for this delegate |
| * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) |
| */ |
| @Override |
| public void init(IWorkbenchWindow workbenchWindow) { |
| this.window = workbenchWindow; |
| } |
| |
| /** |
| * Eliminates from the resource list provided any redundant resources. |
| * Redundant resources are resources that have any other resources in the list |
| * as ancestors. |
| * |
| * @param resourcesList a <code>List</code> object containing resource objects. |
| */ |
| private void eliminateRedundancies(List<IResource> resourcesList) { |
| if (resourcesList.size() <= 1) |
| return; |
| |
| // we sort the resources list by path so it is easier to check for redundancies |
| resourcesList.sort((resource1, resource2) -> resource1.getFullPath().toString().compareTo(resource2.getFullPath().toString())); |
| |
| // We iterate through the list removing any resource which is descendant |
| // from any resource previously visited |
| Iterator<IResource> resourcesIter = resourcesList.iterator(); |
| IResource last = resourcesIter.next(); |
| while (resourcesIter.hasNext()) { |
| IResource current = resourcesIter.next(); |
| if (last.getFullPath().isPrefixOf(current.getFullPath())) |
| resourcesIter.remove(); |
| else |
| last = current; |
| } |
| } |
| } |