Commit | Line | Data |
---|---|---|
f98e9dbe JCK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2016 Ericsson | |
3 | * | |
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; | |
10 | ||
11 | import java.io.File; | |
12 | import java.util.ArrayList; | |
13 | import java.util.Map; | |
14 | ||
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; | |
537572cd | 19 | import org.eclipse.core.runtime.IPath; |
f98e9dbe | 20 | import org.eclipse.core.runtime.IStatus; |
537572cd | 21 | import org.eclipse.core.runtime.Path; |
f98e9dbe JCK |
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; | |
6eca054d GB |
42 | import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlAnalysisModuleSource; |
43 | import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils; | |
f98e9dbe | 44 | import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator; |
f98e9dbe JCK |
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; | |
54 | ||
55 | /** | |
56 | * Dialog for XML analysis files | |
57 | * | |
58 | * @author Jean-Christian Kouame | |
59 | */ | |
60 | public class ManageXMLAnalysisDialog extends Dialog { | |
61 | ||
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; | |
68 | ||
69 | /** | |
70 | * Constructor | |
71 | * | |
72 | * @param parent | |
73 | * Parent shell of this dialog | |
74 | */ | |
75 | public ManageXMLAnalysisDialog(Shell parent) { | |
76 | super(parent); | |
77 | setShellStyle(SWT.RESIZE | SWT.MAX | getShellStyle()); | |
78 | } | |
79 | ||
80 | @Override | |
81 | protected Control createDialogArea(Composite parent) { | |
82 | getShell().setText(Messages.ManageXMLAnalysisDialog_ManageXmlAnalysesFiles); | |
83 | ||
84 | Composite composite = (Composite) super.createDialogArea(parent); | |
85 | composite.setLayout(new GridLayout(2, false)); | |
86 | ||
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; | |
91 | lcgl.marginWidth = 0; | |
92 | listContainer.setLayout(lcgl); | |
93 | ||
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() { | |
97 | @Override | |
98 | public void widgetDefaultSelected(SelectionEvent e) { | |
99 | } | |
100 | ||
101 | @Override | |
102 | public void widgetSelected(SelectionEvent e) { | |
103 | if (fAnalysesList.getSelectionCount() == 0) { | |
104 | fDeleteButton.setEnabled(false); | |
105 | fExportButton.setEnabled(false); | |
106 | } else { | |
107 | fDeleteButton.setEnabled(true); | |
108 | fExportButton.setEnabled(true); | |
109 | handleSelection(fAnalysesList.getSelection()); | |
110 | } | |
111 | } | |
112 | }); | |
113 | ||
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); | |
119 | ||
120 | Composite buttonContainer = new Composite(composite, SWT.NULL); | |
121 | buttonContainer.setLayout(new GridLayout()); | |
122 | buttonContainer.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false)); | |
123 | ||
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() { | |
128 | @Override | |
129 | public void widgetDefaultSelected(SelectionEvent e) { | |
130 | } | |
131 | ||
132 | @Override | |
133 | public void widgetSelected(SelectionEvent e) { | |
134 | importAnalysis(); | |
135 | } | |
136 | }); | |
137 | ||
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() { | |
143 | @Override | |
144 | public void widgetDefaultSelected(SelectionEvent e) { | |
145 | } | |
146 | ||
147 | @Override | |
148 | public void widgetSelected(SelectionEvent e) { | |
149 | exportAnalysis(); | |
150 | } | |
151 | }); | |
152 | ||
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() { | |
158 | @Override | |
159 | public void widgetDefaultSelected(SelectionEvent e) { | |
160 | } | |
161 | ||
162 | @Override | |
163 | public void widgetSelected(SelectionEvent e) { | |
164 | deleteAnalysis(); | |
165 | } | |
166 | ||
167 | }); | |
168 | ||
169 | fillAnalysesList(); | |
170 | ||
171 | getShell().setMinimumSize(300, 275); | |
172 | return composite; | |
173 | } | |
174 | ||
175 | private void handleSelection(String[] selection) { | |
537572cd BH |
176 | Map<String, File> files = XmlUtils.listFiles(); |
177 | File file = files.get(createXmlFileString(selection[0])); | |
f98e9dbe JCK |
178 | if (file != null && XmlUtils.xmlValidate(file).isOK()) { |
179 | fInvalidFileLabel.setVisible(false); | |
180 | } else { | |
181 | fInvalidFileLabel.setVisible(true); | |
182 | } | |
183 | } | |
184 | ||
537572cd | 185 | private static void deleteSupplementaryFile(String xmlFile) { |
f98e9dbe JCK |
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<>(); | |
537572cd | 190 | java.util.List<String> ids = XmlUtils.getAnalysisIdsFromFile(xmlFile); |
f98e9dbe JCK |
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); | |
204 | closeEditor = true; | |
205 | } | |
206 | } | |
207 | } | |
208 | if (closeEditor) { | |
209 | tElement.closeEditors(); | |
210 | } | |
211 | } | |
212 | } | |
213 | } | |
214 | for (IResource resource : resourceToDelete) { | |
215 | try { | |
216 | resource.delete(false, null); | |
217 | } catch (CoreException e) { | |
218 | Activator.logError(NLS.bind(Messages.ManageXMLAnalysisDialog_DeleteFileError, resource.getName())); | |
219 | } | |
220 | } | |
221 | } | |
222 | ||
223 | @Override | |
224 | protected void createButtonsForButtonBar(Composite parent) { | |
225 | createButton(parent, IDialogConstants.OK_ID, IDialogConstants.CLOSE_LABEL, false); | |
226 | } | |
227 | ||
228 | private void fillAnalysesList() { | |
229 | fAnalysesList.removeAll(); | |
537572cd | 230 | Map<String, File> files = XmlUtils.listFiles(); |
f98e9dbe JCK |
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 | |
537572cd BH |
234 | IPath path = new Path(file); |
235 | fAnalysesList.add(path.removeFileExtension().toString()); | |
f98e9dbe JCK |
236 | } |
237 | fDeleteButton.setEnabled(false); | |
238 | fExportButton.setEnabled(false); | |
239 | } | |
240 | ||
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(); | |
247 | if (path != null) { | |
248 | File file = new File(path); | |
249 | IStatus status = XmlUtils.xmlValidate(file); | |
250 | if (status.isOK()) { | |
251 | status = XmlUtils.addXmlFile(file); | |
252 | if (status.isOK()) { | |
253 | fillAnalysesList(); | |
254 | XmlAnalysisModuleSource.notifyModuleChange(); | |
255 | /* | |
256 | * FIXME: It refreshes the list of analysis under a trace, | |
257 | * but since modules are instantiated when the trace opens, | |
258 | * the changes won't apply to an opened trace, it needs to | |
259 | * be closed then reopened | |
260 | */ | |
261 | refreshProject(); | |
262 | } else { | |
263 | Activator.logError(Messages.ManageXMLAnalysisDialog_ImportFileFailed); | |
264 | TraceUtils.displayErrorMsg(Messages.ManageXMLAnalysisDialog_ImportFileFailed, status.getMessage()); | |
265 | } | |
266 | } else { | |
267 | Activator.logError(Messages.ManageXMLAnalysisDialog_ImportFileFailed); | |
268 | TraceUtils.displayErrorMsg(Messages.ManageXMLAnalysisDialog_ImportFileFailed, status.getMessage()); | |
269 | } | |
270 | } | |
271 | } | |
272 | ||
273 | private void exportAnalysis() { | |
274 | FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE); | |
275 | dialog.setText(NLS.bind(Messages.ManageXMLAnalysisDialog_SelectFileExport, fAnalysesList.getSelection()[0])); | |
276 | dialog.setFilterExtensions(new String[] { XML_FILTER_EXTENSION, "*" }); //$NON-NLS-1$ | |
537572cd BH |
277 | String selection = createXmlFileString(fAnalysesList.getSelection()[0]); |
278 | dialog.setFileName(selection); | |
f98e9dbe JCK |
279 | String path = dialog.open(); |
280 | if (path != null) { | |
537572cd BH |
281 | if (!XmlUtils.exportXmlFile(selection, path).isOK()) { |
282 | Activator.logError(NLS.bind(Messages.ManageXMLAnalysisDialog_FailedToExport, selection)); | |
f98e9dbe JCK |
283 | } |
284 | } | |
285 | } | |
286 | ||
287 | private void deleteAnalysis() { | |
288 | boolean confirm = MessageDialog.openQuestion( | |
289 | getShell(), | |
290 | Messages.ManageXMLAnalysisDialog_DeleteFile, | |
291 | NLS.bind(Messages.ManageXMLAnalysisDialog_DeleteConfirmation, fAnalysesList.getSelection()[0])); | |
292 | if (confirm) { | |
537572cd | 293 | String selection = createXmlFileString(fAnalysesList.getSelection()[0]); |
f98e9dbe | 294 | deleteSupplementaryFile(selection); |
537572cd | 295 | XmlUtils.deleteFile(selection); |
f98e9dbe JCK |
296 | fillAnalysesList(); |
297 | fInvalidFileLabel.setVisible(false); | |
298 | XmlAnalysisModuleSource.notifyModuleChange(); | |
299 | /* | |
300 | * FIXME: It refreshes the list of analysis under a trace, but since | |
301 | * modules are instantiated when the trace opens, the changes won't | |
302 | * apply to an opened trace, it needs to be closed then reopened | |
303 | */ | |
304 | refreshProject(); | |
305 | } | |
306 | } | |
307 | ||
308 | /** | |
309 | * Refresh the selected project with the new XML file import | |
310 | */ | |
311 | private static void refreshProject() { | |
312 | // Check if we are closing down | |
313 | IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); | |
314 | if (window == null) { | |
315 | return; | |
316 | } | |
317 | ||
318 | // Get the selection | |
319 | IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); | |
320 | IWorkbenchPart part = page.getActivePart(); | |
321 | if (part == null) { | |
322 | return; | |
323 | } | |
324 | ISelectionProvider selectionProvider = part.getSite().getSelectionProvider(); | |
325 | if (selectionProvider == null) { | |
326 | return; | |
327 | } | |
328 | ISelection selection = selectionProvider.getSelection(); | |
329 | ||
330 | if (selection instanceof TreeSelection) { | |
331 | TreeSelection sel = (TreeSelection) selection; | |
332 | // There should be only one item selected as per the plugin.xml | |
333 | Object element = sel.getFirstElement(); | |
334 | if (element instanceof TmfProjectModelElement) { | |
335 | ((TmfProjectModelElement) element).getProject().refresh(); | |
336 | } | |
337 | } | |
338 | } | |
537572cd BH |
339 | |
340 | private static String createXmlFileString(String baseName) { | |
341 | IPath path = new Path(baseName).addFileExtension(XmlUtils.XML_EXTENSION); | |
342 | return path.toString(); | |
343 | } | |
f98e9dbe | 344 | } |