/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.buckminster.pde.internal.datatransfer;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.buckminster.pde.Messages;
import org.eclipse.buckminster.pde.PDEPlugin;
import org.eclipse.buckminster.pde.internal.dialogs.ContainerGenerator;
import org.eclipse.buckminster.pde.internal.dialogs.IOverwriteQuery;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.osgi.util.NLS;
/**
* An operation which does the actual work of copying objects from the local
* file system into the workspace.
* <p>
* This class may be instantiated; it is not intended to be subclassed.
* </p>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ImportOperation extends WorkspaceJob {
private static final int POLICY_DEFAULT = 0;
private static final int POLICY_SKIP_CHILDREN = 1;
private static final int POLICY_FORCE_OVERWRITE = 2;
private Object source;
private IPath destinationPath;
private IContainer destinationContainer;
private List selectedFiles;
private List rejectedFiles;
private IImportStructureProvider provider;
private IProgressMonitor monitor;
protected IOverwriteQuery overwriteCallback;
// private Shell context;
private List errorTable = new ArrayList();
private boolean createContainerStructure = true;
// The constants for the overwrite 3 state
private static final int OVERWRITE_NOT_SET = 0;
private static final int OVERWRITE_NONE = 1;
private static final int OVERWRITE_ALL = 2;
private int overwriteState = OVERWRITE_NOT_SET;
/**
* Creates a new operation that imports specific file system objects.
* <p>
* The <code>provider</code> parameter allows this operation to deal with
* the source object in an abstract way. This operation calls methods on the
* provider and the provider in turn calls specific methods on the source
* object.
* </p>
* <p>
* The <code>filesToImport</code> parameter specifies what file system
* objects are to be imported.
* </p>
* <p>
* The default import behavior is to recreate the complete container
* structure for the file system objects in their destination. If
* <code>setCreateContainerStructure</code> is set to <code>false</code>,
* then no container structure is created for each of the file system
* objects.
* </p>
*
* @param containerPath
* the full path of the destination container within the
* workspace
* @param provd
* the file system structure provider to use
* @param overwriteImplementor
* the overwrite strategy to use
* @param filesToImport
* the list of file system objects to be imported (element type:
* <code>Object</code>)
*/
public ImportOperation(IPath containerPath, IImportStructureProvider provd, IOverwriteQuery overwriteImplementor, List filesToImport) {
this(containerPath, null, provd, overwriteImplementor);
setFilesToImport(filesToImport);
}
/**
* Creates a new operation that recursively imports the entire contents of
* the specified root file system object.
* <p>
* The <code>source</code> parameter represents the root file system object
* to import. All contents of this object are imported. Valid types for this
* parameter are determined by the supplied
* <code>IImportStructureProvider</code> .
* </p>
* <p>
* The <code>provider</code> parameter allows this operation to deal with
* the source object in an abstract way. This operation calls methods on the
* provider and the provider in turn calls specific methods on the source
* object.
* </p>
* <p>
* The default import behavior is to recreate the complete container
* structure for the contents of the root file system object in their
* destination. If <code>setCreateContainerStructure</code> is set to false
* then the container structure created is relative to the root file system
* object.
* </p>
*
* @param containerPath
* the full path of the destination container within the
* workspace
* @param src
* the root file system object to import
* @param provd
* the file system structure provider to use
* @param overwriteImplementor
* the overwrite strategy to use
*/
public ImportOperation(IPath containerPath, Object src, IImportStructureProvider provd, IOverwriteQuery overwriteImplementor) {
super("ImportOperation"); //$NON-NLS-1$
this.destinationPath = containerPath;
this.source = src;
this.provider = provd;
overwriteCallback = overwriteImplementor;
}
/**
* Creates a new operation that imports specific file system objects. In
* this usage context, the specified source file system object is used by
* the operation solely to determine the destination container structure of
* the file system objects being imported.
* <p>
* The <code>source</code> parameter represents the root file system object
* to import. Valid types for this parameter are determined by the supplied
* <code>IImportStructureProvider</code>. The contents of the source which
* are to be imported are specified in the <code>filesToImport</code>
* parameter.
* </p>
* <p>
* The <code>provider</code> parameter allows this operation to deal with
* the source object in an abstract way. This operation calls methods on the
* provider and the provider in turn calls specific methods on the source
* object.
* </p>
* <p>
* The <code>filesToImport</code> parameter specifies what contents of the
* root file system object are to be imported.
* </p>
* <p>
* The default import behavior is to recreate the complete container
* structure for the file system objects in their destination. If
* <code>setCreateContainerStructure</code> is set to <code>false</code>,
* then the container structure created for each of the file system objects
* is relative to the supplied root file system object.
* </p>
*
* @param containerPath
* the full path of the destination container within the
* workspace
* @param src
* the root file system object to import from
* @param provd
* the file system structure provider to use
* @param overwriteImplementor
* the overwrite strategy to use
* @param filesToImport
* the list of file system objects to be imported (element type:
* <code>Object</code>)
*/
public ImportOperation(IPath containerPath, Object src, IImportStructureProvider provd, IOverwriteQuery overwriteImplementor, List filesToImport) {
this(containerPath, src, provd, overwriteImplementor);
setFilesToImport(filesToImport);
}
/**
* Returns the status of the import operation. If there were any errors, the
* result is a status object containing individual status objects for each
* error. If there were no errors, the result is a status object with error
* code <code>OK</code>.
*
* @return the status
*/
public IStatus getStatus() {
IStatus[] errors = new IStatus[errorTable.size()];
errorTable.toArray(errors);
return new MultiStatus(PDEPlugin.getPluginId(), IStatus.OK, errors, Messages.ImportOperation_importProblems, null);
}
/*
* (non-Javadoc) Method declared on WorkbenchModifyOperation. Imports the
* specified file system objects from the file system.
*/
@Override
public IStatus runInWorkspace(IProgressMonitor progressMonitor) {
monitor = progressMonitor;
try {
if (selectedFiles == null) {
// Set the amount to 1000 as we have no idea of how long this
// will take
monitor.beginTask(Messages.DataTransfer_importTask, 1000);
ContainerGenerator generator = new ContainerGenerator(destinationPath);
monitor.worked(30);
validateFiles(Arrays.asList(new Object[] { source }));
monitor.worked(50);
destinationContainer = generator.generateContainer(new SubProgressMonitor(monitor, 50));
importRecursivelyFrom(source, POLICY_DEFAULT);
// Be sure it finishes
monitor.worked(90);
} else {
// Choose twice the selected files size to take folders into
// account
int creationCount = selectedFiles.size();
monitor.beginTask(Messages.DataTransfer_importTask, creationCount + 100);
ContainerGenerator generator = new ContainerGenerator(destinationPath);
monitor.worked(30);
validateFiles(selectedFiles);
monitor.worked(50);
destinationContainer = generator.generateContainer(new SubProgressMonitor(monitor, 50));
importFileSystemObjects(selectedFiles);
monitor.done();
}
} catch (CoreException e) {
errorTable.add(e.getStatus());
} finally {
monitor.done();
}
return (errorTable.size() == 0) ? Status.OK_STATUS : getStatus();
}
/**
* Sets whether the containment structures that are implied from the full
* paths of file system objects being imported should be duplicated in the
* workbench.
*
* @param value
* <code>true</code> if containers should be created, and
* <code>false</code> otherwise
*/
public void setCreateContainerStructure(boolean value) {
createContainerStructure = value;
}
/**
* Sets the file system objects to import.
*
* @param filesToImport
* the list of file system objects to be imported (element type:
* <code>Object</code>)
*/
public void setFilesToImport(List filesToImport) {
this.selectedFiles = filesToImport;
}
/**
* Sets whether imported file system objects should automatically overwrite
* existing workbench resources when a conflict occurs.
*
* @param value
* <code>true</code> to automatically overwrite, and
* <code>false</code> otherwise
*/
public void setOverwriteResources(boolean value) {
if (value) {
this.overwriteState = OVERWRITE_ALL;
}
}
/**
* Prompts if existing resources should be overwritten. Recursively collects
* existing read-only files to overwrite and resources that should not be
* overwritten.
*
* @param sourceStart
* destination path to check for existing files
* @param sources
* file system objects that may exist in the destination
* @param noOverwrite
* files that were selected to be skipped (don't overwrite).
* object type IPath
* @param overwriteReadonly
* the collected existing read-only files to overwrite. object
* type IPath
* @param policy
* on of the POLICY constants defined in the class.
*/
void collectExistingReadonlyFiles(IPath sourceStart, List sources, ArrayList noOverwrite, ArrayList overwriteReadonly, int policy) {
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
Iterator sourceIter = sources.iterator();
IPath sourceRootPath = null;
if (this.source != null) {
sourceRootPath = new Path(provider.getFullPath(this.source));
}
while (sourceIter.hasNext()) {
Object nextSource = sourceIter.next();
IPath sourcePath = new Path(provider.getFullPath(nextSource));
IPath newDestinationPath;
IResource newDestination;
if (sourceRootPath == null) {
newDestinationPath = sourceStart.append(provider.getLabel(nextSource));
} else {
int prefixLength = sourcePath.matchingFirstSegments(sourceRootPath);
IPath relativeSourcePath = sourcePath.removeFirstSegments(prefixLength);
newDestinationPath = this.destinationPath.append(relativeSourcePath);
}
newDestination = workspaceRoot.findMember(newDestinationPath);
if (newDestination == null) {
continue;
}
IFolder folder = getFolder(newDestination);
if (folder != null) {
if (policy != POLICY_FORCE_OVERWRITE) {
if (this.overwriteState == OVERWRITE_NONE || !queryOverwrite(newDestinationPath)) {
noOverwrite.add(folder);
continue;
}
}
if (provider.isFolder(nextSource)) {
collectExistingReadonlyFiles(newDestinationPath, provider.getChildren(nextSource), noOverwrite, overwriteReadonly,
POLICY_FORCE_OVERWRITE);
}
} else {
IFile file = getFile(newDestination);
if (file != null) {
if (!queryOverwriteFile(file, policy)) {
noOverwrite.add(file.getFullPath());
} else if (file.isReadOnly()) {
overwriteReadonly.add(file);
}
}
}
}
}
/**
* Creates the folders that appear in the specified resource path. These
* folders are created relative to the destination container.
*
* @param path
* the relative path of the resource
* @return the container resource coresponding to the given path
* @exception CoreException
* if this method failed
*/
IContainer createContainersFor(IPath path) throws CoreException {
IContainer currentFolder = destinationContainer;
int segmentCount = path.segmentCount();
// No containers to create
if (segmentCount == 0) {
return currentFolder;
}
// Needs to be handles differently at the root
if (currentFolder.getType() == IResource.ROOT) {
return createFromRoot(path);
}
for (int i = 0; i < segmentCount; i++) {
currentFolder = currentFolder.getFolder(new Path(path.segment(i)));
if (!currentFolder.exists()) {
((IFolder) currentFolder).create(false, true, null);
}
}
return currentFolder;
}
/**
* Deletes the given resource. If the resource fails to be deleted, adds a
* status object to the list to be returned by <code>getResult</code>.
*
* @param resource
* the resource
*/
void deleteResource(IResource resource) {
try {
resource.delete(IResource.KEEP_HISTORY, null);
} catch (CoreException e) {
errorTable.add(e.getStatus());
}
}
/**
* Returns the container resource that the passed file system object should
* be imported into.
*
* @param fileSystemObject
* the file system object being imported
* @return the container resource that the passed file system object should
* be imported into
* @exception CoreException
* if this method failed
*/
IContainer getDestinationContainerFor(Object fileSystemObject) throws CoreException {
IPath pathname = new Path(provider.getFullPath(fileSystemObject));
if (createContainerStructure) {
return createContainersFor(pathname.removeLastSegments(1));
}
if (source == fileSystemObject) {
return null;
}
IPath sourcePath = new Path(provider.getFullPath(source));
IPath destContainerPath = pathname.removeLastSegments(1);
IPath relativePath = destContainerPath.removeFirstSegments(sourcePath.segmentCount()).setDevice(null);
return createContainersFor(relativePath);
}
/**
* Returns the resource either casted to or adapted to an IFile.
*
* @param resource
* resource to cast/adapt
* @return the resource either casted to or adapted to an IFile.
* <code>null</code> if the resource does not adapt to IFile
*/
IFile getFile(IResource resource) {
if (resource instanceof IFile) {
return (IFile) resource;
}
Object adapted = ((IAdaptable) resource).getAdapter(IFile.class);
if (adapted == null) {
return null;
}
return (IFile) adapted;
}
/**
* Returns the resource either casted to or adapted to an IFolder.
*
* @param resource
* resource to cast/adapt
* @return the resource either casted to or adapted to an IFolder.
* <code>null</code> if the resource does not adapt to IFolder
*/
IFolder getFolder(IResource resource) {
if (resource instanceof IFolder) {
return (IFolder) resource;
}
Object adapted = ((IAdaptable) resource).getAdapter(IFolder.class);
if (adapted == null) {
return null;
}
return (IFolder) adapted;
}
/**
* Returns the rejected files based on the given multi status.
*
* @param multiStatus
* multi status to use to determine file rejection
* @param files
* source files
* @return list of rejected files as absolute paths. Object type IPath.
*/
ArrayList getRejectedFiles(IStatus multiStatus, IFile[] files) {
ArrayList filteredFiles = new ArrayList();
IStatus[] status = multiStatus.getChildren();
for (int i = 0; i < status.length; i++) {
if (status[i].isOK() == false) {
errorTable.add(status[i]);
filteredFiles.add(files[i].getFullPath());
}
}
return filteredFiles;
}
/**
* Imports the specified file system object into the workspace. If the
* import fails, adds a status object to the list to be returned by
* <code>getResult</code>.
*
* @param fileObject
* the file system object to be imported
* @param policy
* determines how the file object is imported
*/
void importFile(Object fileObject, int policy) {
IContainer containerResource;
try {
containerResource = getDestinationContainerFor(fileObject);
} catch (CoreException e) {
IStatus coreStatus = e.getStatus();
String newMessage = NLS.bind(Messages.ImportOperation_coreImportError, fileObject, coreStatus.getMessage());
IStatus status = new Status(coreStatus.getSeverity(), coreStatus.getPlugin(), coreStatus.getCode(), newMessage, null);
errorTable.add(status);
return;
}
String fileObjectPath = provider.getFullPath(fileObject);
monitor.subTask(fileObjectPath);
IFile targetResource = containerResource.getFile(new Path(provider.getLabel(fileObject)));
monitor.worked(1);
if (rejectedFiles.contains(targetResource.getFullPath())) {
return;
}
// ensure that the source and target are not the same
IPath targetPath = targetResource.getLocation();
// Use Files for comparison to avoid platform specific case issues
if (targetPath != null && (targetPath.toFile().equals(new File(fileObjectPath)))) {
errorTable.add(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), 0, NLS.bind(Messages.ImportOperation_targetSameAsSourceError,
fileObjectPath), null));
return;
}
InputStream contentStream = provider.getContents(fileObject);
if (contentStream == null) {
errorTable.add(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), 0, NLS.bind(Messages.ImportOperation_openStreamError, fileObjectPath),
null));
return;
}
try {
if (targetResource.exists()) {
targetResource.setContents(contentStream, IResource.KEEP_HISTORY, null);
} else {
targetResource.create(contentStream, false, null);
}
setResourceAttributes(targetResource, fileObject);
/*
* if (provider instanceof TarLeveledStructureProvider) { try {
* targetResource
* .setResourceAttributes(((TarLeveledStructureProvider)
* provider).getResourceAttributes(fileObject)); } catch
* (CoreException e) { errorTable.add(e.getStatus()); } }
*/
} catch (CoreException e) {
errorTable.add(e.getStatus());
} finally {
try {
contentStream.close();
} catch (IOException e) {
errorTable.add(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), 0, NLS.bind(Messages.ImportOperation_closeStreamError,
fileObjectPath), e));
}
}
}
/**
* Imports the specified file system objects into the workspace. If the
* import fails, adds a status object to the list to be returned by
* <code>getStatus</code>.
*
* @param filesToImport
* the list of file system objects to import (element type:
* <code>Object</code>)
* @exception OperationCanceledException
* if canceled
*/
void importFileSystemObjects(List filesToImport) {
Iterator filesEnum = filesToImport.iterator();
while (filesEnum.hasNext()) {
Object fileSystemObject = filesEnum.next();
if (source == null) {
// We just import what we are given into the destination
IPath sourcePath = new Path(provider.getFullPath(fileSystemObject)).removeLastSegments(1);
if (provider.isFolder(fileSystemObject) && sourcePath.isEmpty()) {
// If we don't have a parent then we have selected the
// file systems root. Roots can't copied (at least not
// under windows).
errorTable.add(new Status(IStatus.INFO, PDEPlugin.getPluginId(), 0, Messages.ImportOperation_cannotCopy, null));
continue;
}
source = sourcePath.toFile();
}
importRecursivelyFrom(fileSystemObject, POLICY_DEFAULT);
}
}
/**
* Imports the specified file system container object into the workspace. If
* the import fails, adds a status object to the list to be returned by
* <code>getResult</code>.
*
* @param folderObject
* the file system container object to be imported
* @param policy
* determines how the folder object and children are imported
* @return the policy to use to import the folder's children
*/
int importFolder(Object folderObject, int policy) {
IContainer containerResource;
try {
containerResource = getDestinationContainerFor(folderObject);
} catch (CoreException e) {
errorTable.add(e.getStatus());
return policy;
}
if (containerResource == null) {
return policy;
}
monitor.subTask(provider.getFullPath(folderObject));
IWorkspace workspace = destinationContainer.getWorkspace();
IPath containerPath = containerResource.getFullPath();
IPath resourcePath = containerPath.append(provider.getLabel(folderObject));
// Do not attempt the import if the resource path is unchanged. This may
// happen
// when importing from a zip file.
if (resourcePath.equals(containerPath)) {
return policy;
}
if (workspace.getRoot().exists(resourcePath)) {
if (rejectedFiles.contains(resourcePath)) {
return POLICY_SKIP_CHILDREN;
}
return POLICY_FORCE_OVERWRITE;
}
try {
workspace.getRoot().getFolder(resourcePath).create(false, true, null);
} catch (CoreException e) {
errorTable.add(e.getStatus());
}
return policy;
}
/**
* Imports the specified file system object recursively into the workspace.
* If the import fails, adds a status object to the list to be returned by
* <code>getStatus</code>.
*
* @param fileSystemObject
* the file system object to be imported
* @param policy
* determines how the file system object and children are
* imported
* @exception OperationCanceledException
* if canceled
*/
void importRecursivelyFrom(Object fileSystemObject, int policy) {
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
if (!provider.isFolder(fileSystemObject)) {
importFile(fileSystemObject, policy);
return;
}
int childPolicy = importFolder(fileSystemObject, policy);
if (childPolicy != POLICY_SKIP_CHILDREN) {
Iterator children = provider.getChildren(fileSystemObject).iterator();
while (children.hasNext()) {
importRecursivelyFrom(children.next(), childPolicy);
}
}
}
/**
* Queries the user whether the resource with the specified path should be
* overwritten by a file system object that is being imported.
*
* @param resourcePath
* the workspace path of the resource that needs to be
* overwritten
* @return <code>true</code> to overwrite, <code>false</code> to not
* overwrite
* @exception OperationCanceledException
* if canceled
*/
boolean queryOverwrite(IPath resourcePath) throws OperationCanceledException {
String overwriteAnswer = overwriteCallback.queryOverwrite(resourcePath.makeRelative().toString());
if (overwriteAnswer.equals(IOverwriteQuery.CANCEL)) {
throw new OperationCanceledException();
}
if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
return false;
}
if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
this.overwriteState = OVERWRITE_NONE;
return false;
}
if (overwriteAnswer.equals(IOverwriteQuery.ALL)) {
this.overwriteState = OVERWRITE_ALL;
}
return true;
}
/**
* Sets the context for use by the VCM provider to prompt the user for
* check-out of files.
*
* @param shell
* context for use by the VCM provider to prompt user for
* check-out. The user will not be prompted if set to
* <code>null</code>.
* @see IWorkspace#validateEdit(org.eclipse.core.resources.IFile[],
* java.lang.Object)
* @since 2.1 public void setContext(Shell shell) { context = shell; }
*/
/**
* Returns whether the given file should be overwritten.
*
* @param targetFile
* the file to ask to overwrite
* @param policy
* determines if the user is queried for overwrite
* @return <code>true</code> if the file should be overwritten, and
* <code>false</code> if not.
*/
boolean queryOverwriteFile(IFile targetFile, int policy) {
// If force overwrite is on don't bother
if (policy != POLICY_FORCE_OVERWRITE) {
if (this.overwriteState == OVERWRITE_NOT_SET && !queryOverwrite(targetFile.getFullPath())) {
return false;
}
if (this.overwriteState == OVERWRITE_NONE) {
return false;
}
}
return true;
}
/**
* Validates that the given source resources can be copied to the
* destination as decided by the VCM provider.
*
* @param existingFiles
* existing files to validate
* @return list of rejected files as absolute paths. Object type IPath.
*/
ArrayList validateEdit(List existingFiles) {
if (existingFiles.size() > 0) {
IFile[] files = (IFile[]) existingFiles.toArray(new IFile[existingFiles.size()]);
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IStatus status = workspace.validateEdit(files, null);
// If there was a mix return the bad ones
if (status.isMultiStatus()) {
return getRejectedFiles(status, files);
}
if (!status.isOK()) {
// If just a single status reject them all
errorTable.add(status);
ArrayList filteredFiles = new ArrayList();
for (int i = 0; i < files.length; i++) {
filteredFiles.add(files[i].getFullPath());
}
return filteredFiles;
}
}
return new ArrayList();
}
/**
* Validates the given file system objects. The user is prompted to
* overwrite existing files. Existing read-only files are validated with the
* VCM provider.
*
* @param sourceFiles
* files to validate
*/
void validateFiles(List sourceFiles) {
ArrayList noOverwrite = new ArrayList();
ArrayList overwriteReadonly = new ArrayList();
collectExistingReadonlyFiles(destinationPath, sourceFiles, noOverwrite, overwriteReadonly, POLICY_DEFAULT);
rejectedFiles = validateEdit(overwriteReadonly);
rejectedFiles.addAll(noOverwrite);
}
/**
* Creates the folders that appear in the specified resource path assuming
* that the destinationContainer begins at the root. Do not create projects.
*
* @param path
* the relative path of the resource
* @return the container resource coresponding to the given path
* @exception CoreException
* if this method failed
*/
private IContainer createFromRoot(IPath path) throws CoreException {
int segmentCount = path.segmentCount();
// Assume the project exists
IContainer currentFolder = ((IWorkspaceRoot) destinationContainer).getProject(path.segment(0));
for (int i = 1; i < segmentCount; i++) {
currentFolder = currentFolder.getFolder(new Path(path.segment(i)));
if (!currentFolder.exists()) {
((IFolder) currentFolder).create(false, true, null);
}
}
return currentFolder;
}
/**
* Reuse the file attributes set in the import.
*
* @param targetResource
* @param fileObject
*/
private void setResourceAttributes(IFile targetResource, Object fileObject) {
if (fileObject instanceof File) {
try {
targetResource.setResourceAttributes(ResourceAttributes.fromFile((File) fileObject));
} catch (CoreException e) {
// Inform the log that the attributes reading failed
PDEPlugin.getLogger().error(e, e.getStatus().getMessage());
}
}
}
}