package org.eclipse.core.internal.resources;
import java.net.URI;
import org.eclipse.core.filesystem.*;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.internal.localstore.FileSystemResourceManager;
import org.eclipse.core.internal.properties.IPropertyManager;
import org.eclipse.core.internal.utils.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.resources.team.IResourceTree;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.osgi.util.NLS;
class ResourceTree implements IResourceTree {
private boolean isValid = true;
private final FileSystemResourceManager localManager;
private ILock lock;
private MultiStatus multistatus;
private int updateFlags;
public ResourceTree(FileSystemResourceManager localManager, ILock lock, MultiStatus status, int updateFlags) {
super();
this.localManager = localManager;
this.lock = lock;
this.multistatus = status;
this.updateFlags = updateFlags;
}
@Override
public void addToLocalHistory(IFile file) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!file.exists())
return;
IFileStore store = localManager.getStore(file);
final IFileInfo fileInfo = store.fetchInfo();
if (!fileInfo.exists())
return;
localManager.getHistoryStore().addState(file.getFullPath(), store, fileInfo, false);
} finally {
lock.release();
}
}
private IFileStore computeDestinationStore(IProjectDescription destDescription) throws CoreException {
URI destLocation = destDescription.getLocationURI();
if (destLocation == null) {
IPath rootLocation = ResourcesPlugin.getWorkspace().getRoot().getLocation();
destLocation = rootLocation.append(destDescription.getName()).toFile().toURI();
}
return EFS.getStore(destLocation);
}
@Override
public long computeTimestamp(IFile file) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!file.getProject().exists())
return NULL_TIMESTAMP;
return internalComputeTimestamp(file);
} finally {
lock.release();
}
}
private void copyLocalHistory(IResource source, IResource destination) {
localManager.getHistoryStore().copyHistory(source, destination, true);
}
@Override
public void deletedFile(IFile file) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!file.exists())
return;
try {
((Resource) file).deleteResource(true, null);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorDeleting, file.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, file.getFullPath(), message, e);
failed(status);
}
} finally {
lock.release();
}
}
@Override
public void deletedFolder(IFolder folder) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!folder.exists())
return;
try {
((Resource) folder).deleteResource(true, null);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorDeleting, folder.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, folder.getFullPath(), message, e);
failed(status);
}
} finally {
lock.release();
}
}
@Override
public void deletedProject(IProject target) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!target.exists())
return;
try {
((Project) target).deleteResource(false, null);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorDeleting, target.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, target.getFullPath(), message, e);
failed(status);
}
} finally {
lock.release();
}
}
private boolean ensureDestinationEmpty(IProject source, IFileStore destinationStore, IProgressMonitor monitor) throws CoreException {
String message;
if (!destinationStore.fetchInfo().exists())
return true;
if (destinationStore.childNames(EFS.NONE, Policy.subMonitorFor(monitor, 0)).length > 0) {
if (((Resource) source).getStore().equals(destinationStore))
return true;
message = NLS.bind(Messages.localstore_resourceExists, destinationStore);
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, null);
failed(status);
return false;
}
destinationStore.delete(EFS.NONE, Policy.subMonitorFor(monitor, 0));
return true;
}
@Override
public void failed(IStatus reason) {
Assert.isLegal(isValid);
multistatus.add(reason);
}
protected IStatus getStatus() {
return multistatus;
}
@Override
public long getTimestamp(IFile file) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!file.exists())
return NULL_TIMESTAMP;
ResourceInfo info = ((File) file).getResourceInfo(false, false);
return info == null ? NULL_TIMESTAMP : info.getLocalSyncInfo();
} finally {
lock.release();
}
}
private long internalComputeTimestamp(IFile file) {
IFileInfo fileInfo = localManager.getStore(file).fetchInfo();
return fileInfo.exists() ? fileInfo.getLastModified() : NULL_TIMESTAMP;
}
private boolean internalDeleteFile(IFile file, int flags, IProgressMonitor monitor) {
try {
String message = NLS.bind(Messages.resources_deleting, file.getFullPath());
monitor.beginTask(message, Policy.totalWork);
Policy.checkCanceled(monitor);
if (!file.exists()) {
return true;
}
if (file.isLinked()) {
deletedFile(file);
return true;
}
IFileStore fileStore = localManager.getStore(file);
boolean localExists = fileStore.fetchInfo().exists();
if (!localExists) {
deletedFile(file);
return true;
}
boolean keepHistory = (flags & IResource.KEEP_HISTORY) != 0;
boolean force = (flags & IResource.FORCE) != 0;
if (keepHistory)
addToLocalHistory(file);
monitor.worked(Policy.totalWork / 4);
if (!force) {
boolean inSync = isSynchronized(file, IResource.DEPTH_ZERO);
if (!inSync && localExists) {
message = NLS.bind(Messages.localstore_resourceIsOutOfSync, file.getFullPath());
IStatus status = new ResourceStatus(IResourceStatus.OUT_OF_SYNC_LOCAL, file.getFullPath(), message);
failed(status);
return false;
}
}
monitor.worked(Policy.totalWork / 4);
try {
fileStore.delete(EFS.NONE, Policy.subMonitorFor(monitor, Policy.totalWork / 4));
deletedFile(file);
return true;
} catch (CoreException e) {
message = NLS.bind(Messages.resources_couldnotDelete, fileStore.toString());
IStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, file.getFullPath(), message, e);
failed(status);
}
return false;
} finally {
monitor.done();
}
}
private boolean internalDeleteFolder(IFolder folder, int flags, IProgressMonitor monitor) {
String message = NLS.bind(Messages.resources_deleting, folder.getFullPath());
monitor.beginTask("", Policy.totalWork);
monitor.subTask(message);
Policy.checkCanceled(monitor);
if (!folder.exists())
return true;
if (folder.isLinked()) {
deletedFolder(folder);
return true;
}
IFileStore fileStore = localManager.getStore(folder);
if (!fileStore.fetchInfo().exists()) {
deletedFolder(folder);
return true;
}
try {
localManager.delete(folder, flags, Policy.subMonitorFor(monitor, Policy.totalWork));
} catch (CoreException ce) {
message = NLS.bind(Messages.localstore_couldnotDelete, folder.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, IResourceStatus.FAILED_DELETE_LOCAL, folder.getFullPath(), message, ce);
failed(status);
return false;
}
return true;
}
private boolean internalDeleteProject(IProject project, int flags, IProgressMonitor monitor) {
IResource[] members = null;
try {
members = project.members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorMembers, project.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, project.getFullPath(), message, e);
failed(status);
return false;
}
boolean deletedChildren = true;
for (IResource member : members) {
IResource child = member;
switch (child.getType()) {
case IResource.FILE :
if (!IProjectDescription.DESCRIPTION_FILE_NAME.equals(child.getName()))
deletedChildren &= internalDeleteFile((IFile) child, flags, Policy.subMonitorFor(monitor, Policy.totalWork / members.length));
break;
case IResource.FOLDER :
deletedChildren &= internalDeleteFolder((IFolder) child, flags, Policy.subMonitorFor(monitor, Policy.totalWork / members.length));
break;
}
}
IFileStore projectStore = localManager.getStore(project);
if (!deletedChildren)
return false;
String[] children;
try {
children = projectStore.childNames(EFS.NONE, null);
} catch (CoreException e) {
children = new String[0];
}
boolean force = BitMask.isSet(flags, IResource.FORCE);
if (!force && (children.length != 1 || !IProjectDescription.DESCRIPTION_FILE_NAME.equals(children[0]))) {
String message = NLS.bind(Messages.localstore_resourceIsOutOfSync, project.getName());
failed(new ResourceStatus(IResourceStatus.OUT_OF_SYNC_LOCAL, project.getFullPath(), message));
return false;
}
IResource file = project.findMember(IProjectDescription.DESCRIPTION_FILE_NAME);
if (file == null) {
IFileStore dotProject = projectStore.getChild(IProjectDescription.DESCRIPTION_FILE_NAME);
try {
dotProject.delete(EFS.NONE, null);
} catch (CoreException e) {
failed(e.getStatus());
}
} else {
boolean deletedProjectFile = internalDeleteFile((IFile) file, flags, Policy.monitorFor(null));
if (!deletedProjectFile) {
String message = NLS.bind(Messages.resources_couldnotDelete, file.getFullPath());
IStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, file.getFullPath(), message);
failed(status);
return false;
}
}
try {
projectStore.delete(EFS.NONE, null);
deletedProject(project);
return true;
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_couldnotDelete, projectStore.toString());
IStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, project.getFullPath(), message, e);
failed(status);
return false;
}
}
private boolean isContentChange(IProject project, IProjectDescription destDescription) {
IProjectDescription srcDescription = ((Project) project).internalGetDescription();
URI srcLocation = srcDescription.getLocationURI();
URI destLocation = destDescription.getLocationURI();
if (srcLocation == null || destLocation == null)
return true;
return !srcLocation.equals(destLocation);
}
private boolean isNameChange(IProject project, IProjectDescription description) {
return !project.getName().equals(description.getName());
}
private void safeRefresh(IResource resource) {
try {
resource.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
} catch (CoreException ce) {
IStatus status = new ResourceStatus(IStatus.ERROR, IResourceStatus.FAILED_DELETE_LOCAL, resource.getFullPath(), Messages.refresh_refreshErr, ce);
failed(status);
}
}
@Override
public boolean isSynchronized(IResource resource, int depth) {
try {
lock.acquire();
return localManager.isSynchronized(resource, depth);
} finally {
lock.release();
}
}
void makeInvalid() {
this.isValid = false;
}
@Override
public void movedFile(IFile source, IFile destination) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!source.exists())
return;
if (destination.exists()) {
String message = NLS.bind(Messages.resources_mustNotExist, destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, destination.getFullPath(), message);
failed(status);
}
IPropertyManager propertyManager = ((Resource) source).getPropertyManager();
try {
propertyManager.copy(source, destination, IResource.DEPTH_ZERO);
propertyManager.deleteProperties(source, IResource.DEPTH_ZERO);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorPropertiesMove, source.getFullPath(), destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
}
Workspace workspace = (Workspace) source.getWorkspace();
try {
workspace.move((Resource) source, destination.getFullPath(), IResource.DEPTH_ZERO, updateFlags, false);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorMoving, source.getFullPath(), destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
}
try {
workspace.getMarkerManager().moved(source, destination, IResource.DEPTH_ZERO);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorMarkersDelete, source.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
}
copyLocalHistory(source, destination);
} finally {
lock.release();
}
}
@Override
public void movedFolderSubtree(IFolder source, IFolder destination) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!source.exists())
return;
if (destination.exists()) {
String message = NLS.bind(Messages.resources_mustNotExist, destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, destination.getFullPath(), message);
failed(status);
return;
}
int depth = IResource.DEPTH_INFINITE;
IPropertyManager propertyManager = ((Resource) source).getPropertyManager();
try {
propertyManager.copy(source, destination, depth);
propertyManager.deleteProperties(source, depth);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorPropertiesMove, source.getFullPath(), destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
}
Workspace workspace = (Workspace) source.getWorkspace();
try {
workspace.move((Resource) source, destination.getFullPath(), depth, updateFlags, false);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorMoving, source.getFullPath(), destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
}
try {
workspace.getMarkerManager().moved(source, destination, depth);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorMarkersDelete, source.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
}
copyLocalHistory(source, destination);
} finally {
lock.release();
}
}
@Override
public boolean movedProjectSubtree(IProject project, IProjectDescription destDescription) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!project.exists())
return true;
Project source = (Project) project;
Project destination = (Project) source.getWorkspace().getRoot().getProject(destDescription.getName());
Workspace workspace = (Workspace) source.getWorkspace();
int depth = IResource.DEPTH_INFINITE;
if (isNameChange(source, destDescription)) {
if (destination.exists()) {
String message = NLS.bind(Messages.resources_mustNotExist, destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, destination.getFullPath(), message);
failed(status);
return false;
}
try {
source.getPropertyManager().closePropertyStore(source);
localManager.getHistoryStore().closeHistoryStore(source);
} catch (CoreException e) {
String message = NLS.bind(Messages.properties_couldNotClose, source.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
}
final IFileSystem fileSystem = EFS.getLocalFileSystem();
IFileStore oldMetaArea = fileSystem.getStore(workspace.getMetaArea().locationFor(source));
IFileStore newMetaArea = fileSystem.getStore(workspace.getMetaArea().locationFor(destination));
try {
oldMetaArea.move(newMetaArea, EFS.NONE, new NullProgressMonitor());
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_moveMeta, oldMetaArea, newMetaArea);
IStatus status = new ResourceStatus(IResourceStatus.FAILED_WRITE_METADATA, destination.getFullPath(), message, e);
failed(status);
}
try {
workspace.move(source, destination.getFullPath(), depth, updateFlags, true);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorMoving, source.getFullPath(), destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
}
((ProjectInfo) destination.getResourceInfo(false, true)).fixupAfterMove();
try {
workspace.getMarkerManager().moved(source, destination, depth);
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorMarkersMove, source.getFullPath(), destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
}
copyLocalHistory(source, destination);
}
try {
((ProjectDescription) destDescription).setLinkDescriptions(destination.internalGetDescription().getLinks());
((ProjectDescription) destDescription).setFilterDescriptions(destination.internalGetDescription().getFilters());
((ProjectDescription) destDescription).setVariableDescriptions(destination.internalGetDescription().getVariables());
destination.internalSetDescription(destDescription, true);
destination.writeDescription(IResource.FORCE);
} catch (CoreException e) {
String message = Messages.resources_projectDesc;
IStatus status = new ResourceStatus(IStatus.ERROR, destination.getFullPath(), message, e);
failed(status);
}
try {
workspace.getMetaArea().writePrivateDescription(destination);
} catch (CoreException e) {
failed(e.getStatus());
}
try {
destination.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
} catch (CoreException e) {
String message = NLS.bind(Messages.resources_errorRefresh, destination.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, destination.getFullPath(), message, e);
failed(status);
return false;
}
return true;
} finally {
lock.release();
}
}
private void moveProjectContent(IProject source, IFileStore destStore, int flags, IProgressMonitor monitor) throws CoreException {
try {
String message = NLS.bind(Messages.resources_moving, source.getFullPath());
monitor.beginTask(message, 10);
IProjectDescription srcDescription = source.getDescription();
URI srcLocation = srcDescription.getLocationURI();
if (srcLocation != null && URIUtil.equals(srcLocation, destStore.toURI()))
return;
boolean replace = (flags & IResource.REPLACE) != 0;
if (replace) {
destStore.mkdir(EFS.NONE, Policy.subMonitorFor(monitor, 10));
return;
}
localManager.move(source, destStore, flags, Policy.subMonitorFor(monitor, 9));
if ((flags & IResource.SHALLOW) == 0) {
IResource[] children = source.members();
for (IResource element : children) {
if (element.isLinked()) {
message = NLS.bind(Messages.resources_moving, element.getFullPath());
monitor.subTask(message);
IFileStore linkDestination = destStore.getChild(element.getName());
try {
localManager.move(element, linkDestination, flags, Policy.monitorFor(null));
} catch (CoreException ce) {
failed(ce.getStatus());
}
}
}
}
monitor.worked(1);
} finally {
monitor.done();
}
}
@Override
public void standardDeleteFile(IFile file, int flags, IProgressMonitor monitor) {
Assert.isLegal(isValid);
try {
lock.acquire();
internalDeleteFile(file, flags, monitor);
} finally {
lock.release();
}
}
@Override
public void standardDeleteFolder(IFolder folder, int flags, IProgressMonitor monitor) {
Assert.isLegal(isValid);
try {
lock.acquire();
internalDeleteFolder(folder, flags, monitor);
} catch (OperationCanceledException oce) {
safeRefresh(folder);
throw oce;
} finally {
lock.release();
monitor.done();
}
}
@Override
public void standardDeleteProject(IProject project, int flags, IProgressMonitor monitor) {
Assert.isLegal(isValid);
try {
lock.acquire();
String message = NLS.bind(Messages.resources_deleting, project.getFullPath());
monitor.beginTask(message, Policy.totalWork);
if (!project.exists())
return;
boolean alwaysDeleteContent = (flags & IResource.ALWAYS_DELETE_PROJECT_CONTENT) != 0;
boolean neverDeleteContent = (flags & IResource.NEVER_DELETE_PROJECT_CONTENT) != 0;
boolean success = true;
if (alwaysDeleteContent || (project.isOpen() && !neverDeleteContent)) {
if (alwaysDeleteContent || isSynchronized(project, IResource.DEPTH_INFINITE)) {
flags |= IResource.FORCE;
}
if (project.isOpen()) {
success = internalDeleteProject(project, flags, monitor);
if (!success) {
IFileStore store = localManager.getStore(project);
message = NLS.bind(Messages.resources_couldnotDelete, store.toString());
IStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, project.getFullPath(), message);
failed(status);
}
return;
}
try {
IFileStore projectStore = localManager.getStore(project);
IFileStore members[] = projectStore.childStores(EFS.NONE, null);
for (IFileStore member : members) {
if (!IProjectDescription.DESCRIPTION_FILE_NAME.equals(member.getName())) {
member.delete(EFS.NONE, Policy.subMonitorFor(monitor, Policy.totalWork * 7 / 8 / members.length));
}
}
projectStore.delete(EFS.NONE, Policy.subMonitorFor(monitor, Policy.totalWork * 7 / 8 / (members.length > 0 ? members.length : 1)));
} catch (OperationCanceledException oce) {
safeRefresh(project);
throw oce;
} catch (CoreException ce) {
message = NLS.bind(Messages.localstore_couldnotDelete, project.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, IResourceStatus.FAILED_DELETE_LOCAL, project.getFullPath(), message, ce);
failed(status);
return;
}
}
if (success)
deletedProject(project);
else {
message = NLS.bind(Messages.localstore_couldnotDelete, project.getFullPath());
IStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, project.getFullPath(), message);
failed(status);
}
} finally {
lock.release();
monitor.done();
}
}
@Override
public void standardMoveFile(IFile source, IFile destination, int flags, IProgressMonitor monitor) {
Assert.isLegal(isValid);
try {
lock.acquire();
String message = NLS.bind(Messages.resources_moving, source.getFullPath());
monitor.subTask(message);
if (!source.exists() || destination.exists() || !destination.getParent().isAccessible())
throw new IllegalArgumentException();
boolean force = (flags & IResource.FORCE) != 0;
boolean keepHistory = (flags & IResource.KEEP_HISTORY) != 0;
boolean isDeep = (flags & IResource.SHALLOW) == 0;
if (!force && !isSynchronized(source, IResource.DEPTH_INFINITE)) {
message = NLS.bind(Messages.localstore_resourceIsOutOfSync, source.getFullPath());
IStatus status = new ResourceStatus(IResourceStatus.OUT_OF_SYNC_LOCAL, source.getFullPath(), message);
failed(status);
return;
}
monitor.worked(Policy.totalWork / 4);
if (keepHistory)
addToLocalHistory(source);
monitor.worked(Policy.totalWork / 4);
if (!isDeep && source.isLinked()) {
movedFile(source, destination);
return;
}
IFileStore destStore = null;
boolean failedDeletingSource = false;
try {
destStore = localManager.getStore(destination);
destStore.getParent().mkdir(EFS.NONE, Policy.subMonitorFor(monitor, 0));
localManager.move(source, destStore, flags, monitor);
} catch (CoreException e) {
failed(e.getStatus());
failedDeletingSource = destStore != null && destStore.fetchInfo().exists();
if (!failedDeletingSource)
return;
}
movedFile(source, destination);
updateMovedFileTimestamp(destination, internalComputeTimestamp(destination));
if (failedDeletingSource) {
try {
source.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
}
}
monitor.worked(Policy.totalWork / 4);
return;
} finally {
lock.release();
monitor.done();
}
}
@Override
public void standardMoveFolder(IFolder source, IFolder destination, int flags, IProgressMonitor monitor) {
Assert.isLegal(isValid);
try {
lock.acquire();
String message = NLS.bind(Messages.resources_moving, source.getFullPath());
monitor.beginTask(message, 100);
if (!source.exists() || destination.exists() || !destination.getParent().isAccessible())
throw new IllegalArgumentException();
boolean force = (flags & IResource.FORCE) != 0;
if (!force && !isSynchronized(source, IResource.DEPTH_INFINITE)) {
message = NLS.bind(Messages.localstore_resourceIsOutOfSync, source.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message);
failed(status);
return;
}
monitor.worked(20);
boolean isDeep = (flags & IResource.SHALLOW) == 0;
if (!isDeep && (source.isLinked() || source.isVirtual())) {
movedFolderSubtree(source, destination);
return;
}
IFileStore destStore = null;
boolean failedDeletingSource = false;
try {
destStore = localManager.getStore(destination);
localManager.move(source, destStore, flags, Policy.subMonitorFor(monitor, 60));
} catch (CoreException e) {
failed(e.getStatus());
failedDeletingSource = destStore != null && destStore.fetchInfo().exists();
if (!failedDeletingSource)
return;
}
movedFolderSubtree(source, destination);
monitor.worked(20);
updateTimestamps(destination, isDeep);
if (failedDeletingSource) {
try {
source.refreshLocal(IResource.DEPTH_INFINITE, null);
destination.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
}
}
} finally {
lock.release();
monitor.done();
}
}
@Override
public void standardMoveProject(IProject source, IProjectDescription description, int flags, IProgressMonitor monitor) {
Assert.isLegal(isValid);
try {
lock.acquire();
String message = NLS.bind(Messages.resources_moving, source.getFullPath());
monitor.beginTask(message, Policy.totalWork);
if (!source.isAccessible())
throw new IllegalArgumentException();
if (!isContentChange(source, description)) {
movedProjectSubtree(source, description);
return;
}
boolean force = (flags & IResource.FORCE) != 0;
if (!force && !isSynchronized(source, IResource.DEPTH_INFINITE)) {
message = NLS.bind(Messages.localstore_resourceIsOutOfSync, source.getFullPath());
IStatus status = new ResourceStatus(IResourceStatus.OUT_OF_SYNC_LOCAL, source.getFullPath(), message);
failed(status);
return;
}
IFileStore destinationStore;
try {
destinationStore = computeDestinationStore(description);
if ((flags & IResource.REPLACE) == 0)
if (!ensureDestinationEmpty(source, destinationStore, monitor))
return;
} catch (CoreException e) {
message = NLS.bind(Messages.localstore_couldNotMove, source.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
return;
}
try {
moveProjectContent(source, destinationStore, flags, Policy.subMonitorFor(monitor, Policy.totalWork * 3 / 4));
} catch (CoreException e) {
message = NLS.bind(Messages.localstore_couldNotMove, source.getFullPath());
IStatus status = new ResourceStatus(IStatus.ERROR, source.getFullPath(), message, e);
failed(status);
try {
source.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e2) {
}
}
movedProjectSubtree(source, description);
monitor.worked(Policy.totalWork * 1 / 8);
boolean isDeep = (flags & IResource.SHALLOW) == 0;
updateTimestamps(source.getWorkspace().getRoot().getProject(description.getName()), isDeep);
monitor.worked(Policy.totalWork * 1 / 8);
} finally {
lock.release();
monitor.done();
}
}
@Override
public void updateMovedFileTimestamp(IFile file, long timestamp) {
Assert.isLegal(isValid);
try {
lock.acquire();
if (!file.exists())
return;
ResourceInfo info = ((Resource) file).getResourceInfo(false, true);
localManager.updateLocalSync(info, timestamp);
info.clear(ICoreConstants.M_LINK);
} finally {
lock.release();
}
}
private void updateTimestamps(IResource root, final boolean isDeep) {
IResourceVisitor visitor = resource -> {
if (resource.isLinked()) {
if (isDeep && !((Resource) resource).isUnderVirtual()) {
ResourceInfo info = ((Resource) resource).getResourceInfo(false, true);
info.clear(ICoreConstants.M_LINK);
}
return true;
}
return true;
};
try {
root.accept(visitor, IResource.DEPTH_INFINITE, IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
} catch (CoreException e) {
}
}
}