Remove all existing @since annotations
[deliverable/tracecompass.git] / 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;
8f5221c2 41import org.eclipse.osgi.util.NLS;
2bdf0193 42import org.eclipse.tracecompass.internal.tmf.ui.Activator;
58ffe079 43import org.eclipse.tracecompass.internal.tmf.ui.editors.ITmfEventsEditorConstants;
2bdf0193
AM
44import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
45import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
46import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
5c5fa260 47import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
2bdf0193
AM
48import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor;
49import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor;
12c155f5
FC
50import org.eclipse.ui.views.properties.IPropertyDescriptor;
51import org.eclipse.ui.views.properties.IPropertySource2;
12c155f5
FC
52
53/**
b544077e 54 * Implementation of TMF Experiment Model Element.
12c155f5 55 * <p>
b544077e
BH
56 * @version 1.0
57 * @author Francois Chouinard
c4c81d91 58 *
12c155f5 59 */
16036bc2 60public class TmfExperimentElement extends TmfCommonProjectElement implements IPropertySource2 {
12c155f5
FC
61
62 // ------------------------------------------------------------------------
63 // Constants
64 // ------------------------------------------------------------------------
65
66 // Property View stuff
67 private static final String sfInfoCategory = "Info"; //$NON-NLS-1$
68 private static final String sfName = "name"; //$NON-NLS-1$
69 private static final String sfPath = "path"; //$NON-NLS-1$
70 private static final String sfLocation = "location"; //$NON-NLS-1$
99504bb8 71 private static final String sfFolderSuffix = "_exp"; //$NON-NLS-1$
8f5221c2 72 private static final String sfExperimentType = "type"; //$NON-NLS-1$
12c155f5 73
253d5be1
BH
74 private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName);
75 private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath);
76 private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation,
12c155f5 77 sfLocation);
8f5221c2 78 private static final ReadOnlyTextPropertyDescriptor sfTypeDescriptor = new ReadOnlyTextPropertyDescriptor(sfExperimentType, sfExperimentType);
12c155f5
FC
79
80 private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor,
8f5221c2 81 sfLocationDescriptor, sfTypeDescriptor };
12c155f5
FC
82
83 static {
84 sfNameDescriptor.setCategory(sfInfoCategory);
85 sfPathDescriptor.setCategory(sfInfoCategory);
86 sfLocationDescriptor.setCategory(sfInfoCategory);
8f5221c2 87 sfTypeDescriptor.setCategory(sfInfoCategory);
12c155f5
FC
88 }
89
8f5221c2
GB
90 // The mapping of available trace type IDs to their corresponding
91 // configuration element
92 private static final Map<String, IConfigurationElement> sfTraceTypeAttributes = new HashMap<>();
93 private static final Map<String, IConfigurationElement> sfTraceTypeUIAttributes = new HashMap<>();
94 private static final Map<String, IConfigurationElement> sfTraceCategories = new HashMap<>();
95
96 // ------------------------------------------------------------------------
97 // Static initialization
98 // ------------------------------------------------------------------------
99
100 /**
101 * Initialize statically at startup by getting extensions from the platform
102 * extension registry.
8f5221c2
GB
103 */
104 public static void init() {
105 IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID);
106 for (IConfigurationElement ce : config) {
107 String elementName = ce.getName();
108 if (elementName.equals(TmfTraceType.EXPERIMENT_ELEM)) {
109 String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
110 sfTraceTypeAttributes.put(traceTypeId, ce);
111 } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) {
112 String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR);
113 sfTraceCategories.put(categoryId, ce);
114 }
115 }
116
117 /*
118 * Read the corresponding tmf.ui "tracetypeui" extension point for this
119 * trace type, if it exists.
120 */
121 config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceTypeUIUtils.TMF_TRACE_TYPE_UI_ID);
122 for (IConfigurationElement ce : config) {
123 String elemName = ce.getName();
124 if (TmfTraceTypeUIUtils.EXPERIMENT_ELEM.equals(elemName)) {
125 String traceType = ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR);
126 sfTraceTypeUIAttributes.put(traceType, ce);
127 }
128 }
129 }
c4c81d91 130
12c155f5
FC
131 // ------------------------------------------------------------------------
132 // Constructors
133 // ------------------------------------------------------------------------
b544077e 134 /**
c4c81d91 135 * Constructor
b544077e
BH
136 * @param name The name of the experiment
137 * @param folder The folder reference
138 * @param parent The experiment folder reference.
139 */
12c155f5
FC
140 public TmfExperimentElement(String name, IFolder folder, TmfExperimentFolder parent) {
141 super(name, folder, parent);
12c155f5
FC
142 }
143
144 // ------------------------------------------------------------------------
145 // TmfProjectModelElement
146 // ------------------------------------------------------------------------
147
148 @Override
149 public IFolder getResource() {
150 return (IFolder) fResource;
151 }
152
f537c959
PT
153 @Override
154 void refreshChildren() {
155 IFolder folder = getResource();
156
8f5221c2 157 /* Update the trace children of this experiment */
f537c959
PT
158 // Get the children from the model
159 Map<String, ITmfProjectModelElement> childrenMap = new HashMap<>();
339d539c
PT
160 for (TmfTraceElement trace : getTraces()) {
161 childrenMap.put(trace.getElementPath(), trace);
f537c959
PT
162 }
163
339d539c
PT
164 List<IResource> members = getTraceResources();
165 for (IResource resource : members) {
166 String name = resource.getName();
167 String elementPath = resource.getFullPath().makeRelativeTo(folder.getFullPath()).toString();
168 ITmfProjectModelElement element = childrenMap.get(elementPath);
169 if (element instanceof TmfTraceElement) {
170 childrenMap.remove(elementPath);
171 } else {
172 element = new TmfTraceElement(name, resource, this);
f537c959 173 }
f537c959
PT
174 }
175
176 // Cleanup dangling children from the model
177 for (ITmfProjectModelElement danglingChild : childrenMap.values()) {
178 removeChild(danglingChild);
179 }
8f5221c2 180
8f5221c2 181 /* Update the analysis under this experiment */
9928ddeb 182 super.refreshChildren();
f537c959
PT
183 }
184
339d539c
PT
185 private List<IResource> getTraceResources() {
186 IFolder folder = getResource();
187 final List<IResource> list = new ArrayList<>();
188 try {
189 folder.accept(new IResourceProxyVisitor() {
190 @Override
191 public boolean visit(IResourceProxy resource) throws CoreException {
192 if (resource.isLinked()) {
193 list.add(resource.requestResource());
194 }
195 return true;
196 }
197 }, IResource.NONE);
198 } catch (CoreException e) {
199 }
dca8b422
BH
200 Comparator<IResource> comparator = new Comparator<IResource>() {
201 @Override
202 public int compare(IResource o1, IResource o2) {
203 return o1.getFullPath().toString().compareTo(o2.getFullPath().toString());
204 }
205 };
206 Collections.sort(list, comparator);
339d539c
PT
207 return list;
208 }
209
12c155f5
FC
210 // ------------------------------------------------------------------------
211 // Operations
212 // ------------------------------------------------------------------------
11252342 213
8f5221c2
GB
214 /**
215 * Refreshes the trace type filed by reading the trace type persistent
216 * property of the resource reference.
217 *
218 * If trace type is null after refresh, set it to the generic trace type
219 * (for seamless upgrade)
220 */
221 @Override
222 public void refreshTraceType() {
223 super.refreshTraceType();
224 if (getTraceType() == null) {
a4a116c3 225 IConfigurationElement ce = TmfTraceType.getTraceAttributes(TmfTraceType.DEFAULT_EXPERIMENT_TYPE);
8f5221c2
GB
226 if (ce != null) {
227 try {
228 IFolder experimentFolder = getResource();
229 experimentFolder.setPersistentProperty(TmfCommonConstants.TRACETYPE, ce.getAttribute(TmfTraceType.ID_ATTR));
230 super.refreshTraceType();
231 } catch (InvalidRegistryObjectException | CoreException e) {
232 }
233 }
234 }
235 }
236
b544077e
BH
237 /**
238 * Returns a list of TmfTraceElements contained in this experiment.
239 * @return a list of TmfTraceElements
240 */
8f5221c2 241 @Override
12c155f5
FC
242 public List<TmfTraceElement> getTraces() {
243 List<ITmfProjectModelElement> children = getChildren();
507b1336 244 List<TmfTraceElement> traces = new ArrayList<>();
12c155f5
FC
245 for (ITmfProjectModelElement child : children) {
246 if (child instanceof TmfTraceElement) {
247 traces.add((TmfTraceElement) child);
248 }
249 }
250 return traces;
251 }
252
beb19106
GB
253 /**
254 * Adds a trace to the experiment
255 *
256 * @param trace The trace element to add
beb19106
GB
257 */
258 public void addTrace(TmfTraceElement trace) {
38dfaec4
BH
259 addTrace(trace, true);
260 }
261
262 /**
263 * Adds a trace to the experiment
264 *
265 * @param trace The trace element to add
266 * @param refresh Flag for refreshing the project
38dfaec4
BH
267 */
268 public void addTrace(TmfTraceElement trace, boolean refresh) {
beb19106
GB
269 /**
270 * Create a link to the actual trace and set the trace type
271 */
272 IFolder experiment = getResource();
273 IResource resource = trace.getResource();
274 IPath location = resource.getLocation();
275 IWorkspace workspace = ResourcesPlugin.getWorkspace();
276 try {
4b3b667b 277 String traceTypeId = TmfTraceType.getTraceTypeId(trace.getResource());
a4a116c3 278 TraceTypeHelper traceType = TmfTraceType.getTraceType(traceTypeId);
beb19106
GB
279
280 if (resource instanceof IFolder) {
339d539c
PT
281 IFolder folder = experiment.getFolder(trace.getElementPath());
282 TraceUtils.createFolder((IFolder) folder.getParent(), new NullProgressMonitor());
977ca87f
PT
283 IStatus result = workspace.validateLinkLocation(folder, location);
284 if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) {
beb19106 285 folder.createLink(location, IResource.REPLACE, null);
5f398902 286 if (traceType != null) {
38dfaec4 287 TmfTraceTypeUIUtils.setTraceType(folder, traceType, refresh);
5f398902 288 }
beb19106
GB
289
290 } else {
291 Activator.getDefault().logError("Error creating link. Invalid trace location " + location); //$NON-NLS-1$
292 }
293 } else {
339d539c
PT
294 IFile file = experiment.getFile(trace.getElementPath());
295 TraceUtils.createFolder((IFolder) file.getParent(), new NullProgressMonitor());
977ca87f
PT
296 IStatus result = workspace.validateLinkLocation(file, location);
297 if (result.isOK() || result.matches(IStatus.INFO | IStatus.WARNING)) {
beb19106 298 file.createLink(location, IResource.REPLACE, null);
5f398902 299 if (traceType != null) {
38dfaec4 300 TmfTraceTypeUIUtils.setTraceType(file, traceType, refresh);
5f398902 301 }
beb19106
GB
302 } else {
303 Activator.getDefault().logError("Error creating link. Invalid trace location " + location); //$NON-NLS-1$
304 }
305 }
306 } catch (CoreException e) {
307 Activator.getDefault().logError("Error creating link to location " + location, e); //$NON-NLS-1$
308 }
309
310 }
311
312 /**
313 * Removes a trace from an experiment
314 *
315 * @param trace The trace to remove
316 * @throws CoreException exception
beb19106
GB
317 */
318 public void removeTrace(TmfTraceElement trace) throws CoreException {
319
320 // Close the experiment if open
a72a6830 321 closeEditors();
beb19106
GB
322
323 /* Finally, remove the trace from experiment*/
324 removeChild(trace);
339d539c 325 deleteTraceResource(trace.getResource());
d9030b38 326 deleteSupplementaryResources();
beb19106
GB
327 }
328
339d539c
PT
329 private void deleteTraceResource(IResource resource) throws CoreException {
330 resource.delete(true, null);
331 IContainer parent = resource.getParent();
332 // delete empty folders up to the parent experiment folder
333 if (!parent.equals(getResource()) && parent.members().length == 0) {
334 deleteTraceResource(parent);
335 }
336 }
337
8f5221c2 338 @Override
81fe3479 339 public IFile createBookmarksFile() throws CoreException {
58ffe079 340 return createBookmarksFile(getProject().getExperimentsFolder().getResource(), ITmfEventsEditorConstants.EXPERIMENT_EDITOR_INPUT_TYPE);
8f5221c2
GB
341 }
342
343 @Override
344 public String getEditorId() {
345 /* See if a default editor was set for this experiment type */
346 if (getTraceType() != null) {
347 IConfigurationElement ce = sfTraceTypeUIAttributes.get(getTraceType());
c1c0dfd0
GB
348 if (ce != null) {
349 IConfigurationElement[] defaultEditorCE = ce.getChildren(TmfTraceTypeUIUtils.DEFAULT_EDITOR_ELEM);
350 if (defaultEditorCE.length == 1) {
351 return defaultEditorCE[0].getAttribute(TmfTraceType.ID_ATTR);
352 }
81fe3479 353 }
c4c81d91 354 }
8f5221c2
GB
355
356 /* No default editor, try to find a common editor for all traces */
357 final List<TmfTraceElement> traceEntries = getTraces();
358 String commonEditorId = null;
359
360 for (TmfTraceElement element : traceEntries) {
361 // If all traces use the same editorId, use it, otherwise use the
362 // default
363 final String editorId = element.getEditorId();
364 if (commonEditorId == null) {
365 commonEditorId = (editorId != null) ? editorId : TmfEventsEditor.ID;
366 } else if (!commonEditorId.equals(editorId)) {
367 commonEditorId = TmfEventsEditor.ID;
368 }
369 }
370 return null;
81fe3479
PT
371 }
372
373 /**
8f5221c2
GB
374 * Instantiate a {@link TmfExperiment} object based on the experiment type
375 * and the corresponding extension.
376 *
377 * @return the {@link TmfExperiment} or <code>null</code> for an error
81fe3479 378 */
8f5221c2
GB
379 @Override
380 public TmfExperiment instantiateTrace() {
381 try {
382
383 // make sure that supplementary folder exists
384 refreshSupplementaryFolder();
385
386 if (getTraceType() != null) {
387
388 IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType());
389 if (ce == null) {
390 return null;
391 }
392 TmfExperiment experiment = (TmfExperiment) ce.createExecutableExtension(TmfTraceType.EXPERIMENT_TYPE_ATTR);
393 return experiment;
394 }
395 } catch (CoreException e) {
396 Activator.getDefault().logError(NLS.bind(Messages.TmfExperimentElement_ErrorInstantiatingTrace, getName()), e);
397 }
398 return null;
399 }
400
401 @Override
402 public String getTypeName() {
403 return Messages.TmfExperimentElement_TypeName;
c4c81d91
PT
404 }
405
12c155f5
FC
406 // ------------------------------------------------------------------------
407 // IPropertySource2
408 // ------------------------------------------------------------------------
409
410 @Override
411 public Object getEditableValue() {
412 return null;
413 }
414
415 @Override
416 public IPropertyDescriptor[] getPropertyDescriptors() {
77fdc5df 417 return Arrays.copyOf(sfDescriptors, sfDescriptors.length);
12c155f5
FC
418 }
419
420 @Override
421 public Object getPropertyValue(Object id) {
422
c4c81d91 423 if (sfName.equals(id)) {
12c155f5 424 return getName();
c4c81d91 425 }
12c155f5 426
c4c81d91 427 if (sfPath.equals(id)) {
12c155f5 428 return getPath().toString();
c4c81d91 429 }
12c155f5 430
c4c81d91 431 if (sfLocation.equals(id)) {
12c155f5 432 return getLocation().toString();
c4c81d91 433 }
12c155f5 434
8f5221c2
GB
435 if (sfExperimentType.equals(id)) {
436 if (getTraceType() != null) {
437 IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType());
438 if (ce == null) {
439 return ""; //$NON-NLS-1$
440 }
441 String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR);
442 if (categoryId != null) {
443 IConfigurationElement category = sfTraceCategories.get(categoryId);
444 if (category != null) {
445 return category.getAttribute(TmfTraceType.NAME_ATTR) + ':' + ce.getAttribute(TmfTraceType.NAME_ATTR);
446 }
447 }
448 return ce.getAttribute(TmfTraceType.NAME_ATTR);
449 }
450 }
451
12c155f5
FC
452 return null;
453 }
c4c81d91 454
12c155f5
FC
455 @Override
456 public void resetPropertyValue(Object id) {
457 }
458
459 @Override
460 public void setPropertyValue(Object id, Object value) {
461 }
462
463 @Override
464 public boolean isPropertyResettable(Object id) {
465 return false;
466 }
467
468 @Override
469 public boolean isPropertySet(Object id) {
470 return false;
471 }
472
99504bb8
GB
473 /**
474 * Return the suffix for resource names
475 * @return The folder suffix
476 */
477 @Override
478 public String getSuffix() {
479 return sfFolderSuffix;
480 }
481
12c155f5 482}
This page took 0.092423 seconds and 5 git commands to generate.