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
.IProgressMonitor
;
20 import org
.eclipse
.core
.runtime
.IStatus
;
21 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
22 import org
.eclipse
.core
.runtime
.Status
;
23 import org
.eclipse
.core
.runtime
.jobs
.Job
;
24 import org
.eclipse
.jdt
.annotation
.Nullable
;
25 import org
.eclipse
.jface
.dialogs
.IInputValidator
;
26 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
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
.analysis
.ondemand
.OnDemandAnalysisException
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
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 PARAM_STRING_VALIDATOR
);
113 if (dialog
.open() != Window
.OK
) {
114 /* User clicked Cancel, don't run */
117 String extraParams
= nullToEmptyString(dialog
.getValue());
119 /* Execute the analysis and produce the reports */
120 Job job
= new Job(Messages
.LamiAnalysis_MainTaskName
) {
122 protected @Nullable IStatus
run(@Nullable IProgressMonitor monitor
) {
123 IProgressMonitor mon
= (monitor
== null ?
new NullProgressMonitor() : monitor
);
125 List
<LamiResultTable
> results
= analysis
.execute(trace
, tr
, extraParams
, mon
);
127 String reportName
= analysis
.getName() +' ' + Messages
.ParameterDialog_ReportNameSuffix
;
128 LamiAnalysisReport report
= new LamiAnalysisReport(reportName
, results
);
129 registerNewReport(analysisElem
, report
);
131 /* Automatically open the report for convenience */
132 Display
.getDefault().syncExec(() -> {
134 LamiReportViewFactory
.createNewViews(report
);
135 } catch (PartInitException e
) {
138 return Status
.OK_STATUS
;
140 } catch (OnDemandAnalysisException e
) {
141 String errMsg
= e
.getMessage();
143 if (errMsg
!= null) {
144 /* The analysis execution yielded an error */
145 Display
.getDefault().asyncExec(() -> {
146 MessageDialog
.openError(shell
,
148 Messages
.ParameterDialog_Error
,
150 Messages
.ParameterDialog_ErrorMessage
+ ":\n\n" + //$NON-NLS-1$
155 return Status
.CANCEL_STATUS
;
164 private static final IInputValidator PARAM_STRING_VALIDATOR
= text
-> {
165 if (text
.isEmpty() || text
.matches("[a-zA-Z0-9\\,\\-\\s]+")) { //$NON-NLS-1$
168 return Messages
.ParameterDialog_StringValidatorMessage
;
172 * Register a new report
174 * @param analysisElem
175 * The analysis's project element
179 public void registerNewReport(TmfOnDemandAnalysisElement analysisElem
, IOnDemandAnalysisReport report
) {
180 /* For now the TmfProjectReportsElement manages the reports. */
181 TmfReportsElement reportsElement
= analysisElem
184 .getChildElementReports();
186 reportsElement
.addReport(report
);