1 /*******************************************************************************
2 * Copyright (c) 2015, 2016 EfficiOS Inc., Alexandre Montplaisir
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.provisional
.analysis
.lami
.ui
.handler
;
12 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.nullToEmptyString
;
14 import java
.util
.List
;
16 import org
.eclipse
.core
.commands
.AbstractHandler
;
17 import org
.eclipse
.core
.commands
.ExecutionEvent
;
18 import org
.eclipse
.core
.commands
.ExecutionException
;
19 import org
.eclipse
.core
.runtime
.CoreException
;
20 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
21 import org
.eclipse
.core
.runtime
.IStatus
;
22 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
23 import org
.eclipse
.core
.runtime
.Status
;
24 import org
.eclipse
.core
.runtime
.jobs
.Job
;
25 import org
.eclipse
.jdt
.annotation
.Nullable
;
26 import org
.eclipse
.jface
.dialogs
.ErrorDialog
;
27 import org
.eclipse
.jface
.viewers
.ISelection
;
28 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
29 import org
.eclipse
.jface
.window
.Window
;
30 import org
.eclipse
.swt
.widgets
.Display
;
31 import org
.eclipse
.swt
.widgets
.Shell
;
32 import org
.eclipse
.tracecompass
.internal
.provisional
.analysis
.lami
.core
.module
.LamiAnalysis
;
33 import org
.eclipse
.tracecompass
.internal
.provisional
.analysis
.lami
.core
.module
.LamiAnalysisReport
;
34 import org
.eclipse
.tracecompass
.internal
.provisional
.analysis
.lami
.core
.module
.LamiResultTable
;
35 import org
.eclipse
.tracecompass
.internal
.provisional
.analysis
.lami
.ui
.views
.LamiReportViewFactory
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.ondemand
.IOnDemandAnalysis
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.ondemand
.IOnDemandAnalysisReport
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
41 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.handlers
.HandlerUtils
;
42 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfCommonProjectElement
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfOnDemandAnalysisElement
;
44 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfReportsElement
;
45 import org
.eclipse
.ui
.PartInitException
;
46 import org
.eclipse
.ui
.PlatformUI
;
47 import org
.eclipse
.ui
.handlers
.HandlerUtil
;
50 * The command handler for the "Run External Analysis" menu option.
52 * @author Alexandre Montplaisir
54 public class RunAnalysisHandler
extends AbstractHandler
{
57 public boolean isEnabled() {
58 final Object element
= HandlerUtils
.getSelectedModelElement();
59 if (element
== null) {
64 * plugin.xml should have done type verifications already
66 TmfOnDemandAnalysisElement elem
= (TmfOnDemandAnalysisElement
) element
;
67 if (elem
.getAnalysis() instanceof LamiAnalysis
&& elem
.canRun()) {
75 public @Nullable Object
execute(@Nullable ExecutionEvent event
) throws ExecutionException
{
77 /* Types should have been checked by the plugin.xml already */
78 ISelection selection
= HandlerUtil
.getCurrentSelectionChecked(event
);
79 Object element
= ((IStructuredSelection
) selection
).getFirstElement();
80 final TmfOnDemandAnalysisElement analysisElem
= (TmfOnDemandAnalysisElement
) element
;
82 TmfCommonProjectElement traceElem
= analysisElem
.getParent().getParent();
83 ITmfTrace trace
= traceElem
.getTrace();
85 /* That trace is not currently opened */
89 /* Retrieve and initialize the analysis module, aka read the script's metadata */
90 IOnDemandAnalysis ondemandAnalysis
= analysisElem
.getAnalysis();
91 if (!(ondemandAnalysis
instanceof LamiAnalysis
)) {
94 LamiAnalysis analysis
= (LamiAnalysis
) ondemandAnalysis
;
96 /* Retrieve the current time range, will be used as parameters to the analysis */
97 TmfTraceManager tm
= TmfTraceManager
.getInstance();
98 TmfTimeRange timeRange
= tm
.getCurrentTraceContext().getSelectionRange();
99 if (timeRange
.getStartTime().equals(timeRange
.getEndTime())) {
102 /* Job below needs a final reference... */
103 final TmfTimeRange tr
= timeRange
;
105 /* Pop the dialog to ask for extra parameters */
106 String baseCommand
= analysis
.getFullCommandAsString(trace
, tr
);
108 Shell shell
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell();
109 ParameterDialog dialog
= new ParameterDialog(shell
, Messages
.ParameterDialog_ExternalParameters
,
110 Messages
.ParameterDialog_ExternalParametersDescription
,
112 if (dialog
.open() != Window
.OK
) {
113 /* User clicked Cancel, don't run */
116 String extraParams
= nullToEmptyString(dialog
.getValue());
118 /* Execute the analysis and produce the reports */
119 Job job
= new Job(Messages
.LamiAnalysis_MainTaskName
) {
121 protected @Nullable IStatus
run(@Nullable IProgressMonitor monitor
) {
122 IProgressMonitor mon
= (monitor
== null ?
new NullProgressMonitor() : monitor
);
124 List
<LamiResultTable
> results
= analysis
.execute(trace
, tr
, extraParams
, mon
);
126 String reportName
= analysis
.getName() +' ' + Messages
.ParameterDialog_ReportNameSuffix
;
127 LamiAnalysisReport report
= new LamiAnalysisReport(reportName
, results
);
128 registerNewReport(analysisElem
, report
);
130 /* Automatically open the report for convenience */
131 Display
.getDefault().syncExec(() -> {
133 LamiReportViewFactory
.createNewView(report
);
134 } catch (PartInitException e
) {
137 return Status
.OK_STATUS
;
139 } catch (CoreException e
) {
141 * The analysis execution did not complete normally, we will
142 * report it to the user.
144 IStatus status
= e
.getStatus();
146 /* Don't display a dialog if it was simply cancelled by the user */
147 if (status
.matches(IStatus
.CANCEL
)) {
152 String dialogMessage
;
153 if (status
.matches(IStatus
.ERROR
)) {
154 dialogTitle
= Messages
.ErrorDialog_Error
;
155 dialogMessage
= Messages
.ErrorDialog_ErrorMessage
;
157 dialogTitle
= Messages
.ErrorDialog_Info
;
158 dialogMessage
= Messages
.ErrorDialog_InfoMessage
;
161 Display
.getDefault().asyncExec(() -> {
162 ErrorDialog
.openError(shell
, dialogTitle
, dialogMessage
, status
);
166 * We showed our own error message, no need for the Job to
169 return Status
.OK_STATUS
;
179 * Register a new report
181 * @param analysisElem
182 * The analysis's project element
186 public void registerNewReport(TmfOnDemandAnalysisElement analysisElem
, IOnDemandAnalysisReport report
) {
187 /* For now the TmfProjectReportsElement manages the reports. */
188 TmfReportsElement reportsElement
= analysisElem
191 .getChildElementReports();
193 reportsElement
.addReport(report
);