/******************************************************************************* * Copyright (c) 2012, 2014 Ericsson * * 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: * Bernd Hufmann - Initial API and implementation * Patrick Tasse - Close editors to release resources *******************************************************************************/ package org.eclipse.tracecompass.internal.tmf.ui.project.handlers; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Display; import org.eclipse.tracecompass.internal.tmf.ui.Activator; import org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.SelectSupplementaryResourcesDialog; import org.eclipse.tracecompass.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; import org.eclipse.tracecompass.tmf.ui.project.model.TmfCommonProjectElement; import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.HandlerUtil; import com.google.common.collect.Multimap; import com.google.common.collect.TreeMultimap; /** * Handler for Delete Supplementary Files command on trace */ public class DeleteTraceSupplementaryFilesHandler extends AbstractHandler { // ------------------------------------------------------------------------ // Inner classes // ------------------------------------------------------------------------ private class ElementComparator implements Comparator<TmfCommonProjectElement> { @Override public int compare(TmfCommonProjectElement e1, TmfCommonProjectElement e2) { return e1.getPath().toString().compareTo(e2.getPath().toString()); } } private class ResourceComparator implements Comparator<IResource> { @Override public int compare(IResource r1, IResource r2) { return r1.getFullPath().toString().compareTo(r2.getFullPath().toString()); } } // ------------------------------------------------------------------------ // Execution // ------------------------------------------------------------------------ @Override public Object execute(ExecutionEvent event) throws ExecutionException { // Check if we are closing down IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window == null) { return null; } // Get the selection ISelection selection = HandlerUtil.getCurrentSelection(event); if (!(selection instanceof IStructuredSelection)) { return null; } final Multimap<TmfCommonProjectElement, IResource> resourceMap = TreeMultimap.create(new ElementComparator(), new ResourceComparator()); final Iterator<Object> iterator = ((IStructuredSelection) selection).iterator(); while (iterator.hasNext()) { Object element = iterator.next(); if (element instanceof TmfTraceElement) { TmfTraceElement trace = (TmfTraceElement) element; // If trace is under an experiment, use the original trace from the traces folder trace = trace.getElementUnderTraceFolder(); for (IResource resource : trace.getSupplementaryResources()) { resourceMap.put(trace, resource); } } else if (element instanceof TmfExperimentElement) { TmfExperimentElement experiment = (TmfExperimentElement) element; for (IResource resource : experiment.getSupplementaryResources()) { resourceMap.put(experiment, resource); } for (TmfTraceElement trace : experiment.getTraces()) { // If trace is under an experiment, use the original trace from the traces folder trace = trace.getElementUnderTraceFolder(); for (IResource resource : trace.getSupplementaryResources()) { resourceMap.put(trace, resource); } } } } final SelectSupplementaryResourcesDialog dialog = new SelectSupplementaryResourcesDialog(window.getShell(), resourceMap); if (dialog.open() != Window.OK) { return null; } TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() { @Override public void execute(IProgressMonitor monitor) throws CoreException { Set<IProject> projectsToRefresh = new HashSet<>(); // Delete the resources that were selected List<IResource> allResourcesToDelete = Arrays.asList(dialog.getResources()); SubMonitor subMonitor = SubMonitor.convert(monitor, allResourcesToDelete.size()); for (final TmfCommonProjectElement element : resourceMap.keySet()) { if (monitor.isCanceled()) { throw new OperationCanceledException(); } List<IResource> traceResourcesToDelete = new ArrayList<>(resourceMap.get(element)); traceResourcesToDelete.retainAll(allResourcesToDelete); if (!traceResourcesToDelete.isEmpty()) { subMonitor.setTaskName(NLS.bind(Messages.DeleteSupplementaryFiles_DeletionTask, element.getElementPath())); // Delete the selected resources Display.getDefault().syncExec(new Runnable() { @Override public void run() { element.closeEditors(); } }); element.deleteSupplementaryResources(traceResourcesToDelete.toArray(new IResource[0])); projectsToRefresh.add(element.getProject().getResource()); } subMonitor.worked(traceResourcesToDelete.size()); } subMonitor = SubMonitor.convert(monitor, projectsToRefresh.size()); // Refresh projects Iterator<IProject> projectIterator = projectsToRefresh.iterator(); while (projectIterator.hasNext()) { if (monitor.isCanceled()) { throw new OperationCanceledException(); } IProject project = projectIterator.next(); subMonitor.setTaskName(NLS.bind(Messages.DeleteSupplementaryFiles_ProjectRefreshTask, project.getName())); try { project.refreshLocal(IResource.DEPTH_INFINITE, null); } catch (CoreException e) { Activator.getDefault().logError("Error refreshing project " + project, e); //$NON-NLS-1$ } subMonitor.worked(1); } } }; try { PlatformUI.getWorkbench().getProgressService().run(true, true, operation); } catch (InterruptedException e) { return null; } catch (InvocationTargetException e) { TraceUtils.displayErrorMsg(e.toString(), e.getTargetException().toString()); return null; } return null; } }