| /******************************************************************************* |
| * Copyright (c) 2015 Ericsson |
| * |
| * All rights reserved. This program and the accompanying materials are |
| * made available under the terms of the Eclipse Public License v1.0 which |
| * accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Marc-Andre Laperle - Initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace; |
| |
| import java.io.File; |
| import java.io.InputStream; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Map; |
| |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileInfo; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubMonitor; |
| import org.eclipse.core.runtime.URIUtil; |
| import org.eclipse.jface.operation.ModalContext; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.tracecompass.internal.tmf.ui.Activator; |
| import org.eclipse.tracecompass.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation; |
| import org.eclipse.tracecompass.tmf.core.TmfCommonConstants; |
| import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceImportException; |
| import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType; |
| import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper; |
| import org.eclipse.tracecompass.tmf.core.util.Pair; |
| import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder; |
| import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils; |
| import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils; |
| import org.eclipse.ui.dialogs.FileSystemElement; |
| import org.eclipse.ui.dialogs.IOverwriteQuery; |
| import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; |
| import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; |
| import org.eclipse.ui.wizards.datatransfer.ImportOperation; |
| |
| /** |
| * An operation that performs validation and importing of traces. Its primary |
| * inputs are a collection of TraceFileSystemElement and several flags that control |
| * |
| */ |
| public class TraceValidateAndImportOperation extends TmfWorkspaceModifyOperation { |
| |
| private static final String TRACE_IMPORT_TEMP_FOLDER = ".traceImport"; //$NON-NLS-1$ |
| |
| private String fTraceType; |
| private IPath fDestinationContainerPath; |
| private IPath fBaseSourceContainerPath; |
| private boolean fImportFromArchive; |
| private int fImportOptionFlags; |
| private Shell fShell; |
| private TmfTraceFolder fTraceFolderElement; |
| private List<TraceFileSystemElement> fSelectedFileSystemElements; |
| |
| private IStatus fStatus; |
| private ImportConflictHandler fConflictHandler; |
| private String fCurrentPath; |
| |
| private List<IResource> fImportedResources; |
| |
| /** |
| * Constructs a new validate and import operation. |
| * |
| * @param shell |
| * the parent shell to use for possible error messages |
| * @param traceFileSystemElements |
| * the trace file elements to import |
| * @param traceId |
| * the trace type to import the traces as (can be set to null for |
| * automatic detection) |
| * @param baseSourceContainerPath |
| * the path to the container of the source. This is used as a |
| * "base" to generate the folder structure for the |
| * "preserve folder structure" option. |
| * @param destinationContainerPath |
| * the destination path of the import operation, typically a |
| * trace folder path. |
| * @param importFromArchive |
| * whether or not the source is an archive |
| * @param importOptionFlags |
| * bit-wise 'or' of import option flag constants ( |
| * {@link ImportTraceWizardPage#OPTION_PRESERVE_FOLDER_STRUCTURE} |
| * , |
| * {@link ImportTraceWizardPage#OPTION_CREATE_LINKS_IN_WORKSPACE} |
| * , |
| * {@link ImportTraceWizardPage#OPTION_IMPORT_UNRECOGNIZED_TRACES} |
| * , and |
| * {@link ImportTraceWizardPage#OPTION_OVERWRITE_EXISTING_RESOURCES} |
| * ) |
| * @param traceFolderElement |
| * the destination trace folder of the import operation. |
| */ |
| public TraceValidateAndImportOperation(Shell shell, List<TraceFileSystemElement> traceFileSystemElements, String traceId, IPath baseSourceContainerPath, IPath destinationContainerPath, boolean importFromArchive, int importOptionFlags, TmfTraceFolder traceFolderElement) { |
| fTraceType = traceId; |
| fBaseSourceContainerPath = baseSourceContainerPath; |
| fDestinationContainerPath = destinationContainerPath; |
| fImportOptionFlags = importOptionFlags; |
| fImportFromArchive = importFromArchive; |
| fShell = shell; |
| fTraceFolderElement = traceFolderElement; |
| |
| boolean overwriteExistingResources = (importOptionFlags & ImportTraceWizardPage.OPTION_OVERWRITE_EXISTING_RESOURCES) != 0; |
| if (overwriteExistingResources) { |
| fConflictHandler = new ImportConflictHandler(fShell, fTraceFolderElement, ImportConfirmation.OVERWRITE_ALL); |
| } else { |
| fConflictHandler = new ImportConflictHandler(fShell, fTraceFolderElement, ImportConfirmation.SKIP); |
| } |
| fImportedResources = new ArrayList<>(); |
| fSelectedFileSystemElements = traceFileSystemElements; |
| } |
| |
| @Override |
| protected void execute(IProgressMonitor progressMonitor) throws CoreException, InvocationTargetException, InterruptedException { |
| try { |
| final int ARCHIVE_OR_DIRECTORY_PROGRESS = 45; |
| final int EXTRA_IMPORT_OPERATION_PROGRESS = 45; |
| final int DELETE_PROGRESS = 10; |
| final int TOTAL_PROGRESS = ARCHIVE_OR_DIRECTORY_PROGRESS + |
| EXTRA_IMPORT_OPERATION_PROGRESS + DELETE_PROGRESS; |
| |
| final List<TraceFileSystemElement> selectedFileSystemElements = fSelectedFileSystemElements; |
| |
| // List fileSystemElements will be filled using the |
| // passThroughFilter |
| SubMonitor subMonitor = SubMonitor.convert(progressMonitor, TOTAL_PROGRESS); |
| |
| // Check if operation was cancelled. |
| ModalContext.checkCanceled(subMonitor); |
| |
| // Temporary directory to contain any extracted files |
| IFolder destTempFolder = fTraceFolderElement.getProject().getResource().getFolder(TRACE_IMPORT_TEMP_FOLDER); |
| if (destTempFolder.exists()) { |
| SubMonitor monitor = subMonitor.newChild(1); |
| destTempFolder.delete(true, monitor); |
| } |
| SubMonitor monitor = subMonitor.newChild(1); |
| destTempFolder.create(IResource.HIDDEN, true, monitor); |
| |
| String baseSourceLocation = null; |
| if (fImportFromArchive) { |
| // When importing from archive, we first extract the |
| // *selected* files to a temporary folder then create new |
| // TraceFileSystemElements |
| |
| SubMonitor archiveMonitor = SubMonitor.convert(subMonitor.newChild(ARCHIVE_OR_DIRECTORY_PROGRESS), 2); |
| |
| // Extract selected files from source archive to temporary |
| // folder |
| extractArchiveContent(selectedFileSystemElements.iterator(), destTempFolder, archiveMonitor.newChild(1)); |
| |
| if (!selectedFileSystemElements.isEmpty()) { |
| // Even if the files were extracted to temporary folder, they |
| // have to look like they originate from the source archive |
| baseSourceLocation = getRootElement(selectedFileSystemElements.get(0)).getSourceLocation(); |
| // Extract additional archives contained in the extracted files |
| // (archives in archives) |
| List<TraceFileSystemElement> tempFolderFileSystemElements = createElementsForFolder(destTempFolder); |
| extractAllArchiveFiles(tempFolderFileSystemElements, destTempFolder, destTempFolder.getLocation(), archiveMonitor.newChild(1)); |
| } |
| } else { |
| SubMonitor directoryMonitor = SubMonitor.convert(subMonitor.newChild(ARCHIVE_OR_DIRECTORY_PROGRESS), 2); |
| // Import selected files, excluding archives (done in a later |
| // step) |
| importFileSystemElements(directoryMonitor.newChild(1), selectedFileSystemElements); |
| |
| // Extract archives in selected files (if any) to temporary |
| // folder |
| extractAllArchiveFiles(selectedFileSystemElements, destTempFolder, fBaseSourceContainerPath, directoryMonitor.newChild(1)); |
| // Even if the files were extracted to temporary folder, they |
| // have to look like they originate from the source folder |
| baseSourceLocation = URIUtil.toUnencodedString(fBaseSourceContainerPath.toFile().getCanonicalFile().toURI()); |
| } |
| |
| /* |
| * Import extracted files that are now in the temporary folder, if |
| * any |
| */ |
| |
| // We need to update the source container path because the |
| // "preserve folder structure" option would create the |
| // wrong trace folders otherwise. |
| fBaseSourceContainerPath = destTempFolder.getLocation(); |
| List<TraceFileSystemElement> tempFolderFileSystemElements = createElementsForFolder(destTempFolder); |
| if (!tempFolderFileSystemElements.isEmpty()) { |
| calculateSourceLocations(tempFolderFileSystemElements, baseSourceLocation); |
| // Never import extracted files as links, they would link to the |
| // temporary directory that will be deleted |
| fImportOptionFlags = fImportOptionFlags & ~ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE; |
| SubMonitor importTempMonitor = subMonitor.newChild(EXTRA_IMPORT_OPERATION_PROGRESS); |
| importFileSystemElements(importTempMonitor, tempFolderFileSystemElements); |
| } |
| |
| if (destTempFolder.exists()) { |
| destTempFolder.delete(true, subMonitor.newChild(TOTAL_PROGRESS)); |
| } |
| |
| setStatus(Status.OK_STATUS); |
| } catch (InterruptedException e) { |
| setStatus(Status.CANCEL_STATUS); |
| } catch (Exception e) { |
| String errorMessage = Messages.ImportTraceWizard_ImportProblem + ": " + //$NON-NLS-1$ |
| (fCurrentPath != null ? fCurrentPath : ""); //$NON-NLS-1$ |
| Activator.getDefault().logError(errorMessage, e); |
| setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, errorMessage, e)); |
| } |
| } |
| |
| /** |
| * Get the list of resources that were imported by this operation. An |
| * example use case would be to use this to open traces that were imported |
| * by this operation. |
| * |
| * @return the resources that were imported |
| */ |
| public List<IResource> getImportedResources() { |
| return fImportedResources; |
| } |
| |
| /** |
| * Import a collection of file system elements into the workspace. |
| */ |
| private void importFileSystemElements(IProgressMonitor monitor, List<TraceFileSystemElement> fileSystemElements) |
| throws InterruptedException, TmfTraceImportException, CoreException, InvocationTargetException { |
| SubMonitor subMonitor = SubMonitor.convert(monitor, fileSystemElements.size()); |
| |
| ListIterator<TraceFileSystemElement> fileSystemElementsIter = fileSystemElements.listIterator(); |
| |
| // Map to remember already imported directory traces |
| final Map<String, TraceFileSystemElement> directoryTraces = new HashMap<>(); |
| while (fileSystemElementsIter.hasNext()) { |
| ModalContext.checkCanceled(monitor); |
| fCurrentPath = null; |
| TraceFileSystemElement element = fileSystemElementsIter.next(); |
| IFileSystemObject fileSystemObject = element.getFileSystemObject(); |
| String resourcePath = element.getFileSystemObject().getAbsolutePath(); |
| element.setDestinationContainerPath(computeDestinationContainerPath(new Path(resourcePath))); |
| |
| fCurrentPath = resourcePath; |
| SubMonitor sub = subMonitor.newChild(1); |
| if (element.isDirectory()) { |
| if (!directoryTraces.containsKey(resourcePath) && isDirectoryTrace(element)) { |
| directoryTraces.put(resourcePath, element); |
| validateAndImportTrace(element, sub); |
| } |
| } else { |
| TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); |
| String parentPath = parentElement.getFileSystemObject().getAbsolutePath(); |
| parentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath))); |
| fCurrentPath = parentPath; |
| if (!directoryTraces.containsKey(parentPath)) { |
| if (isDirectoryTrace(parentElement)) { |
| directoryTraces.put(parentPath, parentElement); |
| validateAndImportTrace(parentElement, sub); |
| } else { |
| boolean validateFile = true; |
| TraceFileSystemElement grandParentElement = (TraceFileSystemElement) parentElement.getParent(); |
| // Special case for LTTng trace that may contain index |
| // directory and files |
| if (grandParentElement != null) { |
| String grandParentPath = grandParentElement.getFileSystemObject().getAbsolutePath(); |
| grandParentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath))); |
| fCurrentPath = grandParentPath; |
| if (directoryTraces.containsKey(grandParentPath)) { |
| validateFile = false; |
| } else if (isDirectoryTrace(grandParentElement)) { |
| directoryTraces.put(grandParentPath, grandParentElement); |
| validateAndImportTrace(grandParentElement, sub); |
| validateFile = false; |
| } |
| } |
| if (validateFile && (fileSystemObject.exists())) { |
| validateAndImportTrace(element, sub); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Generate a new list of file system elements for the specified folder. |
| */ |
| private static List<TraceFileSystemElement> createElementsForFolder(IFolder folder) { |
| // Create the new import provider and root element based on the |
| // specified folder |
| FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null); |
| IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(folder.getLocation().toOSString())); |
| TraceFileSystemElement createRootElement = TraceFileSystemElement.createRootTraceFileElement(rootElement, importStructureProvider); |
| List<TraceFileSystemElement> list = new LinkedList<>(); |
| createRootElement.getAllChildren(list); |
| return list; |
| } |
| |
| /** |
| * Extract all file system elements (File) to destination folder (typically |
| * workspace/TraceProject/.traceImport) |
| */ |
| private void extractAllArchiveFiles(List<TraceFileSystemElement> fileSystemElements, IFolder destFolder, IPath baseSourceContainerPath, IProgressMonitor progressMonitor) throws InterruptedException, CoreException, InvocationTargetException { |
| SubMonitor subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size()); |
| ListIterator<TraceFileSystemElement> fileSystemElementsIter = fileSystemElements.listIterator(); |
| while (fileSystemElementsIter.hasNext()) { |
| ModalContext.checkCanceled(subMonitor); |
| |
| SubMonitor elementProgress = subMonitor.newChild(1); |
| TraceFileSystemElement element = fileSystemElementsIter.next(); |
| File archiveFile = (File) element.getFileSystemObject().getRawFileSystemObject(); |
| boolean isArchiveFileElement = element.getFileSystemObject() instanceof FileFileSystemObject && ArchiveUtil.isArchiveFile(archiveFile); |
| if (isArchiveFileElement) { |
| elementProgress = SubMonitor.convert(elementProgress, 4); |
| IPath relativeToSourceContainer = new Path(element.getFileSystemObject().getAbsolutePath()).makeRelativeTo(baseSourceContainerPath); |
| IFolder folder = safeCreateExtractedFolder(destFolder, relativeToSourceContainer, elementProgress.newChild(1)); |
| extractArchiveToFolder(archiveFile, folder, elementProgress.newChild(1)); |
| |
| // Delete original archive, we don't want to import this, just |
| // the extracted content |
| IFile fileRes = destFolder.getFile(relativeToSourceContainer); |
| fileRes.delete(true, elementProgress.newChild(1)); |
| IPath newPath = destFolder.getFullPath().append(relativeToSourceContainer); |
| // Rename extracted folder (.extract) to original archive name |
| folder.move(newPath, true, elementProgress.newChild(1)); |
| folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(newPath); |
| |
| // Create the new import provider and root element based on |
| // the newly extracted temporary folder |
| FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null); |
| IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(folder.getLocation().toOSString())); |
| TraceFileSystemElement newElement = TraceFileSystemElement.createRootTraceFileElement(rootElement, importStructureProvider); |
| List<TraceFileSystemElement> extractedChildren = new ArrayList<>(); |
| newElement.getAllChildren(extractedChildren); |
| extractAllArchiveFiles(extractedChildren, folder, folder.getLocation(), progressMonitor); |
| } |
| } |
| } |
| |
| /** |
| * Extract a file (File) to a destination folder |
| */ |
| private void extractArchiveToFolder(File sourceFile, IFolder destinationFolder, IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException { |
| Pair<IFileSystemObject, FileSystemObjectImportStructureProvider> rootObjectAndProvider = ArchiveUtil.getRootObjectAndProvider(sourceFile, fShell); |
| TraceFileSystemElement rootElement = TraceFileSystemElement.createRootTraceFileElement(rootObjectAndProvider.getFirst(), rootObjectAndProvider.getSecond()); |
| List<TraceFileSystemElement> fileSystemElements = new ArrayList<>(); |
| rootElement.getAllChildren(fileSystemElements); |
| extractArchiveContent(fileSystemElements.listIterator(), destinationFolder, progressMonitor); |
| rootObjectAndProvider.getSecond().dispose(); |
| } |
| |
| /** |
| * Safely create a folder meant to receive extracted content by making sure |
| * there is no name clash. |
| */ |
| private static IFolder safeCreateExtractedFolder(IFolder destinationFolder, IPath relativeContainerRelativePath, IProgressMonitor monitor) throws CoreException { |
| SubMonitor subMonitor = SubMonitor.convert(monitor, 2); |
| IFolder extractedFolder; |
| String suffix = ""; //$NON-NLS-1$ |
| int i = 2; |
| while (true) { |
| IPath fullPath = destinationFolder.getFullPath().append(relativeContainerRelativePath + ".extract" + suffix); //$NON-NLS-1$ |
| IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(fullPath); |
| if (!folder.exists()) { |
| extractedFolder = folder; |
| break; |
| } |
| suffix = "(" + i + ")"; //$NON-NLS-1$//$NON-NLS-2$ |
| i++; |
| } |
| subMonitor.worked(1); |
| |
| TraceUtils.createFolder(extractedFolder, subMonitor.newChild(1)); |
| return extractedFolder; |
| } |
| |
| private void calculateSourceLocations(List<TraceFileSystemElement> fileSystemElements, String baseSourceLocation) { |
| for (TraceFileSystemElement element : fileSystemElements) { |
| IPath tempRelative = new Path(element.getFileSystemObject().getAbsolutePath()).makeRelativeTo(fBaseSourceContainerPath); |
| String sourceLocation = baseSourceLocation + tempRelative; |
| element.setSourceLocation(sourceLocation); |
| |
| TraceFileSystemElement parentElement = (TraceFileSystemElement) element.getParent(); |
| tempRelative = new Path(parentElement.getFileSystemObject().getAbsolutePath()).makeRelativeTo(fBaseSourceContainerPath); |
| sourceLocation = baseSourceLocation + tempRelative + '/'; |
| parentElement.setSourceLocation(sourceLocation); |
| } |
| } |
| |
| /** |
| * Extract all file system elements (Tar, Zip elements) to destination |
| * folder (typically workspace/TraceProject/.traceImport or a subfolder of |
| * it) |
| */ |
| private void extractArchiveContent(Iterator<TraceFileSystemElement> fileSystemElementsIter, IFolder tempFolder, IProgressMonitor progressMonitor) throws InterruptedException, |
| InvocationTargetException { |
| List<TraceFileSystemElement> subList = new ArrayList<>(); |
| // Collect all the elements |
| while (fileSystemElementsIter.hasNext()) { |
| ModalContext.checkCanceled(progressMonitor); |
| TraceFileSystemElement element = fileSystemElementsIter.next(); |
| if (element.isDirectory()) { |
| Object[] array = element.getFiles().getChildren(); |
| for (int i = 0; i < array.length; i++) { |
| subList.add((TraceFileSystemElement) array[i]); |
| } |
| } |
| subList.add(element); |
| } |
| |
| if (subList.isEmpty()) { |
| return; |
| } |
| |
| TraceFileSystemElement root = getRootElement(subList.get(0)); |
| |
| ImportProvider fileSystemStructureProvider = new ImportProvider(); |
| |
| IOverwriteQuery myQueryImpl = new IOverwriteQuery() { |
| @Override |
| public String queryOverwrite(String file) { |
| return IOverwriteQuery.NO_ALL; |
| } |
| }; |
| |
| progressMonitor.setTaskName(Messages.ImportTraceWizard_ExtractImportOperationTaskName); |
| IPath containerPath = tempFolder.getFullPath(); |
| ImportOperation operation = new ImportOperation(containerPath, root, fileSystemStructureProvider, myQueryImpl, subList); |
| operation.setContext(fShell); |
| |
| operation.setCreateContainerStructure(true); |
| operation.setOverwriteResources(false); |
| operation.setVirtualFolders(false); |
| |
| operation.run(SubMonitor.convert(progressMonitor).newChild(subList.size())); |
| } |
| |
| private static TraceFileSystemElement getRootElement(TraceFileSystemElement element) { |
| TraceFileSystemElement root = element; |
| while (root.getParent() != null) { |
| root = (TraceFileSystemElement) root.getParent(); |
| } |
| return root; |
| } |
| |
| private IPath computeDestinationContainerPath(Path resourcePath) { |
| IPath destinationContainerPath = fDestinationContainerPath; |
| |
| // We need to figure out the new destination path relative to the |
| // selected "base" source directory. |
| // Here for example, the selected source directory is /home/user |
| if ((fImportOptionFlags & ImportTraceWizardPage.OPTION_PRESERVE_FOLDER_STRUCTURE) != 0) { |
| // /home/user/bar/foo/trace -> /home/user/bar/foo |
| IPath sourceContainerPath = resourcePath.removeLastSegments(1); |
| if (fBaseSourceContainerPath.equals(resourcePath)) { |
| // Use resourcePath directory if fBaseSourceContainerPath |
| // points to a directory trace |
| sourceContainerPath = resourcePath; |
| } |
| // /home/user/bar/foo, /home/user -> bar/foo |
| IPath relativeContainerPath = sourceContainerPath.makeRelativeTo(fBaseSourceContainerPath); |
| // project/Traces + bar/foo -> project/Traces/bar/foo |
| destinationContainerPath = fDestinationContainerPath.append(relativeContainerPath); |
| } |
| return destinationContainerPath; |
| } |
| |
| /** |
| * Import a single file system element into the workspace. |
| */ |
| private void validateAndImportTrace(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) |
| throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException { |
| String path = fileSystemElement.getFileSystemObject().getAbsolutePath(); |
| TraceTypeHelper traceTypeHelper = null; |
| |
| File file = (File) fileSystemElement.getFileSystemObject().getRawFileSystemObject(); |
| boolean isArchiveFileElement = fileSystemElement.getFileSystemObject() instanceof FileFileSystemObject && ArchiveUtil.isArchiveFile(file); |
| if (isArchiveFileElement) { |
| // We'll be extracting this later, do not import as a trace |
| return; |
| } |
| |
| if (fTraceType == null) { |
| // Auto Detection |
| try { |
| traceTypeHelper = TmfTraceTypeUIUtils.selectTraceType(path, null, null); |
| } catch (TmfTraceImportException e) { |
| // the trace did not match any trace type |
| } |
| if (traceTypeHelper == null) { |
| if ((fImportOptionFlags & ImportTraceWizardPage.OPTION_IMPORT_UNRECOGNIZED_TRACES) != 0) { |
| importResource(fileSystemElement, monitor); |
| } |
| return; |
| } |
| } else { |
| boolean isDirectoryTraceType = TmfTraceType.isDirectoryTraceType(fTraceType); |
| if (fileSystemElement.isDirectory() != isDirectoryTraceType) { |
| return; |
| } |
| traceTypeHelper = TmfTraceType.getTraceType(fTraceType); |
| |
| if (traceTypeHelper == null) { |
| // Trace type not found |
| throw new TmfTraceImportException(Messages.ImportTraceWizard_TraceTypeNotFound); |
| } |
| |
| if (!traceTypeHelper.validate(path).isOK()) { |
| // Trace type exist but doesn't validate for given trace. |
| return; |
| } |
| } |
| |
| // Finally import trace |
| IResource importedResource = importResource(fileSystemElement, monitor); |
| if (importedResource != null) { |
| TmfTraceTypeUIUtils.setTraceType(importedResource, traceTypeHelper, false); |
| fImportedResources.add(importedResource); |
| } |
| |
| } |
| |
| /** |
| * Imports a trace resource to project. In case of name collision the user |
| * will be asked to confirm overwriting the existing trace, overwriting or |
| * skipping the trace to be imported. |
| * |
| * @param fileSystemElement |
| * trace file system object to import |
| * @param monitor |
| * a progress monitor |
| * @return the imported resource or null if no resource was imported |
| * |
| * @throws InvocationTargetException |
| * if problems during import operation |
| * @throws InterruptedException |
| * if cancelled |
| * @throws CoreException |
| * if problems with workspace |
| */ |
| private IResource importResource(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor) |
| throws InvocationTargetException, InterruptedException, CoreException { |
| |
| IPath tracePath = getInitialDestinationPath(fileSystemElement); |
| String newName = fConflictHandler.checkAndHandleNameClash(tracePath, monitor); |
| |
| if (newName == null) { |
| return null; |
| } |
| fileSystemElement.setLabel(newName); |
| |
| List<TraceFileSystemElement> subList = new ArrayList<>(); |
| |
| FileSystemElement parentFolder = fileSystemElement.getParent(); |
| |
| IPath containerPath = fileSystemElement.getDestinationContainerPath(); |
| tracePath = containerPath.addTrailingSeparator().append(fileSystemElement.getLabel()); |
| boolean createLinksInWorkspace = (fImportOptionFlags & ImportTraceWizardPage.OPTION_CREATE_LINKS_IN_WORKSPACE) != 0; |
| if (fileSystemElement.isDirectory() && !createLinksInWorkspace) { |
| containerPath = tracePath; |
| |
| Object[] array = fileSystemElement.getFiles().getChildren(); |
| for (int i = 0; i < array.length; i++) { |
| subList.add((TraceFileSystemElement) array[i]); |
| } |
| parentFolder = fileSystemElement; |
| |
| } else { |
| if (!fileSystemElement.isDirectory()) { |
| // File traces |
| IFileInfo info = EFS.getStore(new File(fileSystemElement.getFileSystemObject().getAbsolutePath()).toURI()).fetchInfo(); |
| if (info.getLength() == 0) { |
| // Don't import empty traces |
| return null; |
| } |
| } |
| subList.add(fileSystemElement); |
| } |
| |
| ImportProvider fileSystemStructureProvider = new ImportProvider(); |
| |
| IOverwriteQuery myQueryImpl = new IOverwriteQuery() { |
| @Override |
| public String queryOverwrite(String file) { |
| return IOverwriteQuery.NO_ALL; |
| } |
| }; |
| |
| monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + fileSystemElement.getFileSystemObject().getAbsolutePath()); //$NON-NLS-1$ |
| ImportOperation operation = new ImportOperation(containerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList); |
| operation.setContext(fShell); |
| |
| operation.setCreateContainerStructure(false); |
| operation.setOverwriteResources(false); |
| operation.setCreateLinks(createLinksInWorkspace); |
| operation.setVirtualFolders(false); |
| |
| operation.run(SubMonitor.convert(monitor).newChild(1)); |
| String sourceLocation = fileSystemElement.getSourceLocation(); |
| IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(tracePath); |
| if ((sourceLocation != null) && (resource != null)) { |
| resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation); |
| } |
| |
| return resource; |
| } |
| |
| private static boolean isDirectoryTrace(TraceFileSystemElement fileSystemElement) { |
| String path = fileSystemElement.getFileSystemObject().getAbsolutePath(); |
| if (TmfTraceType.isDirectoryTrace(path)) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * @return the initial destination path, before rename, if any |
| */ |
| private static IPath getInitialDestinationPath(TraceFileSystemElement fileSystemElement) { |
| IPath traceFolderPath = fileSystemElement.getDestinationContainerPath(); |
| return traceFolderPath.append(fileSystemElement.getFileSystemObject().getName()); |
| } |
| |
| /** |
| * Set the status for this operation |
| * |
| * @param status |
| * the status |
| */ |
| private void setStatus(IStatus status) { |
| fStatus = status; |
| } |
| |
| /** |
| * Get the resulting status of this operation. Clients can use this for |
| * error reporting, etc. |
| * |
| * @return the resulting status |
| */ |
| public IStatus getStatus() { |
| return fStatus; |
| } |
| |
| private class ImportProvider implements IImportStructureProvider { |
| |
| ImportProvider() { |
| } |
| |
| @Override |
| public String getLabel(Object element) { |
| TraceFileSystemElement resource = (TraceFileSystemElement) element; |
| return resource.getLabel(); |
| } |
| |
| @Override |
| public List getChildren(Object element) { |
| TraceFileSystemElement resource = (TraceFileSystemElement) element; |
| Object[] array = resource.getFiles().getChildren(); |
| List<Object> list = new ArrayList<>(); |
| for (int i = 0; i < array.length; i++) { |
| list.add(array[i]); |
| } |
| return list; |
| } |
| |
| @Override |
| public InputStream getContents(Object element) { |
| TraceFileSystemElement resource = (TraceFileSystemElement) element; |
| return resource.getProvider().getContents(resource.getFileSystemObject()); |
| } |
| |
| @Override |
| public String getFullPath(Object element) { |
| TraceFileSystemElement resource = (TraceFileSystemElement) element; |
| return resource.getProvider().getFullPath(resource.getFileSystemObject()); |
| } |
| |
| @Override |
| public boolean isFolder(Object element) { |
| TraceFileSystemElement resource = (TraceFileSystemElement) element; |
| return resource.isDirectory(); |
| } |
| } |
| } |