1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
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
10 * Marc-Andre Laperle - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.wizards
.importtrace
;
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
.Comparator
;
21 import java
.util
.HashMap
;
22 import java
.util
.Iterator
;
23 import java
.util
.LinkedList
;
24 import java
.util
.List
;
25 import java
.util
.ListIterator
;
28 import org
.eclipse
.core
.filesystem
.EFS
;
29 import org
.eclipse
.core
.filesystem
.IFileInfo
;
30 import org
.eclipse
.core
.resources
.IFile
;
31 import org
.eclipse
.core
.resources
.IFolder
;
32 import org
.eclipse
.core
.resources
.IResource
;
33 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
34 import org
.eclipse
.core
.runtime
.CoreException
;
35 import org
.eclipse
.core
.runtime
.IPath
;
36 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
37 import org
.eclipse
.core
.runtime
.IStatus
;
38 import org
.eclipse
.core
.runtime
.Path
;
39 import org
.eclipse
.core
.runtime
.Status
;
40 import org
.eclipse
.core
.runtime
.SubMonitor
;
41 import org
.eclipse
.core
.runtime
.URIUtil
;
42 import org
.eclipse
.jface
.operation
.ModalContext
;
43 import org
.eclipse
.swt
.widgets
.Shell
;
44 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
45 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.operations
.TmfWorkspaceModifyOperation
;
46 import org
.eclipse
.tracecompass
.tmf
.core
.TmfCommonConstants
;
47 import org
.eclipse
.tracecompass
.tmf
.core
.project
.model
.TmfTraceImportException
;
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
.util
.Pair
;
51 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceFolder
;
52 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceTypeUIUtils
;
53 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TraceUtils
;
54 import org
.eclipse
.ui
.dialogs
.FileSystemElement
;
55 import org
.eclipse
.ui
.dialogs
.IOverwriteQuery
;
56 import org
.eclipse
.ui
.wizards
.datatransfer
.FileSystemStructureProvider
;
57 import org
.eclipse
.ui
.wizards
.datatransfer
.IImportStructureProvider
;
58 import org
.eclipse
.ui
.wizards
.datatransfer
.ImportOperation
;
61 * An operation that performs validation and importing of traces. Its primary
62 * inputs are a collection of TraceFileSystemElement and several flags that
66 public class TraceValidateAndImportOperation
extends TmfWorkspaceModifyOperation
{
68 private static final String TRACE_IMPORT_TEMP_FOLDER
= ".traceImport"; //$NON-NLS-1$
70 private String fTraceType
;
71 private IPath fDestinationContainerPath
;
72 private IPath fBaseSourceContainerPath
;
73 private boolean fImportFromArchive
;
74 private int fImportOptionFlags
;
76 private TmfTraceFolder fTraceFolderElement
;
77 private List
<TraceFileSystemElement
> fSelectedFileSystemElements
;
79 private IStatus fStatus
;
80 private ImportConflictHandler fConflictHandler
;
81 private String fCurrentPath
;
83 private List
<IResource
> fImportedResources
;
86 * Constructs a new validate and import operation.
89 * the parent shell to use for possible error messages
90 * @param traceFileSystemElements
91 * the trace file elements to import
93 * the trace type to import the traces as (can be set to null for
94 * automatic detection)
95 * @param baseSourceContainerPath
96 * the path to the container of the source. This is used as a
97 * "base" to generate the folder structure for the
98 * "preserve folder structure" option.
99 * @param destinationContainerPath
100 * the destination path of the import operation, typically a
102 * @param importFromArchive
103 * whether or not the source is an archive
104 * @param importOptionFlags
105 * bit-wise 'or' of import option flag constants (
106 * {@link ImportTraceWizardPage#OPTION_PRESERVE_FOLDER_STRUCTURE}
108 * {@link ImportTraceWizardPage#OPTION_CREATE_LINKS_IN_WORKSPACE}
110 * {@link ImportTraceWizardPage#OPTION_IMPORT_UNRECOGNIZED_TRACES}
112 * {@link ImportTraceWizardPage#OPTION_OVERWRITE_EXISTING_RESOURCES}
114 * @param traceFolderElement
115 * the destination trace folder of the import operation.
117 public TraceValidateAndImportOperation(Shell shell
, List
<TraceFileSystemElement
> traceFileSystemElements
, String traceId
, IPath baseSourceContainerPath
, IPath destinationContainerPath
, boolean importFromArchive
, int importOptionFlags
,
118 TmfTraceFolder traceFolderElement
) {
119 fTraceType
= traceId
;
120 fBaseSourceContainerPath
= baseSourceContainerPath
;
121 fDestinationContainerPath
= destinationContainerPath
;
122 fImportOptionFlags
= importOptionFlags
;
123 fImportFromArchive
= importFromArchive
;
125 fTraceFolderElement
= traceFolderElement
;
127 boolean overwriteExistingResources
= (importOptionFlags
& ImportTraceWizardPage
.OPTION_OVERWRITE_EXISTING_RESOURCES
) != 0;
128 if (overwriteExistingResources
) {
129 setConflictHandler(new ImportConflictHandler(fShell
, fTraceFolderElement
, ImportConfirmation
.OVERWRITE_ALL
));
131 setConflictHandler(new ImportConflictHandler(fShell
, fTraceFolderElement
, ImportConfirmation
.SKIP
));
133 fImportedResources
= new ArrayList
<>();
134 fSelectedFileSystemElements
= traceFileSystemElements
;
138 * This orders by files first then the folders. Then by lexical order.
139 * This comparator handles full paths.
140 * Example of ordering:
144 * /folderA/folderB/trace.txt
147 private final class FileObjectPathComparator
implements Comparator
<TraceFileSystemElement
> {
149 public int compare(TraceFileSystemElement e1
, TraceFileSystemElement e2
) {
150 IFileSystemObject o1
= e1
.getFileSystemObject();
151 IFileSystemObject o2
= e2
.getFileSystemObject();
152 IPath p1
= new Path(e1
.getProvider().getFullPath(o1
));
153 IPath p2
= new Path(e2
.getProvider().getFullPath(o2
));
154 int segmentCount1
= p1
.segmentCount();
155 int segmentCount2
= p2
.segmentCount();
157 int commonParentSegmentCount
= Math
.min(segmentCount1
, segmentCount2
) - 1;
158 // Compare parents that are common (in terms of segment number).
159 // If one of them is different, we do not need to worry about any
160 // children, we already know in which order they are going to be.
161 for (int i
= 0; i
< commonParentSegmentCount
; i
++) {
162 int compare
= p1
.segment(i
).compareToIgnoreCase(p2
.segment(i
));
168 // At this point, we know all the common parent folders are the same.
170 // - One of them is shorter which means it should be processed first because files are processed before sub-folders.
172 // - They are the same level so only the name matters.
173 if (segmentCount1
!= segmentCount2
) {
174 return Integer
.compare(segmentCount1
, segmentCount2
);
178 return o1
.getName().compareToIgnoreCase(o2
.getName());
183 protected void execute(IProgressMonitor progressMonitor
) throws CoreException
, InvocationTargetException
, InterruptedException
{
185 final int ARCHIVE_OR_DIRECTORY_PROGRESS
= 45;
186 final int EXTRA_IMPORT_OPERATION_PROGRESS
= 45;
187 final int DELETE_PROGRESS
= 10;
188 final int TOTAL_PROGRESS
= ARCHIVE_OR_DIRECTORY_PROGRESS
+
189 EXTRA_IMPORT_OPERATION_PROGRESS
+ DELETE_PROGRESS
;
191 final List
<TraceFileSystemElement
> selectedFileSystemElements
= fSelectedFileSystemElements
;
193 // List fileSystemElements will be filled using the
195 SubMonitor subMonitor
= SubMonitor
.convert(progressMonitor
, TOTAL_PROGRESS
);
197 // Check if operation was cancelled.
198 ModalContext
.checkCanceled(subMonitor
);
200 // Temporary directory to contain any extracted files
201 IFolder destTempFolder
= fTraceFolderElement
.getProject().getResource().getFolder(TRACE_IMPORT_TEMP_FOLDER
);
202 if (destTempFolder
.exists()) {
203 SubMonitor monitor
= subMonitor
.newChild(1);
204 destTempFolder
.delete(true, monitor
);
206 SubMonitor monitor
= subMonitor
.newChild(1);
207 destTempFolder
.create(IResource
.HIDDEN
, true, monitor
);
209 String baseSourceLocation
= null;
210 if (fImportFromArchive
) {
211 // When importing from archive, we first extract the
212 // *selected* files to a temporary folder then create new
213 // TraceFileSystemElements
215 SubMonitor archiveMonitor
= SubMonitor
.convert(subMonitor
.newChild(ARCHIVE_OR_DIRECTORY_PROGRESS
), 2);
217 // Extract selected files from source archive to temporary
219 extractArchiveContent(selectedFileSystemElements
.iterator(), destTempFolder
, archiveMonitor
.newChild(1));
221 if (!selectedFileSystemElements
.isEmpty()) {
222 // Even if the files were extracted to temporary folder, they
223 // have to look like they originate from the source archive
224 baseSourceLocation
= getRootElement(selectedFileSystemElements
.get(0)).getSourceLocation();
225 // Extract additional archives contained in the extracted files
226 // (archives in archives)
227 List
<TraceFileSystemElement
> tempFolderFileSystemElements
= createElementsForFolder(destTempFolder
);
228 extractAllArchiveFiles(tempFolderFileSystemElements
, destTempFolder
, destTempFolder
.getLocation(), archiveMonitor
.newChild(1));
231 SubMonitor directoryMonitor
= SubMonitor
.convert(subMonitor
.newChild(ARCHIVE_OR_DIRECTORY_PROGRESS
), 2);
232 // Import selected files, excluding archives (done in a later step)
233 importFileSystemElements(directoryMonitor
.newChild(1), selectedFileSystemElements
);
235 // Extract archives in selected files (if any) to temporary folder
236 extractAllArchiveFiles(selectedFileSystemElements
, destTempFolder
, fBaseSourceContainerPath
, directoryMonitor
.newChild(1));
237 // Even if the files were extracted to temporary folder, they
238 // have to look like they originate from the source folder
239 baseSourceLocation
= URIUtil
.toUnencodedString(fBaseSourceContainerPath
.toFile().getCanonicalFile().toURI());
243 * Import extracted files that are now in the temporary folder, if any
246 // We need to update the source container path because the
247 // "preserve folder structure" option would create the
248 // wrong trace folders otherwise.
249 fBaseSourceContainerPath
= destTempFolder
.getLocation();
250 List
<TraceFileSystemElement
> tempFolderFileSystemElements
= createElementsForFolder(destTempFolder
);
251 if (!tempFolderFileSystemElements
.isEmpty()) {
252 calculateSourceLocations(tempFolderFileSystemElements
, baseSourceLocation
);
253 // Never import extracted files as links, they would link to the
254 // temporary directory that will be deleted
255 fImportOptionFlags
= fImportOptionFlags
& ~ImportTraceWizardPage
.OPTION_CREATE_LINKS_IN_WORKSPACE
;
256 SubMonitor importTempMonitor
= subMonitor
.newChild(EXTRA_IMPORT_OPERATION_PROGRESS
);
257 importFileSystemElements(importTempMonitor
, tempFolderFileSystemElements
);
260 if (destTempFolder
.exists()) {
261 destTempFolder
.delete(true, subMonitor
.newChild(TOTAL_PROGRESS
));
264 setStatus(Status
.OK_STATUS
);
265 } catch (InterruptedException e
) {
266 setStatus(Status
.CANCEL_STATUS
);
267 } catch (Exception e
) {
268 String errorMessage
= Messages
.ImportTraceWizard_ImportProblem
+ ": " + //$NON-NLS-1$
269 (fCurrentPath
!= null ? fCurrentPath
: ""); //$NON-NLS-1$
270 Activator
.getDefault().logError(errorMessage
, e
);
271 setStatus(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, errorMessage
, e
));
276 * Get the list of resources that were imported by this operation. An
277 * example use case would be to use this to open traces that were imported
280 * Note this includes only valid traces and doesn'tinclude unrecognized
283 * @return the trace resources that were imported
285 public List
<IResource
> getImportedResources() {
286 return fImportedResources
;
290 * Import a collection of file system elements into the workspace.
292 private void importFileSystemElements(IProgressMonitor monitor
, List
<TraceFileSystemElement
> fileSystemElements
)
293 throws InterruptedException
, TmfTraceImportException
, CoreException
, InvocationTargetException
{
294 SubMonitor subMonitor
= SubMonitor
.convert(monitor
, fileSystemElements
.size());
295 // Sort the elements in a sensible order to make it more predictable to
296 // the user when there can be name clashes. Otherwise, the order can
297 // seem pretty random depending on the OS/Filesystem.
298 fileSystemElements
.sort(new FileObjectPathComparator());
300 ListIterator
<TraceFileSystemElement
> fileSystemElementsIter
= fileSystemElements
.listIterator();
302 // Map to remember already imported directory traces
303 final Map
<String
, TraceFileSystemElement
> directoryTraces
= new HashMap
<>();
304 while (fileSystemElementsIter
.hasNext()) {
305 ModalContext
.checkCanceled(monitor
);
307 TraceFileSystemElement element
= fileSystemElementsIter
.next();
308 IFileSystemObject fileSystemObject
= element
.getFileSystemObject();
309 String resourcePath
= element
.getFileSystemObject().getAbsolutePath();
310 element
.setDestinationContainerPath(computeDestinationContainerPath(new Path(resourcePath
)));
312 fCurrentPath
= resourcePath
;
313 SubMonitor sub
= subMonitor
.newChild(1);
314 if (element
.isDirectory()) {
315 if (!directoryTraces
.containsKey(resourcePath
) && isDirectoryTrace(element
)) {
316 directoryTraces
.put(resourcePath
, element
);
317 validateAndImportTrace(element
, sub
);
320 TraceFileSystemElement parentElement
= (TraceFileSystemElement
) element
.getParent();
321 String parentPath
= parentElement
.getFileSystemObject().getAbsolutePath();
322 parentElement
.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath
)));
323 fCurrentPath
= parentPath
;
324 if (!directoryTraces
.containsKey(parentPath
)) {
325 if (isDirectoryTrace(parentElement
)) {
326 directoryTraces
.put(parentPath
, parentElement
);
327 validateAndImportTrace(parentElement
, sub
);
329 boolean validateFile
= true;
330 TraceFileSystemElement grandParentElement
= (TraceFileSystemElement
) parentElement
.getParent();
331 // Special case for LTTng trace that may contain index
332 // directory and files
333 if (grandParentElement
!= null) {
334 String grandParentPath
= grandParentElement
.getFileSystemObject().getAbsolutePath();
335 grandParentElement
.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath
)));
336 fCurrentPath
= grandParentPath
;
337 if (directoryTraces
.containsKey(grandParentPath
)) {
338 validateFile
= false;
339 } else if (isDirectoryTrace(grandParentElement
)) {
340 directoryTraces
.put(grandParentPath
, grandParentElement
);
341 validateAndImportTrace(grandParentElement
, sub
);
342 validateFile
= false;
345 if (validateFile
&& (fileSystemObject
.exists())) {
346 validateAndImportTrace(element
, sub
);
355 * Generate a new list of file system elements for the specified folder.
357 private static List
<TraceFileSystemElement
> createElementsForFolder(IFolder folder
) {
358 // Create the new import provider and root element based on the
360 FileSystemObjectImportStructureProvider importStructureProvider
= new FileSystemObjectImportStructureProvider(FileSystemStructureProvider
.INSTANCE
, null);
361 IFileSystemObject rootElement
= importStructureProvider
.getIFileSystemObject(new File(folder
.getLocation().toOSString()));
362 TraceFileSystemElement createRootElement
= TraceFileSystemElement
.createRootTraceFileElement(rootElement
, importStructureProvider
);
363 List
<TraceFileSystemElement
> list
= new LinkedList
<>();
364 createRootElement
.getAllChildren(list
);
369 * Extract all file system elements (File) to destination folder (typically
370 * workspace/TraceProject/.traceImport)
372 private void extractAllArchiveFiles(List
<TraceFileSystemElement
> fileSystemElements
, IFolder destFolder
, IPath baseSourceContainerPath
, IProgressMonitor progressMonitor
) throws InterruptedException
, CoreException
, InvocationTargetException
{
373 SubMonitor subMonitor
= SubMonitor
.convert(progressMonitor
, fileSystemElements
.size());
374 ListIterator
<TraceFileSystemElement
> fileSystemElementsIter
= fileSystemElements
.listIterator();
375 while (fileSystemElementsIter
.hasNext()) {
376 ModalContext
.checkCanceled(subMonitor
);
378 SubMonitor elementProgress
= subMonitor
.newChild(1);
379 TraceFileSystemElement element
= fileSystemElementsIter
.next();
380 File archiveFile
= (File
) element
.getFileSystemObject().getRawFileSystemObject();
381 boolean isArchiveFileElement
= element
.getFileSystemObject() instanceof FileFileSystemObject
&& ArchiveUtil
.isArchiveFile(archiveFile
);
382 if (isArchiveFileElement
) {
383 elementProgress
= SubMonitor
.convert(elementProgress
, 4);
384 IPath makeAbsolute
= baseSourceContainerPath
.makeAbsolute();
385 IPath relativeToSourceContainer
= new Path(element
.getFileSystemObject().getAbsolutePath()).makeRelativeTo(makeAbsolute
);
386 IFolder folder
= safeCreateExtractedFolder(destFolder
, relativeToSourceContainer
, elementProgress
.newChild(1));
387 extractArchiveToFolder(archiveFile
, folder
, elementProgress
.newChild(1));
389 // Delete original archive, we don't want to import this, just
390 // the extracted content
391 IFile fileRes
= destFolder
.getFile(relativeToSourceContainer
);
392 fileRes
.delete(true, elementProgress
.newChild(1));
393 IPath newPath
= destFolder
.getFullPath().append(relativeToSourceContainer
);
394 // Rename extracted folder (.extract) to original archive name
395 folder
.move(newPath
, true, elementProgress
.newChild(1));
396 folder
= ResourcesPlugin
.getWorkspace().getRoot().getFolder(newPath
);
398 // Create the new import provider and root element based on
399 // the newly extracted temporary folder
400 FileSystemObjectImportStructureProvider importStructureProvider
= new FileSystemObjectImportStructureProvider(FileSystemStructureProvider
.INSTANCE
, null);
401 IFileSystemObject rootElement
= importStructureProvider
.getIFileSystemObject(new File(folder
.getLocation().toOSString()));
402 TraceFileSystemElement newElement
= TraceFileSystemElement
.createRootTraceFileElement(rootElement
, importStructureProvider
);
403 List
<TraceFileSystemElement
> extractedChildren
= new ArrayList
<>();
404 newElement
.getAllChildren(extractedChildren
);
405 extractAllArchiveFiles(extractedChildren
, folder
, folder
.getLocation(), progressMonitor
);
411 * Extract a file (File) to a destination folder
413 private void extractArchiveToFolder(File sourceFile
, IFolder destinationFolder
, IProgressMonitor progressMonitor
) throws InvocationTargetException
, InterruptedException
{
414 Pair
<IFileSystemObject
, FileSystemObjectImportStructureProvider
> rootObjectAndProvider
= ArchiveUtil
.getRootObjectAndProvider(sourceFile
, fShell
);
415 TraceFileSystemElement rootElement
= TraceFileSystemElement
.createRootTraceFileElement(rootObjectAndProvider
.getFirst(), rootObjectAndProvider
.getSecond());
416 List
<TraceFileSystemElement
> fileSystemElements
= new ArrayList
<>();
417 rootElement
.getAllChildren(fileSystemElements
);
418 extractArchiveContent(fileSystemElements
.listIterator(), destinationFolder
, progressMonitor
);
419 rootObjectAndProvider
.getSecond().dispose();
423 * Safely create a folder meant to receive extracted content by making sure
424 * there is no name clash.
426 private static IFolder
safeCreateExtractedFolder(IFolder destinationFolder
, IPath relativeContainerRelativePath
, IProgressMonitor monitor
) throws CoreException
{
427 SubMonitor subMonitor
= SubMonitor
.convert(monitor
, 2);
428 IFolder extractedFolder
;
429 String suffix
= ""; //$NON-NLS-1$
432 IPath fullPath
= destinationFolder
.getFullPath().append(relativeContainerRelativePath
+ ".extract" + suffix
); //$NON-NLS-1$
433 IFolder folder
= ResourcesPlugin
.getWorkspace().getRoot().getFolder(fullPath
);
434 if (!folder
.exists()) {
435 extractedFolder
= folder
;
438 suffix
= "(" + i
+ ")"; //$NON-NLS-1$//$NON-NLS-2$
441 subMonitor
.worked(1);
443 TraceUtils
.createFolder(extractedFolder
, subMonitor
.newChild(1));
444 return extractedFolder
;
447 private void calculateSourceLocations(List
<TraceFileSystemElement
> fileSystemElements
, String baseSourceLocation
) {
448 for (TraceFileSystemElement element
: fileSystemElements
) {
449 IPath tempRelative
= new Path(element
.getFileSystemObject().getAbsolutePath()).makeRelativeTo(fBaseSourceContainerPath
);
450 String sourceLocation
= baseSourceLocation
+ tempRelative
;
451 element
.setSourceLocation(sourceLocation
);
453 TraceFileSystemElement parentElement
= (TraceFileSystemElement
) element
.getParent();
454 tempRelative
= new Path(parentElement
.getFileSystemObject().getAbsolutePath()).makeRelativeTo(fBaseSourceContainerPath
);
455 sourceLocation
= baseSourceLocation
+ tempRelative
+ '/';
456 parentElement
.setSourceLocation(sourceLocation
);
461 * Extract all file system elements (Tar, Zip elements) to destination
462 * folder (typically workspace/TraceProject/.traceImport or a subfolder of
465 private void extractArchiveContent(Iterator
<TraceFileSystemElement
> fileSystemElementsIter
, IFolder tempFolder
, IProgressMonitor progressMonitor
) throws InterruptedException
,
466 InvocationTargetException
{
467 List
<TraceFileSystemElement
> subList
= new ArrayList
<>();
468 // Collect all the elements
469 while (fileSystemElementsIter
.hasNext()) {
470 ModalContext
.checkCanceled(progressMonitor
);
471 TraceFileSystemElement element
= fileSystemElementsIter
.next();
472 if (element
.isDirectory()) {
473 Object
[] array
= element
.getFiles().getChildren();
474 for (int i
= 0; i
< array
.length
; i
++) {
475 subList
.add((TraceFileSystemElement
) array
[i
]);
478 subList
.add(element
);
481 if (subList
.isEmpty()) {
485 TraceFileSystemElement root
= getRootElement(subList
.get(0));
487 ImportProvider fileSystemStructureProvider
= new ImportProvider();
489 IOverwriteQuery myQueryImpl
= new IOverwriteQuery() {
491 public String
queryOverwrite(String file
) {
492 return IOverwriteQuery
.NO_ALL
;
496 progressMonitor
.setTaskName(Messages
.ImportTraceWizard_ExtractImportOperationTaskName
);
497 IPath containerPath
= tempFolder
.getFullPath();
498 ImportOperation operation
= new ImportOperation(containerPath
, root
, fileSystemStructureProvider
, myQueryImpl
, subList
);
499 operation
.setContext(fShell
);
501 operation
.setCreateContainerStructure(true);
502 operation
.setOverwriteResources(false);
503 operation
.setVirtualFolders(false);
505 operation
.run(SubMonitor
.convert(progressMonitor
).newChild(subList
.size()));
508 private static TraceFileSystemElement
getRootElement(TraceFileSystemElement element
) {
509 TraceFileSystemElement root
= element
;
510 while (root
.getParent() != null) {
511 root
= (TraceFileSystemElement
) root
.getParent();
516 private IPath
computeDestinationContainerPath(Path resourcePath
) {
517 IPath destinationContainerPath
= fDestinationContainerPath
;
519 // We need to figure out the new destination path relative to the
520 // selected "base" source directory.
521 // Here for example, the selected source directory is /home/user
522 if ((fImportOptionFlags
& ImportTraceWizardPage
.OPTION_PRESERVE_FOLDER_STRUCTURE
) != 0) {
523 // /home/user/bar/foo/trace -> /home/user/bar/foo
524 IPath sourceContainerPath
= resourcePath
.removeLastSegments(1);
525 if (fBaseSourceContainerPath
.equals(resourcePath
)) {
526 // Use resourcePath directory if fBaseSourceContainerPath
527 // points to a directory trace
528 sourceContainerPath
= resourcePath
;
530 // /home/user/bar/foo, /home/user -> bar/foo
531 IPath relativeContainerPath
= sourceContainerPath
.makeRelativeTo(fBaseSourceContainerPath
);
532 // project/Traces + bar/foo -> project/Traces/bar/foo
533 destinationContainerPath
= fDestinationContainerPath
.append(relativeContainerPath
);
535 return destinationContainerPath
;
539 * Import a single file system element into the workspace.
541 private void validateAndImportTrace(TraceFileSystemElement fileSystemElement
, IProgressMonitor monitor
)
542 throws TmfTraceImportException
, CoreException
, InvocationTargetException
, InterruptedException
{
543 String path
= fileSystemElement
.getFileSystemObject().getAbsolutePath();
544 TraceTypeHelper traceTypeHelper
= null;
546 File file
= (File
) fileSystemElement
.getFileSystemObject().getRawFileSystemObject();
547 boolean isArchiveFileElement
= fileSystemElement
.getFileSystemObject() instanceof FileFileSystemObject
&& ArchiveUtil
.isArchiveFile(file
);
548 if (isArchiveFileElement
) {
549 // We'll be extracting this later, do not import as a trace
553 if (fTraceType
== null) {
556 traceTypeHelper
= TmfTraceTypeUIUtils
.selectTraceType(path
, null, null);
557 } catch (TmfTraceImportException e
) {
558 // the trace did not match any trace type
560 if (traceTypeHelper
== null) {
561 if ((fImportOptionFlags
& ImportTraceWizardPage
.OPTION_IMPORT_UNRECOGNIZED_TRACES
) != 0) {
562 importResource(fileSystemElement
, monitor
);
567 boolean isDirectoryTraceType
= TmfTraceType
.isDirectoryTraceType(fTraceType
);
568 if (fileSystemElement
.isDirectory() != isDirectoryTraceType
) {
571 traceTypeHelper
= TmfTraceType
.getTraceType(fTraceType
);
573 if (traceTypeHelper
== null) {
574 // Trace type not found
575 throw new TmfTraceImportException(Messages
.ImportTraceWizard_TraceTypeNotFound
);
578 if (!traceTypeHelper
.validate(path
).isOK()) {
579 // Trace type exist but doesn't validate for given trace.
584 // Finally import trace
585 IResource importedResource
= importResource(fileSystemElement
, monitor
);
586 if (importedResource
!= null) {
587 TmfTraceTypeUIUtils
.setTraceType(importedResource
, traceTypeHelper
, false);
588 fImportedResources
.add(importedResource
);
594 * Imports a trace resource to project. In case of name collision the user
595 * will be asked to confirm overwriting the existing trace, overwriting or
596 * skipping the trace to be imported.
598 * @param fileSystemElement
599 * trace file system object to import
602 * @return the imported resource or null if no resource was imported
604 * @throws InvocationTargetException
605 * if problems during import operation
606 * @throws InterruptedException
608 * @throws CoreException
609 * if problems with workspace
611 private IResource
importResource(TraceFileSystemElement fileSystemElement
, IProgressMonitor monitor
)
612 throws InvocationTargetException
, InterruptedException
, CoreException
{
614 IPath tracePath
= getInitialDestinationPath(fileSystemElement
);
615 String newName
= fConflictHandler
.checkAndHandleNameClash(tracePath
, monitor
);
617 if (newName
== null) {
620 fileSystemElement
.setLabel(newName
);
622 List
<TraceFileSystemElement
> subList
= new ArrayList
<>();
624 FileSystemElement parentFolder
= fileSystemElement
.getParent();
626 IPath containerPath
= fileSystemElement
.getDestinationContainerPath();
627 tracePath
= containerPath
.addTrailingSeparator().append(fileSystemElement
.getLabel());
628 boolean createLinksInWorkspace
= (fImportOptionFlags
& ImportTraceWizardPage
.OPTION_CREATE_LINKS_IN_WORKSPACE
) != 0;
629 if (fileSystemElement
.isDirectory() && !createLinksInWorkspace
) {
630 containerPath
= tracePath
;
632 Object
[] array
= fileSystemElement
.getFiles().getChildren();
633 for (int i
= 0; i
< array
.length
; i
++) {
634 subList
.add((TraceFileSystemElement
) array
[i
]);
636 parentFolder
= fileSystemElement
;
639 if (!fileSystemElement
.isDirectory()) {
641 IFileInfo info
= EFS
.getStore(new File(fileSystemElement
.getFileSystemObject().getAbsolutePath()).toURI()).fetchInfo();
642 if (info
.getLength() == 0) {
643 // Don't import empty traces
647 subList
.add(fileSystemElement
);
650 ImportProvider fileSystemStructureProvider
= new ImportProvider();
652 IOverwriteQuery myQueryImpl
= new IOverwriteQuery() {
654 public String
queryOverwrite(String file
) {
655 return IOverwriteQuery
.NO_ALL
;
659 monitor
.setTaskName(Messages
.ImportTraceWizard_ImportOperationTaskName
+ " " + fileSystemElement
.getFileSystemObject().getAbsolutePath()); //$NON-NLS-1$
660 ImportOperation operation
= new ImportOperation(containerPath
, parentFolder
, fileSystemStructureProvider
, myQueryImpl
, subList
);
661 operation
.setContext(fShell
);
663 operation
.setCreateContainerStructure(false);
664 operation
.setOverwriteResources(false);
665 operation
.setCreateLinks(createLinksInWorkspace
);
666 operation
.setVirtualFolders(false);
668 operation
.run(SubMonitor
.convert(monitor
).newChild(1));
669 String sourceLocation
= fileSystemElement
.getSourceLocation();
670 IResource resource
= ResourcesPlugin
.getWorkspace().getRoot().findMember(tracePath
);
671 if ((sourceLocation
!= null) && (resource
!= null)) {
672 resource
.setPersistentProperty(TmfCommonConstants
.SOURCE_LOCATION
, sourceLocation
);
678 private static boolean isDirectoryTrace(TraceFileSystemElement fileSystemElement
) {
679 String path
= fileSystemElement
.getFileSystemObject().getAbsolutePath();
680 if (TmfTraceType
.isDirectoryTrace(path
)) {
687 * @return the initial destination path, before rename, if any
689 private static IPath
getInitialDestinationPath(TraceFileSystemElement fileSystemElement
) {
690 IPath traceFolderPath
= fileSystemElement
.getDestinationContainerPath();
691 return traceFolderPath
.append(fileSystemElement
.getFileSystemObject().getName());
695 * Set the status for this operation
700 private void setStatus(IStatus status
) {
705 * Get the resulting status of this operation. Clients can use this for
706 * error reporting, etc.
708 * @return the resulting status
710 public IStatus
getStatus() {
714 private class ImportProvider
implements IImportStructureProvider
{
720 public String
getLabel(Object element
) {
721 TraceFileSystemElement resource
= (TraceFileSystemElement
) element
;
722 return resource
.getLabel();
726 public List
getChildren(Object element
) {
727 TraceFileSystemElement resource
= (TraceFileSystemElement
) element
;
728 return Arrays
.asList(resource
.getFiles().getChildren());
732 public InputStream
getContents(Object element
) {
733 TraceFileSystemElement resource
= (TraceFileSystemElement
) element
;
734 return resource
.getProvider().getContents(resource
.getFileSystemObject());
738 public String
getFullPath(Object element
) {
739 TraceFileSystemElement resource
= (TraceFileSystemElement
) element
;
740 return resource
.getProvider().getFullPath(resource
.getFileSystemObject());
744 public boolean isFolder(Object element
) {
745 TraceFileSystemElement resource
= (TraceFileSystemElement
) element
;
746 return resource
.isDirectory();
751 * Sets the conflict handler
753 * @param conflictHandler
754 * the conflict handler
756 public void setConflictHandler(ImportConflictHandler conflictHandler
) {
757 fConflictHandler
= conflictHandler
;