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