tmf: support for renaming, overwriting or skipping during import
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / project / model / TmfTraceTypeUIUtils.java
1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson
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 * Alexandre Montplaisir - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.ui.project.model;
14
15 import java.io.File;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.Map;
22
23 import org.eclipse.core.resources.IResource;
24 import org.eclipse.core.resources.ResourcesPlugin;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IConfigurationElement;
27 import org.eclipse.core.runtime.IPath;
28 import org.eclipse.core.runtime.IStatus;
29 import org.eclipse.core.runtime.Status;
30 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
31 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
32 import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException;
33 import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType;
34 import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper;
35 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
36 import org.eclipse.swt.SWT;
37 import org.eclipse.swt.events.SelectionEvent;
38 import org.eclipse.swt.events.SelectionListener;
39 import org.eclipse.swt.layout.RowLayout;
40 import org.eclipse.swt.widgets.Button;
41 import org.eclipse.swt.widgets.Display;
42 import org.eclipse.swt.widgets.Shell;
43 import org.eclipse.ui.dialogs.FileSystemElement;
44
45 /**
46 * Utils class for the UI-specific parts of @link {@link TmfTraceType}.
47 *
48 * @author Alexandre Montplaisir
49 * @since 3.0
50 */
51 public final class TmfTraceTypeUIUtils {
52
53 private static final String DEFAULT_TRACE_ICON_PATH = "icons" + File.separator + "elcl16" + File.separator + "trace.gif"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
54
55 private static final char SEPARATOR = ':';
56
57 private TmfTraceTypeUIUtils() {}
58
59 private static List<File> isolateTraces(List<FileSystemElement> selectedResources) {
60 List<File> traces = new ArrayList<>();
61
62 // Get the selection
63 Iterator<FileSystemElement> resources = selectedResources.iterator();
64
65 // Get the sorted list of unique entries
66 Map<String, File> fileSystemObjects = new HashMap<>();
67 while (resources.hasNext()) {
68 File resource = (File) resources.next().getFileSystemObject();
69 String key = resource.getAbsolutePath();
70 fileSystemObjects.put(key, resource);
71 }
72 List<String> files = new ArrayList<>(fileSystemObjects.keySet());
73 Collections.sort(files);
74
75 // After sorting, traces correspond to the unique prefixes
76 String prefix = null;
77 for (int i = 0; i < files.size(); i++) {
78 File file = fileSystemObjects.get(files.get(i));
79 String name = file.getAbsolutePath();
80 if (prefix == null || !name.startsWith(prefix)) {
81 prefix = name; // new prefix
82 traces.add(file);
83 }
84 }
85
86 return traces;
87 }
88
89 private static List<TraceTypeHelper> reduce(List<TraceTypeHelper> candidates) {
90 List<TraceTypeHelper> retVal = new ArrayList<>();
91
92 // get all the tracetypes that are unique in that stage
93 for (TraceTypeHelper trace : candidates) {
94 if (isUnique(trace, candidates)) {
95 retVal.add(trace);
96 }
97 }
98 return retVal;
99 }
100
101 /*
102 * Only return the leaves of the trace types. Ignore custom trace types.
103 */
104 private static boolean isUnique(TraceTypeHelper trace, List<TraceTypeHelper> set) {
105 if (isCustomTraceId(trace.getCanonicalName())) {
106 return true;
107 }
108 // check if the trace type is the leaf. we make an instance of the trace
109 // type and if it is only an instance of itself, it is a leaf
110 final ITmfTrace tmfTrace = trace.getTrace();
111 int count = -1;
112 for (TraceTypeHelper child : set) {
113 final ITmfTrace traceCandidate = child.getTrace();
114 if (tmfTrace.getClass().isInstance(traceCandidate)) {
115 count++;
116 }
117 }
118 return count == 0;
119 }
120
121 /**
122 * Is the trace type id a custom (user-defined) trace type. These are the
123 * traces like : text and xml defined by the custom trace wizard.
124 *
125 * @param traceTypeId
126 * the trace type id
127 * @return true if the trace is a custom type
128 */
129 private static boolean isCustomTraceId(String traceTypeId) {
130 TraceTypeHelper traceType = TmfTraceType.getInstance().getTraceType(traceTypeId);
131 if (traceType != null) {
132 return TmfTraceType.isCustomTrace(traceType.getCategoryName() + SEPARATOR + traceType.getName());
133 }
134 return false;
135 }
136
137 private static TraceTypeHelper getTraceTypeToSet(TmfTraceType type, List<TraceTypeHelper> candidates, Shell shell) {
138 final Map<String, String> names = new HashMap<>();
139 Shell shellToShow = new Shell(shell);
140 shellToShow.setText(Messages.TmfTraceType_SelectTraceType);
141 final String candidatesToSet[] = new String[1];
142 for (TraceTypeHelper candidate : candidates) {
143 Button b = new Button(shellToShow, SWT.RADIO);
144 final String displayName = candidate.getCategoryName() + ':' + candidate.getName();
145 b.setText(displayName);
146 names.put(displayName, candidate.getCanonicalName());
147
148 b.addSelectionListener(new SelectionListener() {
149
150 @Override
151 public void widgetSelected(SelectionEvent e) {
152 final Button source = (Button) e.getSource();
153 candidatesToSet[0] = (names.get(source.getText()));
154 source.getParent().dispose();
155 }
156
157 @Override
158 public void widgetDefaultSelected(SelectionEvent e) {
159
160 }
161 });
162 }
163 shellToShow.setLayout(new RowLayout(SWT.VERTICAL));
164 shellToShow.pack();
165 shellToShow.open();
166
167 Display display = shellToShow.getDisplay();
168 while (!shellToShow.isDisposed()) {
169 if (!display.readAndDispatch()) {
170 display.sleep();
171 }
172 }
173 return type.getTraceTypeHelper(candidatesToSet[0]);
174 }
175
176 /**
177 * validate list of traces with a tracetype
178 *
179 * @param type
180 * The TmfTraceType instance
181 * @param traceTypeName
182 * the trace category (canonical name)
183 * @param selectedResources
184 * List of traces to validate
185 * @return true if all the traces are valid
186 */
187 public static boolean validateTrace(TmfTraceType type, String traceTypeName, List<FileSystemElement> selectedResources) {
188 List<File> traces = isolateTraces(selectedResources);
189 return type.validateTraceFiles(traceTypeName, traces);
190 }
191
192 /**
193 * This member figures out the trace type of a given file. It will prompt
194 * the user if it needs more information to properly pick the trace type.
195 *
196 * @param path
197 * The path of file to import
198 * @param shell
199 * a shell to display the message to. If it is null, it is
200 * assumed to be cancelled.
201 * @param traceTypeHint
202 * the ID of a trace (like "o.e.l.specifictrace" )
203 * @return null if the request is cancelled or a TraceTypeHelper if it
204 * passes.
205 * @throws TmfTraceImportException
206 * if the traces don't match or there are errors in the trace
207 * file
208 */
209 public static TraceTypeHelper selectTraceType(String path, Shell shell, String traceTypeHint) throws TmfTraceImportException {
210 TmfTraceType type = TmfTraceType.getInstance();
211 List<TraceTypeHelper> validCandidates = new ArrayList<>();
212 final Iterable<String> traceTypes = type.getTraceTypeIDs();
213 for (String traceType : traceTypes) {
214 if (type.validate(traceType, path)) {
215 validCandidates.add(type.getTraceTypeHelper(traceType));
216 }
217 }
218
219 TraceTypeHelper traceTypeToSet = null;
220 if (validCandidates.isEmpty()) {
221 final String errorMsg = Messages.TmfOpenTraceHelper_NoTraceTypeMatch + path;
222 throw new TmfTraceImportException(errorMsg);
223 } else if (validCandidates.size() != 1) {
224 List<TraceTypeHelper> reducedCandidates = reduce(validCandidates);
225 for (TraceTypeHelper tth : reducedCandidates) {
226 if (tth.getCanonicalName().equals(traceTypeHint)) {
227 traceTypeToSet = tth;
228 }
229 }
230 if (traceTypeToSet == null) {
231 if (reducedCandidates.size() == 0) {
232 throw new TmfTraceImportException(Messages.TmfOpenTraceHelper_ReduceError);
233 } else if (reducedCandidates.size() == 1) {
234 traceTypeToSet = reducedCandidates.get(0);
235 } else {
236 if (shell == null) {
237 traceTypeToSet = reducedCandidates.get(0);
238 } else {
239 traceTypeToSet = getTraceTypeToSet(type, reducedCandidates, shell);
240 }
241 }
242 }
243 } else {
244 traceTypeToSet = validCandidates.get(0);
245 }
246 return traceTypeToSet;
247 }
248
249
250 /**
251 * Set the trace type of a {@Link TraceTypeHelper}. Should only be
252 * used internally by this project.
253 *
254 * @param path
255 * the {@link IPath} path of the resource to set
256 * @param traceType
257 * the {@link TraceTypeHelper} to set the trace type to.
258 * @return Status.OK_Status if successful, error is otherwise.
259 * @throws CoreException
260 * An exception caused by accessing eclipse project items.
261 */
262 public static IStatus setTraceType(IPath path, TraceTypeHelper traceType) throws CoreException {
263 IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
264 String traceBundle = null, traceTypeId = traceType.getCanonicalName(), traceIcon = null;
265 if (isCustomTraceId(traceTypeId)) {
266 traceBundle = Activator.getDefault().getBundle().getSymbolicName();
267 traceIcon = DEFAULT_TRACE_ICON_PATH;
268 } else {
269 IConfigurationElement ce = TmfTraceType.getInstance().getTraceAttributes(traceTypeId);
270 traceBundle = ce.getContributor().getName();
271 traceIcon = ce.getAttribute(TmfTraceType.ICON_ATTR);
272 }
273
274 resource.setPersistentProperty(TmfCommonConstants.TRACEBUNDLE, traceBundle);
275 resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, traceTypeId);
276 resource.setPersistentProperty(TmfCommonConstants.TRACEICON, traceIcon);
277
278 TmfProjectElement tmfProject = TmfProjectRegistry.getProject(resource.getProject(), true);
279 final TmfTraceFolder tracesFolder = tmfProject.getTracesFolder();
280 List<TmfTraceElement> traces = tracesFolder.getTraces();
281 for (TmfTraceElement traceElement : traces) {
282 if (traceElement.getName().equals(resource.getName())) {
283 traceElement.refreshTraceType();
284 break;
285 }
286 }
287 tmfProject.refresh();
288 return Status.OK_STATUS;
289 }
290 }
This page took 0.039113 seconds and 6 git commands to generate.