93b1ee9d67cd97558b07342cdf010648c30535f9
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / project / wizards / importtrace / TraceValidateAndImportOperation.java
1 /*******************************************************************************
2 * Copyright (c) 2015 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 * Marc-Andre Laperle - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;
14
15 import java.io.File;
16 import java.io.InputStream;
17 import java.lang.reflect.InvocationTargetException;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.LinkedList;
23 import java.util.List;
24 import java.util.ListIterator;
25 import java.util.Map;
26
27 import org.eclipse.core.filesystem.EFS;
28 import org.eclipse.core.filesystem.IFileInfo;
29 import org.eclipse.core.resources.IFile;
30 import org.eclipse.core.resources.IFolder;
31 import org.eclipse.core.resources.IResource;
32 import org.eclipse.core.resources.ResourcesPlugin;
33 import org.eclipse.core.runtime.CoreException;
34 import org.eclipse.core.runtime.IPath;
35 import org.eclipse.core.runtime.IProgressMonitor;
36 import org.eclipse.core.runtime.IStatus;
37 import org.eclipse.core.runtime.Path;
38 import org.eclipse.core.runtime.Status;
39 import org.eclipse.core.runtime.SubMonitor;
40 import org.eclipse.core.runtime.URIUtil;
41 import org.eclipse.jface.operation.ModalContext;
42 import org.eclipse.swt.widgets.Shell;
43 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
44 import org.eclipse.tracecompass.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation;
45 import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
46 import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException;
47 import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
48 import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
49 import org.eclipse.tracecompass.tmf.core.util.Pair;
50 import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
51 import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils;
52 import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils;
53 import org.eclipse.ui.dialogs.FileSystemElement;
54 import org.eclipse.ui.dialogs.IOverwriteQuery;
55 import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
56 import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
57 import org.eclipse.ui.wizards.datatransfer.ImportOperation;
58
59 /**
60 * An operation that performs validation and importing of traces. Its primary
61 * inputs are a collection of TraceFileSystemElement and several flags that
62 * control
63 *
64 */
65 public class TraceValidateAndImportOperation extends TmfWorkspaceModifyOperation {
66
67 private static final String TRACE_IMPORT_TEMP_FOLDER = ".traceImport"; //$NON-NLS-1$
68
69 private String fTraceType;
70 private IPath fDestinationContainerPath;
71 private IPath fBaseSourceContainerPath;
72 private boolean fImportFromArchive;
73 private int fImportOptionFlags;
74 private Shell fShell;
75 private TmfTraceFolder fTraceFolderElement;
76 private List<TraceFileSystemElement> fSelectedFileSystemElements;
77
78 private IStatus fStatus;
79 private ImportConflictHandler fConflictHandler;
80 private String fCurrentPath;
81
82 private List<IResource> fImportedResources;
83
84 /**
85 * Constructs a new validate and import operation.
86 *
87 * @param shell
88 * the parent shell to use for possible error messages
89 * @param traceFileSystemElements
90 * the trace file elements to import
91 * @param traceId
92 * the trace type to import the traces as (can be set to null for
93 * automatic detection)
94 * @param baseSourceContainerPath
95 * the path to the container of the source. This is used as a
96 * "base" to generate the folder structure for the
97 * "preserve folder structure" option.
98 * @param destinationContainerPath
99 * the destination path of the import operation, typically a
100 * trace folder path.
101 * @param importFromArchive
102 * whether or not the source is an archive
103 * @param importOptionFlags
104 * bit-wise 'or' of import option flag constants (
105 * {@link ImportTraceWizardPage#OPTION_PRESERVE_FOLDER_STRUCTURE}
106 * ,
107 * {@link ImportTraceWizardPage#OPTION_CREATE_LINKS_IN_WORKSPACE}
108 * ,
109 * {@link ImportTraceWizardPage#OPTION_IMPORT_UNRECOGNIZED_TRACES}
110 * , and
111 * {@link ImportTraceWizardPage#OPTION_OVERWRITE_EXISTING_RESOURCES}
112 * )
113 * @param traceFolderElement
114 * the destination trace folder of the import operation.
115 */
116 public TraceValidateAndImportOperation(Shell shell, List<TraceFileSystemElement> traceFileSystemElements, String traceId, IPath baseSourceContainerPath, IPath destinationContainerPath, boolean importFromArchive, int importOptionFlags,
117 TmfTraceFolder traceFolderElement) {
118 fTraceType = traceId;
119 fBaseSourceContainerPath = baseSourceContainerPath;
120 fDestinationContainerPath = destinationContainerPath;
121 fImportOptionFlags = importOptionFlags;
122 fImportFromArchive = importFromArchive;
123 fShell = shell;
124 fTraceFolderElement = traceFolderElement;
125
126 boolean overwriteExistingResources = (importOptionFlags & ImportTraceWizardPage.OPTION_OVERWRITE_EXISTING_RESOURCES) != 0;
127 if (overwriteExistingResources) {
128 setConflictHandler(new ImportConflictHandler(fShell, fTraceFolderElement, ImportConfirmation.OVERWRITE_ALL));
129 } else {
130 setConflictHandler(new ImportConflictHandler(fShell, fTraceFolderElement, ImportConfirmation.SKIP));
131 }
132 fImportedResources = new ArrayList<>();
133 fSelectedFileSystemElements = traceFileSystemElements;
134 }
135
136 @Override
137 protected void execute(IProgressMonitor progressMonitor) throws CoreException, InvocationTargetException, InterruptedException {
138 try {
139 final int ARCHIVE_OR_DIRECTORY_PROGRESS = 45;
140 final int EXTRA_IMPORT_OPERATION_PROGRESS = 45;
141 final int DELETE_PROGRESS = 10;
142 final int TOTAL_PROGRESS = ARCHIVE_OR_DIRECTORY_PROGRESS +
143 EXTRA_IMPORT_OPERATION_PROGRESS + DELETE_PROGRESS;
144
145 final List<TraceFileSystemElement> selectedFileSystemElements = fSelectedFileSystemElements;
146
147 // List fileSystemElements will be filled using the
148 // passThroughFilter
149 SubMonitor subMonitor = SubMonitor.convert(progressMonitor, TOTAL_PROGRESS);
150
151 // Check if operation was cancelled.
152 ModalContext.checkCanceled(subMonitor);
153
154 // Temporary directory to contain any extracted files
155 IFolder destTempFolder = fTraceFolderElement.getProject().getResource().getFolder(TRACE_IMPORT_TEMP_FOLDER);
156 if (destTempFolder.exists()) {
157 SubMonitor monitor = subMonitor.newChild(1);
158 destTempFolder.delete(true, monitor);
159 }
160 SubMonitor monitor = subMonitor.newChild(1);
161 destTempFolder.create(IResource.HIDDEN, true, monitor);
162
163 String baseSourceLocation = null;
164 if (fImportFromArchive) {
165 // When importing from archive, we first extract the
166 // *selected* files to a temporary folder then create new
167 // TraceFileSystemElements
168
169 SubMonitor archiveMonitor = SubMonitor.convert(subMonitor.newChild(ARCHIVE_OR_DIRECTORY_PROGRESS), 2);
170
171 // Extract selected files from source archive to temporary
172 // folder
173 extractArchiveContent(selectedFileSystemElements.iterator(), destTempFolder, archiveMonitor.newChild(1));
174
175 if (!selectedFileSystemElements.isEmpty()) {
176 // Even if the files were extracted to temporary folder, they
177 // have to look like they originate from the source archive
178 baseSourceLocation = getRootElement(selectedFileSystemElements.get(0)).getSourceLocation();
179 // Extract additional archives contained in the extracted files
180 // (archives in archives)
181 List<TraceFileSystemElement> tempFolderFileSystemElements = createElementsForFolder(destTempFolder);
182 extractAllArchiveFiles(tempFolderFileSystemElements, destTempFolder, destTempFolder.getLocation(), archiveMonitor.newChild(1));
183 }
184 } else {
185 SubMonitor directoryMonitor = SubMonitor.convert(subMonitor.newChild(ARCHIVE_OR_DIRECTORY_PROGRESS), 2);
186 // Import selected files, excluding archives (done in a later step)
187 importFileSystemElements(directoryMonitor.newChild(1), selectedFileSystemElements);
188
189 // Extract archives in selected files (if any) to temporary folder
190 extractAllArchiveFiles(selectedFileSystemElements, destTempFolder, fBaseSourceContainerPath, directoryMonitor.newChild(1));
191 // Even if the files were extracted to temporary folder, they
192 // have to look like they originate from the source folder
193 baseSourceLocation = URIUtil.toUnencodedString(fBaseSourceContainerPath.toFile().getCanonicalFile().toURI());
194 }
195
196 /*
197 * Import extracted files that are now in the temporary folder, if any
198 */
199
200 // We need to update the source container path because the
201 // "preserve folder structure" option would create the
202 // wrong trace folders otherwise.
203 fBaseSourceContainerPath = destTempFolder.getLocation();
204 List<TraceFileSystemElement> tempFolderFileSystemElements = createElementsForFolder(destTempFolder);
205 if (!tempFolderFileSystemElements.isEmpty()) {
206 calculateSourceLocations(tempFolderFileSystemElements, baseSourceLocation);
207 // Never import extracted files as links, they would link to the
208 // temporary directory that will be deleted
209 fImportOptionFlags = fImportOptionFlags & ~ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE;
210 SubMonitor importTempMonitor = subMonitor.newChild(EXTRA_IMPORT_OPERATION_PROGRESS);
211 importFileSystemElements(importTempMonitor, tempFolderFileSystemElements);
212 }
213
214 if (destTempFolder.exists()) {
215 destTempFolder.delete(true, subMonitor.newChild(TOTAL_PROGRESS));
216 }
217
218 setStatus(Status.OK_STATUS);
219 } catch (InterruptedException e) {
220 setStatus(Status.CANCEL_STATUS);
221 } catch (Exception e) {
222 String errorMessage = Messages.ImportTraceWizard_ImportProblem + ": " + //$NON-NLS-1$
223 (fCurrentPath != null ? fCurrentPath : ""); //$NON-NLS-1$
224 Activator.getDefault().logError(errorMessage, e);
225 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, errorMessage, e));
226 }
227 }
228
229 /**
230 * Get the list of resources that were imported by this operation. An
231 * example use case would be to use this to open traces that were imported
232 * by this operation.
233 *
234 * Note this includes only valid traces and doesn'tinclude unrecognized
235 * files.
236 *
237 * @return the trace resources that were imported
238 */
239 public List<IResource> getImportedResources() {
240 return fImportedResources;
241 }
242
243 /**
244 * Import a collection of file system elements into the workspace.
245 */
246 private void importFileSystemElements(IProgressMonitor monitor, List<TraceFileSystemElement> fileSystemElements)
247 throws InterruptedException, TmfTraceImportException, CoreException, InvocationTargetException {
248 SubMonitor subMonitor = SubMonitor.convert(monitor, fileSystemElements.size());
249
250 ListIterator<TraceFileSystemElement> fileSystemElementsIter = fileSystemElements.listIterator();
251
252 // Map to remember already imported directory traces
253 final Map<String, TraceFileSystemElement> directoryTraces = new HashMap<>();
254 while (fileSystemElementsIter.hasNext()) {
255 ModalContext.checkCanceled(monitor);
256 fCurrentPath = null;
257 TraceFileSystemElement element = fileSystemElementsIter.next();
258 IFileSystemObject fileSystemObject = element.getFileSystemObject();
259 String resourcePath = element.getFileSystemObject().getAbsolutePath();
260 element.setDestinationContainerPath(computeDestinationContainerPath(new Path(resourcePath)));
261
262 fCurrentPath = resourcePath;
263 SubMonitor sub = subMonitor.newChild(1);
264 if (element.isDirectory()) {
265 if (!directoryTraces.containsKey(resourcePath) && isDirectoryTrace(element)) {
266 directoryTraces.put(resourcePath, element);
267 validateAndImportTrace(element, sub);
268 }
269 } else {
270 TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent();
271 String parentPath = parentElement.getFileSystemObject().getAbsolutePath();
272 parentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath)));
273 fCurrentPath = parentPath;
274 if (!directoryTraces.containsKey(parentPath)) {
275 if (isDirectoryTrace(parentElement)) {
276 directoryTraces.put(parentPath, parentElement);
277 validateAndImportTrace(parentElement, sub);
278 } else {
279 boolean validateFile = true;
280 TraceFileSystemElement grandParentElement = (TraceFileSystemElement) parentElement.getParent();
281 // Special case for LTTng trace that may contain index
282 // directory and files
283 if (grandParentElement != null) {
284 String grandParentPath = grandParentElement.getFileSystemObject().getAbsolutePath();
285 grandParentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath)));
286 fCurrentPath = grandParentPath;
287 if (directoryTraces.containsKey(grandParentPath)) {
288 validateFile = false;
289 } else if (isDirectoryTrace(grandParentElement)) {
290 directoryTraces.put(grandParentPath, grandParentElement);
291 validateAndImportTrace(grandParentElement, sub);
292 validateFile = false;
293 }
294 }
295 if (validateFile && (fileSystemObject.exists())) {
296 validateAndImportTrace(element, sub);
297 }
298 }
299 }
300 }
301 }
302 }
303
304 /**
305 * Generate a new list of file system elements for the specified folder.
306 */
307 private static List<TraceFileSystemElement> createElementsForFolder(IFolder folder) {
308 // Create the new import provider and root element based on the
309 // specified folder
310 FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
311 IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(folder.getLocation().toOSString()));
312 TraceFileSystemElement createRootElement = TraceFileSystemElement.createRootTraceFileElement(rootElement, importStructureProvider);
313 List<TraceFileSystemElement> list = new LinkedList<>();
314 createRootElement.getAllChildren(list);
315 return list;
316 }
317
318 /**
319 * Extract all file system elements (File) to destination folder (typically
320 * workspace/TraceProject/.traceImport)
321 */
322 private void extractAllArchiveFiles(List<TraceFileSystemElement> fileSystemElements, IFolder destFolder, IPath baseSourceContainerPath, IProgressMonitor progressMonitor) throws InterruptedException, CoreException, InvocationTargetException {
323 SubMonitor subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size());
324 ListIterator<TraceFileSystemElement> fileSystemElementsIter = fileSystemElements.listIterator();
325 while (fileSystemElementsIter.hasNext()) {
326 ModalContext.checkCanceled(subMonitor);
327
328 SubMonitor elementProgress = subMonitor.newChild(1);
329 TraceFileSystemElement element = fileSystemElementsIter.next();
330 File archiveFile = (File) element.getFileSystemObject().getRawFileSystemObject();
331 boolean isArchiveFileElement = element.getFileSystemObject() instanceof FileFileSystemObject && ArchiveUtil.isArchiveFile(archiveFile);
332 if (isArchiveFileElement) {
333 elementProgress = SubMonitor.convert(elementProgress, 4);
334 IPath makeAbsolute = baseSourceContainerPath.makeAbsolute();
335 IPath relativeToSourceContainer = new Path(element.getFileSystemObject().getAbsolutePath()).makeRelativeTo(makeAbsolute);
336 IFolder folder = safeCreateExtractedFolder(destFolder, relativeToSourceContainer, elementProgress.newChild(1));
337 extractArchiveToFolder(archiveFile, folder, elementProgress.newChild(1));
338
339 // Delete original archive, we don't want to import this, just
340 // the extracted content
341 IFile fileRes = destFolder.getFile(relativeToSourceContainer);
342 fileRes.delete(true, elementProgress.newChild(1));
343 IPath newPath = destFolder.getFullPath().append(relativeToSourceContainer);
344 // Rename extracted folder (.extract) to original archive name
345 folder.move(newPath, true, elementProgress.newChild(1));
346 folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(newPath);
347
348 // Create the new import provider and root element based on
349 // the newly extracted temporary folder
350 FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
351 IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(folder.getLocation().toOSString()));
352 TraceFileSystemElement newElement = TraceFileSystemElement.createRootTraceFileElement(rootElement, importStructureProvider);
353 List<TraceFileSystemElement> extractedChildren = new ArrayList<>();
354 newElement.getAllChildren(extractedChildren);
355 extractAllArchiveFiles(extractedChildren, folder, folder.getLocation(), progressMonitor);
356 }
357 }
358 }
359
360 /**
361 * Extract a file (File) to a destination folder
362 */
363 private void extractArchiveToFolder(File sourceFile, IFolder destinationFolder, IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException {
364 Pair<IFileSystemObject, FileSystemObjectImportStructureProvider> rootObjectAndProvider = ArchiveUtil.getRootObjectAndProvider(sourceFile, fShell);
365 TraceFileSystemElement rootElement = TraceFileSystemElement.createRootTraceFileElement(rootObjectAndProvider.getFirst(), rootObjectAndProvider.getSecond());
366 List<TraceFileSystemElement> fileSystemElements = new ArrayList<>();
367 rootElement.getAllChildren(fileSystemElements);
368 extractArchiveContent(fileSystemElements.listIterator(), destinationFolder, progressMonitor);
369 rootObjectAndProvider.getSecond().dispose();
370 }
371
372 /**
373 * Safely create a folder meant to receive extracted content by making sure
374 * there is no name clash.
375 */
376 private static IFolder safeCreateExtractedFolder(IFolder destinationFolder, IPath relativeContainerRelativePath, IProgressMonitor monitor) throws CoreException {
377 SubMonitor subMonitor = SubMonitor.convert(monitor, 2);
378 IFolder extractedFolder;
379 String suffix = ""; //$NON-NLS-1$
380 int i = 2;
381 while (true) {
382 IPath fullPath = destinationFolder.getFullPath().append(relativeContainerRelativePath + ".extract" + suffix); //$NON-NLS-1$
383 IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(fullPath);
384 if (!folder.exists()) {
385 extractedFolder = folder;
386 break;
387 }
388 suffix = "(" + i + ")"; //$NON-NLS-1$//$NON-NLS-2$
389 i++;
390 }
391 subMonitor.worked(1);
392
393 TraceUtils.createFolder(extractedFolder, subMonitor.newChild(1));
394 return extractedFolder;
395 }
396
397 private void calculateSourceLocations(List<TraceFileSystemElement> fileSystemElements, String baseSourceLocation) {
398 for (TraceFileSystemElement element : fileSystemElements) {
399 IPath tempRelative = new Path(element.getFileSystemObject().getAbsolutePath()).makeRelativeTo(fBaseSourceContainerPath);
400 String sourceLocation = baseSourceLocation + tempRelative;
401 element.setSourceLocation(sourceLocation);
402
403 TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent();
404 tempRelative = new Path(parentElement.getFileSystemObject().getAbsolutePath()).makeRelativeTo(fBaseSourceContainerPath);
405 sourceLocation = baseSourceLocation + tempRelative + '/';
406 parentElement.setSourceLocation(sourceLocation);
407 }
408 }
409
410 /**
411 * Extract all file system elements (Tar, Zip elements) to destination
412 * folder (typically workspace/TraceProject/.traceImport or a subfolder of
413 * it)
414 */
415 private void extractArchiveContent(Iterator<TraceFileSystemElement> fileSystemElementsIter, IFolder tempFolder, IProgressMonitor progressMonitor) throws InterruptedException,
416 InvocationTargetException {
417 List<TraceFileSystemElement> subList = new ArrayList<>();
418 // Collect all the elements
419 while (fileSystemElementsIter.hasNext()) {
420 ModalContext.checkCanceled(progressMonitor);
421 TraceFileSystemElement element = fileSystemElementsIter.next();
422 if (element.isDirectory()) {
423 Object[] array = element.getFiles().getChildren();
424 for (int i = 0; i < array.length; i++) {
425 subList.add((TraceFileSystemElement) array[i]);
426 }
427 }
428 subList.add(element);
429 }
430
431 if (subList.isEmpty()) {
432 return;
433 }
434
435 TraceFileSystemElement root = getRootElement(subList.get(0));
436
437 ImportProvider fileSystemStructureProvider = new ImportProvider();
438
439 IOverwriteQuery myQueryImpl = new IOverwriteQuery() {
440 @Override
441 public String queryOverwrite(String file) {
442 return IOverwriteQuery.NO_ALL;
443 }
444 };
445
446 progressMonitor.setTaskName(Messages.ImportTraceWizard_ExtractImportOperationTaskName);
447 IPath containerPath = tempFolder.getFullPath();
448 ImportOperation operation = new ImportOperation(containerPath, root, fileSystemStructureProvider, myQueryImpl, subList);
449 operation.setContext(fShell);
450
451 operation.setCreateContainerStructure(true);
452 operation.setOverwriteResources(false);
453 operation.setVirtualFolders(false);
454
455 operation.run(SubMonitor.convert(progressMonitor).newChild(subList.size()));
456 }
457
458 private static TraceFileSystemElement getRootElement(TraceFileSystemElement element) {
459 TraceFileSystemElement root = element;
460 while (root.getParent() != null) {
461 root = (TraceFileSystemElement) root.getParent();
462 }
463 return root;
464 }
465
466 private IPath computeDestinationContainerPath(Path resourcePath) {
467 IPath destinationContainerPath = fDestinationContainerPath;
468
469 // We need to figure out the new destination path relative to the
470 // selected "base" source directory.
471 // Here for example, the selected source directory is /home/user
472 if ((fImportOptionFlags & ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) {
473 // /home/user/bar/foo/trace -> /home/user/bar/foo
474 IPath sourceContainerPath = resourcePath.removeLastSegments(1);
475 if (fBaseSourceContainerPath.equals(resourcePath)) {
476 // Use resourcePath directory if fBaseSourceContainerPath
477 // points to a directory trace
478 sourceContainerPath = resourcePath;
479 }
480 // /home/user/bar/foo, /home/user -> bar/foo
481 IPath relativeContainerPath = sourceContainerPath.makeRelativeTo(fBaseSourceContainerPath);
482 // project/Traces + bar/foo -> project/Traces/bar/foo
483 destinationContainerPath = fDestinationContainerPath.append(relativeContainerPath);
484 }
485 return destinationContainerPath;
486 }
487
488 /**
489 * Import a single file system element into the workspace.
490 */
491 private void validateAndImportTrace(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor)
492 throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException {
493 String path = fileSystemElement.getFileSystemObject().getAbsolutePath();
494 TraceTypeHelper traceTypeHelper = null;
495
496 File file = (File) fileSystemElement.getFileSystemObject().getRawFileSystemObject();
497 boolean isArchiveFileElement = fileSystemElement.getFileSystemObject() instanceof FileFileSystemObject && ArchiveUtil.isArchiveFile(file);
498 if (isArchiveFileElement) {
499 // We'll be extracting this later, do not import as a trace
500 return;
501 }
502
503 if (fTraceType == null) {
504 // Auto Detection
505 try {
506 traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(path, null, null);
507 } catch (TmfTraceImportException e) {
508 // the trace did not match any trace type
509 }
510 if (traceTypeHelper == null) {
511 if ((fImportOptionFlags & ImportTraceWizardPage.OPTION_IMPORT_UNRECOGNIZED_TRACES) != 0) {
512 importResource(fileSystemElement, monitor);
513 }
514 return;
515 }
516 } else {
517 boolean isDirectoryTraceType = TmfTraceType.isDirectoryTraceType(fTraceType);
518 if (fileSystemElement.isDirectory() != isDirectoryTraceType) {
519 return;
520 }
521 traceTypeHelper = TmfTraceType.getTraceType(fTraceType);
522
523 if (traceTypeHelper == null) {
524 // Trace type not found
525 throw new TmfTraceImportException(Messages.ImportTraceWizard_TraceTypeNotFound);
526 }
527
528 if (!traceTypeHelper.validate(path).isOK()) {
529 // Trace type exist but doesn't validate for given trace.
530 return;
531 }
532 }
533
534 // Finally import trace
535 IResource importedResource = importResource(fileSystemElement, monitor);
536 if (importedResource != null) {
537 TmfTraceTypeUIUtils.setTraceType(importedResource, traceTypeHelper, false);
538 fImportedResources.add(importedResource);
539 }
540
541 }
542
543 /**
544 * Imports a trace resource to project. In case of name collision the user
545 * will be asked to confirm overwriting the existing trace, overwriting or
546 * skipping the trace to be imported.
547 *
548 * @param fileSystemElement
549 * trace file system object to import
550 * @param monitor
551 * a progress monitor
552 * @return the imported resource or null if no resource was imported
553 *
554 * @throws InvocationTargetException
555 * if problems during import operation
556 * @throws InterruptedException
557 * if cancelled
558 * @throws CoreException
559 * if problems with workspace
560 */
561 private IResource importResource(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor)
562 throws InvocationTargetException, InterruptedException, CoreException {
563
564 IPath tracePath = getInitialDestinationPath(fileSystemElement);
565 String newName = fConflictHandler.checkAndHandleNameClash(tracePath, monitor);
566
567 if (newName == null) {
568 return null;
569 }
570 fileSystemElement.setLabel(newName);
571
572 List<TraceFileSystemElement> subList = new ArrayList<>();
573
574 FileSystemElement parentFolder = fileSystemElement.getParent();
575
576 IPath containerPath = fileSystemElement.getDestinationContainerPath();
577 tracePath = containerPath.addTrailingSeparator().append(fileSystemElement.getLabel());
578 boolean createLinksInWorkspace = (fImportOptionFlags & ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE) != 0;
579 if (fileSystemElement.isDirectory() && !createLinksInWorkspace) {
580 containerPath = tracePath;
581
582 Object[] array = fileSystemElement.getFiles().getChildren();
583 for (int i = 0; i < array.length; i++) {
584 subList.add((TraceFileSystemElement) array[i]);
585 }
586 parentFolder = fileSystemElement;
587
588 } else {
589 if (!fileSystemElement.isDirectory()) {
590 // File traces
591 IFileInfo info = EFS.getStore(new File(fileSystemElement.getFileSystemObject().getAbsolutePath()).toURI()).fetchInfo();
592 if (info.getLength() == 0) {
593 // Don't import empty traces
594 return null;
595 }
596 }
597 subList.add(fileSystemElement);
598 }
599
600 ImportProvider fileSystemStructureProvider = new ImportProvider();
601
602 IOverwriteQuery myQueryImpl = new IOverwriteQuery() {
603 @Override
604 public String queryOverwrite(String file) {
605 return IOverwriteQuery.NO_ALL;
606 }
607 };
608
609 monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + fileSystemElement.getFileSystemObject().getAbsolutePath()); //$NON-NLS-1$
610 ImportOperation operation = new ImportOperation(containerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList);
611 operation.setContext(fShell);
612
613 operation.setCreateContainerStructure(false);
614 operation.setOverwriteResources(false);
615 operation.setCreateLinks(createLinksInWorkspace);
616 operation.setVirtualFolders(false);
617
618 operation.run(SubMonitor.convert(monitor).newChild(1));
619 String sourceLocation = fileSystemElement.getSourceLocation();
620 IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(tracePath);
621 if ((sourceLocation != null) && (resource != null)) {
622 resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation);
623 }
624
625 return resource;
626 }
627
628 private static boolean isDirectoryTrace(TraceFileSystemElement fileSystemElement) {
629 String path = fileSystemElement.getFileSystemObject().getAbsolutePath();
630 if (TmfTraceType.isDirectoryTrace(path)) {
631 return true;
632 }
633 return false;
634 }
635
636 /**
637 * @return the initial destination path, before rename, if any
638 */
639 private static IPath getInitialDestinationPath(TraceFileSystemElement fileSystemElement) {
640 IPath traceFolderPath = fileSystemElement.getDestinationContainerPath();
641 return traceFolderPath.append(fileSystemElement.getFileSystemObject().getName());
642 }
643
644 /**
645 * Set the status for this operation
646 *
647 * @param status
648 * the status
649 */
650 private void setStatus(IStatus status) {
651 fStatus = status;
652 }
653
654 /**
655 * Get the resulting status of this operation. Clients can use this for
656 * error reporting, etc.
657 *
658 * @return the resulting status
659 */
660 public IStatus getStatus() {
661 return fStatus;
662 }
663
664 private class ImportProvider implements IImportStructureProvider {
665
666 ImportProvider() {
667 }
668
669 @Override
670 public String getLabel(Object element) {
671 TraceFileSystemElement resource = (TraceFileSystemElement) element;
672 return resource.getLabel();
673 }
674
675 @Override
676 public List getChildren(Object element) {
677 TraceFileSystemElement resource = (TraceFileSystemElement) element;
678 return Arrays.asList(resource.getFiles().getChildren());
679 }
680
681 @Override
682 public InputStream getContents(Object element) {
683 TraceFileSystemElement resource = (TraceFileSystemElement) element;
684 return resource.getProvider().getContents(resource.getFileSystemObject());
685 }
686
687 @Override
688 public String getFullPath(Object element) {
689 TraceFileSystemElement resource = (TraceFileSystemElement) element;
690 return resource.getProvider().getFullPath(resource.getFileSystemObject());
691 }
692
693 @Override
694 public boolean isFolder(Object element) {
695 TraceFileSystemElement resource = (TraceFileSystemElement) element;
696 return resource.isDirectory();
697 }
698 }
699
700 /**
701 * Sets the conflict handler
702 *
703 * @param conflictHandler
704 * the conflict handler
705 */
706 public void setConflictHandler(ImportConflictHandler conflictHandler) {
707 fConflictHandler = conflictHandler;
708 }
709 }
This page took 0.056751 seconds and 4 git commands to generate.