Fix new null warnings
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / project / wizards / tracepkg / importexport / TracePackageImportOperation.java
CommitLineData
6e651d8b 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2013, 2015 Ericsson
6e651d8b
MAL
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 * Marc-Andre Laperle - Initial API and implementation
89730b51 11 * Patrick Tasse - Add support for source location
6e651d8b
MAL
12 *******************************************************************************/
13
2bdf0193 14package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport;
6e651d8b 15
e2659565
AM
16import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
17
89730b51 18import java.io.File;
6e651d8b
MAL
19import java.io.IOException;
20import java.io.InputStream;
21import java.lang.reflect.InvocationTargetException;
89730b51 22import java.net.URI;
6e651d8b
MAL
23import java.text.MessageFormat;
24import java.util.ArrayList;
25import java.util.Enumeration;
26import java.util.List;
27import java.util.Map;
5e1ce4e2 28import java.util.Map.Entry;
6e651d8b
MAL
29
30import org.eclipse.core.resources.IFile;
89730b51 31import org.eclipse.core.resources.IFolder;
6e651d8b
MAL
32import org.eclipse.core.resources.IMarker;
33import org.eclipse.core.resources.IResource;
34import org.eclipse.core.runtime.CoreException;
35import org.eclipse.core.runtime.IPath;
36import org.eclipse.core.runtime.IProgressMonitor;
37import org.eclipse.core.runtime.IStatus;
38import org.eclipse.core.runtime.Path;
39import org.eclipse.core.runtime.Status;
728810b6 40import org.eclipse.core.runtime.SubMonitor;
89730b51 41import org.eclipse.core.runtime.URIUtil;
5b3fe39a 42import org.eclipse.jdt.annotation.NonNull;
6e651d8b 43import org.eclipse.jface.operation.ModalContext;
2bdf0193
AM
44import org.eclipse.tracecompass.internal.tmf.ui.Activator;
45import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation;
46import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement;
47import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement;
48import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement;
49import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement;
50import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement;
51import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement;
52import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
53import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException;
54import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
55import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
56import org.eclipse.tracecompass.tmf.core.util.Pair;
57import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor;
58import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
59import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
60import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils;
6e651d8b
MAL
61import org.eclipse.ui.dialogs.IOverwriteQuery;
62import org.eclipse.ui.ide.IDE;
63import org.eclipse.ui.internal.wizards.datatransfer.TarException;
64import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
65import org.eclipse.ui.wizards.datatransfer.ImportOperation;
66
67/**
68 * An operation that imports a trace package from an archive
69 *
70 * @author Marc-Andre Laperle
71 */
72@SuppressWarnings("restriction")
73public class TracePackageImportOperation extends AbstractTracePackageOperation implements IOverwriteQuery {
74
195355a9 75 private final TracePackageElement[] fImportTraceElements;
6e651d8b
MAL
76 private final TmfTraceFolder fTmfTraceFolder;
77
6e651d8b
MAL
78 /**
79 * Constructs a new import operation
80 *
195355a9 81 * @param importTraceElements
6e651d8b
MAL
82 * the trace element to be imported
83 * @param fileName
84 * the output file name
85 * @param tmfTraceFolder
86 * the destination folder
87 */
195355a9 88 public TracePackageImportOperation(String fileName, TracePackageElement[] importTraceElements, TmfTraceFolder tmfTraceFolder) {
6e651d8b 89 super(fileName);
195355a9 90 fImportTraceElements = importTraceElements;
6e651d8b
MAL
91 fTmfTraceFolder = tmfTraceFolder;
92 }
93
94 private class ImportProvider implements IImportStructureProvider {
95
96 private Exception fException;
97
98 @Override
99 public List getChildren(Object element) {
100 return null;
101 }
102
103 @Override
104 public InputStream getContents(Object element) {
105 InputStream inputStream = null;
106 // We can add throws
107 try {
108 inputStream = ((ArchiveProviderElement) element).getContents();
109 } catch (IOException e) {
110 fException = e;
111 } catch (TarException e) {
112 fException = e;
113 }
114 return inputStream;
115 }
116
117 @Override
118 public String getFullPath(Object element) {
119 return ((ArchiveProviderElement) element).getFullPath();
120 }
121
122 @Override
123 public String getLabel(Object element) {
124 return ((ArchiveProviderElement) element).getLabel();
125 }
126
127 @Override
128 public boolean isFolder(Object element) {
129 return ((ArchiveProviderElement) element).isFolder();
130 }
131
132 public Exception getException() {
133 return fException;
134 }
135 }
136
137 private class ArchiveProviderElement {
138
139 private final String fPath;
140 private final String fLabel;
141
142 private ArchiveFile fArchiveFile;
143 private ArchiveEntry fEntry;
144
145 public ArchiveProviderElement(String destinationPath, String label, ArchiveFile archiveFile, ArchiveEntry entry) {
146 fPath = destinationPath;
147 fLabel = label;
148 this.fArchiveFile = archiveFile;
149 this.fEntry = entry;
150 }
151
152 public InputStream getContents() throws TarException, IOException {
153 return fArchiveFile.getInputStream(fEntry);
154 }
155
156 public String getFullPath() {
157 return fPath;
158 }
159
160 public String getLabel() {
161 return fLabel;
162 }
163
164 public boolean isFolder() {
165 return false;
166 }
167 }
168
169 /**
170 * Run the operation. The status (result) of the operation can be obtained
171 * with {@link #getStatus}
172 *
173 * @param progressMonitor
174 * the progress monitor to use to display progress and receive
175 * requests for cancellation
176 */
177 @Override
178 public void run(IProgressMonitor progressMonitor) {
195355a9 179 int totalWork = getNbCheckedElements(fImportTraceElements) * 2;
6e651d8b
MAL
180 progressMonitor.beginTask(Messages.TracePackageImportOperation_ImportingPackage, totalWork);
181 doRun(progressMonitor);
182 progressMonitor.done();
183 }
184
185 private void doRun(IProgressMonitor progressMonitor) {
186 try {
195355a9 187 setStatus(deleteExistingTraces(progressMonitor));
6e651d8b
MAL
188 if (getStatus().getSeverity() != IStatus.OK) {
189 return;
190 }
191
89730b51 192 TracePackageFilesElement traceFilesElement = null;
195355a9
MAL
193 for (TracePackageElement packageElement : fImportTraceElements) {
194 TracePackageTraceElement traceElement = (TracePackageTraceElement) packageElement;
195 if (!isFilesChecked(packageElement)) {
196 continue;
197 }
198
199 TracePackageElement[] children = traceElement.getChildren();
200 for (TracePackageElement element : children) {
201 ModalContext.checkCanceled(progressMonitor);
202
203 if (element instanceof TracePackageFilesElement) {
89730b51 204 traceFilesElement = (TracePackageFilesElement) element;
a6ee485c 205 setStatus(importTraceFiles(traceFilesElement, traceElement, progressMonitor));
6e651d8b 206
195355a9
MAL
207 } else if (element instanceof TracePackageSupplFilesElement) {
208 TracePackageSupplFilesElement suppFilesElement = (TracePackageSupplFilesElement) element;
209 setStatus(importSupplFiles(suppFilesElement, traceElement, progressMonitor));
210 }
6e651d8b 211
195355a9
MAL
212 if (getStatus().getSeverity() != IStatus.OK) {
213 return;
214 }
6e651d8b 215 }
89730b51 216 }
6e651d8b
MAL
217
218 } catch (InterruptedException e) {
219 setStatus(Status.CANCEL_STATUS);
220 }
221 }
222
a6ee485c
MAL
223 /**
224 * Returns whether or not the Files element is checked under the given trace
225 * package element
226 *
227 * @param tracePackageElement
228 * the trace package element
229 * @return whether or not the Files element is checked under the given trace
230 * package element
231 */
232 public static boolean isFilesChecked(TracePackageElement tracePackageElement) {
233 for (TracePackageElement element : tracePackageElement.getChildren()) {
234 if (element instanceof TracePackageFilesElement) {
235 return element.isChecked();
236 }
237 }
238
239 return false;
240 }
241
242 /**
243 * Return the matching TmfTraceElement for a given trace element.
244 */
245 private TmfTraceElement getMatchingTraceElement(TracePackageTraceElement tracePackageElement) {
246 IPath tracePath = fTmfTraceFolder.getPath().append(tracePackageElement.getDestinationElementPath());
6e651d8b 247 List<TmfTraceElement> traces = fTmfTraceFolder.getTraces();
a6ee485c
MAL
248 for (TmfTraceElement t : traces) {
249 if (t.getPath().equals(tracePath)) {
250 return t;
251 }
252 }
253
254 return null;
255 }
6e651d8b 256
a6ee485c 257 private IStatus deleteExistingTraces(IProgressMonitor progressMonitor) {
195355a9
MAL
258 for (TracePackageElement packageElement : fImportTraceElements) {
259 TracePackageTraceElement traceElement = (TracePackageTraceElement) packageElement;
260 if (!isFilesChecked(traceElement)) {
261 continue;
6e651d8b 262 }
6e651d8b 263
a6ee485c 264 TmfTraceElement existingTrace = getMatchingTraceElement(traceElement);
195355a9
MAL
265 if (existingTrace != null) {
266 try {
728810b6 267 existingTrace.delete(SubMonitor.convert(progressMonitor));
195355a9 268 } catch (CoreException e) {
2bdf0193 269 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e);
195355a9 270 }
6e651d8b
MAL
271 }
272 }
273
274 return Status.OK_STATUS;
275 }
276
195355a9
MAL
277 private void importBookmarks(IResource traceRes, TracePackageTraceElement traceElement, IProgressMonitor monitor) {
278 for (TracePackageElement o : traceElement.getChildren()) {
6e651d8b
MAL
279 if (o instanceof TracePackageBookmarkElement && o.isChecked()) {
280
281 // Get element
282 IFile bookmarksFile = null;
a6ee485c
MAL
283 TmfTraceElement tmfTraceElement = getMatchingTraceElement(traceElement);
284 if (tmfTraceElement != null) {
285 try {
286 bookmarksFile = tmfTraceElement.createBookmarksFile();
6e651d8b 287
a6ee485c
MAL
288 // Make sure that if a bookmark is double-clicked first
289 // before opening the trace, it opens the right editor
6e651d8b 290
a6ee485c
MAL
291 // Get the editor id from the extension point
292 String traceEditorId = tmfTraceElement.getEditorId();
293 final String editorId = (traceEditorId != null) ? traceEditorId : TmfEventsEditor.ID;
294 IDE.setDefaultEditor(bookmarksFile, editorId);
6e651d8b 295
a6ee485c
MAL
296 } catch (CoreException e) {
297 Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmarkFile, traceRes.getName()), e);
6e651d8b
MAL
298 }
299 }
300
301 if (bookmarksFile == null) {
302 break;
303 }
304
305 TracePackageBookmarkElement bookmarkElement = (TracePackageBookmarkElement) o;
306
307 List<Map<String, String>> bookmarks = bookmarkElement.getBookmarks();
308 for (Map<String, String> attrs : bookmarks) {
309 IMarker createMarker = null;
310 try {
311 createMarker = bookmarksFile.createMarker(IMarker.BOOKMARK);
312 } catch (CoreException e) {
313 Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmark, traceRes.getName()), e);
314 }
315 if (createMarker != null && createMarker.exists()) {
316 try {
5e1ce4e2
MK
317 for (Entry<String, String> entry : attrs.entrySet()) {
318 String key = entry.getKey();
319 String value = entry.getValue();
6e651d8b 320 if (key.equals(IMarker.LOCATION)) {
7697e148
PT
321 try {
322 /* try location as an integer for backward compatibility */
323 createMarker.setAttribute(IMarker.LOCATION, Integer.parseInt(value));
324 } catch (NumberFormatException e) {
325 createMarker.setAttribute(IMarker.LOCATION, value);
326 }
6e651d8b
MAL
327 } else {
328 createMarker.setAttribute(key, value);
329 }
330 }
331 } catch (CoreException e) {
332 Activator.getDefault().logError(MessageFormat.format(Messages.TracePackageImportOperation_ErrorCreatingBookmark, traceRes.getName()), e);
333 }
334 }
335 }
336 }
337 }
338
339 monitor.worked(1);
340 }
341
a6ee485c 342 private IStatus importTraceFiles(TracePackageFilesElement traceFilesElement, TracePackageTraceElement traceElement, IProgressMonitor monitor) {
7441221c
MAL
343 List<Pair<String, String>> fileNameAndLabelPairs = new ArrayList<>();
344
e2659565
AM
345 String sourceName = checkNotNull(traceFilesElement.getFileName());
346 String destinationName = checkNotNull(traceElement.getImportName());
7441221c
MAL
347
348 fileNameAndLabelPairs.add(new Pair<>(sourceName, destinationName));
349
6e651d8b 350 IPath containerPath = fTmfTraceFolder.getPath();
a6ee485c
MAL
351 IStatus status = importFiles(getSpecifiedArchiveFile(), fileNameAndLabelPairs, containerPath, Path.EMPTY, monitor);
352 if (getStatus().getSeverity() != IStatus.OK) {
353 return status;
354 }
355
356 // We need to set the trace type before importing the supplementary files so we do it here
357 IResource traceRes = fTmfTraceFolder.getResource().findMember(traceElement.getDestinationElementPath());
358 if (traceRes == null || !traceRes.exists()) {
359 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorFindingImportedTrace, destinationName));
360 }
361
362 TraceTypeHelper traceType = null;
363 String traceTypeStr = traceElement.getTraceType();
364 if (traceTypeStr != null) {
a4a116c3 365 traceType = TmfTraceType.getTraceType(traceTypeStr);
a6ee485c
MAL
366 if (traceType == null) {
367 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorSettingTraceType, traceElement.getTraceType(), destinationName));
368 }
369 } else {
370 try {
371 monitor.subTask(MessageFormat.format(Messages.TracePackageImportOperation_DetectingTraceType, destinationName));
372 traceType = TmfTraceTypeUIUtils.selectTraceType(traceRes.getLocation().toOSString(), null, null);
373 } catch (TmfTraceImportException e) {
374 // Could not figure out the type
375 }
376 }
377
378 if (traceType != null) {
379 try {
380 TmfTraceTypeUIUtils.setTraceType(traceRes, traceType);
381 } catch (CoreException e) {
382 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportTracePackageWizardPage_ErrorSettingTraceType, traceElement.getTraceType(), destinationName), e);
383 }
384 }
385
386 importBookmarks(traceRes, traceElement, monitor);
387
388 try {
389 URI uri = new File(getFileName()).toURI();
390 IPath entryPath = new Path(traceFilesElement.getFileName());
391 if (traceRes instanceof IFolder) {
392 entryPath = entryPath.addTrailingSeparator();
393 }
394 String sourceLocation = URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath));
395 traceRes.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation);
396 } catch (CoreException e) {
397 }
398
6e651d8b
MAL
399 return status;
400 }
401
195355a9 402 private IStatus importSupplFiles(TracePackageSupplFilesElement suppFilesElement, TracePackageTraceElement traceElement, IProgressMonitor monitor) {
7441221c 403 List<Pair<String, String>> fileNameAndLabelPairs = new ArrayList<>();
6e651d8b 404 for (TracePackageElement child : suppFilesElement.getChildren()) {
4d40b148
MAL
405 if (child.isChecked()) {
406 TracePackageSupplFileElement supplFile = (TracePackageSupplFileElement) child;
e2659565 407 fileNameAndLabelPairs.add(new Pair<>(checkNotNull(supplFile.getText()), checkNotNull(new Path(supplFile.getText()).lastSegment())));
4d40b148 408 }
6e651d8b
MAL
409 }
410
7441221c 411 if (!fileNameAndLabelPairs.isEmpty()) {
a6ee485c
MAL
412 TmfTraceElement existingTrace = getMatchingTraceElement(traceElement);
413 if (existingTrace != null) {
6e651d8b 414 ArchiveFile archiveFile = getSpecifiedArchiveFile();
a6ee485c
MAL
415 existingTrace.refreshSupplementaryFolder();
416 // Project/Traces/A/B -> A/B
417 IPath traceFolderRelativePath = fTmfTraceFolder.getPath().makeRelativeTo(fTmfTraceFolder.getProject().getTracesFolder().getPath());
418 // Project/.tracing/A/B/
419 IFolder traceSupplementaryFolder = fTmfTraceFolder.getTraceSupplementaryFolder(traceFolderRelativePath.toString());
420 IPath destinationContainerPath = traceSupplementaryFolder.getFullPath();
421 // Remove the .tracing segment at the beginnin so that a file in folder .tracing/A/B/ imports destinationContainerPath/A/B/
422 Path baseSourcePath = new Path(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER_NAME);
423 return importFiles(archiveFile, fileNameAndLabelPairs, destinationContainerPath, baseSourcePath, monitor);
6e651d8b
MAL
424 }
425 }
426
427 return Status.OK_STATUS;
428 }
429
a6ee485c 430 private IStatus importFiles(ArchiveFile archiveFile, List<Pair<String, String>> fileNameAndLabelPairs, IPath destinationContainerPath, IPath baseSourcePath, IProgressMonitor monitor) {
507b1336 431 List<ArchiveProviderElement> objects = new ArrayList<>();
5b3fe39a 432 Enumeration<@NonNull ?> entries = archiveFile.entries();
6e651d8b
MAL
433 while (entries.hasMoreElements()) {
434 ArchiveEntry entry = (ArchiveEntry) entries.nextElement();
435 String entryName = entry.getName();
436 IPath fullArchivePath = new Path(entryName);
437 if (fullArchivePath.hasTrailingSeparator()) {
438 // We only care about file entries as the folders will get created by the ImportOperation
439 continue;
440 }
441
7441221c 442 for (Pair<String, String> fileNameAndLabel : fileNameAndLabelPairs) {
f7885d6d 443
a6ee485c 444 // Examples: Traces/aaa/kernel/ .tracing/aaa/testtexttrace.txt/statistics.ht
7441221c 445 IPath searchedArchivePath = new Path(fileNameAndLabel.getFirst());
f7885d6d 446
6e651d8b 447 // Check if this archive entry matches the searched file name at this archive location
7441221c 448 boolean fileMatch = entryName.equalsIgnoreCase(searchedArchivePath.toString());
a6ee485c 449 // For example Traces/aaa/kernel/metadata matches Traces/aaa/kernel/
7441221c
MAL
450 boolean folderMatch = entryName.startsWith(searchedArchivePath + "/"); //$NON-NLS-1$
451
452 if (fileMatch || folderMatch) {
a6ee485c
MAL
453 // .tracing/aaa/testtexttrace.txt/statistics.ht -> aaa/testtexttrace.txt/statistics.ht
454 IPath destinationPath = fullArchivePath.makeRelativeTo(baseSourcePath);
7441221c 455
f7885d6d 456 // metadata statistics.ht
7441221c
MAL
457 // We don't use the label when the entry is a folder match because the labels for individual files
458 // under the folder are not specified in the manifest so just use the last segment.
459 String resourceLabel = folderMatch ? fullArchivePath.lastSegment() : fileNameAndLabel.getSecond();
6e651d8b
MAL
460
461 ArchiveProviderElement pe = new ArchiveProviderElement(destinationPath.toString(), resourceLabel, archiveFile, entry);
462 objects.add(pe);
463 break;
464 }
465 }
466 }
467
468 ImportProvider provider = new ImportProvider();
469
470 ImportOperation operation = new ImportOperation(destinationContainerPath,
471 null, provider, this,
472 objects);
473 operation.setCreateContainerStructure(true);
474 operation.setOverwriteResources(true);
475
476 try {
728810b6 477 operation.run(SubMonitor.convert(monitor));
6e651d8b
MAL
478 archiveFile.close();
479 } catch (InvocationTargetException e) {
2bdf0193 480 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e);
6e651d8b
MAL
481 } catch (InterruptedException e) {
482 return Status.CANCEL_STATUS;
483 } catch (IOException e) {
2bdf0193 484 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e);
6e651d8b
MAL
485 }
486
487 if (provider.getException() != null) {
2bdf0193 488 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, provider.getException());
6e651d8b
MAL
489 }
490
491 return operation.getStatus();
492 }
493
494 @Override
495 public String queryOverwrite(String pathString) {
496 // We always overwrite once we reach this point
497 return null;
498 }
6e651d8b 499}
This page took 0.122021 seconds and 5 git commands to generate.