1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
4 * All rights reserved. This program and the accompanying materials are made
5 * 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 *******************************************************************************/
9 package org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.ui
.handler
;
12 import java
.util
.ArrayList
;
15 import org
.eclipse
.core
.resources
.IProject
;
16 import org
.eclipse
.core
.resources
.IResource
;
17 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
18 import org
.eclipse
.core
.runtime
.CoreException
;
19 import org
.eclipse
.core
.runtime
.IPath
;
20 import org
.eclipse
.core
.runtime
.IStatus
;
21 import org
.eclipse
.core
.runtime
.Path
;
22 import org
.eclipse
.jface
.dialogs
.Dialog
;
23 import org
.eclipse
.jface
.dialogs
.IDialogConstants
;
24 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
25 import org
.eclipse
.jface
.viewers
.ISelection
;
26 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
27 import org
.eclipse
.jface
.viewers
.TreeSelection
;
28 import org
.eclipse
.osgi
.util
.NLS
;
29 import org
.eclipse
.swt
.SWT
;
30 import org
.eclipse
.swt
.events
.SelectionEvent
;
31 import org
.eclipse
.swt
.events
.SelectionListener
;
32 import org
.eclipse
.swt
.layout
.GridData
;
33 import org
.eclipse
.swt
.layout
.GridLayout
;
34 import org
.eclipse
.swt
.widgets
.Button
;
35 import org
.eclipse
.swt
.widgets
.Composite
;
36 import org
.eclipse
.swt
.widgets
.Control
;
37 import org
.eclipse
.swt
.widgets
.Display
;
38 import org
.eclipse
.swt
.widgets
.FileDialog
;
39 import org
.eclipse
.swt
.widgets
.Label
;
40 import org
.eclipse
.swt
.widgets
.List
;
41 import org
.eclipse
.swt
.widgets
.Shell
;
42 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.module
.XmlAnalysisModuleSource
;
43 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
44 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.ui
.Activator
;
45 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfCommonProjectElement
;
46 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectElement
;
47 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectModelElement
;
48 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
49 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TraceUtils
;
50 import org
.eclipse
.ui
.IWorkbenchPage
;
51 import org
.eclipse
.ui
.IWorkbenchPart
;
52 import org
.eclipse
.ui
.IWorkbenchWindow
;
53 import org
.eclipse
.ui
.PlatformUI
;
56 * Dialog for XML analysis files
58 * @author Jean-Christian Kouame
60 public class ManageXMLAnalysisDialog
extends Dialog
{
62 private final String XML_FILTER_EXTENSION
= "*.xml"; //$NON-NLS-1$
63 private List fAnalysesList
;
64 private Button fDeleteButton
;
65 private Button fImportButton
;
66 private Button fExportButton
;
67 private Label fInvalidFileLabel
;
73 * Parent shell of this dialog
75 public ManageXMLAnalysisDialog(Shell parent
) {
77 setShellStyle(SWT
.RESIZE
| SWT
.MAX
| getShellStyle());
81 protected Control
createDialogArea(Composite parent
) {
82 getShell().setText(Messages
.ManageXMLAnalysisDialog_ManageXmlAnalysesFiles
);
84 Composite composite
= (Composite
) super.createDialogArea(parent
);
85 composite
.setLayout(new GridLayout(2, false));
87 Composite listContainer
= new Composite(composite
, SWT
.NONE
);
88 listContainer
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
89 GridLayout lcgl
= new GridLayout();
90 lcgl
.marginHeight
= 0;
92 listContainer
.setLayout(lcgl
);
94 fAnalysesList
= new List(listContainer
, SWT
.SINGLE
| SWT
.BORDER
| SWT
.H_SCROLL
| SWT
.V_SCROLL
);
95 fAnalysesList
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
96 fAnalysesList
.addSelectionListener(new SelectionListener() {
98 public void widgetDefaultSelected(SelectionEvent e
) {
102 public void widgetSelected(SelectionEvent e
) {
103 if (fAnalysesList
.getSelectionCount() == 0) {
104 fDeleteButton
.setEnabled(false);
105 fExportButton
.setEnabled(false);
107 fDeleteButton
.setEnabled(true);
108 fExportButton
.setEnabled(true);
109 handleSelection(fAnalysesList
.getSelection());
114 fInvalidFileLabel
= new Label(listContainer
, SWT
.ICON_ERROR
);
115 fInvalidFileLabel
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, false, false));
116 fInvalidFileLabel
.setForeground(getShell().getDisplay().getSystemColor(SWT
.COLOR_RED
));
117 fInvalidFileLabel
.setText(Messages
.ManageXMLAnalysisDialog_FileValidationError
);
118 fInvalidFileLabel
.setVisible(false);
120 Composite buttonContainer
= new Composite(composite
, SWT
.NULL
);
121 buttonContainer
.setLayout(new GridLayout());
122 buttonContainer
.setLayoutData(new GridData(SWT
.CENTER
, SWT
.TOP
, false, false));
124 fImportButton
= new Button(buttonContainer
, SWT
.PUSH
);
125 fImportButton
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, false, false));
126 fImportButton
.setText(Messages
.ManageXMLAnalysisDialog_Import
);
127 fImportButton
.addSelectionListener(new SelectionListener() {
129 public void widgetDefaultSelected(SelectionEvent e
) {
133 public void widgetSelected(SelectionEvent e
) {
138 fExportButton
= new Button(buttonContainer
, SWT
.PUSH
);
139 fExportButton
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, false, false));
140 fExportButton
.setText(Messages
.ManageXMLAnalysisDialog_Export
);
141 fExportButton
.setEnabled(false);
142 fExportButton
.addSelectionListener(new SelectionListener() {
144 public void widgetDefaultSelected(SelectionEvent e
) {
148 public void widgetSelected(SelectionEvent e
) {
153 fDeleteButton
= new Button(buttonContainer
, SWT
.PUSH
);
154 fDeleteButton
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, false, false));
155 fDeleteButton
.setText(Messages
.ManageXMLAnalysisDialog_Delete
);
156 fDeleteButton
.setEnabled(false);
157 fDeleteButton
.addSelectionListener(new SelectionListener() {
159 public void widgetDefaultSelected(SelectionEvent e
) {
163 public void widgetSelected(SelectionEvent e
) {
171 getShell().setMinimumSize(300, 275);
175 private void handleSelection(String
[] selection
) {
176 Map
<String
, File
> files
= XmlUtils
.listFiles();
177 File file
= files
.get(createXmlFileString(selection
[0]));
178 if (file
!= null && XmlUtils
.xmlValidate(file
).isOK()) {
179 fInvalidFileLabel
.setVisible(false);
181 fInvalidFileLabel
.setVisible(true);
185 private static void deleteSupplementaryFile(String xmlFile
) {
186 // 1. Look for all traces that have this analysis
187 // 2. Close them if they are opened.
188 // 3. Delete the related supplementary files
189 java
.util
.List
<IResource
> resourceToDelete
= new ArrayList
<>();
190 java
.util
.List
<String
> ids
= XmlUtils
.getAnalysisIdsFromFile(xmlFile
);
191 IProject
[] projects
= ResourcesPlugin
.getWorkspace().getRoot().getProjects(0);
192 for (IProject project
: projects
) {
193 TmfProjectElement pElement
= TmfProjectRegistry
.getProject(project
);
194 if (pElement
!= null) {
195 java
.util
.List
<TmfCommonProjectElement
> tElements
= new ArrayList
<>();
196 tElements
.addAll(pElement
.getTracesFolder().getTraces());
197 tElements
.addAll(pElement
.getExperimentsFolder().getExperiments());
198 for (TmfCommonProjectElement tElement
: tElements
) {
199 boolean closeEditor
= false;
200 for (IResource resource
: tElement
.getSupplementaryResources()) {
201 for (String id
: ids
) {
202 if (resource
.getName().startsWith(id
)) {
203 resourceToDelete
.add(resource
);
209 tElement
.closeEditors();
214 for (IResource resource
: resourceToDelete
) {
216 resource
.delete(false, null);
217 } catch (CoreException e
) {
218 Activator
.logError(NLS
.bind(Messages
.ManageXMLAnalysisDialog_DeleteFileError
, resource
.getName()));
224 protected void createButtonsForButtonBar(Composite parent
) {
225 createButton(parent
, IDialogConstants
.OK_ID
, IDialogConstants
.CLOSE_LABEL
, false);
228 private void fillAnalysesList() {
229 fAnalysesList
.removeAll();
230 Map
<String
, File
> files
= XmlUtils
.listFiles();
231 for (String file
: files
.keySet()) {
232 // Remove the extension from the file path. The extension is at the
233 // end of the file path
234 IPath path
= new Path(file
);
235 fAnalysesList
.add(path
.removeFileExtension().toString());
237 fDeleteButton
.setEnabled(false);
238 fExportButton
.setEnabled(false);
241 private void importAnalysis() {
242 FileDialog dialog
= new FileDialog(Display
.getCurrent().getActiveShell(), SWT
.OPEN
);
243 dialog
.setText(Messages
.ManageXMLAnalysisDialog_SelectFileImport
);
244 dialog
.setFilterNames(new String
[] { Messages
.ManageXMLAnalysisDialog_ImportXmlFile
+ " (*.xml)" }); //$NON-NLS-1$
245 dialog
.setFilterExtensions(new String
[] { XML_FILTER_EXTENSION
});
246 String path
= dialog
.open();
248 File file
= new File(path
);
249 IStatus status
= XmlUtils
.xmlValidate(file
);
251 deleteSupplementaryFile(file
.getName());
252 status
= XmlUtils
.addXmlFile(file
);
255 XmlAnalysisModuleSource
.notifyModuleChange();
257 * FIXME: It refreshes the list of analysis under a trace,
258 * but since modules are instantiated when the trace opens,
259 * the changes won't apply to an opened trace, it needs to
260 * be closed then reopened
264 Activator
.logError(Messages
.ManageXMLAnalysisDialog_ImportFileFailed
);
265 TraceUtils
.displayErrorMsg(Messages
.ManageXMLAnalysisDialog_ImportFileFailed
, status
.getMessage());
268 Activator
.logError(Messages
.ManageXMLAnalysisDialog_ImportFileFailed
);
269 TraceUtils
.displayErrorMsg(Messages
.ManageXMLAnalysisDialog_ImportFileFailed
, status
.getMessage());
274 private void exportAnalysis() {
275 FileDialog dialog
= new FileDialog(Display
.getCurrent().getActiveShell(), SWT
.SAVE
);
276 dialog
.setText(NLS
.bind(Messages
.ManageXMLAnalysisDialog_SelectFileExport
, fAnalysesList
.getSelection()[0]));
277 dialog
.setFilterExtensions(new String
[] { XML_FILTER_EXTENSION
, "*" }); //$NON-NLS-1$
278 String selection
= createXmlFileString(fAnalysesList
.getSelection()[0]);
279 dialog
.setFileName(selection
);
280 String path
= dialog
.open();
282 if (!XmlUtils
.exportXmlFile(selection
, path
).isOK()) {
283 Activator
.logError(NLS
.bind(Messages
.ManageXMLAnalysisDialog_FailedToExport
, selection
));
288 private void deleteAnalysis() {
289 boolean confirm
= MessageDialog
.openQuestion(
291 Messages
.ManageXMLAnalysisDialog_DeleteFile
,
292 NLS
.bind(Messages
.ManageXMLAnalysisDialog_DeleteConfirmation
, fAnalysesList
.getSelection()[0]));
294 String selection
= createXmlFileString(fAnalysesList
.getSelection()[0]);
295 deleteSupplementaryFile(selection
);
296 XmlUtils
.deleteFile(selection
);
298 fInvalidFileLabel
.setVisible(false);
299 XmlAnalysisModuleSource
.notifyModuleChange();
301 * FIXME: It refreshes the list of analysis under a trace, but since
302 * modules are instantiated when the trace opens, the changes won't
303 * apply to an opened trace, it needs to be closed then reopened
310 * Refresh the selected project with the new XML file import
312 private static void refreshProject() {
313 // Check if we are closing down
314 IWorkbenchWindow window
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
315 if (window
== null) {
320 IWorkbenchPage page
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getActivePage();
321 IWorkbenchPart part
= page
.getActivePart();
325 ISelectionProvider selectionProvider
= part
.getSite().getSelectionProvider();
326 if (selectionProvider
== null) {
329 ISelection selection
= selectionProvider
.getSelection();
331 if (selection
instanceof TreeSelection
) {
332 TreeSelection sel
= (TreeSelection
) selection
;
333 // There should be only one item selected as per the plugin.xml
334 Object element
= sel
.getFirstElement();
335 if (element
instanceof TmfProjectModelElement
) {
336 ((TmfProjectModelElement
) element
).getProject().refresh();
341 private static String
createXmlFileString(String baseName
) {
342 IPath path
= new Path(baseName
).addFileExtension(XmlUtils
.XML_EXTENSION
);
343 return path
.toString();