### Eclipse Workspace Patch 1.0 #P com.stambia.di diff --git designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ResourceDelta.java designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ResourceDelta.java index f09ceb3..2b12049 100644 --- designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ResourceDelta.java +++ designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ResourceDelta.java @@ -17,10 +17,22 @@ import java.util.Map; import java.util.Map.Entry; -import org.eclipse.core.internal.resources.*; + +import org.eclipse.core.internal.resources.ICoreConstants; +import org.eclipse.core.internal.resources.IMarkerSetElement; +import org.eclipse.core.internal.resources.MarkerSet; +import org.eclipse.core.internal.resources.ResourceInfo; import org.eclipse.core.internal.watson.ElementTree; -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.PlatformObject; /** * Concrete implementation of the IResourceDelta interface. Each ResourceDelta @@ -131,35 +143,38 @@ if (!path.isRoot() && !nodeIDMap.isEmpty()) { int kind = getKind(); switch (kind) { - case CHANGED : - case ADDED : - IPath oldPath = nodeIDMap.getOldPath(newInfo.getNodeId()); - if (oldPath != null && !oldPath.equals(path)) { - //get the old info from the old tree - ResourceInfo actualOldInfo = (ResourceInfo) oldTree.getElementData(oldPath); - // Replace change flags by comparing old info with new info, - // Note that we want to retain the kind flag, but replace all other flags - // This is done only for MOVED_FROM, not MOVED_TO, since a resource may be both. - status = (status & KIND_MASK) | (deltaInfo.getComparator().compare(actualOldInfo, newInfo) & ~KIND_MASK); - status |= MOVED_FROM; - //our API states that MOVED_FROM must be in conjunction with ADDED | (CHANGED + REPLACED) - if (kind == CHANGED) - status = status | REPLACED | CONTENT; - //check for gender change - if (oldInfo != null && newInfo != null && oldInfo.getType() != newInfo.getType()) - status |= TYPE; - } + case CHANGED : + case ADDED : + IPath oldPath = nodeIDMap.getOldPath(newInfo.getNodeId()); + if (oldPath != null && !oldPath.equals(path)) { + //get the old info from the old tree + ResourceInfo actualOldInfo = (ResourceInfo) oldTree.getElementData(oldPath); + // Replace change flags by comparing old info with new info, + // Note that we want to retain the kind flag, but replace all other flags + // This is done only for MOVED_FROM, not MOVED_TO, since a resource may be both. + status = (status & KIND_MASK) | (deltaInfo.getComparator().compare(actualOldInfo, newInfo) & ~KIND_MASK); + status |= MOVED_FROM; + //our API states that MOVED_FROM must be in conjunction with ADDED | (CHANGED + REPLACED) + if (kind == CHANGED) + status = status | REPLACED | CONTENT; + //check for gender change + if (oldInfo != null && newInfo != null && oldInfo.getType() != newInfo.getType()) + status |= TYPE; + } else if (kind == ADDED && oldInfo != null) { + // We only have an oldInfo if not a move then for a copy + status |= COPIED_FROM; + } } switch (kind) { - case REMOVED : - case CHANGED : - IPath newPath = nodeIDMap.getNewPath(oldInfo.getNodeId()); - if (newPath != null && !newPath.equals(path)) { - status |= MOVED_TO; - //our API states that MOVED_TO must be in conjunction with REMOVED | (CHANGED + REPLACED) - if (kind == CHANGED) - status = status | REPLACED | CONTENT; - } + case REMOVED : + case CHANGED : + IPath newPath = nodeIDMap.getNewPath(oldInfo.getNodeId()); + if (newPath != null && !newPath.equals(path)) { + status |= MOVED_TO; + //our API states that MOVED_TO must be in conjunction with REMOVED | (CHANGED + REPLACED) + if (kind == CHANGED) + status = status | REPLACED | CONTENT; + } } } @@ -272,6 +287,12 @@ if ((status & MOVED_FROM) != 0) { return deltaInfo.getNodeIDMap().getOldPath(newInfo.getNodeId()); } + if ((status & (COPIED_FROM)) != 0) { + // We can do this because the this implementation is only good within + // the listener + IResource oldRes = (IResource) deltaInfo.getWorkspace().getCopyMapRead().get(Long.valueOf(newInfo.getNodeId())); + return oldRes.getFullPath(); + } return null; } @@ -411,27 +432,27 @@ buffer.append(getFullPath()); buffer.append('['); switch (getKind()) { - case ADDED : - buffer.append('+'); - break; - case ADDED_PHANTOM : - buffer.append('>'); - break; - case REMOVED : - buffer.append('-'); - break; - case REMOVED_PHANTOM : - buffer.append('<'); - break; - case CHANGED : - buffer.append('*'); - break; - case NO_CHANGE : - buffer.append('~'); - break; - default : - buffer.append('?'); - break; + case ADDED : + buffer.append('+'); + break; + case ADDED_PHANTOM : + buffer.append('>'); + break; + case REMOVED : + buffer.append('-'); + break; + case REMOVED_PHANTOM : + buffer.append('<'); + break; + case CHANGED : + buffer.append('*'); + break; + case NO_CHANGE : + buffer.append('~'); + break; + default : + buffer.append('?'); + break; } buffer.append("]: {"); //$NON-NLS-1$ int changeFlags = getFlags(); @@ -442,6 +463,12 @@ buffer.append("CONTENT"); //$NON-NLS-1$ prev = true; } + if ((changeFlags & COPIED_FROM) != 0) { + if (prev) + buffer.append(" | "); //$NON-NLS-1$ + buffer.append("COPIED_FROM(" + getMovedFromPath() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + prev = true; + } if ((changeFlags & LOCAL_CHANGED) != 0) { if (prev) buffer.append(" | "); //$NON-NLS-1$ @@ -532,15 +559,15 @@ if (addComma) buffer.append(','); switch (delta.getKind()) { - case IResourceDelta.ADDED : - buffer.append('+'); - break; - case IResourceDelta.REMOVED : - buffer.append('-'); - break; - case IResourceDelta.CHANGED : - buffer.append('*'); - break; + case IResourceDelta.ADDED : + buffer.append('+'); + break; + case IResourceDelta.REMOVED : + buffer.append('-'); + break; + case IResourceDelta.CHANGED : + buffer.append('*'); + break; } buffer.append(delta.getId()); addComma = true; diff --git designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ResourceDeltaFactory.java designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ResourceDeltaFactory.java index 6b4ed0a..dbf44a6 100644 --- designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ResourceDeltaFactory.java +++ designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/events/ResourceDeltaFactory.java @@ -15,9 +15,15 @@ package org.eclipse.core.internal.events; import java.util.Map; + import org.eclipse.core.internal.dtree.DeltaDataTree; import org.eclipse.core.internal.dtree.NodeComparison; -import org.eclipse.core.internal.resources.*; +import org.eclipse.core.internal.resources.ICoreConstants; +import org.eclipse.core.internal.resources.MarkerSet; +import org.eclipse.core.internal.resources.Project; +import org.eclipse.core.internal.resources.Resource; +import org.eclipse.core.internal.resources.ResourceInfo; +import org.eclipse.core.internal.resources.Workspace; import org.eclipse.core.internal.watson.ElementTree; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResourceDelta; @@ -103,21 +109,21 @@ ResourceDelta child = (ResourceDelta) element; IPath path = child.getFullPath(); switch (child.getKind()) { - case IResourceDelta.ADDED : - nodeIDMap.putNewPath(child.newInfo.getNodeId(), path); - break; - case IResourceDelta.REMOVED : - nodeIDMap.putOldPath(child.oldInfo.getNodeId(), path); - break; - case IResourceDelta.CHANGED : - long oldID = child.oldInfo.getNodeId(); - long newID = child.newInfo.getNodeId(); - //don't add entries to the map if nothing has changed. - if (oldID != newID) { - nodeIDMap.putOldPath(oldID, path); - nodeIDMap.putNewPath(newID, path); - } - break; + case IResourceDelta.ADDED : + nodeIDMap.putNewPath(child.newInfo.getNodeId(), path); + break; + case IResourceDelta.REMOVED : + nodeIDMap.putOldPath(child.oldInfo.getNodeId(), path); + break; + case IResourceDelta.CHANGED : + long oldID = child.oldInfo.getNodeId(); + long newID = child.newInfo.getNodeId(); + //don't add entries to the map if nothing has changed. + if (oldID != newID) { + nodeIDMap.putOldPath(oldID, path); + nodeIDMap.putNewPath(newID, path); + } + break; } //recurse computeNodeIDMap(child, nodeIDMap); @@ -145,6 +151,14 @@ result.setOldInfo((ResourceInfo) compare.getOldData()); result.setNewInfo((ResourceInfo) compare.getNewData()); } + // fix bug 217489 + // See if this is a copy and get the info + if (comparison == IResourceDelta.ADDED && workspace.getCopyMapRead() != null) { + Resource sourceRes = (Resource) workspace.getCopyMapRead().get(Long.valueOf(result.newInfo.getNodeId())); + if (sourceRes != null) + result.setOldInfo(sourceRes.getResourceInfo(false, false)); + } + // recurse over the children IPath[] childKeys = delta.getChildren(pathInDelta); int numChildren = childKeys.length; diff --git designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java index 5a0b018..26a6571 100644 --- designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java +++ designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java @@ -11,17 +11,33 @@ * Contributors: * IBM Corporation - initial API and implementation * Serge Beauchamp (Freescale Semiconductor) - [252996] add resource filtering -*******************************************************************************/ + *******************************************************************************/ package org.eclipse.core.internal.localstore; import java.net.URI; import java.util.LinkedList; + import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; -import org.eclipse.core.internal.resources.*; +import org.eclipse.core.internal.resources.Container; +import org.eclipse.core.internal.resources.File; +import org.eclipse.core.internal.resources.FilterDescription; +import org.eclipse.core.internal.resources.Folder; +import org.eclipse.core.internal.resources.Project; +import org.eclipse.core.internal.resources.Resource; +import org.eclipse.core.internal.resources.ResourceInfo; +import org.eclipse.core.internal.resources.ResourceStatus; +import org.eclipse.core.internal.resources.Workspace; import org.eclipse.core.internal.utils.Messages; -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceStatus; +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.MultiStatus; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.osgi.util.NLS; // @@ -70,7 +86,12 @@ Resource destination = getDestinationResource(source, sufix); if (!copyProperties(source, destination)) return false; - return copyContents(node, source, destination); + boolean result = copyContents(node, source, destination); + + // fix bug 217489 + ((Workspace) source.getWorkspace()).getCopyMap() + .put(Long.valueOf(destination.getResourceInfo(false, false).getNodeId()), source); + return result; } protected boolean copyContents(UnifiedTreeNode node, Resource source, Resource destination) { diff --git designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Project.java designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Project.java index ead6c1f..c9a3d78 100644 --- designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Project.java +++ designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Project.java @@ -20,13 +20,45 @@ package org.eclipse.core.internal.resources; import java.net.URI; -import java.util.*; -import org.eclipse.core.filesystem.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.TreeSet; + +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileInfo; +import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.internal.events.LifecycleEvent; -import org.eclipse.core.internal.utils.*; -import org.eclipse.core.resources.*; +import org.eclipse.core.internal.utils.FileUtil; +import org.eclipse.core.internal.utils.Messages; +import org.eclipse.core.internal.utils.Policy; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IProjectNature; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceStatus; +import org.eclipse.core.resources.ISaveContext; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.team.IMoveDeleteHook; -import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ICoreRunnable; +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.SubMonitor; import org.eclipse.core.runtime.content.IContentTypeMatcher; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; @@ -690,6 +722,13 @@ // write out the new project description to the meta area try { destination.writeDescription(IResource.FORCE); + // fix bug 217489 + Resource descFileSource = (Resource) getFile(IProjectDescription.DESCRIPTION_FILE_NAME); + Resource descFileDest = (Resource) destination.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); + // For tracking COPIED_FROM + workspace.getCopyMap().put(Long.valueOf(descFileDest.getResourceInfo(false, false).getNodeId()), + descFileSource); + } catch (CoreException e) { try { destination.delete((updateFlags & IResource.FORCE) != 0, null); diff --git designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java index 1c70c20..095e964 100644 --- designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java +++ designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java @@ -25,18 +25,57 @@ import java.net.URI; import java.net.URISyntaxException; -import java.util.*; -import org.eclipse.core.filesystem.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileInfo; +import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.filesystem.provider.FileInfo; import org.eclipse.core.internal.events.LifecycleEvent; import org.eclipse.core.internal.localstore.FileSystemResourceManager; import org.eclipse.core.internal.properties.IPropertyManager; -import org.eclipse.core.internal.utils.*; -import org.eclipse.core.internal.watson.*; -import org.eclipse.core.resources.*; +import org.eclipse.core.internal.utils.FileUtil; +import org.eclipse.core.internal.utils.Messages; +import org.eclipse.core.internal.utils.WrappedRuntimeException; +import org.eclipse.core.internal.watson.ElementTreeIterator; +import org.eclipse.core.internal.watson.IElementContentVisitor; +import org.eclipse.core.internal.watson.IPathRequestor; +import org.eclipse.core.resources.FileInfoMatcherDescription; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IPathVariableManager; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceProxy; +import org.eclipse.core.resources.IResourceProxyVisitor; +import org.eclipse.core.resources.IResourceStatus; +import org.eclipse.core.resources.IResourceVisitor; +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.team.IMoveDeleteHook; -import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.Assert; +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.MultiStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.MultiRule; import org.eclipse.osgi.util.NLS; @@ -72,15 +111,15 @@ try { boolean shouldContinue = true; switch (depth) { - case DEPTH_ZERO : - shouldContinue = false; - break; - case DEPTH_ONE : - shouldContinue = !path.equals(requestor.requestPath().removeLastSegments(1)); - break; - case DEPTH_INFINITE : - shouldContinue = true; - break; + case DEPTH_ZERO : + shouldContinue = false; + break; + case DEPTH_ONE : + shouldContinue = !path.equals(requestor.requestPath().removeLastSegments(1)); + break; + case DEPTH_INFINITE : + shouldContinue = true; + break; } return visitor.visit(proxy) && shouldContinue; } catch (CoreException e) { @@ -586,6 +625,11 @@ // Copy over the properties. getPropertyManager().copy(this, destProject, DEPTH_ZERO); + + // fix bug 217489 + // For tracking COPIED_FROM + workspace.getCopyMap().put(Long.valueOf(destProject.getResourceInfo(false, false).getNodeId()), this); + progress.split(18); } catch (OperationCanceledException e) { workspace.getWorkManager().operationCanceled(); @@ -1202,14 +1246,14 @@ public String getTypeString() { switch (getType()) { - case FILE : - return "L"; //$NON-NLS-1$ - case FOLDER : - return "F"; //$NON-NLS-1$ - case PROJECT : - return "P"; //$NON-NLS-1$ - case ROOT : - return "R"; //$NON-NLS-1$ + case FILE : + return "L"; //$NON-NLS-1$ + case FOLDER : + return "F"; //$NON-NLS-1$ + case PROJECT : + return "P"; //$NON-NLS-1$ + case ROOT : + return "R"; //$NON-NLS-1$ } return ""; //$NON-NLS-1$ } @@ -1856,37 +1900,37 @@ private void broadcastPreDeleteEvent() throws CoreException { switch (getType()) { - case IResource.PROJECT : - workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_DELETE, this)); - break; - case IResource.ROOT : - // All root children including hidden projects will be deleted so notify. - IResource[] projects = ((Container) this).getChildren(IContainer.INCLUDE_HIDDEN); - for (IResource project2 : projects) { - workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_DELETE, project2)); - } - break; + case IResource.PROJECT : + workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_DELETE, this)); + break; + case IResource.ROOT : + // All root children including hidden projects will be deleted so notify. + IResource[] projects = ((Container) this).getChildren(IContainer.INCLUDE_HIDDEN); + for (IResource project2 : projects) { + workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_DELETE, project2)); + } + break; } } private void broadcastPreMoveEvent(final IResource destination, int updateFlags) throws CoreException { switch (getType()) { - case IResource.FILE : - if (isLinked()) - workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_LINK_MOVE, this, destination, updateFlags)); - break; - case IResource.FOLDER : - if (isLinked()) - workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_LINK_MOVE, this, destination, updateFlags)); - if (isVirtual()) - workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_GROUP_MOVE, this, destination, updateFlags)); - break; - case IResource.PROJECT : - if (!getName().equals(destination.getName())) { - // If there is a change in name, we are deleting the source project so notify. - workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_MOVE, this, destination, updateFlags)); - } - break; + case IResource.FILE : + if (isLinked()) + workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_LINK_MOVE, this, destination, updateFlags)); + break; + case IResource.FOLDER : + if (isLinked()) + workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_LINK_MOVE, this, destination, updateFlags)); + if (isVirtual()) + workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_GROUP_MOVE, this, destination, updateFlags)); + break; + case IResource.PROJECT : + if (!getName().equals(destination.getName())) { + // If there is a change in name, we are deleting the source project so notify. + workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_MOVE, this, destination, updateFlags)); + } + break; } } diff --git designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java index e72cc42..49adb43 100644 --- designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java +++ designer/bundles/patch/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java @@ -22,13 +22,34 @@ import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; -import java.util.*; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Predicate; + import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.URIUtil; -import org.eclipse.core.internal.events.*; +import org.eclipse.core.internal.events.BuildManager; +import org.eclipse.core.internal.events.ILifecycleListener; +import org.eclipse.core.internal.events.LifecycleEvent; +import org.eclipse.core.internal.events.NotificationManager; +import org.eclipse.core.internal.events.ResourceChangeEvent; +import org.eclipse.core.internal.events.ResourceComparator; import org.eclipse.core.internal.localstore.FileSystemResourceManager; import org.eclipse.core.internal.preferences.PreferencesService; import org.eclipse.core.internal.properties.IPropertyManager; @@ -36,12 +57,63 @@ import org.eclipse.core.internal.refresh.RefreshManager; import org.eclipse.core.internal.resources.ComputeProjectOrder.Digraph; import org.eclipse.core.internal.resources.ComputeProjectOrder.VertexOrder; -import org.eclipse.core.internal.utils.*; -import org.eclipse.core.internal.watson.*; -import org.eclipse.core.resources.*; -import org.eclipse.core.resources.team.*; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.*; +import org.eclipse.core.internal.utils.Messages; +import org.eclipse.core.internal.utils.Policy; +import org.eclipse.core.internal.utils.StringPoolJob; +import org.eclipse.core.internal.watson.ElementTree; +import org.eclipse.core.internal.watson.ElementTreeIterator; +import org.eclipse.core.internal.watson.IElementContentVisitor; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFileModificationValidator; +import org.eclipse.core.resources.IFilterMatcherDescriptor; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IPathVariableManager; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IProjectNatureDescriptor; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceRuleFactory; +import org.eclipse.core.resources.IResourceStatus; +import org.eclipse.core.resources.ISaveContext; +import org.eclipse.core.resources.ISaveParticipant; +import org.eclipse.core.resources.ISavedState; +import org.eclipse.core.resources.ISynchronizer; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceDescription; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.resources.team.FileModificationValidationContext; +import org.eclipse.core.resources.team.FileModificationValidator; +import org.eclipse.core.resources.team.IMoveDeleteHook; +import org.eclipse.core.resources.team.TeamHook; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.ICoreRunnable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobGroup; import org.eclipse.osgi.util.NLS; import org.osgi.framework.Bundle; import org.xml.sax.InputSource; @@ -188,6 +260,20 @@ protected IFileModificationValidator validator = null; /** + * Map K(new resource node Id (Long)) V(old resource (Resource)) used to + * find the resource that was copied from. Used only during Resource.copy() + * We use the nodeId as the key so we don't have to create a resource + * when checking the map during delta computation. The value can be a resource + * because that's already available during the copy. + * + * The copyMap is created automatically when first written to, and removed at + * the end of the top level operation if it exists. + * + * fix bug 217489 + */ + protected Map copyMap; + + /** * Data structure for holding the multi-part outcome of * IWorkspace.computeProjectBuildConfigOrder. *

@@ -1139,6 +1225,9 @@ project.writeDescription(updateFlags); } + // For tracking COPIED_FROM + getCopyMap().put(Long.valueOf(newInfo.getNodeId()), source); + // do the recursion. if we have a file then it has no members so return. otherwise // recursively call this method on the container's members if the depth tells us to if (depth == IResource.DEPTH_ZERO || source.getType() == IResource.FILE) @@ -1195,7 +1284,7 @@ IPath srcValue = URIUtil.toPath(srcPathVariableManager.getURIValue(variable)); if (srcValue == null) // if the variable doesn't exist, return another - // variable that doesn't exist either + // variable that doesn't exist either return PathVariableUtil.getUniqueVariableName(variable, dest); IPath resolvedSrcValue = URIUtil.toPath(srcPathVariableManager.resolveURI(URIUtil.toURI(srcValue))); @@ -1276,19 +1365,19 @@ if (!tree.includes(root)) return 0; switch (depth) { - case IResource.DEPTH_ZERO : - return 1; - case IResource.DEPTH_ONE : - return 1 + tree.getChildCount(root); - case IResource.DEPTH_INFINITE : - final int[] count = new int[1]; - IElementContentVisitor visitor = (aTree, requestor, elementContents) -> { - if (phantom || !((ResourceInfo) elementContents).isSet(M_PHANTOM)) - count[0]++; - return true; - }; - new ElementTreeIterator(tree, root).iterate(visitor); - return count[0]; + case IResource.DEPTH_ZERO : + return 1; + case IResource.DEPTH_ONE : + return 1 + tree.getChildCount(root); + case IResource.DEPTH_INFINITE : + final int[] count = new int[1]; + IElementContentVisitor visitor = (aTree, requestor, elementContents) -> { + if (phantom || !((ResourceInfo) elementContents).isSet(M_PHANTOM)) + count[0]++; + return true; + }; + new ElementTreeIterator(tree, root).iterate(visitor); + return count[0]; } return 0; } @@ -1639,7 +1728,7 @@ for (IProject project : projects) { if (!project.isAccessible()) { continue; - } + } IProject[] refs = ((Project)project).internalGetDescription().getReferencedProjects(false); List dangling = new ArrayList<>(refs.length); for (IProject ref : refs) { @@ -1904,8 +1993,8 @@ //create anonymous subclass because TeamHook is abstract if (teamHook == null) teamHook = new TeamHook() { - // empty - }; + // empty + }; } } @@ -2101,16 +2190,16 @@ protected ResourceInfo newElement(int type) { ResourceInfo result = null; switch (type) { - case IResource.FILE : - case IResource.FOLDER : - result = new ResourceInfo(); - break; - case IResource.PROJECT : - result = new ProjectInfo(); - break; - case IResource.ROOT : - result = new RootInfo(); - break; + case IResource.FILE : + case IResource.FOLDER : + result = new ResourceInfo(); + break; + case IResource.PROJECT : + result = new ProjectInfo(); + break; + case IResource.ROOT : + result = new RootInfo(); + break; } result.setNodeId(nextNodeId()); updateModificationStamp(result); @@ -2133,22 +2222,22 @@ public Resource newResource(IPath path, int type) { String message; switch (type) { - case IResource.FOLDER : - if (path.segmentCount() < ICoreConstants.MINIMUM_FOLDER_SEGMENT_LENGTH) { - message = "Path must include project and resource name: " + path.toString(); //$NON-NLS-1$ - Assert.isLegal(false, message); - } - return new Folder(path.makeAbsolute(), this); - case IResource.FILE : - if (path.segmentCount() < ICoreConstants.MINIMUM_FILE_SEGMENT_LENGTH) { - message = "Path must include project and resource name: " + path.toString(); //$NON-NLS-1$ - Assert.isLegal(false, message); - } - return new File(path.makeAbsolute(), this); - case IResource.PROJECT : - return (Resource) getRoot().getProject(path.lastSegment()); - case IResource.ROOT : - return (Resource) getRoot(); + case IResource.FOLDER : + if (path.segmentCount() < ICoreConstants.MINIMUM_FOLDER_SEGMENT_LENGTH) { + message = "Path must include project and resource name: " + path.toString(); //$NON-NLS-1$ + Assert.isLegal(false, message); + } + return new Folder(path.makeAbsolute(), this); + case IResource.FILE : + if (path.segmentCount() < ICoreConstants.MINIMUM_FILE_SEGMENT_LENGTH) { + message = "Path must include project and resource name: " + path.toString(); //$NON-NLS-1$ + Assert.isLegal(false, message); + } + return new File(path.makeAbsolute(), this); + case IResource.PROJECT : + return (Resource) getRoot().getProject(path.lastSegment()); + case IResource.ROOT : + return (Resource) getRoot(); } Assert.isLegal(false); // will never get here because of assertion. @@ -2648,4 +2737,15 @@ } return Status.OK_STATUS; } + + public Map getCopyMap() { + if (copyMap == null) + copyMap = new HashMap<>(); + return copyMap; + } + + public Map getCopyMapRead() { + // Don't create it + return copyMap; + } }