/******************************************************************************* * Copyright (c) 2016 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 *******************************************************************************/ package org.eclipse.tracecompass.internal.tmf.ui.project.operations; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; 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.SubMonitor; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.operation.ModalContext; import org.eclipse.swt.widgets.Display; import org.eclipse.tracecompass.internal.tmf.ui.Activator; import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder; import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; /** * Operation to add traces to an experiment. * * @author Bernd Hufmann */ public class SelectTracesOperation implements IRunnableWithProgress { private final @Nullable TmfExperimentElement fExperimentElement; private final @Nullable TmfTraceFolder fParentTraceFolder; private final @Nullable List<TmfTraceElement> fTraceElements; private final @Nullable List<IResource> fResources; private final @Nullable Map<String, TmfTraceElement> fPreviousTraces; private @NonNull IStatus fStatus = Status.OK_STATUS; /** * Constructor * * @param experimentFolderElement * workspace experiment folder containing the experiment * @param experiment * experiment folder where to add traces * @param parentTraceFolder * the parent trace folder containing the trace resources * @param resources * the trace resources to add to the experiment */ public SelectTracesOperation(@NonNull TmfExperimentFolder experimentFolderElement, @NonNull IFolder experiment, @NonNull TmfTraceFolder parentTraceFolder, @NonNull List<IResource> resources) { this(experimentFolderElement.getExperiment(experiment), parentTraceFolder, null, resources, null); } /** * Constructor. It will add traces to given experiment and remove traces * that don't exist anymore. * * @param experimentElement * the experiment element to add the traces * @param traces * the trace elements * @param previousTraces * map of traces currently available in the experiment */ public SelectTracesOperation(@NonNull TmfExperimentElement experimentElement, @NonNull TmfTraceElement[] traces, @NonNull Map<String, TmfTraceElement> previousTraces) { this(experimentElement, null, traces, null, previousTraces); } // Full constructor for internal use only private SelectTracesOperation(TmfExperimentElement experimentElement, TmfTraceFolder parentTraceFolder, TmfTraceElement[] traces, List<IResource> resources, Map<String, TmfTraceElement> previousTraces) { fExperimentElement = experimentElement; fParentTraceFolder = parentTraceFolder; if (traces == null) { fTraceElements = null; } else { fTraceElements = new ArrayList<>(); fTraceElements.addAll(Arrays.asList(traces)); } fResources = resources; fPreviousTraces = previousTraces; } @Override public void run(IProgressMonitor progressMonitor) { TmfExperimentElement experimentElement = fExperimentElement; if (experimentElement == null) { return; } // Check if operation was cancelled. boolean changed = false; Map<String, TmfTraceElement> previousTraces = new HashMap<>(); if (fPreviousTraces != null) { previousTraces = fPreviousTraces; } List<TmfTraceElement> elements = fTraceElements; if (elements == null) { if ((fParentTraceFolder != null) && (fResources != null)) { elements = fParentTraceFolder.getTraceElements(fResources); } else { return; } } Set<String> keys = previousTraces.keySet(); SubMonitor subMonitor = SubMonitor.convert(progressMonitor, elements.size() + keys.size()); // Add the selected traces to the experiment try { for (TmfTraceElement trace : elements) { ModalContext.checkCanceled(progressMonitor); String name = trace.getElementPath(); if (keys.contains(name)) { subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$ keys.remove(name); } else { subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceSelectionTask + " " + trace.getElementPath()); //$NON-NLS-1$ experimentElement.addTrace(trace, false); changed = true; } subMonitor.worked(1); } // Remove traces that were unchecked (thus left in fPreviousTraces) for (Map.Entry<String, TmfTraceElement> entry : previousTraces.entrySet()) { ModalContext.checkCanceled(progressMonitor); TmfTraceElement trace = entry.getValue(); subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$ try { experimentElement.removeTrace(trace); } catch (CoreException e) { Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError + " " + experimentElement.getName(), e); //$NON-NLS-1$ } changed = true; subMonitor.worked(1); } if (changed) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { experimentElement.closeEditors(); } }); experimentElement.deleteSupplementaryResources(); } setStatus(Status.OK_STATUS); } catch (InterruptedException e) { setStatus(Status.CANCEL_STATUS); } catch (Exception e) { Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError, e); setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SelectTracesWizardPage_SelectionError, e)); } } /** * Set the status for this operation * * @param status * the status */ protected void setStatus(@NonNull IStatus status) { fStatus = status; } /** * Returns the status of the operation execution. * * @return status */ public @NonNull IStatus getStatus() { return fStatus; } }