tmf: Fix duplicate trace check in TmfOpenTraceHelper
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / project / model / TmfOpenTraceHelper.java
CommitLineData
76fccfb0 1/**********************************************************************
9d2e08b9 2 * Copyright (c) 2013, 2014 Ericsson, École Polytechnique de Montréal
76fccfb0
MK
3 *
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 *
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
67c53011 11 * Patrick Tasse - Update open trace and add open experiment
9d2e08b9 12 * Geneviève Bastien - Merge methods to open trace and experiments
1aec2e92 13 * Bernd Hufmann - Updated handling of directory traces
76fccfb0
MK
14 **********************************************************************/
15
2bdf0193 16package org.eclipse.tracecompass.tmf.ui.project.model;
76fccfb0
MK
17
18import java.io.File;
b1f91ef7 19import java.io.IOException;
76fccfb0
MK
20import java.util.List;
21
22import org.eclipse.core.resources.IFile;
23import org.eclipse.core.resources.IFolder;
76fccfb0 24import org.eclipse.core.resources.IResource;
76fccfb0
MK
25import org.eclipse.core.runtime.CoreException;
26import org.eclipse.core.runtime.IPath;
27import org.eclipse.core.runtime.IStatus;
28import org.eclipse.core.runtime.Path;
29import org.eclipse.core.runtime.Status;
89730b51 30import org.eclipse.core.runtime.URIUtil;
09b9832c 31import org.eclipse.jface.util.OpenStrategy;
9d2e08b9 32import org.eclipse.osgi.util.NLS;
76fccfb0
MK
33import org.eclipse.swt.widgets.Display;
34import org.eclipse.swt.widgets.MessageBox;
35import org.eclipse.swt.widgets.Shell;
2bdf0193
AM
36import org.eclipse.tracecompass.internal.tmf.ui.Activator;
37import org.eclipse.tracecompass.internal.tmf.ui.project.model.TmfImportHelper;
38import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
39import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
40import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
41import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException;
42import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
43import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
44import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
5c5fa260 45import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
2bdf0193
AM
46import org.eclipse.tracecompass.tmf.ui.editors.TmfEditorInput;
47import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor;
76fccfb0
MK
48import org.eclipse.ui.IEditorInput;
49import org.eclipse.ui.IEditorPart;
371536f0 50import org.eclipse.ui.IEditorReference;
eb271b88 51import org.eclipse.ui.IReusableEditor;
76fccfb0
MK
52import org.eclipse.ui.IWorkbench;
53import org.eclipse.ui.IWorkbenchPage;
54import org.eclipse.ui.PartInitException;
55import org.eclipse.ui.PlatformUI;
56import org.eclipse.ui.ide.IDE;
57import org.eclipse.ui.part.FileEditorInput;
58
59/**
60 * Open trace helper
61 *
62 * Helper class for opening trace resources and loading them to a tracing
63 * project.
64 *
65 * @author Matthew Khouzam
76fccfb0
MK
66 */
67public class TmfOpenTraceHelper {
68
977ca87f
PT
69 private TmfOpenTraceHelper() {
70 }
71
76fccfb0
MK
72 private static final String ENDL = System.getProperty("line.separator"); //$NON-NLS-1$
73
74 /**
977ca87f
PT
75 * Opens a trace from a path while importing it to the destination folder.
76 * The trace is linked as a resource.
76fccfb0 77 *
977ca87f
PT
78 * @param destinationFolder
79 * The destination trace folder
76fccfb0
MK
80 * @param path
81 * the file to import
82 * @param shell
83 * the shell to use for dialogs
84 * @return IStatus OK if successful
85 * @throws CoreException
86 * core exceptions if something is not well set up in the back
87 * end
88 */
977ca87f
PT
89 public static IStatus openTraceFromPath(TmfTraceFolder destinationFolder, String path, Shell shell) throws CoreException {
90 return openTraceFromPath(destinationFolder, path, shell, null);
4958a213
MK
91 }
92
93 /**
977ca87f
PT
94 * Opens a trace from a path while importing it to the destination folder.
95 * The trace is linked as a resource.
4958a213 96 *
977ca87f
PT
97 * @param destinationFolder
98 * The destination trace folder
4958a213
MK
99 * @param path
100 * the file to import
101 * @param shell
102 * the shell to use for dialogs
103 * @param tracetypeHint
104 * The trace type id, can be null
105 * @return IStatus OK if successful
106 * @throws CoreException
107 * core exceptions if something is not well set up in the back
108 * end
4958a213 109 */
977ca87f 110 public static IStatus openTraceFromPath(TmfTraceFolder destinationFolder, String path, Shell shell, String tracetypeHint) throws CoreException {
1aec2e92 111 final String pathToUse = checkTracePath(path);
76fccfb0
MK
112 TraceTypeHelper traceTypeToSet = null;
113 try {
1aec2e92 114 traceTypeToSet = TmfTraceTypeUIUtils.selectTraceType(pathToUse, null, tracetypeHint);
76fccfb0
MK
115 } catch (TmfTraceImportException e) {
116 MessageBox mb = new MessageBox(shell);
117 mb.setMessage(e.getMessage());
118 mb.open();
119 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage());
120 }
1aec2e92 121
977ca87f 122 IFolder folder = destinationFolder.getResource();
1aec2e92
BH
123 String traceName = getTraceName(pathToUse, folder);
124 if (traceExists(pathToUse, folder)) {
977ca87f 125 return openTraceFromFolder(destinationFolder, traceName);
76fccfb0 126 }
1aec2e92 127 final IPath pathString = Path.fromOSString(pathToUse);
76fccfb0 128 IResource linkedTrace = TmfImportHelper.createLink(folder, pathString, traceName);
d3e89107
BH
129
130 if (linkedTrace == null || !linkedTrace.exists()) {
131 return new Status(IStatus.ERROR, Activator.PLUGIN_ID,
132 Messages.TmfOpenTraceHelper_LinkFailed);
133 }
134
1aec2e92 135 String sourceLocation = URIUtil.toUnencodedString(pathString.toFile().toURI());
89730b51
PT
136 linkedTrace.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation);
137
d3e89107
BH
138 // No trace type was determined.
139 if (traceTypeToSet == null) {
140 return Status.OK_STATUS;
141 }
142
a6e37e4c 143 IStatus ret = TmfTraceTypeUIUtils.setTraceType(linkedTrace, traceTypeToSet);
d3e89107 144 if (ret.isOK()) {
977ca87f 145 ret = openTraceFromFolder(destinationFolder, traceName);
76fccfb0 146 }
d3e89107 147 return ret;
76fccfb0
MK
148 }
149
1aec2e92
BH
150 /**
151 * Checks whether the parent or grandparent of given path to a file is a
152 * valid directory trace. If it is a directory trace then return the parent
153 * or grandparent path.
154 *
155 * @param path
156 * the path to check
157 * @return path to use for trace type validation.
158 */
159 private static String checkTracePath(String path) {
160 File file = new File(path);
161 if (file.exists() && !file.isDirectory()) {
162 // First check parent
163 File parent = file.getParentFile();
164 String pathToUse = parent.getAbsolutePath();
a4a116c3 165 if (TmfTraceType.isDirectoryTrace(pathToUse)) {
1aec2e92
BH
166 return pathToUse;
167 }
168 // Second check grandparent
169 File grandParent = parent.getParentFile();
170 if (grandParent != null) {
171 pathToUse = grandParent.getAbsolutePath();
a4a116c3 172 if (TmfTraceType.isDirectoryTrace(pathToUse)) {
1aec2e92
BH
173 return pathToUse;
174 }
175 }
176 }
177 return path;
178 }
179
977ca87f
PT
180 private static boolean traceExists(String path, IFolder folder) {
181 String val = getTraceName(path, folder);
76fccfb0
MK
182 return (folder.findMember(val) != null);
183 }
184
977ca87f
PT
185 private static boolean isWrongMember(IFolder folder, String name, final File traceFile) {
186 final IResource candidate = folder.findMember(name);
76fccfb0
MK
187 if (candidate != null) {
188 final IPath rawLocation = candidate.getRawLocation();
189 final File file = rawLocation.toFile();
190 return !file.equals(traceFile);
191 }
192 return false;
193 }
194
195 /**
196 * Gets the display name, either "filename" or "filename(n)" if there is
977ca87f 197 * already a filename existing where n is the next unused integer starting
76fccfb0
MK
198 * from 2
199 *
977ca87f
PT
200 * @param path
201 * the file path
76fccfb0
MK
202 * @param folder
203 * the folder to import to
204 * @return the filename
205 */
977ca87f
PT
206 private static String getTraceName(String path, IFolder folder) {
207 String name;
b1f91ef7
PT
208 File traceFile = new File(path);
209 try {
210 traceFile = traceFile.getCanonicalFile();
211 } catch (IOException e) {
212 /* just use original file path */
213 }
977ca87f
PT
214 name = traceFile.getName();
215 for (int i = 2; isWrongMember(folder, name, traceFile); i++) {
216 name = traceFile.getName() + '(' + i + ')';
76fccfb0 217 }
977ca87f 218 return name;
76fccfb0
MK
219 }
220
221 /**
977ca87f 222 * Open a trace from a trace folder
76fccfb0 223 *
977ca87f
PT
224 * @param destinationFolder
225 * The destination trace folder
76fccfb0
MK
226 * @param traceName
227 * the trace name
228 * @return success or error
229 */
977ca87f
PT
230 private static IStatus openTraceFromFolder(TmfTraceFolder destinationFolder, String traceName) {
231 final List<ITmfProjectModelElement> elements = destinationFolder.getChildren();
232 TmfTraceElement traceElement = null;
233 for (ITmfProjectModelElement element : elements) {
234 if (element instanceof TmfTraceElement && element.getName().equals(traceName)) {
235 traceElement = (TmfTraceElement) element;
76fccfb0
MK
236 }
237 }
977ca87f 238 if (traceElement == null) {
9d2e08b9 239 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, NLS.bind(Messages.TmfOpenTraceHelper_TraceNotFound, traceName));
76fccfb0 240 }
977ca87f 241 openTraceFromElement(traceElement);
67c53011 242 return Status.OK_STATUS;
76fccfb0
MK
243 }
244
9d2e08b9
GB
245 private static ITmfTrace openTraceElement(final TmfTraceElement traceElement) {
246 final ITmfTrace trace = traceElement.instantiateTrace();
247 final ITmfEvent traceEvent = traceElement.instantiateEvent();
248 if ((trace == null) || (traceEvent == null)) {
249 TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()),
2d2397a6 250 Messages.TmfOpenTraceHelper_NoTraceType);
9d2e08b9
GB
251 if (trace != null) {
252 trace.dispose();
253 }
254 return null;
255 }
67c53011 256
67c53011 257 try {
2b0005f0 258 trace.initTrace(traceElement.getResource(), traceElement.getResource().getLocation().toOSString(), traceEvent.getClass(), traceElement.getElementPath(), traceElement.getTraceType());
9d2e08b9
GB
259 } catch (final TmfTraceException e) {
260 TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()),
261 Messages.TmfOpenTraceHelper_InitError + ENDL + ENDL + e);
262 trace.dispose();
263 return null;
67c53011 264 }
9d2e08b9
GB
265 return trace;
266 }
67c53011 267
deaae6e1 268 private static ITmfTrace openExperimentElement(final TmfExperimentElement experimentElement) {
9d2e08b9
GB
269 /* Experiment element now has an experiment type associated with it */
270 final TmfExperiment experiment = experimentElement.instantiateTrace();
271 if (experiment == null) {
272 TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, experimentElement.getTypeName()),
273 NLS.bind(Messages.TmfOpenTraceHelper_NoTraceOrExperimentType, experimentElement.getTypeName()));
274 return null;
67c53011
PT
275 }
276
9d2e08b9
GB
277 // Instantiate the experiment's traces
278 final List<TmfTraceElement> traceEntries = experimentElement.getTraces();
279 int cacheSize = Integer.MAX_VALUE;
280 final ITmfTrace[] traces = new ITmfTrace[traceEntries.size()];
281 for (int i = 0; i < traceEntries.size(); i++) {
282 TmfTraceElement element = traceEntries.get(i);
76fccfb0 283
9d2e08b9
GB
284 // Since trace is under an experiment, use the original trace from
285 // the traces folder
286 element = element.getElementUnderTraceFolder();
76fccfb0 287
9d2e08b9
GB
288 ITmfTrace trace = openTraceElement(element);
289
290 if (trace == null) {
291 for (int j = 0; j < i; j++) {
292 traces[j].dispose();
76fccfb0 293 }
9d2e08b9
GB
294 return null;
295 }
296 cacheSize = Math.min(cacheSize, trace.getCacheSize());
76fccfb0 297
9d2e08b9
GB
298 traces[i] = trace;
299 }
76fccfb0 300
9d2e08b9
GB
301 // Create the experiment
302 experiment.initExperiment(ITmfEvent.class, experimentElement.getName(), traces, cacheSize, experimentElement.getResource());
9d2e08b9
GB
303
304 return experiment;
305 }
306
deaae6e1 307 private static ITmfTrace openProjectElement(final TmfCommonProjectElement element) {
9d2e08b9
GB
308 ITmfTrace trace = null;
309 if (element instanceof TmfTraceElement) {
310 trace = openTraceElement((TmfTraceElement) element);
311 } else if (element instanceof TmfExperimentElement) {
deaae6e1 312 trace = openExperimentElement((TmfExperimentElement) element);
9d2e08b9
GB
313 }
314 return trace;
67c53011
PT
315 }
316
317 /**
9d2e08b9
GB
318 * Open a trace (or experiment) from a project element. If the trace is already opened, its
319 * editor is activated and brought to top.
67c53011 320 *
9d2e08b9
GB
321 * @param traceElement
322 * the {@link TmfTraceElement} to open
67c53011 323 */
9d2e08b9 324 public static void openTraceFromElement(final TmfCommonProjectElement traceElement) {
67c53011
PT
325
326 final IFile file;
327 try {
9d2e08b9 328 file = traceElement.createBookmarksFile();
67c53011 329 } catch (final CoreException e) {
9d2e08b9
GB
330 Activator.getDefault().logError(NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ' ' + traceElement.getName());
331 TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()),
332 NLS.bind(Messages.TmfOpenTraceHelper_ErrorElement, traceElement.getTypeName()) + ENDL + ENDL + e.getMessage());
67c53011
PT
333 return;
334 }
335
336 final IWorkbench wb = PlatformUI.getWorkbench();
337 final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
371536f0 338 final IEditorPart editor = findEditor(new FileEditorInput(file), true);
67c53011
PT
339 if (editor != null) {
340 activePage.activate(editor);
341 return;
342 }
343
09b9832c
BH
344 // If a trace type is not set then delegate it to the eclipse platform
345 if ((traceElement instanceof TmfTraceElement) && (traceElement.getResource() instanceof IFile) && (traceElement.getTraceType() == null)) {
346 try {
347 boolean activate = OpenStrategy.activateOnOpen();
348 // only local open is supported
349 IDE.openEditor(activePage, file, activate);
350 } catch (PartInitException e) {
351 TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()),
352 NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getElementPath()) + ENDL + ENDL + e.getMessage());
353 }
354 return;
355 }
356
67c53011
PT
357 Thread thread = new Thread() {
358 @Override
359 public void run() {
deaae6e1 360 final ITmfTrace trace = openProjectElement(traceElement);
09b9832c 361
9d2e08b9
GB
362 if (trace == null) {
363 return;
67c53011
PT
364 }
365
9d2e08b9
GB
366 // Get the editor id from the extension point
367 String traceEditorId = traceElement.getEditorId();
368 final String editorId = (traceEditorId != null) ? traceEditorId : TmfEventsEditor.ID;
369 final IEditorInput editorInput = new TmfEditorInput(file, trace);
67c53011
PT
370
371 Display.getDefault().asyncExec(new Runnable() {
372 @Override
373 public void run() {
374 try {
375 activePage.openEditor(editorInput, editorId);
376 IDE.setDefaultEditor(file, editorId);
377 // editor should dispose the trace on close
378 } catch (final PartInitException e) {
9d2e08b9
GB
379 TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()),
380 NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ENDL + ENDL + e.getMessage());
381 Activator.getDefault().logError(NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ' ' + traceElement.getName());
382 trace.dispose();
67c53011
PT
383 }
384 }
385 });
386 }
387 };
388 thread.start();
76fccfb0
MK
389 }
390
371536f0 391 /**
4958a213
MK
392 * Returns the editor with the specified input. Returns null if there is no
393 * opened editor with that input. If restore is requested, the method finds
394 * and returns the editor even if it is not restored yet after a restart.
395 *
396 * @param input
397 * the editor input
398 * @param restore
399 * true if the editor should be restored
400 * @return an editor with input equals to <code>input</code>
401 */
371536f0
PT
402 private static IEditorPart findEditor(IEditorInput input, boolean restore) {
403 final IWorkbench wb = PlatformUI.getWorkbench();
404 final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
405 for (IEditorReference editorReference : activePage.getEditorReferences()) {
406 try {
407 IEditorInput editorInput = editorReference.getEditorInput();
408 if (editorInput.equals(input)) {
409 return editorReference.getEditor(restore);
410 }
411 } catch (PartInitException e) {
412 }
413 }
414 return null;
4958a213 415 }
371536f0 416
eb271b88 417 /**
9d2e08b9
GB
418 * Reopen a trace or experiment from a project element in the provided
419 * editor
eb271b88
PT
420 *
421 * @param traceElement
422 * the {@link TmfTraceElement} to open
423 * @param editor
424 * the reusable editor
425 */
9d2e08b9 426 public static void reopenTraceFromElement(final TmfCommonProjectElement traceElement, final IReusableEditor editor) {
eb271b88
PT
427
428 final IFile file;
429 try {
430 file = traceElement.createBookmarksFile();
431 } catch (final CoreException e) {
9d2e08b9
GB
432 Activator.getDefault().logError(NLS.bind(Messages.TmfOpenTraceHelper_ErrorOpeningElement, traceElement.getTypeName()) + ' ' + traceElement.getName());
433 TraceUtils.displayErrorMsg(NLS.bind(Messages.TmfOpenTraceHelper_OpenElement, traceElement.getTypeName()),
434 NLS.bind(Messages.TmfOpenTraceHelper_ErrorElement, traceElement.getTypeName()) + ENDL + ENDL + e.getMessage());
eb271b88
PT
435 return;
436 }
437
438 Thread thread = new Thread() {
439 @Override
440 public void run() {
441
deaae6e1 442 final ITmfTrace trace = openProjectElement(traceElement);
9d2e08b9 443 if (trace == null) {
eb271b88
PT
444 return;
445 }
446
447 final IEditorInput editorInput = new TmfEditorInput(file, trace);
448
449 Display.getDefault().asyncExec(new Runnable() {
450 @Override
451 public void run() {
452 final IWorkbench wb = PlatformUI.getWorkbench();
453 final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
454 activePage.reuseEditor(editor, editorInput);
455 activePage.activate(editor);
456 }
457 });
458 }
459 };
460 thread.start();
461 }
462
76fccfb0 463}
This page took 0.105052 seconds and 5 git commands to generate.