Skip to content

Commit a791b17

Browse files
committed
Cleanup progress monitor handling in resource plugin
This resolves several trace errors thrown by an improper use of the progress monitor while moving, deleting or copying files or folders. - ResourceTree The deprecated SubProgressMonitor has been replaced by a SubMonitor, due to an improved handling of rounding errors when reporting fractional work back to its parent. In addition, the standardMoveFile() method now explicitly calls beginTask() on its given progress monitor, to remain consistent with the standardMoveFolder() and standardMoveProject() methods and to avoid an error being reported when moving files. - DeleteVisitor beginTask() is called on the given progress monitor by converting it to a SubMonitor with the given number of ticks. This number is based on the number of to-be-deleted files. When deleting a file, a SubMonitor is used instead of the deprecated SubProgressMonitor, consuming a number of ticks based on the total number of ticks. - CopyVisitor This method has been adapted similarly to the DeleteVisitor as beginTask() also needs to be called on the given progress monitor here. Additionally, the progress handling has been adapted to avoid creating "zero ticks" SubMonitors, as this also causes an error.
1 parent f4e6c3b commit a791b17

File tree

5 files changed

+38
-26
lines changed

5 files changed

+38
-26
lines changed

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/CopyVisitor.java

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2015 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -68,13 +68,16 @@ public class CopyVisitor implements IUnifiedTreeVisitor {
6868

6969
private final FileSystemResourceManager localManager;
7070

71-
public CopyVisitor(IResource rootSource, IResource destination, int updateFlags, IProgressMonitor monitor) {
71+
/** amount of ticks consumed by the current file. Either 0 (out-of-sync) or 1 (in-sync) */
72+
private int work;
73+
74+
public CopyVisitor(IResource rootSource, IResource destination, int updateFlags, IProgressMonitor monitor, int ticks) {
7275
this.localManager = ((Resource) rootSource).getLocalManager();
7376
this.rootDestination = destination;
7477
this.updateFlags = updateFlags;
7578
this.isDeep = (updateFlags & IResource.SHALLOW) == 0;
7679
this.force = (updateFlags & IResource.FORCE) != 0;
77-
this.monitor = SubMonitor.convert(monitor);
80+
this.monitor = SubMonitor.convert(monitor, ticks);
7881
this.segmentsToDrop = rootSource.getFullPath().segmentCount();
7982
this.status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IStatus.INFO, Messages.localstore_copyProblem, null);
8083
}
@@ -111,10 +114,12 @@ protected boolean copyContents(UnifiedTreeNode node, Resource source, Resource d
111114

112115
IFileStore sourceStore = node.getStore();
113116
IFileStore destinationStore = destination.getStore();
117+
SubMonitor subMonitor = SubMonitor.convert(monitor.newChild(work), 2);
118+
work = 0;
114119
//ensure the parent of the root destination exists (bug 126104)
115120
if (destination == rootDestination)
116-
destinationStore.getParent().mkdir(EFS.NONE, monitor.newChild(0));
117-
sourceStore.copy(destinationStore, EFS.SHALLOW, monitor.newChild(0));
121+
destinationStore.getParent().mkdir(EFS.NONE, subMonitor.newChild(1));
122+
sourceStore.copy(destinationStore, EFS.SHALLOW, subMonitor.newChild(1));
118123
//create the destination in the workspace
119124
ResourceInfo info = localManager.getWorkspace().createResource(destination, updateFlags);
120125
localManager.updateLocalSync(info, destinationStore.fetchInfo().getLastModified());
@@ -189,7 +194,7 @@ protected void synchronize(UnifiedTreeNode node) throws CoreException {
189194
@Override
190195
public boolean visit(UnifiedTreeNode node) throws CoreException {
191196
monitor.checkCanceled();
192-
int work = 1;
197+
work = 1;
193198
try {
194199
//location can be null if based on an undefined variable
195200
if (node.getStore() == null) {
@@ -221,7 +226,10 @@ public boolean visit(UnifiedTreeNode node) throws CoreException {
221226
}
222227
return copy(node);
223228
} finally {
224-
monitor.worked(work);
229+
if (work != 0) {
230+
monitor.worked(work);
231+
}
232+
work = 0;
225233
}
226234
}
227235

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/DeleteVisitor.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2015 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -30,7 +30,7 @@
3030
public class DeleteVisitor implements IUnifiedTreeVisitor, ICoreConstants {
3131
protected boolean force;
3232
protected boolean keepHistory;
33-
protected IProgressMonitor monitor;
33+
protected SubMonitor monitor;
3434
protected List<Resource> skipList;
3535
protected MultiStatus status;
3636

@@ -44,7 +44,7 @@ public DeleteVisitor(List<Resource> skipList, int flags, IProgressMonitor monito
4444
this.ticks = ticks;
4545
this.force = (flags & IResource.FORCE) != 0;
4646
this.keepHistory = (flags & IResource.KEEP_HISTORY) != 0;
47-
this.monitor = monitor;
47+
this.monitor = SubMonitor.convert(monitor, ticks);
4848
status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_DELETE_LOCAL, Messages.localstore_deleteProblem, null);
4949
}
5050

@@ -63,7 +63,7 @@ protected void delete(UnifiedTreeNode node, boolean shouldKeepHistory) {
6363
int work = ticks < 0 ? 0 : ticks;
6464
ticks -= work;
6565
if (deleteLocalFile)
66-
localFile.delete(EFS.NONE, Policy.subMonitorFor(monitor, work));
66+
localFile.delete(EFS.NONE, monitor.split(work));
6767
else
6868
monitor.worked(work);
6969
//delete from tree

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2017 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -378,7 +378,8 @@ public void copy(IResource target, IResource destination, int updateFlags, IProg
378378
throw new ResourceException(IResourceStatus.FAILED_WRITE_LOCAL, destination.getFullPath(), message, null);
379379
}
380380
getHistoryStore().copyHistory(target, destination, false);
381-
CopyVisitor visitor = new CopyVisitor(target, destination, updateFlags, subMonitor.split(100));
381+
int totalWork = ((Resource) target).countResources(IResource.DEPTH_INFINITE, false);
382+
CopyVisitor visitor = new CopyVisitor(target, destination, updateFlags, subMonitor.split(100), totalWork);
382383
UnifiedTree tree = new UnifiedTree(target);
383384
tree.accept(visitor, IResource.DEPTH_INFINITE);
384385
IStatus status = visitor.getStatus();

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ResourceTree.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2015 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -337,9 +337,8 @@ private boolean internalDeleteFile(IFile file, int flags, IProgressMonitor monit
337337
*/
338338
private boolean internalDeleteFolder(IFolder folder, int flags, IProgressMonitor monitor) {
339339
String message = NLS.bind(Messages.resources_deleting, folder.getFullPath());
340-
monitor.beginTask("", Policy.totalWork); //$NON-NLS-1$
341-
monitor.subTask(message);
342-
Policy.checkCanceled(monitor);
340+
SubMonitor subMonitor = SubMonitor.convert(monitor, Policy.totalWork).checkCanceled();
341+
subMonitor.subTask(message);
343342

344343
// Do nothing if the folder doesn't exist in the workspace.
345344
if (!folder.exists())
@@ -360,7 +359,7 @@ private boolean internalDeleteFolder(IFolder folder, int flags, IProgressMonitor
360359

361360
try {
362361
//this will delete local and workspace
363-
localManager.delete(folder, flags, Policy.subMonitorFor(monitor, Policy.totalWork));
362+
localManager.delete(folder, flags, subMonitor.split(Policy.totalWork, SubMonitor.SUPPRESS_NONE));
364363
} catch (CoreException ce) {
365364
message = NLS.bind(Messages.localstore_couldnotDelete, folder.getFullPath());
366365
IStatus status = new ResourceStatus(IStatus.ERROR, IResourceStatus.FAILED_DELETE_LOCAL, folder.getFullPath(), message, ce);
@@ -907,7 +906,7 @@ public void standardMoveFile(IFile source, IFile destination, int flags, IProgre
907906
try {
908907
lock.acquire();
909908
String message = NLS.bind(Messages.resources_moving, source.getFullPath());
910-
monitor.subTask(message);
909+
monitor.beginTask(message, Policy.totalWork);
911910

912911
// These pre-conditions should all be ok but just in case...
913912
if (!source.exists() || destination.exists() || !destination.getParent().isAccessible())

resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/ResourceTestUtil.java

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023, 2024 Vector Informatik GmbH and others.
2+
* Copyright (c) 2023, 2025 Vector Informatik GmbH and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -63,6 +63,7 @@
6363
import org.eclipse.core.runtime.OperationCanceledException;
6464
import org.eclipse.core.runtime.Platform;
6565
import org.eclipse.core.runtime.Status;
66+
import org.eclipse.core.runtime.SubMonitor;
6667
import org.eclipse.core.runtime.jobs.ISchedulingRule;
6768
import org.eclipse.core.runtime.jobs.Job;
6869
import org.eclipse.core.tests.harness.FileSystemHelper;
@@ -187,8 +188,9 @@ public static void createInWorkspace(final IResource resource) throws CoreExcept
187188
*/
188189
public static void createInWorkspace(final IResource[] resources) throws CoreException {
189190
IWorkspaceRunnable body = monitor -> {
191+
SubMonitor subMonitor = SubMonitor.convert(monitor, resources.length);
190192
for (IResource resource : resources) {
191-
createInWorkspace(resource, monitor);
193+
createInWorkspace(resource, subMonitor.split(1));
192194
}
193195
};
194196
getWorkspace().run(body, createTestMonitor());
@@ -198,19 +200,21 @@ private static void createInWorkspace(final IResource resource, IProgressMonitor
198200
if (resource == null || resource.exists()) {
199201
return;
200202
}
203+
SubMonitor subMonitor = SubMonitor.convert(monitor, 2);
201204
if (!resource.getParent().exists()) {
202-
createInWorkspace(resource.getParent(), monitor);
205+
createInWorkspace(resource.getParent(), subMonitor.split(1));
203206
}
204207
switch (resource.getType()) {
205208
case IResource.FILE:
206-
((IFile) resource).create(nullInputStream(), true, monitor);
209+
((IFile) resource).create(nullInputStream(), true, subMonitor.split(1));
207210
break;
208211
case IResource.FOLDER:
209-
((IFolder) resource).create(true, true, monitor);
212+
((IFolder) resource).create(true, true, subMonitor.split(1));
210213
break;
211214
case IResource.PROJECT:
212-
((IProject) resource).create(monitor);
213-
((IProject) resource).open(monitor);
215+
subMonitor.setWorkRemaining(2);
216+
((IProject) resource).create(subMonitor.split(1));
217+
((IProject) resource).open(subMonitor.split(1));
214218
break;
215219
}
216220
}

0 commit comments

Comments
 (0)