package org.eclipse.ltk.core.refactoring.resource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.ChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.internal.core.refactoring.BasicElementLabels;
import org.eclipse.ltk.internal.core.refactoring.Messages;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCoreMessages;
public class MoveResourceChange extends ResourceChange {
private final IResource fSource;
private final IContainer fTarget;
private final long fStampToRestore;
private final Change fRestoreSourceChange;
private ChangeDescriptor fDescriptor;
public MoveResourceChange(IResource source, IContainer target) {
this(source, target, IResource.NULL_STAMP, null);
}
protected MoveResourceChange(IResource source, IContainer target, long stampToRestore, Change restoreSourceChange) {
fSource= source;
fTarget= target;
fStampToRestore= stampToRestore;
fRestoreSourceChange= restoreSourceChange;
setValidationMethod(VALIDATE_NOT_DIRTY);
}
@Override
public ChangeDescriptor getDescriptor() {
return fDescriptor;
}
public void setDescriptor(ChangeDescriptor descriptor) {
fDescriptor= descriptor;
}
@Override
public final Change perform(IProgressMonitor monitor) throws CoreException, OperationCanceledException {
try {
if (monitor == null)
monitor= new NullProgressMonitor();
monitor.beginTask(getName(), 4);
Change deleteUndo= null;
IResource resourceAtDestination= fTarget.findMember(fSource.getName());
if (resourceAtDestination != null && resourceAtDestination.exists()) {
deleteUndo= performDestinationDelete(resourceAtDestination, new SubProgressMonitor(monitor, 1));
} else {
monitor.worked(1);
}
long currentStamp= fSource.getModificationStamp();
IPath destinationPath= fTarget.getFullPath().append(fSource.getName());
fSource.move(destinationPath, IResource.KEEP_HISTORY | IResource.SHALLOW, new SubProgressMonitor(monitor, 2));
resourceAtDestination= ResourcesPlugin.getWorkspace().getRoot().findMember(destinationPath);
if (fStampToRestore != IResource.NULL_STAMP) {
resourceAtDestination.revertModificationStamp(fStampToRestore);
}
if (fRestoreSourceChange != null) {
performSourceRestore(new SubProgressMonitor(monitor, 1));
} else {
monitor.worked(1);
}
return new MoveResourceChange(resourceAtDestination, fSource.getParent(), currentStamp, deleteUndo);
} finally {
monitor.done();
}
}
private Change performDestinationDelete(IResource newResource, IProgressMonitor monitor) throws CoreException {
monitor.beginTask(RefactoringCoreMessages.MoveResourceChange_progress_delete_destination, 3);
try {
DeleteResourceChange deleteChange= new DeleteResourceChange(newResource.getFullPath(), true);
deleteChange.initializeValidationData(new SubProgressMonitor(monitor, 1));
RefactoringStatus deleteStatus= deleteChange.isValid(new SubProgressMonitor(monitor, 1));
if (!deleteStatus.hasFatalError()) {
return deleteChange.perform(new SubProgressMonitor(monitor, 1));
}
return null;
} finally {
monitor.done();
}
}
private void performSourceRestore(IProgressMonitor monitor) throws CoreException {
monitor.beginTask(RefactoringCoreMessages.MoveResourceChange_progress_restore_source, 3);
try {
fRestoreSourceChange.initializeValidationData(new SubProgressMonitor(monitor, 1));
RefactoringStatus restoreStatus= fRestoreSourceChange.isValid(new SubProgressMonitor(monitor, 1));
if (!restoreStatus.hasFatalError()) {
fRestoreSourceChange.perform(new SubProgressMonitor(monitor, 1));
}
} finally {
monitor.done();
}
}
@Override
protected IResource getModifiedResource() {
return fSource;
}
@Override
public String getName() {
return Messages.format(RefactoringCoreMessages.MoveResourceChange_name, new String[] { BasicElementLabels.getPathLabel(fSource.getFullPath(), false), BasicElementLabels.getResourceName(fTarget) });
}
}