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