tmf: Move icon and label text into ITmfProjectModelElement
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / project / model / TmfExperimentElement.java
CommitLineData
12c155f5 1/*******************************************************************************
58ffe079 2 * Copyright (c) 2010, 2015 Ericsson, École Polytechnique de Montréal
c4c81d91 3 *
12c155f5
FC
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
c4c81d91 8 *
12c155f5
FC
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
beb19106 11 * Geneviève Bastien - Copied code to add/remove traces in this class
a72a6830 12 * Patrick Tasse - Close editors to release resources
8f5221c2 13 * Geneviève Bastien - Experiment instantiated with trace type
12c155f5
FC
14 *******************************************************************************/
15
2bdf0193 16package org.eclipse.tracecompass.tmf.ui.project.model;
12c155f5
FC
17
18import java.util.ArrayList;
5a5c2fc7 19import java.util.Arrays;
dca8b422
BH
20import java.util.Collections;
21import java.util.Comparator;
f537c959 22import java.util.HashMap;
12c155f5 23import java.util.List;
beb19106 24import java.util.Map;
12c155f5 25
339d539c 26import org.eclipse.core.resources.IContainer;
c4c81d91 27import org.eclipse.core.resources.IFile;
12c155f5 28import org.eclipse.core.resources.IFolder;
c4c81d91 29import org.eclipse.core.resources.IResource;
339d539c
PT
30import org.eclipse.core.resources.IResourceProxy;
31import org.eclipse.core.resources.IResourceProxyVisitor;
beb19106
GB
32import org.eclipse.core.resources.IWorkspace;
33import org.eclipse.core.resources.ResourcesPlugin;
c4c81d91 34import org.eclipse.core.runtime.CoreException;
8f5221c2 35import org.eclipse.core.runtime.IConfigurationElement;
beb19106 36import org.eclipse.core.runtime.IPath;
977ca87f 37import org.eclipse.core.runtime.IStatus;
8f5221c2 38import org.eclipse.core.runtime.InvalidRegistryObjectException;
339d539c 39import org.eclipse.core.runtime.NullProgressMonitor;
8f5221c2 40import org.eclipse.core.runtime.Platform;
dff70ccd 41import org.eclipse.jdt.annotation.NonNull;
8f5221c2 42import org.eclipse.osgi.util.NLS;
dff70ccd 43import org.eclipse.swt.graphics.Image;
ea01e5a2 44import org.eclipse.swt.widgets.Display;
2bdf0193 45import org.eclipse.tracecompass.internal.tmf.ui.Activator;
58ffe079 46import org.eclipse.tracecompass.internal.tmf.ui.editors.ITmfEventsEditorConstants;
2bdf0193 47import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
ff7b95a5
GB
48import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
49import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
2bdf0193
AM
50import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
51import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
ff7b95a5 52import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
5c5fa260 53import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
2bdf0193
AM
54import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor;
55import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor;
12c155f5
FC
56import org.eclipse.ui.views.properties.IPropertyDescriptor;
57import org.eclipse.ui.views.properties.IPropertySource2;
12c155f5
FC
58
59/**
b544077e 60 * Implementation of TMF Experiment Model Element.
12c155f5 61 * <p>
dc62dbee 62 *
b544077e
BH
63 * @version 1.0
64 * @author Francois Chouinard
c4c81d91 65 *
12c155f5 66 */
16036bc2 67public class TmfExperimentElement extends TmfCommonProjectElement implements IPropertySource2 {
12c155f5
FC
68
69 // ------------------------------------------------------------------------
70 // Constants
71 // ------------------------------------------------------------------------
72
73 // Property View stuff
067cd9de
BH
74 private static final String INFO_CATEGORY = "Info"; //$NON-NLS-1$
75 private static final String NAME = "name"; //$NON-NLS-1$
76 private static final String PATH = "path"; //$NON-NLS-1$
77 private static final String LOCATION = "location"; //$NON-NLS-1$
78 private static final String FOLDER_SUFFIX = "_exp"; //$NON-NLS-1$
79 private static final String EXPERIMENT_TYPE = "type"; //$NON-NLS-1$
80
81 private static final ReadOnlyTextPropertyDescriptor NAME_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(NAME, NAME);
82 private static final ReadOnlyTextPropertyDescriptor PATH_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(PATH, PATH);
83 private static final ReadOnlyTextPropertyDescriptor LOCATION_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(LOCATION,
84 LOCATION);
85 private static final ReadOnlyTextPropertyDescriptor TYPE_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(EXPERIMENT_TYPE, EXPERIMENT_TYPE);
86
87 private static final IPropertyDescriptor[] DESCRIPTORS = { NAME_DESCRIPTOR, PATH_DESCRIPTOR,
88 LOCATION_DESCRIPTOR, TYPE_DESCRIPTOR };
12c155f5
FC
89
90 static {
067cd9de
BH
91 NAME_DESCRIPTOR.setCategory(INFO_CATEGORY);
92 PATH_DESCRIPTOR.setCategory(INFO_CATEGORY);
93 LOCATION_DESCRIPTOR.setCategory(INFO_CATEGORY);
94 TYPE_DESCRIPTOR.setCategory(INFO_CATEGORY);
12c155f5
FC
95 }
96
8f5221c2
GB
97 // The mapping of available trace type IDs to their corresponding
98 // configuration element
067cd9de
BH
99 private static final Map<String, IConfigurationElement> TRACE_TYPE_ATTRIBUTES = new HashMap<>();
100 private static final Map<String, IConfigurationElement> TRACE_TYPE_UI_ATTRIBUTES = new HashMap<>();
101 private static final Map<String, IConfigurationElement> TRACE_CATEGORIES = new HashMap<>();
8f5221c2
GB
102
103 // ------------------------------------------------------------------------
104 // Static initialization
105 // ------------------------------------------------------------------------
106
107 /**
108 * Initialize statically at startup by getting extensions from the platform
109 * extension registry.
8f5221c2
GB
110 */
111 public static void init() {
112 IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID);
113 for (IConfigurationElement ce : config) {
114 String elementName = ce.getName();
115 if (elementName.equals(TmfTraceType.EXPERIMENT_ELEM)) {
116 String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
067cd9de 117 TRACE_TYPE_ATTRIBUTES.put(traceTypeId, ce);
8f5221c2
GB
118 } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) {
119 String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR);
067cd9de 120 TRACE_CATEGORIES.put(categoryId, ce);
8f5221c2
GB
121 }
122 }
123
124 /*
125 * Read the corresponding tmf.ui "tracetypeui" extension point for this
126 * trace type, if it exists.
127 */
128 config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceTypeUIUtils.TMF_TRACE_TYPE_UI_ID);
129 for (IConfigurationElement ce : config) {
130 String elemName = ce.getName();
131 if (TmfTraceTypeUIUtils.EXPERIMENT_ELEM.equals(elemName)) {
132 String traceType = ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR);
067cd9de 133 TRACE_TYPE_UI_ATTRIBUTES.put(traceType, ce);
8f5221c2
GB
134 }
135 }
136 }
c4c81d91 137
12c155f5
FC
138 // ------------------------------------------------------------------------
139 // Constructors
140 // ------------------------------------------------------------------------
b544077e 141 /**
c4c81d91 142 * Constructor
dc62dbee
CB
143 *
144 * @param name
145 * The name of the experiment
146 * @param folder
147 * The folder reference
148 * @param parent
149 * The experiment folder reference.
b544077e 150 */
12c155f5
FC
151 public TmfExperimentElement(String name, IFolder folder, TmfExperimentFolder parent) {
152 super(name, folder, parent);
12c155f5
FC
153 }
154
155 // ------------------------------------------------------------------------
156 // TmfProjectModelElement
157 // ------------------------------------------------------------------------
158
159 @Override
160 public IFolder getResource() {
b3e4798c 161 return (IFolder) super.getResource();
12c155f5
FC
162 }
163
b3e4798c
AM
164 /**
165 * @since 2.0
166 */
f537c959 167 @Override
b3e4798c 168 protected void refreshChildren() {
f537c959
PT
169 IFolder folder = getResource();
170
8f5221c2 171 /* Update the trace children of this experiment */
f537c959
PT
172 // Get the children from the model
173 Map<String, ITmfProjectModelElement> childrenMap = new HashMap<>();
339d539c
PT
174 for (TmfTraceElement trace : getTraces()) {
175 childrenMap.put(trace.getElementPath(), trace);
f537c959
PT
176 }
177
339d539c
PT
178 List<IResource> members = getTraceResources();
179 for (IResource resource : members) {
180 String name = resource.getName();
181 String elementPath = resource.getFullPath().makeRelativeTo(folder.getFullPath()).toString();
182 ITmfProjectModelElement element = childrenMap.get(elementPath);
183 if (element instanceof TmfTraceElement) {
184 childrenMap.remove(elementPath);
185 } else {
186 element = new TmfTraceElement(name, resource, this);
b3e4798c 187 addChild(element);
f537c959 188 }
f537c959
PT
189 }
190
191 // Cleanup dangling children from the model
192 for (ITmfProjectModelElement danglingChild : childrenMap.values()) {
193 removeChild(danglingChild);
194 }
8f5221c2 195
8f5221c2 196 /* Update the analysis under this experiment */
9928ddeb 197 super.refreshChildren();
ff7b95a5
GB
198
199 /*
200 * If the experiment is opened, add any analysis that was not added by
201 * the parent if it is available with the experiment
202 */
203 ITmfTrace experiment = getTrace();
204 if (experiment == null) {
205 return;
206 }
207 Map<String, TmfAnalysisElement> analysisMap = new HashMap<>();
208 for (TmfAnalysisElement analysis : getAvailableAnalysis()) {
209 analysisMap.put(analysis.getAnalysisId(), analysis);
210 }
211 for (IAnalysisModuleHelper module : TmfAnalysisManager.getAnalysisModules().values()) {
212 if (!analysisMap.containsKey(module.getId()) && module.appliesToExperiment() && (experiment.getAnalysisModule(module.getId()) != null)) {
b3e4798c 213 IFolder newresource = ResourcesPlugin.getWorkspace().getRoot().getFolder(getResource().getFullPath().append(module.getId()));
ff7b95a5 214 TmfAnalysisElement analysis = new TmfAnalysisElement(module.getName(), newresource, this, module);
b3e4798c 215 addChild(analysis);
ff7b95a5
GB
216 analysis.refreshChildren();
217 analysisMap.put(module.getId(), analysis);
218 }
219 }
f537c959
PT
220 }
221
339d539c
PT
222 private List<IResource> getTraceResources() {
223 IFolder folder = getResource();
224 final List<IResource> list = new ArrayList<>();
225 try {
226 folder.accept(new IResourceProxyVisitor() {
227 @Override
228 public boolean visit(IResourceProxy resource) throws CoreException {
229 if (resource.isLinked()) {
230 list.add(resource.requestResource());
231 }
232 return true;
233 }
234 }, IResource.NONE);
235 } catch (CoreException e) {
236 }
dca8b422
BH
237 Comparator<IResource> comparator = new Comparator<IResource>() {
238 @Override
239 public int compare(IResource o1, IResource o2) {
240 return o1.getFullPath().toString().compareTo(o2.getFullPath().toString());
241 }
242 };
243 Collections.sort(list, comparator);
339d539c
PT
244 return list;
245 }
246
dff70ccd
AM
247 /**
248 * @since 2.0
249 */
250 @Override
251 public @NonNull Image getIcon() {
252 Image icon = super.getIcon();
253 return (icon == null ? TmfProjectModelIcons.DEFAULT_EXPERIMENT_ICON : icon);
254 }
255
256 /**
257 * @since 2.0
258 */
259 @Override
260 public String getLabelText() {
261 return getName() + " [" + getTraces().size() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
262 }
263
12c155f5
FC
264 // ------------------------------------------------------------------------
265 // Operations
266 // ------------------------------------------------------------------------
11252342 267
8f5221c2
GB
268 /**
269 * Refreshes the trace type filed by reading the trace type persistent
270 * property of the resource reference.
271 *
272 * If trace type is null after refresh, set it to the generic trace type
273 * (for seamless upgrade)
274 */
275 @Override
276 public void refreshTraceType() {
277 super.refreshTraceType();
278 if (getTraceType() == null) {
a4a116c3 279 IConfigurationElement ce = TmfTraceType.getTraceAttributes(TmfTraceType.DEFAULT_EXPERIMENT_TYPE);
8f5221c2
GB
280 if (ce != null) {
281 try {
282 IFolder experimentFolder = getResource();
283 experimentFolder.setPersistentProperty(TmfCommonConstants.TRACETYPE, ce.getAttribute(TmfTraceType.ID_ATTR));
284 super.refreshTraceType();
285 } catch (InvalidRegistryObjectException | CoreException e) {
286 }
287 }
288 }
289 }
290
b544077e
BH
291 /**
292 * Returns a list of TmfTraceElements contained in this experiment.
dc62dbee 293 *
b544077e
BH
294 * @return a list of TmfTraceElements
295 */
8f5221c2 296 @Override
12c155f5
FC
297 public List<TmfTraceElement> getTraces() {
298 List<ITmfProjectModelElement> children = getChildren();
507b1336 299 List<TmfTraceElement> traces = new ArrayList<>();
12c155f5
FC
300 for (ITmfProjectModelElement child : children) {
301 if (child instanceof TmfTraceElement) {
302 traces.add((TmfTraceElement) child);
303 }
304 }
305 return traces;
306 }
307
beb19106
GB
308 /**
309 * Adds a trace to the experiment
310 *
dc62dbee
CB
311 * @param trace
312 * The trace element to add
beb19106
GB
313 */
314 public void addTrace(TmfTraceElement trace) {
38dfaec4
BH
315 addTrace(trace, true);
316 }
317
318 /**
319 * Adds a trace to the experiment
320 *
dc62dbee
CB
321 * @param trace
322 * The trace element to add
323 * @param refresh
324 * Flag for refreshing the project
38dfaec4
BH
325 */
326 public void addTrace(TmfTraceElement trace, boolean refresh) {
beb19106
GB
327 /**
328 * Create a link to the actual trace and set the trace type
329 */
330 IFolder experiment = getResource();
331 IResource resource = trace.getResource();
332 IPath location = resource.getLocation();
333 IWorkspace workspace = ResourcesPlugin.getWorkspace();
334 try {
4b3b667b 335 String traceTypeId = TmfTraceType.getTraceTypeId(trace.getResource());
a4a116c3 336 TraceTypeHelper traceType = TmfTraceType.getTraceType(traceTypeId);
beb19106
GB
337
338 if (resource instanceof IFolder) {
339d539c
PT
339 IFolder folder = experiment.getFolder(trace.getElementPath());
340 TraceUtils.createFolder((IFolder) folder.getParent(), new NullProgressMonitor());
977ca87f
PT
341 IStatus result = workspace.validateLinkLocation(folder, location);
342 if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) {
beb19106 343 folder.createLink(location, IResource.REPLACE, null);
5f398902 344 if (traceType != null) {
38dfaec4 345 TmfTraceTypeUIUtils.setTraceType(folder, traceType, refresh);
5f398902 346 }
beb19106
GB
347
348 } else {
349 Activator.getDefault().logError("Error creating link. Invalid trace location " + location); //$NON-NLS-1$
350 }
351 } else {
339d539c
PT
352 IFile file = experiment.getFile(trace.getElementPath());
353 TraceUtils.createFolder((IFolder) file.getParent(), new NullProgressMonitor());
977ca87f
PT
354 IStatus result = workspace.validateLinkLocation(file, location);
355 if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) {
beb19106 356 file.createLink(location, IResource.REPLACE, null);
5f398902 357 if (traceType != null) {
38dfaec4 358 TmfTraceTypeUIUtils.setTraceType(file, traceType, refresh);
5f398902 359 }
beb19106
GB
360 } else {
361 Activator.getDefault().logError("Error creating link. Invalid trace location " + location); //$NON-NLS-1$
362 }
363 }
364 } catch (CoreException e) {
365 Activator.getDefault().logError("Error creating link to location " + location, e); //$NON-NLS-1$
366 }
367
368 }
369
370 /**
371 * Removes a trace from an experiment
372 *
dc62dbee
CB
373 * @param trace
374 * The trace to remove
375 * @throws CoreException
376 * exception
beb19106
GB
377 */
378 public void removeTrace(TmfTraceElement trace) throws CoreException {
379
ea01e5a2
PT
380 // Close editors in UI Thread
381 Display.getDefault().syncExec(new Runnable() {
382 @Override
383 public void run() {
384 closeEditors();
385 }
386 });
beb19106 387
dc62dbee 388 /* Finally, remove the trace from experiment */
beb19106 389 removeChild(trace);
339d539c 390 deleteTraceResource(trace.getResource());
d9030b38 391 deleteSupplementaryResources();
beb19106
GB
392 }
393
339d539c
PT
394 private void deleteTraceResource(IResource resource) throws CoreException {
395 resource.delete(true, null);
396 IContainer parent = resource.getParent();
397 // delete empty folders up to the parent experiment folder
398 if (!parent.equals(getResource()) && parent.members().length == 0) {
399 deleteTraceResource(parent);
400 }
401 }
402
8f5221c2 403 @Override
81fe3479 404 public IFile createBookmarksFile() throws CoreException {
58ffe079 405 return createBookmarksFile(getProject().getExperimentsFolder().getResource(), ITmfEventsEditorConstants.EXPERIMENT_EDITOR_INPUT_TYPE);
8f5221c2
GB
406 }
407
408 @Override
409 public String getEditorId() {
410 /* See if a default editor was set for this experiment type */
411 if (getTraceType() != null) {
067cd9de 412 IConfigurationElement ce = TRACE_TYPE_UI_ATTRIBUTES.get(getTraceType());
c1c0dfd0
GB
413 if (ce != null) {
414 IConfigurationElement[] defaultEditorCE = ce.getChildren(TmfTraceTypeUIUtils.DEFAULT_EDITOR_ELEM);
415 if (defaultEditorCE.length == 1) {
416 return defaultEditorCE[0].getAttribute(TmfTraceType.ID_ATTR);
417 }
81fe3479 418 }
c4c81d91 419 }
8f5221c2
GB
420
421 /* No default editor, try to find a common editor for all traces */
422 final List<TmfTraceElement> traceEntries = getTraces();
423 String commonEditorId = null;
424
425 for (TmfTraceElement element : traceEntries) {
426 // If all traces use the same editorId, use it, otherwise use the
427 // default
428 final String editorId = element.getEditorId();
429 if (commonEditorId == null) {
430 commonEditorId = (editorId != null) ? editorId : TmfEventsEditor.ID;
431 } else if (!commonEditorId.equals(editorId)) {
432 commonEditorId = TmfEventsEditor.ID;
433 }
434 }
435 return null;
81fe3479
PT
436 }
437
438 /**
8f5221c2
GB
439 * Instantiate a {@link TmfExperiment} object based on the experiment type
440 * and the corresponding extension.
441 *
442 * @return the {@link TmfExperiment} or <code>null</code> for an error
81fe3479 443 */
8f5221c2
GB
444 @Override
445 public TmfExperiment instantiateTrace() {
446 try {
447
448 // make sure that supplementary folder exists
449 refreshSupplementaryFolder();
450
451 if (getTraceType() != null) {
452
067cd9de 453 IConfigurationElement ce = TRACE_TYPE_ATTRIBUTES.get(getTraceType());
8f5221c2
GB
454 if (ce == null) {
455 return null;
456 }
457 TmfExperiment experiment = (TmfExperiment) ce.createExecutableExtension(TmfTraceType.EXPERIMENT_TYPE_ATTR);
458 return experiment;
459 }
460 } catch (CoreException e) {
461 Activator.getDefault().logError(NLS.bind(Messages.TmfExperimentElement_ErrorInstantiatingTrace, getName()), e);
462 }
463 return null;
464 }
465
466 @Override
467 public String getTypeName() {
468 return Messages.TmfExperimentElement_TypeName;
c4c81d91
PT
469 }
470
12c155f5
FC
471 // ------------------------------------------------------------------------
472 // IPropertySource2
473 // ------------------------------------------------------------------------
474
475 @Override
476 public Object getEditableValue() {
477 return null;
478 }
479
480 @Override
481 public IPropertyDescriptor[] getPropertyDescriptors() {
067cd9de 482 return Arrays.copyOf(DESCRIPTORS, DESCRIPTORS.length);
12c155f5
FC
483 }
484
485 @Override
486 public Object getPropertyValue(Object id) {
487
067cd9de 488 if (NAME.equals(id)) {
12c155f5 489 return getName();
c4c81d91 490 }
12c155f5 491
067cd9de 492 if (PATH.equals(id)) {
12c155f5 493 return getPath().toString();
c4c81d91 494 }
12c155f5 495
067cd9de 496 if (LOCATION.equals(id)) {
12c155f5 497 return getLocation().toString();
c4c81d91 498 }
12c155f5 499
067cd9de 500 if (EXPERIMENT_TYPE.equals(id)) {
8f5221c2 501 if (getTraceType() != null) {
067cd9de 502 IConfigurationElement ce = TRACE_TYPE_ATTRIBUTES.get(getTraceType());
8f5221c2
GB
503 if (ce == null) {
504 return ""; //$NON-NLS-1$
505 }
506 String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR);
507 if (categoryId != null) {
067cd9de 508 IConfigurationElement category = TRACE_CATEGORIES.get(categoryId);
8f5221c2
GB
509 if (category != null) {
510 return category.getAttribute(TmfTraceType.NAME_ATTR) + ':' + ce.getAttribute(TmfTraceType.NAME_ATTR);
511 }
512 }
513 return ce.getAttribute(TmfTraceType.NAME_ATTR);
514 }
515 }
516
12c155f5
FC
517 return null;
518 }
c4c81d91 519
12c155f5
FC
520 @Override
521 public void resetPropertyValue(Object id) {
522 }
523
524 @Override
525 public void setPropertyValue(Object id, Object value) {
526 }
527
528 @Override
529 public boolean isPropertyResettable(Object id) {
530 return false;
531 }
532
533 @Override
534 public boolean isPropertySet(Object id) {
535 return false;
536 }
537
99504bb8
GB
538 /**
539 * Return the suffix for resource names
dc62dbee 540 *
99504bb8
GB
541 * @return The folder suffix
542 */
543 @Override
544 public String getSuffix() {
067cd9de 545 return FOLDER_SUFFIX;
99504bb8
GB
546 }
547
12c155f5 548}
This page took 0.131737 seconds and 5 git commands to generate.