From 4ab0a3883871b7c83288dc8a93f0e1b495555b8b Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Fri, 6 Oct 2023 11:59:42 -0400 Subject: [PATCH 1/5] Fixes #1162 - Consume api pushdown of resource descriptions (#1163) Fixes #1162 - Consume api pushdown of resource descriptions Signed-off-by: Rob Stryker --- .../org.eclipse.ui.ide/META-INF/MANIFEST.MF | 4 +- .../AbstractCreateResourcesOperation.java | 5 +- .../ui/ide/undo/AbstractMarkersOperation.java | 13 +- .../ide/undo/AbstractResourcesOperation.java | 15 +- .../ui/ide/undo/CopyProjectOperation.java | 11 +- .../ui/ide/undo/CopyResourcesOperation.java | 23 +- .../ui/ide/undo/CreateFileOperation.java | 60 +--- .../ui/ide/undo/CreateFolderOperation.java | 54 ++- .../ui/ide/undo/CreateMarkersOperation.java | 16 +- .../ui/ide/undo/CreateProjectOperation.java | 6 +- .../ui/ide/undo/DeleteResourcesOperation.java | 3 +- .../ui/ide/undo/MoveProjectOperation.java | 3 +- .../ui/ide/undo/MoveResourcesOperation.java | 11 +- .../ui/ide/undo/ResourceDescription.java | 123 ++++--- .../ui/ide/undo/WorkspaceUndoUtil.java | 89 +++-- .../ide/undo/AbstractResourceDescription.java | 141 -------- .../ide/undo/ContainerDescription.java | 311 ------------------ .../ui/internal/ide/undo/FileDescription.java | 212 ------------ .../internal/ide/undo/FolderDescription.java | 104 ------ .../ide/undo/IFileContentDescription.java | 60 ---- .../internal/ide/undo/MarkerDescription.java | 111 ------- .../internal/ide/undo/ProjectDescription.java | 119 ------- .../ui/internal/ide/undo/UndoMessages.java | 6 - .../ui/internal/ide/undo/messages.properties | 5 - 24 files changed, 251 insertions(+), 1254 deletions(-) delete mode 100755 bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/AbstractResourceDescription.java delete mode 100644 bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/ContainerDescription.java delete mode 100644 bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/FileDescription.java delete mode 100644 bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/FolderDescription.java delete mode 100644 bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/IFileContentDescription.java delete mode 100644 bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/MarkerDescription.java delete mode 100644 bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/ProjectDescription.java diff --git a/bundles/org.eclipse.ui.ide/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.ide/META-INF/MANIFEST.MF index c8e6aa8ad1c..22c448543e6 100644 --- a/bundles/org.eclipse.ui.ide/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ui.ide/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Plugin.name Bundle-SymbolicName: org.eclipse.ui.ide; singleton:=true -Bundle-Version: 3.21.200.qualifier +Bundle-Version: 3.22.0.qualifier Bundle-Activator: org.eclipse.ui.internal.ide.IDEWorkbenchPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %Plugin.providerName @@ -45,7 +45,7 @@ Export-Package: org.eclipse.ui, org.eclipse.ui.views.tasklist, org.eclipse.ui.wizards.datatransfer, org.eclipse.ui.wizards.newresource -Require-Bundle: org.eclipse.core.resources;bundle-version="[3.19.0,4.0.0)";resolution:=optional, +Require-Bundle: org.eclipse.core.resources;bundle-version="[3.20.0,4.0.0)";resolution:=optional, org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.core.filesystem;bundle-version="[1.10.0,2.0.0)", org.eclipse.help;bundle-version="[3.10.0,4.0.0)", diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractCreateResourcesOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractCreateResourcesOperation.java index 77c4717a62a..737d31be168 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractCreateResourcesOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractCreateResourcesOperation.java @@ -16,6 +16,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; @@ -44,7 +45,7 @@ abstract class AbstractCreateResourcesOperation extends * the label of the operation */ AbstractCreateResourcesOperation( - ResourceDescription[] resourceDescriptions, String label) { + IResourceSnapshot[] resourceDescriptions, String label) { super(resourceDescriptions, label); } @@ -80,7 +81,7 @@ protected boolean updateResourceChangeDescriptionFactory( modified = true; } } else { - for (ResourceDescription resourceDescription : resourceDescriptions) { + for (IResourceSnapshot resourceDescription : resourceDescriptions) { if (resourceDescription != null) { IResource resource = resourceDescription.createResourceHandle(); factory.create(resource); diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractMarkersOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractMarkersOperation.java index 321f47e5740..8ab607f5710 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractMarkersOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractMarkersOperation.java @@ -20,13 +20,14 @@ import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.undo.snapshot.IMarkerSnapshot; +import org.eclipse.core.resources.undo.snapshot.ResourceSnapshotFactory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.MultiRule; -import org.eclipse.ui.internal.ide.undo.MarkerDescription; import org.eclipse.ui.internal.ide.undo.UndoMessages; import org.eclipse.ui.views.markers.internal.MarkerType; import org.eclipse.ui.views.markers.internal.MarkerTypesModel; @@ -44,7 +45,7 @@ */ abstract class AbstractMarkersOperation extends AbstractWorkspaceOperation { - MarkerDescription[] markerDescriptions; + IMarkerSnapshot[] markerDescriptions; IMarker[] markers; @@ -68,7 +69,7 @@ abstract class AbstractMarkersOperation extends AbstractWorkspaceOperation { * the name used to describe the operation */ AbstractMarkersOperation(IMarker[] markers, - MarkerDescription[] markerDescriptions, Map attributes, String name) { + IMarkerSnapshot[] markerDescriptions, Map attributes, String name) { super(name); this.markers = markers; this.attributes = null; @@ -111,9 +112,9 @@ protected void deleteMarkers(int work, IProgressMonitor monitor) return; } int markerWork = work / markers.length; - markerDescriptions = new MarkerDescription[markers.length]; + markerDescriptions = new IMarkerSnapshot[markers.length]; for (int i = 0; i < markers.length; i++) { - markerDescriptions[i] = new MarkerDescription(markers[i]); + markerDescriptions[i] = ResourceSnapshotFactory.fromMarker(markers[i]); markers[i].delete(); monitor.worked(markerWork); } @@ -199,7 +200,7 @@ protected void updateMarkers(int work, IProgressMonitor monitor, * @param descriptions * the descriptions of markers that can be created. */ - protected void setMarkerDescriptions(MarkerDescription[] descriptions) { + protected void setMarkerDescriptions(IMarkerSnapshot[] descriptions) { markerDescriptions = descriptions; addUndoContexts(); updateTargetResources(); diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractResourcesOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractResourcesOperation.java index d559180ee84..24389594c14 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractResourcesOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractResourcesOperation.java @@ -18,6 +18,7 @@ import java.util.Set; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; @@ -54,7 +55,7 @@ abstract class AbstractResourcesOperation extends AbstractWorkspaceOperation { * The array of resource descriptions known by this operation to create or * restore overwritten resources. */ - protected ResourceDescription[] resourceDescriptions; + protected IResourceSnapshot[] resourceDescriptions; /* * Return true if the specified subResource is a descendant of the specified @@ -91,7 +92,7 @@ private static boolean isDescendantOf(IResource subResource, * @param label * the label of the operation */ - AbstractResourcesOperation(ResourceDescription[] resourceDescriptions, + AbstractResourcesOperation(IResourceSnapshot[] resourceDescriptions, String label) { super(label); addContext(WorkspaceUndoUtil.getWorkspaceUndoContext()); @@ -143,7 +144,7 @@ protected void recreate(IProgressMonitor monitor, IAdaptable uiInfo) throws CoreException { setTargetResources(WorkspaceUndoUtil.recreate(resourceDescriptions, monitor, uiInfo)); - setResourceDescriptions(new ResourceDescription[0]); + setResourceDescriptions(new IResourceSnapshot[0]); } /** @@ -171,7 +172,7 @@ protected IStatus computeCreateStatus(boolean allowOverwrite) { markInvalid(); return getErrorStatus(UndoMessages.AbstractResourcesOperation_NotEnoughInfo); } - for (ResourceDescription resourceDescription : resourceDescriptions) { + for (IResourceSnapshot resourceDescription : resourceDescriptions) { // Check for enough info to restore the resource if (resourceDescription == null || !resourceDescription.isValid()) { markInvalid(); @@ -245,9 +246,9 @@ IStatus checkReadOnlyResources(IResource[] resourcesToCheck) { * @param descriptions * the array of resource descriptions */ - protected void setResourceDescriptions(ResourceDescription[] descriptions) { + protected void setResourceDescriptions(IResourceSnapshot[] descriptions) { if (descriptions == null) { - resourceDescriptions = new ResourceDescription[0]; + resourceDescriptions = new IResourceSnapshot[0]; } else { resourceDescriptions = descriptions; } @@ -313,7 +314,7 @@ protected ISchedulingRule computeDeleteSchedulingRule() { protected void setTargetResources(IResource[] targetResources) { // Remove any descendants if the parent has also // been specified. - Set subResources = new HashSet(); + Set subResources = new HashSet<>(); for (IResource subResource : targetResources) { for (IResource superResource : targetResources) { if (isDescendantOf(subResource, superResource) && !subResources.contains(subResource)) diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CopyProjectOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CopyProjectOperation.java index 059c928101b..5dbc26951e6 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CopyProjectOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CopyProjectOperation.java @@ -21,6 +21,8 @@ import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; +import org.eclipse.core.resources.undo.snapshot.ResourceSnapshotFactory; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; @@ -30,7 +32,6 @@ import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.ui.internal.ide.undo.ProjectDescription; import org.eclipse.ui.internal.ide.undo.UndoMessages; /** @@ -52,7 +53,7 @@ public class CopyProjectOperation extends AbstractCopyOrMoveResourcesOperation { private IProject originalProject; - private ProjectDescription originalProjectDescription; + private IResourceSnapshot originalProjectDescription; /** * Create a CopyProjectOperation that copies the specified project and sets @@ -123,7 +124,7 @@ protected void doExecute(IProgressMonitor monitor, IAdaptable uiInfo) IProject newProject = copyProject(originalProject, destination, projectLocation, monitor); setTargetResources(new IResource[] { newProject }); - setResourceDescriptions(new ResourceDescription[0]); + setResourceDescriptions(new IResourceSnapshot[0]); } /* @@ -137,7 +138,7 @@ protected void doUndo(IProgressMonitor monitor, IAdaptable uiInfo) WorkspaceUndoUtil.delete(resources, subMonitor.split(1), uiInfo, true); // Set the target resource to the original setTargetResources(new IResource[] { originalProject }); - setResourceDescriptions(new ResourceDescription[0]); + setResourceDescriptions(new IResourceSnapshot[0]); } @Override @@ -204,7 +205,7 @@ IProject copyProject(IProject project, IPath destinationPath, // description for performing the undo. project.open(null); } - originalProjectDescription = new ProjectDescription(project); + originalProjectDescription = ResourceSnapshotFactory.fromResource(project); IProjectDescription description = project.getDescription(); // Set the new name and location into the project's description diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CopyResourcesOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CopyResourcesOperation.java index 9a9917ec231..1e6670d9648 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CopyResourcesOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CopyResourcesOperation.java @@ -20,6 +20,8 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; +import org.eclipse.core.resources.undo.snapshot.ResourceSnapshotFactory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; @@ -55,7 +57,7 @@ public class CopyResourcesOperation extends IResource[] originalResources; - ResourceDescription[] snapshotResourceDescriptions; + IResourceSnapshot[] snapshotResourceDescriptions; /** * Create a CopyResourcesOperation that copies a single resource to a new @@ -148,12 +150,12 @@ protected void copy(IProgressMonitor monitor, IAdaptable uiInfo) resources.length + (resourceDescriptions != null ? resourceDescriptions.length : 0)); subMonitor.setTaskName(UndoMessages.AbstractResourcesOperation_CopyingResourcesProgress); List resourcesAtDestination = new ArrayList<>(); - List overwrittenResources = new ArrayList<>(); + List> overwrittenResources = new ArrayList<>(); for (int i = 0; i < resources.length; i++) { // Copy the resources and record the overwrites that would // be restored if this operation were reversed - ResourceDescription[] overwrites; + IResourceSnapshot[] overwrites; overwrites = WorkspaceUndoUtil.copy(new IResource[] { resources[i] }, getDestinationPath(resources[i], i), resourcesAtDestination, subMonitor.split(1), uiInfo, true, fCreateGroups, fCreateLinks, fRelativeToVariable); @@ -163,7 +165,7 @@ protected void copy(IProgressMonitor monitor, IAdaptable uiInfo) // Are there any previously overwritten resources to restore now? if (resourceDescriptions != null) { - for (ResourceDescription resourceDescription : resourceDescriptions) { + for (IResourceSnapshot resourceDescription : resourceDescriptions) { if (resourceDescription != null) { resourceDescription.createResource(subMonitor.split(1)); } @@ -172,7 +174,7 @@ protected void copy(IProgressMonitor monitor, IAdaptable uiInfo) // Reset resource descriptions to the just overwritten resources setResourceDescriptions(overwrittenResources - .toArray(new ResourceDescription[overwrittenResources.size()])); + .toArray(new IResourceSnapshot[overwrittenResources.size()])); // Reset the target resources to refer to the resources in their new // location. @@ -193,7 +195,7 @@ protected void doUndo(IProgressMonitor monitor, IAdaptable uiInfo) WorkspaceUndoUtil.delete(resources, subMonitor.split(1), uiInfo, true); // then restoring any overwritten by the previous copy... WorkspaceUndoUtil.recreate(resourceDescriptions, subMonitor.split(1), uiInfo); - setResourceDescriptions(new ResourceDescription[0]); + setResourceDescriptions(new IResourceSnapshot[0]); // then setting the target resources back to the original ones. // Note that the destination paths never changed since they // are not used during undo. @@ -210,7 +212,7 @@ protected boolean updateResourceChangeDescriptionFactory( update = true; factory.delete(resource); } - for (ResourceDescription resourceDescription : resourceDescriptions) { + for (IResourceSnapshot resourceDescription : resourceDescriptions) { if (resourceDescription != null) { update = true; IResource resource = resourceDescription.createResourceHandle(); @@ -244,7 +246,7 @@ public IStatus computeUndoableStatus(IProgressMonitor monitor) { markInvalid(); return getErrorStatus(UndoMessages.CopyResourcesOperation_NotAllowedDueToDataLoss); } - for (ResourceDescription snapshotResourceDescription : snapshotResourceDescriptions) { + for (IResourceSnapshot snapshotResourceDescription : snapshotResourceDescriptions) { if (!snapshotResourceDescription.verifyExistence(true)) { markInvalid(); return getErrorStatus(UndoMessages.CopyResourcesOperation_NotAllowedDueToDataLoss); @@ -271,10 +273,9 @@ public IStatus computeUndoableStatus(IProgressMonitor monitor) { */ private void setOriginalResources(IResource[] originals) { originalResources = originals; - snapshotResourceDescriptions = new ResourceDescription[originals.length]; + snapshotResourceDescriptions = new IResourceSnapshot[originals.length]; for (int i = 0; i < originals.length; i++) { - snapshotResourceDescriptions[i] = ResourceDescription - .fromResource(originals[i]); + snapshotResourceDescriptions[i] = ResourceSnapshotFactory.fromResource(originals[i]); } } } diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateFileOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateFileOperation.java index 888c8d23c3e..1ff6f9bab0b 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateFileOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateFileOperation.java @@ -14,17 +14,17 @@ package org.eclipse.ui.ide.undo; -import java.io.ByteArrayInputStream; import java.io.InputStream; import java.net.URI; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.undo.snapshot.IContainerSnapshot; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; +import org.eclipse.core.resources.undo.snapshot.ResourceSnapshotFactory; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; -import org.eclipse.ui.internal.ide.undo.ContainerDescription; -import org.eclipse.ui.internal.ide.undo.FileDescription; -import org.eclipse.ui.internal.ide.undo.IFileContentDescription; /** * A CreateFileOperation represents an undoable operation for creating a file in @@ -63,57 +63,22 @@ public class CreateFileOperation extends AbstractCreateResourcesOperation { public CreateFileOperation(IFile fileHandle, URI linkLocation, InputStream contents, String label) { super(null, label); - ResourceDescription resourceDescription; + IResourceSnapshot resourceDescription; if (fileHandle.getParent().exists()) { - resourceDescription = new FileDescription(fileHandle, linkLocation, - createFileContentDescription(fileHandle, contents)); + resourceDescription = ResourceSnapshotFactory.fromFileDetails(fileHandle, linkLocation, contents); } else { // must first ensure descriptions for the parent folders are // created - ContainerDescription containerDescription = ContainerDescription + IContainerSnapshot containerDescription = ResourceSnapshotFactory .fromContainer(fileHandle.getParent()); - containerDescription.getFirstLeafFolder() - .addMember( - new FileDescription(fileHandle, linkLocation, - createFileContentDescription(fileHandle, - contents))); + IResourceSnapshot fileDescription = ResourceSnapshotFactory.fromFileDetails(fileHandle, linkLocation, + contents); + WorkspaceUndoUtil.getFirstLeafFolder(containerDescription).addMember(fileDescription); resourceDescription = containerDescription; } - setResourceDescriptions(new ResourceDescription[] { resourceDescription }); - + setResourceDescriptions(new IResourceSnapshot[] { resourceDescription }); } - /* - * Create a file state that represents the desired contents and attributes - * of the file to be created. Used to mimic file history when a resource is - * first created. - */ - private IFileContentDescription createFileContentDescription( - final IFile file, final InputStream contents) { - return new IFileContentDescription() { - @Override - public InputStream getContents() { - if (contents != null) { - return contents; - } - return new ByteArrayInputStream(new byte[0]); - } - - @Override - public String getCharset() { - try { - return file.getCharset(false); - } catch (CoreException e) { - return null; - } - } - - @Override - public boolean exists() { - return true; - } - }; - } @Override public IStatus computeExecutionStatus(IProgressMonitor monitor) { @@ -124,4 +89,5 @@ public IStatus computeExecutionStatus(IProgressMonitor monitor) { } return status; } + } diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateFolderOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateFolderOperation.java index 1487cecfab4..31377014554 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateFolderOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateFolderOperation.java @@ -15,10 +15,21 @@ package org.eclipse.ui.ide.undo; import java.net.URI; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.eclipse.core.resources.FileInfoMatcherDescription; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceFilterDescription; +import org.eclipse.core.resources.undo.snapshot.IContainerSnapshot; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; +import org.eclipse.core.resources.undo.snapshot.ResourceSnapshotFactory; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.ui.ide.dialogs.UIResourceFilterDescription; -import org.eclipse.ui.internal.ide.undo.ContainerDescription; /** * A CreateFolderOperation represents an undoable operation for creating a @@ -76,14 +87,41 @@ public CreateFolderOperation(IFolder folderHandle, URI linkLocation, boolean virtual, UIResourceFilterDescription[] filterList, String label) { super(null, label); - ContainerDescription containerDescription = virtual? ContainerDescription - .fromVirtualFolderContainer(folderHandle): - ContainerDescription.fromContainer(folderHandle); + IContainerSnapshot containerDescription = virtual + ? ResourceSnapshotFactory.fromVirtualFolderContainer(folderHandle) + : ResourceSnapshotFactory.fromContainer(folderHandle); if (linkLocation != null) { - containerDescription.getFirstLeafFolder().setLocation(linkLocation); + WorkspaceUndoUtil.getFirstLeafFolder(containerDescription).setLocation(linkLocation); } - if (filterList != null) - containerDescription.getFirstLeafFolder().setFilters(filterList); - setResourceDescriptions(new ResourceDescription[] { containerDescription }); + if (filterList != null) { + List l = Arrays.asList(filterList).stream().map(x -> convert(x)) + .collect(Collectors.toList()); + IResourceFilterDescription[] asArr = l.toArray(new IResourceFilterDescription[l.size()]); + WorkspaceUndoUtil.getFirstLeafFolder(containerDescription).setFilters(asArr); + } + setResourceDescriptions(new IResourceSnapshot[] { containerDescription }); + } + + private IResourceFilterDescription convert(final UIResourceFilterDescription desc) { + return new IResourceFilterDescription() { + @Override + public FileInfoMatcherDescription getFileInfoMatcherDescription() { + return desc.getFileInfoMatcherDescription(); + } + + @Override + public IResource getResource() { + return desc.getProject(); + } + + @Override + public int getType() { + return desc.getType(); + } + + @Override + public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException { + } + }; } } diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateMarkersOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateMarkersOperation.java index 6c32d7151f0..8d70644ad60 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateMarkersOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateMarkersOperation.java @@ -17,12 +17,13 @@ import java.util.Map; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.undo.snapshot.IMarkerSnapshot; +import org.eclipse.core.resources.undo.snapshot.ResourceSnapshotFactory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.ui.internal.ide.undo.MarkerDescription; import org.eclipse.ui.internal.ide.undo.UndoMessages; /** @@ -56,7 +57,8 @@ public class CreateMarkersOperation extends AbstractMarkersOperation { */ public CreateMarkersOperation(String type, Map attributes, IResource resource, String name) { - super(null, new MarkerDescription[] { new MarkerDescription(type, + super(null, new IMarkerSnapshot[] { + ResourceSnapshotFactory.fromMarkerDetails(type, attributes, resource) }, null, name); } @@ -79,10 +81,9 @@ public CreateMarkersOperation(String type, Map attributes, public CreateMarkersOperation(String[] types, Map[] attributes, IResource[] resources, String name) { super(null, null, null, name); - MarkerDescription[] markersToCreate = new MarkerDescription[attributes.length]; + IMarkerSnapshot[] markersToCreate = new IMarkerSnapshot[attributes.length]; for (int i = 0; i < markersToCreate.length; i++) { - markersToCreate[i] = new MarkerDescription(types[i], attributes[i], - resources[i]); + markersToCreate[i] = ResourceSnapshotFactory.fromMarkerDetails(types[i], attributes[i], resources[i]); } setMarkerDescriptions(markersToCreate); } @@ -106,10 +107,9 @@ public CreateMarkersOperation(String[] types, Map[] attributes, public CreateMarkersOperation(String type, Map[] attributes, IResource[] resources, String name) { super(null, null, null, name); - MarkerDescription[] markersToCreate = new MarkerDescription[attributes.length]; + IMarkerSnapshot[] markersToCreate = new IMarkerSnapshot[attributes.length]; for (int i = 0; i < markersToCreate.length; i++) { - markersToCreate[i] = new MarkerDescription(type, attributes[i], - resources[i]); + markersToCreate[i] = ResourceSnapshotFactory.fromMarkerDetails(type, attributes[i], resources[i]); } setMarkerDescriptions(markersToCreate); } diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateProjectOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateProjectOperation.java index 3090e482964..e9e0bc40b0c 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateProjectOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateProjectOperation.java @@ -15,7 +15,8 @@ package org.eclipse.ui.ide.undo; import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.ui.internal.ide.undo.ProjectDescription; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; +import org.eclipse.core.resources.undo.snapshot.ResourceSnapshotFactory; /** * A CreateProjectOperation represents an undoable operation for creating a @@ -40,7 +41,6 @@ public class CreateProjectOperation extends AbstractCreateResourcesOperation { */ public CreateProjectOperation(IProjectDescription projectDescription, String label) { - super(new ProjectDescription[] { new ProjectDescription( - projectDescription) }, label); + super(new IResourceSnapshot[] { ResourceSnapshotFactory.fromProjectDescription(projectDescription) }, label); } } diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/DeleteResourcesOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/DeleteResourcesOperation.java index d2931f77955..a3a74643573 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/DeleteResourcesOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/DeleteResourcesOperation.java @@ -18,6 +18,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; @@ -80,7 +81,7 @@ protected boolean updateResourceChangeDescriptionFactory( IResourceChangeDescriptionFactory factory, int operation) { boolean modified = false; if (operation == UNDO) { - for (ResourceDescription resourceDescription : resourceDescriptions) { + for (IResourceSnapshot resourceDescription : resourceDescriptions) { if (resourceDescription != null) { IResource resource = resourceDescription.createResourceHandle(); factory.create(resource); diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/MoveProjectOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/MoveProjectOperation.java index 28955af61e9..d7daa6d0c73 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/MoveProjectOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/MoveProjectOperation.java @@ -21,6 +21,7 @@ import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; @@ -119,7 +120,7 @@ protected void doExecute(IProgressMonitor monitor, IAdaptable uiInfo) throws CoreException { projectLocation = moveProject(getProject(), projectLocation, monitor); // nothing was overwritten - setResourceDescriptions(new ResourceDescription[0]); + setResourceDescriptions(new IResourceSnapshot[0]); } @Override diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/MoveResourcesOperation.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/MoveResourcesOperation.java index 52c1eec15dc..4a5ddb36577 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/MoveResourcesOperation.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/MoveResourcesOperation.java @@ -20,6 +20,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; @@ -129,12 +130,12 @@ protected void move(IProgressMonitor monitor, IAdaptable uiInfo) subMonitor.setTaskName(UndoMessages.AbstractResourcesOperation_MovingResources); List resourcesAtDestination = new ArrayList<>(); List undoDestinationPaths = new ArrayList<>(); - List overwrittenResources = new ArrayList<>(); + List> overwrittenResources = new ArrayList<>(); for (int i = 0; i < resources.length; i++) { // Move the resources and record the overwrites that would // be restored if this operation were reversed - ResourceDescription[] overwrites; + IResourceSnapshot[] overwrites; overwrites = WorkspaceUndoUtil.move(new IResource[] { resources[i] }, getDestinationPath(resources[i], i), resourcesAtDestination, undoDestinationPaths, subMonitor.split(1), uiInfo, true); @@ -144,7 +145,7 @@ protected void move(IProgressMonitor monitor, IAdaptable uiInfo) // Are there any previously overwritten resources to restore now? if (resourceDescriptions != null) { - for (ResourceDescription resourceDescription : resourceDescriptions) { + for (IResourceSnapshot resourceDescription : resourceDescriptions) { if (resourceDescription != null) { resourceDescription.createResource(subMonitor.split(1)); } @@ -153,7 +154,7 @@ protected void move(IProgressMonitor monitor, IAdaptable uiInfo) // Reset resource descriptions to the just overwritten resources setResourceDescriptions(overwrittenResources - .toArray(new ResourceDescription[overwrittenResources.size()])); + .toArray(new IResourceSnapshot[overwrittenResources.size()])); // Reset the target resources to refer to the resources in their new // location. @@ -180,7 +181,7 @@ protected void doUndo(IProgressMonitor monitor, IAdaptable uiInfo) // only the files that were originally merged. This makes us more // adaptable to changes in the target. setTargetResources(originalResources); - this.resourceDescriptions = new ResourceDescription[0]; + this.resourceDescriptions = new IResourceSnapshot[0]; this.destination = originalDestination; this.destinationPaths = originalDestinationPaths; } diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/ResourceDescription.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/ResourceDescription.java index 14f8db98600..579116d8c4f 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/ResourceDescription.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/ResourceDescription.java @@ -14,15 +14,11 @@ package org.eclipse.ui.ide.undo; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; +import org.eclipse.core.resources.undo.snapshot.ResourceSnapshotFactory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.ui.internal.ide.undo.FileDescription; -import org.eclipse.ui.internal.ide.undo.FolderDescription; -import org.eclipse.ui.internal.ide.undo.ProjectDescription; /** * ResourceDescription is a lightweight description that describes the common @@ -31,37 +27,68 @@ * This class is not intended to be extended by clients. * * @since 3.3 - * + * @deprecated Replaced by IResourceSnapshot and ResourceSnapshotFactory in the + * org.eclipse.core.resources.undo.snapshot package */ +@Deprecated public abstract class ResourceDescription { /** - * Create a resource description given the specified resource. The resource - * is assumed to exist. + * Create a resource description given the specified resource. The resource is + * assumed to exist. * - * @param resource - * the resource from which a description should be created + * @param resource the resource from which a description should be created * @return the resource description */ public static ResourceDescription fromResource(IResource resource) { - if (resource.getType() == IResource.PROJECT) { - return new ProjectDescription((IProject) resource); - } else if (resource.getType() == IResource.FOLDER) { - return new FolderDescription((IFolder) resource, resource.isVirtual()); - } else if (resource.getType() == IResource.FILE) { - return new FileDescription((IFile) resource); - } else { - throw new IllegalArgumentException(); - } + IResourceSnapshot delegate = ResourceSnapshotFactory.fromResource(resource); + return new ResourceDescription() { + + @Override + public IResource createResourceHandle() { + return delegate.createResourceHandle(); + } + + @Override + public String getName() { + return delegate.getName(); + } + + @Override + public IResource createResource(IProgressMonitor monitor) throws CoreException { + return delegate.createResource(monitor); + } + + @Override + public void createExistentResourceFromHandle(IResource resource, IProgressMonitor monitor) + throws CoreException { + delegate.createExistentResourceFromHandle(monitor); + } + + @Override + public boolean isValid() { + return delegate.isValid(); + } + + @Override + public void recordStateFromHistory(IResource resource, IProgressMonitor monitor) throws CoreException { + delegate.recordStateFromHistory(monitor); + } + + @Override + public boolean verifyExistence(boolean checkMembers) { + return delegate.verifyExistence(checkMembers); + } + }; } /** * Create a resource handle that can be used to create a resource from this - * resource description. This handle can be used to create the actual - * resource, or to describe the creation to a resource delta factory. + * resource description. This handle can be used to create the actual resource, + * or to describe the creation to a resource delta factory. * - * @return the resource handle that can be used to create a resource from - * this description + * @return the resource handle that can be used to create a resource from this + * description */ public abstract IResource createResourceHandle(); @@ -75,25 +102,22 @@ public static ResourceDescription fromResource(IResource resource) { /** * Create an existent resource from this resource description. * - * @param monitor - * the progress monitor to use + * @param monitor the progress monitor to use * @return a resource that has the attributes of this resource description * @throws CoreException if creation failed */ public abstract IResource createResource(IProgressMonitor monitor) throws CoreException; /** - * Given a resource handle, create an actual resource with the attributes of - * the receiver resource description. + * Given a resource handle, create an actual resource with the attributes of the + * receiver resource description. * - * @param resource - * the resource handle - * @param monitor - * the progress monitor to be used when creating the resource + * @param resource the resource handle + * @param monitor the progress monitor to be used when creating the resource * @throws CoreException if creation failed */ - public abstract void createExistentResourceFromHandle(IResource resource, - IProgressMonitor monitor) throws CoreException; + public abstract void createExistentResourceFromHandle(IResource resource, IProgressMonitor monitor) + throws CoreException; /** * Return a boolean indicating whether this resource description has enough @@ -105,30 +129,27 @@ public abstract void createExistentResourceFromHandle(IResource resource, public abstract boolean isValid(); /** - * Record the appropriate state of this resource description using - * any available resource history. + * Record the appropriate state of this resource description using any available + * resource history. * - * @param resource - * the resource whose state is to be recorded. - * @param monitor - * the progress monitor to be used + * @param resource the resource whose state is to be recorded. + * @param monitor the progress monitor to be used * @throws CoreException in case of error */ - public abstract void recordStateFromHistory(IResource resource, - IProgressMonitor monitor) throws CoreException; + public abstract void recordStateFromHistory(IResource resource, IProgressMonitor monitor) throws CoreException; /** - * Return a boolean indicating whether this description represents an - * existent resource. + * Return a boolean indicating whether this description represents an existent + * resource. * - * @param checkMembers - * Use true if members should also exist in order - * for this description to be considered existent. A value of - * false indicates that the existence of members - * does not matter. + * @param checkMembers Use true if members should also exist in + * order for this description to be considered existent. A + * value of false indicates that the existence + * of members does not matter. * - * @return a boolean indicating whether this description represents an - * existent resource. + * @return a boolean indicating whether this description represents an existent + * resource. */ public abstract boolean verifyExistence(boolean checkMembers); } + diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/WorkspaceUndoUtil.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/WorkspaceUndoUtil.java index 77f0e928787..f8e47727fbb 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/WorkspaceUndoUtil.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/WorkspaceUndoUtil.java @@ -32,6 +32,9 @@ import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.resources.undo.snapshot.IContainerSnapshot; +import org.eclipse.core.resources.undo.snapshot.IResourceSnapshot; +import org.eclipse.core.resources.undo.snapshot.ResourceSnapshotFactory; import org.eclipse.core.runtime.Adapters; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; @@ -51,8 +54,6 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; -import org.eclipse.ui.internal.ide.undo.ContainerDescription; -import org.eclipse.ui.internal.ide.undo.FileDescription; import org.eclipse.ui.internal.ide.undo.UndoMessages; @@ -179,13 +180,14 @@ private WorkspaceUndoUtil() { * @throws CoreException * propagates any CoreExceptions thrown from the resources API */ - static ResourceDescription[] delete(IResource[] resourcesToDelete, IProgressMonitor mon, IAdaptable uiInfo, + static IResourceSnapshot[] delete(IResource[] resourcesToDelete, IProgressMonitor mon, + IAdaptable uiInfo, boolean deleteContent) throws CoreException { SubMonitor subMonitor = SubMonitor.convert(mon, resourcesToDelete.length); final List exceptions = new ArrayList<>(); boolean forceOutOfSyncDelete = false; - ResourceDescription[] returnedResourceDescriptions = new ResourceDescription[resourcesToDelete.length]; + IResourceSnapshot[] returnedResourceDescriptions = new IResourceSnapshot[resourcesToDelete.length]; subMonitor.setTaskName(UndoMessages.AbstractResourcesOperation_DeleteResourcesProgress); for (int i = 0; i < resourcesToDelete.length; ++i) { IResource resource = resourcesToDelete[i]; @@ -258,7 +260,8 @@ static ResourceDescription[] delete(IResource[] resourcesToDelete, IProgressMoni * @throws CoreException * propagates any CoreExceptions thrown from the resources API */ - static ResourceDescription[] copy(IResource[] resources, IPath destination, List resourcesAtDestination, + static IResourceSnapshot[] copy(IResource[] resources, IPath destination, + List resourcesAtDestination, IProgressMonitor monitor, IAdaptable uiInfo, boolean pathIncludesName) throws CoreException { return copy(resources, destination, resourcesAtDestination, monitor, uiInfo, pathIncludesName, false, false, null); @@ -308,12 +311,13 @@ static ResourceDescription[] copy(IResource[] resources, IPath destination, List * @throws CoreException * propagates any CoreExceptions thrown from the resources API */ - static ResourceDescription[] copy(IResource[] resources, IPath destination, List resourcesAtDestination, + static IResourceSnapshot[] copy(IResource[] resources, IPath destination, + List resourcesAtDestination, IProgressMonitor monitor, IAdaptable uiInfo, boolean pathIncludesName, boolean createVirtual, boolean createLinks, String relativeToVariable) throws CoreException { SubMonitor subMonitor = SubMonitor.convert(monitor, resources.length); subMonitor.setTaskName(UndoMessages.AbstractResourcesOperation_CopyingResourcesProgress); - List overwrittenResources = new ArrayList<>(); + List> overwrittenResources = new ArrayList<>(); for (IResource source : resources) { SubMonitor iterationProgress = subMonitor.split(1).setWorkRemaining(100); IPath destinationPath; @@ -335,7 +339,7 @@ static ResourceDescription[] copy(IResource[] resources, IPath destination, List // copy only linked resource children (267173) if (source.isLinked() && source.getLocation().equals(existing.getLocation())) children = filterNonLinkedResources(children); - ResourceDescription[] overwritten = copy(children, + IResourceSnapshot[] overwritten = copy(children, destinationPath, resourcesAtDestination, iterationProgress, uiInfo, false, createVirtual, createLinks, relativeToVariable); @@ -345,7 +349,8 @@ static ResourceDescription[] copy(IResource[] resources, IPath destination, List } else { // delete the destination folder, copying a linked folder // over an unlinked one or vice versa. Fixes bug 28772. - ResourceDescription[] deleted = delete(new IResource[] { existing }, iterationProgress.split(1), + IResourceSnapshot[] deleted = delete(new IResource[] { existing }, + iterationProgress.split(1), uiInfo, false); iterationProgress.setWorkRemaining(100); if ((createLinks || createVirtual) && (source.isLinked() == false) @@ -376,7 +381,7 @@ static ResourceDescription[] copy(IResource[] resources, IPath destination, List && (source.isLinked() == false)) { // we create a linked file, and overwrite the // destination - ResourceDescription[] deleted = delete( + IResourceSnapshot[] deleted = delete( new IResource[] { existing }, iterationProgress.split(1), uiInfo, false); @@ -415,7 +420,7 @@ static ResourceDescription[] copy(IResource[] resources, IPath destination, List // Copying a linked resource over unlinked or vice // versa. Can't use setContents here. Fixes bug // 28772. - ResourceDescription[] deleted = delete( + IResourceSnapshot[] deleted = delete( new IResource[] { existing }, iterationProgress.split(1), uiInfo, false); @@ -472,7 +477,7 @@ static ResourceDescription[] copy(IResource[] resources, IPath destination, List } } return overwrittenResources - .toArray(new ResourceDescription[overwrittenResources.size()]); + .toArray(new IResourceSnapshot[overwrittenResources.size()]); } /** @@ -530,13 +535,14 @@ static private URI createRelativePath(URI locationURI, String relativeVariable, * @throws CoreException * propagates any CoreExceptions thrown from the resources API */ - static ResourceDescription[] move(IResource[] resources, IPath destination, List resourcesAtDestination, + static IResourceSnapshot[] move(IResource[] resources, IPath destination, + List resourcesAtDestination, List reverseDestinations, IProgressMonitor mon, IAdaptable uiInfo, boolean pathIncludesName) throws CoreException { SubMonitor subMonitor = SubMonitor.convert(mon, resources.length); subMonitor.setTaskName(UndoMessages.AbstractResourcesOperation_MovingResources); - List overwrittenResources = new ArrayList<>(); + List> overwrittenResources = new ArrayList<>(); for (IResource resource : resources) { SubMonitor iterationProgress = subMonitor.split(1); IPath destinationPath; @@ -555,7 +561,8 @@ static ResourceDescription[] move(IResource[] resources, IPath destination, List // move only linked resource children (267173) if (resource.isLinked() && resource.getLocation().equals(existing.getLocation())) children = filterNonLinkedResources(children); - ResourceDescription[] overwritten = move(children, destinationPath, resourcesAtDestination, + IResourceSnapshot[] overwritten = move(children, destinationPath, + resourcesAtDestination, reverseDestinations, iterationProgress.split(90), uiInfo, false); // We don't record the moved resources since the recursive // call has done so. Just record the overwrites. @@ -566,7 +573,8 @@ static ResourceDescription[] move(IResource[] resources, IPath destination, List } else { // delete the destination folder, moving a linked folder // over an unlinked one or vice versa. Fixes bug 28772. - ResourceDescription[] deleted = delete(new IResource[] { existing }, iterationProgress.split(10), + IResourceSnapshot[] deleted = delete(new IResource[] { existing }, + iterationProgress.split(10), uiInfo, false); // Record the original path reverseDestinations.add(resource.getFullPath()); @@ -587,7 +595,7 @@ static ResourceDescription[] move(IResource[] resources, IPath destination, List } else { // Moving a linked resource over unlinked or vice // versa. Can't use setContents here. Fixes bug 28772. - ResourceDescription[] deleted = delete( + IResourceSnapshot[] deleted = delete( new IResource[] { existing }, iterationProgress.split(1), uiInfo, false); @@ -625,7 +633,7 @@ static ResourceDescription[] move(IResource[] resources, IPath destination, List } } return overwrittenResources - .toArray(new ResourceDescription[overwrittenResources.size()]); + .toArray(new IResourceSnapshot[overwrittenResources.size()]); } @@ -660,7 +668,7 @@ private static IResource[] filterNonLinkedResources(IResource[] resources) { * @throws CoreException * propagates any CoreExceptions thrown from the resources API */ - static IResource[] recreate(ResourceDescription[] resourcesToRecreate, + static IResource[] recreate(IResourceSnapshot[] resourcesToRecreate, IProgressMonitor monitor, IAdaptable uiInfo) throws CoreException { SubMonitor subMonitor = SubMonitor.convert(monitor, resourcesToRecreate.length); final List exceptions = new ArrayList<>(); @@ -705,12 +713,12 @@ static IResource[] recreate(ResourceDescription[] resourcesToRecreate, * @throws CoreException * propagates any CoreExceptions thrown from the resources API */ - static ResourceDescription delete(IResource resourceToDelete, + static IResourceSnapshot delete(IResource resourceToDelete, IProgressMonitor monitor, IAdaptable uiInfo, boolean forceOutOfSyncDelete, boolean deleteContent) throws CoreException { SubMonitor subMonitor = SubMonitor.convert(monitor); - ResourceDescription resourceDescription = ResourceDescription + IResourceSnapshot resourceDescription = ResourceSnapshotFactory .fromResource(resourceToDelete); if (resourceToDelete.getType() == IResource.PROJECT) { // it is a project @@ -730,7 +738,7 @@ static ResourceDescription delete(IResource resourceToDelete, updateFlags = IResource.KEEP_HISTORY; } resourceToDelete.delete(updateFlags, subMonitor.split(1)); - resourceDescription.recordStateFromHistory(resourceToDelete, subMonitor.split(1)); + resourceDescription.recordStateFromHistory(subMonitor.split(1)); } return resourceDescription; @@ -741,7 +749,7 @@ static ResourceDescription delete(IResource resourceToDelete, * returning a ResourceDescription that can be used to restore the original * content. Do nothing if the resources are not files. */ - private static ResourceDescription copyOverExistingResource( + private static IResourceSnapshot copyOverExistingResource( IResource source, IResource existing, IProgressMonitor monitor, IAdaptable uiInfo, boolean deleteSourceFile) throws CoreException { if (!(source instanceof IFile && existing instanceof IFile)) { @@ -755,10 +763,10 @@ private static ResourceDescription copyOverExistingResource( if (validateEdit(file, existingFile, getShell(uiInfo))) { // Remember the state of the existing file so it can be // restored. - FileDescription fileDescription = new FileDescription(existingFile); + IResourceSnapshot fileDescription = ResourceSnapshotFactory.fromResource(existingFile); // Reset the contents to that of the file being moved existingFile.setContents(file.getContents(), IResource.KEEP_HISTORY, subMonitor.split(1)); - fileDescription.recordStateFromHistory(existingFile, subMonitor.split(1)); + fileDescription.recordStateFromHistory(subMonitor.split(1)); // Now delete the source file if requested // We don't need to remember anything about it, because // any undo involving this operation will move the original @@ -772,6 +780,32 @@ private static ResourceDescription copyOverExistingResource( return null; } + /** + * Return the first folder found that has no child folders. + * + * @since 3.22 + * @param parent the parent folder + * + * @return the container description for the first child in the receiver that is + * a leaf, or this container if there are no children. + */ + public static IContainerSnapshot getFirstLeafFolder( + IContainerSnapshot parent) { + // If there are no members, this is a leaf + IResourceSnapshot[] members = parent.getMembers(); + if (members == null || members.length == 0) { + return parent; + } + // Traverse the members and find the first potential leaf + for (IResourceSnapshot member : members) { + if (member instanceof IContainerSnapshot) { + return getFirstLeafFolder(((IContainerSnapshot) member)); + } + } + // No child folders were found, this is a leaf + return parent; + } + /* * Check for existence of the specified path and generate any containers * that do not yet exist. Return any generated containers, or null if no @@ -798,11 +832,10 @@ private static IContainer generateContainers(IPath path) container = ResourcesPlugin.getWorkspace().getRoot() .getFolder(path); } - ContainerDescription containerDescription = ContainerDescription + IResourceSnapshot containerDescription = ResourceSnapshotFactory .fromContainer((IContainer) container); container = containerDescription.createResourceHandle(); - containerDescription.createExistentResourceFromHandle(container, - new NullProgressMonitor()); + containerDescription.createExistentResourceFromHandle(new NullProgressMonitor()); return (IContainer) container; } diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/AbstractResourceDescription.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/AbstractResourceDescription.java deleted file mode 100755 index fe92c8f4c81..00000000000 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/AbstractResourceDescription.java +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2015 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ - -package org.eclipse.ui.internal.ide.undo; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.ResourceAttributes; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.ui.ide.undo.ResourceDescription; - -/** - * Base implementation of ResourceDescription that describes the common - * attributes of a resource to be created. - * - * This class is not intended to be instantiated or used by clients. - * - * @since 3.3 - * - */ -abstract class AbstractResourceDescription extends ResourceDescription { - IContainer parent; - - long modificationStamp = IResource.NULL_STAMP; - - long localTimeStamp = IResource.NULL_STAMP; - - ResourceAttributes resourceAttributes; - - MarkerDescription[] markerDescriptions; - - /** - * Create a resource description with no initial attributes - */ - protected AbstractResourceDescription() { - super(); - } - - /** - * Create a resource description from the specified resource. - * - * @param resource - * the resource to be described - */ - protected AbstractResourceDescription(IResource resource) { - super(); - parent = resource.getParent(); - if (resource.isAccessible()) { - modificationStamp = resource.getModificationStamp(); - localTimeStamp = resource.getLocalTimeStamp(); - resourceAttributes = resource.getResourceAttributes(); - try { - IMarker[] markers = resource.findMarkers(null, true, - IResource.DEPTH_INFINITE); - markerDescriptions = new MarkerDescription[markers.length]; - for (int i = 0; i < markers.length; i++) { - markerDescriptions[i] = new MarkerDescription(markers[i]); - } - } catch (CoreException e) { - // Eat this exception because it only occurs when the resource - // does not exist and we have already checked this. - // We do not want to throw exceptions on the simple constructor, - // as no one has actually tried to do anything yet. - } - } - } - - @Override - public IResource createResource(IProgressMonitor monitor) - throws CoreException { - IResource resource = createResourceHandle(); - createExistentResourceFromHandle(resource, monitor); - restoreResourceAttributes(resource); - return resource; - } - - @Override - public boolean isValid() { - return parent == null || parent.exists(); - } - - /** - * Restore any saved attributed of the specified resource. This method is - * called after the existent resource represented by the receiver has been - * created. - * - * @param resource - * the newly created resource - * @throws CoreException - */ - protected void restoreResourceAttributes(IResource resource) - throws CoreException { - if (modificationStamp != IResource.NULL_STAMP) { - resource.revertModificationStamp(modificationStamp); - } - if (localTimeStamp != IResource.NULL_STAMP) { - resource.setLocalTimeStamp(localTimeStamp); - } - if (resourceAttributes != null) { - resource.setResourceAttributes(resourceAttributes); - } - if (markerDescriptions != null) { - for (MarkerDescription markerDescription : markerDescriptions) { - if (markerDescription.resource.exists()) - markerDescription.createMarker(); - } - } - } - - /* - * Return the workspace. - */ - IWorkspace getWorkspace() { - return ResourcesPlugin.getWorkspace(); - } - - @Override - public boolean verifyExistence(boolean checkMembers) { - IContainer p = parent; - if (p == null) { - p = getWorkspace().getRoot(); - } - IResource handle = p.findMember(getName()); - return handle != null; - } -} diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/ContainerDescription.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/ContainerDescription.java deleted file mode 100644 index 7db77570eeb..00000000000 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/ContainerDescription.java +++ /dev/null @@ -1,311 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2015 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ - -package org.eclipse.ui.internal.ide.undo; - -import java.net.URI; - -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.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -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.SubMonitor; -import org.eclipse.ui.ide.dialogs.UIResourceFilterDescription; -import org.eclipse.ui.ide.undo.ResourceDescription; - -/** - * ContainerDescription is a lightweight description that describes a container - * to be created. - * - * This class is not intended to be instantiated or used by clients. - * - * @since 3.3 - * - */ -public abstract class ContainerDescription extends AbstractResourceDescription { - - String name; - - URI location; - - UIResourceFilterDescription[] filters; - - String defaultCharSet; - - AbstractResourceDescription[] members; - - /** - * Create a container description from the specified container handle that - * can be used to create the container. The returned ContainerDescription - * should represent any non-existing parents in addition to the specified - * container. - * - * @param container - * the handle of the container to be described - * @return a container description describing the container and any - * non-existing parents. - */ - - public static ContainerDescription fromContainer(IContainer container) { - return fromContainer(container, false); - } - - /** - * Create a group container description from the specified container handle that - * can be used to create the container. The returned ContainerDescription - * should represent any non-existing parents in addition to the specified - * container. - * - * @param container - * the handle of the container to be described - * @return a container description describing the container and any - * non-existing parents. - */ - - public static ContainerDescription fromVirtualFolderContainer(IContainer container) { - return fromContainer(container, true); - } - - protected static ContainerDescription fromContainer(IContainer container, boolean usingVirtualFolder) { - IPath fullPath = container.getFullPath(); - ContainerDescription firstCreatedParent = null; - ContainerDescription currentContainerDescription = null; - - // Does the container exist already? If so, then the parent exists and - // we use the normal creation constructor. - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - IContainer currentContainer = (IContainer) root.findMember(fullPath); - if (currentContainer != null) { - return (ContainerDescription) ResourceDescription - .fromResource(container); - } - - // Create container descriptions for any uncreated parents in the given - // path. - currentContainer = root; - for (int i = 0; i < fullPath.segmentCount(); i++) { - String currentSegment = fullPath.segment(i); - IResource resource = currentContainer.findMember(currentSegment); - if (resource != null) { - // parent already exists, no need to create a description for it - currentContainer = (IContainer) resource; - } else if (i == 0) { - // parent does not exist and it is a project - firstCreatedParent = new ProjectDescription(root - .getProject(currentSegment)); - currentContainerDescription = firstCreatedParent; - } else { - IFolder folderHandle = currentContainer.getFolder(IPath.fromOSString(currentSegment)); - ContainerDescription currentFolder; - currentFolder = new FolderDescription(folderHandle, usingVirtualFolder); - currentContainer = folderHandle; - if (currentContainerDescription != null) { - currentContainerDescription.addMember(currentFolder); - } - currentContainerDescription = currentFolder; - if (firstCreatedParent == null) { - firstCreatedParent = currentFolder; - } - } - } - return firstCreatedParent; - } - - /** - * Create a ContainerDescription with no state. - */ - public ContainerDescription() { - - } - - /** - * Create a ContainerDescription from the specified container handle. - * Typically used when the container handle represents a resource that - * actually exists, although it will not fail if the resource is - * non-existent. - * - * @param container - * the container to be described - */ - public ContainerDescription(IContainer container) { - super(container); - this.name = container.getName(); - if (container.isLinked()) { - this.location = container.getLocationURI(); - } - try { - if (container.isAccessible()) { - defaultCharSet = container.getDefaultCharset(false); - IResource[] resourceMembers = container.members(); - members = new AbstractResourceDescription[resourceMembers.length]; - for (int i = 0; i < resourceMembers.length; i++) { - members[i] = (AbstractResourceDescription) ResourceDescription - .fromResource(resourceMembers[i]); - } - } - } catch (CoreException e) { - // Eat this exception because it only occurs when the resource - // does not exist and we have already checked this. - // We do not want to throw exceptions on the simple constructor, as - // no one has actually tried to do anything yet. - } - } - - /** - * Create any child resources known by this container description. - * - * @param parentHandle - * the handle of the created parent - * @param monitor - * the progress monitor to be used - * @throws CoreException - */ - protected final void createChildResources(IContainer parentHandle, - IProgressMonitor monitor) throws CoreException { - // restore any children - if (members != null && members.length > 0) { - SubMonitor subMonitor = SubMonitor.convert(monitor, members.length); - for (AbstractResourceDescription member : members) { - member.parent = parentHandle; - member.createResource(subMonitor.split(1)); - } - } - } - - @Override - public void recordStateFromHistory(IResource resource, IProgressMonitor mon) throws CoreException { - if (members != null) { - SubMonitor subMonitor = SubMonitor.convert(mon, UndoMessages.FolderDescription_SavingUndoInfoProgress, - members.length); - for (AbstractResourceDescription member : members) { - SubMonitor iterationMonitor = subMonitor.split(1); - if (member instanceof FileDescription) { - IPath path = resource.getFullPath().append(((FileDescription) member).name); - IFile fileHandle = resource.getWorkspace().getRoot().getFile(path); - member.recordStateFromHistory(fileHandle, iterationMonitor); - } else if (member instanceof FolderDescription) { - IPath path = resource.getFullPath().append(((FolderDescription) member).name); - IFolder folderHandle = resource.getWorkspace().getRoot().getFolder(path); - member.recordStateFromHistory(folderHandle, iterationMonitor); - } - } - } - } - - /** - * Return the name of the container described by this ContainerDescription. - * - * @return the name of the container. - */ - @Override - public String getName() { - return name; - } - - /** - * Return the first folder found that has no child folders. - * - * @return the container description for the first child in the receiver - * that is a leaf, or this container if there are no children. - */ - public ContainerDescription getFirstLeafFolder() { - // If there are no members, this is a leaf - if (members == null || members.length == 0) { - return this; - } - // Traverse the members and find the first potential leaf - for (AbstractResourceDescription member : members) { - if (member instanceof ContainerDescription) { - return ((ContainerDescription) member).getFirstLeafFolder(); - } - } - // No child folders were found, this is a leaf - return this; - } - - /** - * Add the specified resource description as a member of this resource - * description - * - * @param member - * the resource description considered a member of this - * container. - */ - public void addMember(AbstractResourceDescription member) { - if (members == null) { - members = new AbstractResourceDescription[] { member }; - } else { - AbstractResourceDescription[] expandedMembers = new AbstractResourceDescription[members.length + 1]; - System.arraycopy(members, 0, expandedMembers, 0, members.length); - expandedMembers[members.length] = member; - members = expandedMembers; - } - } - - @Override - protected void restoreResourceAttributes(IResource resource) - throws CoreException { - super.restoreResourceAttributes(resource); - Assert.isLegal(resource instanceof IContainer); - IContainer container = (IContainer) resource; - if (defaultCharSet != null) { - container.setDefaultCharset(defaultCharSet, null); - } - } - - /** - * Set the location to which this container is linked. - * - * @param location - * the location URI, or null if there is no link - */ - public void setLocation(URI location) { - this.location = location; - } - - /** - * Set the filters to which should be created on this container. - * - * @param filters - * the filters - */ - public void setFilters(UIResourceFilterDescription[] filters) { - this.filters = filters; - } - - @Override - public boolean verifyExistence(boolean checkMembers) { - boolean existence = super.verifyExistence(checkMembers); - if (existence) { - if (checkMembers) { - // restore any children - if (members != null && members.length > 0) { - for (AbstractResourceDescription member : members) { - if (!member.verifyExistence(checkMembers)) { - return false; - } - } - } - } - return true; - } - return false; - } -} diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/FileDescription.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/FileDescription.java deleted file mode 100644 index 907d08bb8f6..00000000000 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/FileDescription.java +++ /dev/null @@ -1,212 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2015 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ - -package org.eclipse.ui.internal.ide.undo; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.net.URI; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFileState; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceStatus; -import org.eclipse.core.resources.IWorkspaceRoot; -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.SubMonitor; - -/** - * FileDescription is a lightweight description that describes a file to be - * created. - * - * This class is not intended to be instantiated or used by clients. - * - * @since 3.3 - * - */ -public class FileDescription extends AbstractResourceDescription { - - String name; - - URI location; - - String charset; - - private IFileContentDescription fileContentDescription; - - /** - * Create a FileDescription that can be used to later restore the given - * file. The file typically already exists, but this constructor will not - * fail if the file does not exist. - * - * @param file - * the file to be restored. - */ - public FileDescription(IFile file) { - super(file); - this.name = file.getName(); - try { - this.charset = file.getCharset(false); - } catch (CoreException e) { - // we don't care, a null charset is fine. - } - if (file.isLinked()) { - location = file.getLocationURI(); - } - - } - - /** - * Create a file description from the specified file handle. The handle does - * not exist, so no information should be derived from it. If a location - * path is specified, this file should represent a link to another location. - * The content description describes any state that should be used when the - * file resource is created. - * - * @param file - * the file to be described - * @param linkLocation - * the location of the file's link, or null if the - * file is not linked - * @param fileContentDescription - * the file content description that can be used to get - * information about the file, such as its initial content - */ - public FileDescription(IFile file, URI linkLocation, - IFileContentDescription fileContentDescription) { - super(file); - this.name = file.getName(); - this.location = linkLocation; - this.charset = null; - this.fileContentDescription = fileContentDescription; - } - - @Override - public void recordStateFromHistory(IResource resource, - IProgressMonitor monitor) throws CoreException { - Assert.isLegal(resource.getType() == IResource.FILE); - - if (location != null) { - // file is linked, no need to record any history - return; - } - IFileState[] states = ((IFile) resource).getHistory(monitor); - if (states.length > 0) { - final IFileState state = getMatchingFileState(states); - this.fileContentDescription = new IFileContentDescription() { - @Override - public boolean exists() { - return state.exists(); - } - - @Override - public InputStream getContents() throws CoreException { - return state.getContents(); - } - - @Override - public String getCharset() throws CoreException { - return state.getCharset(); - } - }; - } - } - - @Override - public IResource createResourceHandle() { - IWorkspaceRoot workspaceRoot = parent.getWorkspace().getRoot(); - IPath fullPath = parent.getFullPath().append(name); - return workspaceRoot.getFile(fullPath); - } - - @Override - public void createExistentResourceFromHandle(IResource resource, IProgressMonitor mon) throws CoreException { - - Assert.isLegal(resource instanceof IFile); - if (resource.exists()) { - return; - } - IFile fileHandle = (IFile) resource; - SubMonitor subMonitor = SubMonitor.convert(mon, 200); - subMonitor.setTaskName(UndoMessages.FileDescription_NewFileProgress); - try { - if (location != null) { - fileHandle.createLink(location, IResource.ALLOW_MISSING_LOCAL, subMonitor.split(200)); - } else { - InputStream contents = new ByteArrayInputStream( - UndoMessages.FileDescription_ContentsCouldNotBeRestored - .getBytes()); - // Retrieve the contents from the file content - // description. Other file state attributes, such as timestamps, - // have already been retrieved from the original IResource - // object and are restored in #restoreResourceAttributes - if (fileContentDescription != null - && fileContentDescription.exists()) { - contents = fileContentDescription.getContents(); - } - fileHandle.create(contents, false, subMonitor.split(100)); - fileHandle.setCharset(charset, subMonitor.split(100)); - } - } catch (CoreException e) { - if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) { - fileHandle.refreshLocal(IResource.DEPTH_ZERO, null); - } else { - throw e; - } - } - } - - @Override - public boolean isValid() { - if (location != null) { - return super.isValid(); - } - return super.isValid() && fileContentDescription != null - && fileContentDescription.exists(); - } - - @Override - public String getName() { - return name; - } - - /* - * Get the file state that matches this file description. The local time - * stamp is used to try to find a matching file state. If none can be found, - * the most recent copy of the file state is used. - */ - private IFileState getMatchingFileState(IFileState[] states) { - for (IFileState state : states) { - if (localTimeStamp == state.getModificationTime()) { - return state; - } - } - return states[0]; - - } - - @Override - protected void restoreResourceAttributes(IResource resource) - throws CoreException { - super.restoreResourceAttributes(resource); - Assert.isLegal(resource instanceof IFile); - IFile file = (IFile) resource; - if (charset != null) { - file.setCharset(charset, null); - } - } -} diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/FolderDescription.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/FolderDescription.java deleted file mode 100644 index 4744ed11dd6..00000000000 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/FolderDescription.java +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2015 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - ******************************************************************************/ - -package org.eclipse.ui.internal.ide.undo; - -import java.net.URI; - -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRoot; -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.SubMonitor; -import org.eclipse.ui.ide.dialogs.UIResourceFilterDescription; - -/** - * FolderDescription is a lightweight description that describes a folder to be - * created. - * - * This class is not intended to be instantiated or used by clients. - * - * @since 3.3 - * - */ -public class FolderDescription extends ContainerDescription { - - private boolean virtual = false; - /** - * Create a FolderDescription from the specified folder handle. Typically - * used when the folder handle represents a resource that actually exists, - * although it will not fail if the resource is non-existent. - * - * @param folder - * the folder to be described - * @param virtual - * the folder is a virtual folder - */ - public FolderDescription(IFolder folder, boolean virtual) { - super(folder); - this.virtual = virtual; - } - - /** - * Create a FolderDescription from the specified folder handle. If the - * folder to be created should be linked to a different location, specify - * the location. - * - * @param folder - * the folder to be described - * @param linkLocation - * the location to which the folder is linked, or - * null if it is not linked - */ - public FolderDescription(IFolder folder, URI linkLocation) { - super(folder); - this.name = folder.getName(); - this.location = linkLocation; - } - - @Override - public IResource createResourceHandle() { - IWorkspaceRoot workspaceRoot = getWorkspace().getRoot(); - IPath folderPath = parent.getFullPath().append(name); - return workspaceRoot.getFolder(folderPath); - } - - @Override - public void createExistentResourceFromHandle(IResource resource, IProgressMonitor mon) throws CoreException { - Assert.isLegal(resource instanceof IFolder); - if (resource.exists()) { - return; - } - IFolder folderHandle = (IFolder) resource; - SubMonitor subMonitor = SubMonitor.convert(mon, 300); - subMonitor.setTaskName(UndoMessages.FolderDescription_NewFolderProgress); - if (filters != null) { - SubMonitor loopMonitor = subMonitor.split(100).setWorkRemaining(filters.length); - for (UIResourceFilterDescription filter : filters) { - folderHandle.createFilter(filter.getType(), filter.getFileInfoMatcherDescription(), 0, - loopMonitor.split(1)); - } - } - subMonitor.setWorkRemaining(200); - if (location != null) { - folderHandle.createLink(location, IResource.ALLOW_MISSING_LOCAL, subMonitor.split(100)); - } else { - folderHandle.create(virtual ? IResource.VIRTUAL : 0, true, subMonitor.split(100)); - } - createChildResources(folderHandle, subMonitor.split(100)); - } -} \ No newline at end of file diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/IFileContentDescription.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/IFileContentDescription.java deleted file mode 100644 index 57f3479fbec..00000000000 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/IFileContentDescription.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2015 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.ui.internal.ide.undo; - -import java.io.InputStream; - -import org.eclipse.core.runtime.CoreException; - -/** - * IFileContentDescription is a description of a file's content. - * - * This class is not intended to be instantiated or used by clients. - * - * @since 3.3 - * - */ -public interface IFileContentDescription { - /** - * Returns an open input stream on the contents of the file described. The - * client is responsible for closing the stream when finished. - * - * @return an input stream containing the contents of the file - * @throws CoreException - * any CoreException encountered retrieving the contents - */ - public InputStream getContents() throws CoreException; - - /** - * Returns whether this file content description still exists. If it does - * not exist, it will be unable to produce the contents. - * - * @return true if this description exists, and - * false if it does not - */ - public boolean exists(); - - /** - * Returns the name of a charset encoding to be used when decoding the - * contents into characters. Returns null if a charset - * has not been explicitly specified. - * - * @return the name of a charset, or null - * @throws CoreException - * any CoreException encountered while determining the character - * set - * - */ - public String getCharset() throws CoreException; -} \ No newline at end of file diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/MarkerDescription.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/MarkerDescription.java deleted file mode 100644 index f84154edf11..00000000000 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/MarkerDescription.java +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2015 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - ******************************************************************************/ - -package org.eclipse.ui.internal.ide.undo; - -import java.util.Map; - -import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; - -/** - * MarkerDescription is a lightweight description of a marker that can be used - * to describe a marker to be created or updated. - * - * This class is not intended to be instantiated or used by clients. - * - * @since 3.3 - * - */ -public class MarkerDescription { - String type; - - Map attributes; - - IResource resource; - - /** - * - * Create a marker description from the specified marker. - * - * @param marker - * the marker to be described - * @throws CoreException - */ - public MarkerDescription(IMarker marker) throws CoreException { - this.type = marker.getType(); - this.attributes = marker.getAttributes(); - this.resource = marker.getResource(); - - } - - /** - * Create a marker description from the specified marker type, attributes, - * and resource. - * - * @param type - * the type of marker to be created. - * @param attributes - * the attributes to be assigned to the marker - * @param resource - * the resource on which the marker should be created - */ - public MarkerDescription(String type, Map attributes, IResource resource) { - this.type = type; - this.attributes = attributes; - this.resource = resource; - } - - /** - * Create a marker from the marker description. - * - * @return the created marker - * @throws CoreException - */ - public IMarker createMarker() throws CoreException { - IMarker marker = resource.createMarker(type); - marker.setAttributes(attributes); - return marker; - } - - /** - * Update an existing marker using the attributes in the marker description. - * - * @param marker - * the marker to be updated - * @throws CoreException - */ - public void updateMarker(IMarker marker) throws CoreException { - marker.setAttributes(attributes); - } - - /** - * Return the resource associated with this marker. - * - * @return the resource associated with this marker - */ - public IResource getResource() { - return resource; - } - - /** - * Return the marker type associated with this marker. - * - * @return the string marker type of this marker - */ - public String getType() { - return type; - } -} \ No newline at end of file diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/ProjectDescription.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/ProjectDescription.java deleted file mode 100644 index afac8aad90f..00000000000 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/ProjectDescription.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2015 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - ******************************************************************************/ - -package org.eclipse.ui.internal.ide.undo; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubMonitor; - -/** - * ProjectDescription is a lightweight description that describes a project to - * be created. - * - * This class is not intended to be instantiated or used by clients. - * - * @since 3.3 - * - */ -public class ProjectDescription extends ContainerDescription { - - private IProjectDescription projectDescription; - private boolean openOnCreate = true; - - /** - * Create a project description from a specified project. - * - * @param project - * The project to be described. The project must exist. - */ - public ProjectDescription(IProject project) { - super(project); - Assert.isLegal(project.exists()); - if (project.isOpen()) { - try { - this.projectDescription = project.getDescription(); - } catch (CoreException e) { - // Eat this exception because it only occurs when the project - // is not accessible and we have already checked this. We - // don't want to propagate the CoreException into the - // constructor - // API. - } - } else { - openOnCreate = false; - } - } - - /** - * Create a project description from a specified IProjectDescription. Used - * when the project does not yet exist. - * - * @param projectDescription - * the project description for the future project - */ - public ProjectDescription(IProjectDescription projectDescription) { - super(); - this.projectDescription = projectDescription; - } - - @Override - public IResource createResourceHandle() { - return ResourcesPlugin.getWorkspace().getRoot().getProject(getName()); - } - - @Override - public void createExistentResourceFromHandle(IResource resource, - IProgressMonitor monitor) throws CoreException { - SubMonitor subMonitor = SubMonitor.convert(monitor, 200); - Assert.isLegal(resource instanceof IProject); - if (resource.exists()) { - return; - } - IProject projectHandle = (IProject) resource; - subMonitor.setTaskName(UndoMessages.FolderDescription_NewFolderProgress); - if (projectDescription == null) { - projectHandle.create(subMonitor.split(100)); - } else { - projectHandle.create(projectDescription, subMonitor.split(100)); - } - - if (openOnCreate) { - projectHandle.open(IResource.NONE, subMonitor.split(100)); - } - } - - @Override - public String getName() { - if (projectDescription != null) { - return projectDescription.getName(); - } - return super.getName(); - } - - @Override - public boolean verifyExistence(boolean checkMembers) { - // We can only check members if the project is open. - IProject projectHandle = (IProject) createResourceHandle(); - if (projectHandle.isAccessible()) { - return super.verifyExistence(checkMembers); - } - return super.verifyExistence(false); - } -} \ No newline at end of file diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/UndoMessages.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/UndoMessages.java index 56e00222062..5f9dbdbb156 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/UndoMessages.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/UndoMessages.java @@ -61,12 +61,6 @@ public class UndoMessages extends NLS { public static String CopyResourcesOperation_NotAllowedDueToDataLoss; - public static String FileDescription_NewFileProgress; - public static String FileDescription_ContentsCouldNotBeRestored; - public static String FolderDescription_NewFolderProgress; - public static String FolderDescription_SavingUndoInfoProgress; - - public static String MarkerOperation_ResourceDoesNotExist; public static String MarkerOperation_MarkerDoesNotExist; public static String MarkerOperation_NotEnoughInfo; diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/messages.properties b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/messages.properties index c960a2d5bc6..f6a1c41160c 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/messages.properties +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/messages.properties @@ -42,11 +42,6 @@ AbstractCopyOrMoveResourcesOperation_copyProjectProgress=Copying project... AbstractCopyOrMoveResourcesOperation_moveProjectProgress=Moving project... CopyResourcesOperation_NotAllowedDueToDataLoss=The original resources that were copied no longer exist. Undoing the copy is no longer valid, since data could be lost. - -FileDescription_NewFileProgress=Creating new file... -FileDescription_ContentsCouldNotBeRestored=Unexpected error. File contents could not be restored from local history during undo/redo. -FolderDescription_NewFolderProgress=Creating new folder... -FolderDescription_SavingUndoInfoProgress=Saving folder info... MarkerOperation_ResourceDoesNotExist=Cannot complete operation because resource no longer exists. MarkerOperation_MarkerDoesNotExist=Cannot complete operation because marker no longer exists. From 0b926ef9d63ccaa0cee67dab511610b5d95c1af0 Mon Sep 17 00:00:00 2001 From: Ed Merks Date: Sun, 8 Oct 2023 08:42:49 +0200 Subject: [PATCH 2/5] Remove batik includes from the org.eclipse.e4.rcp feature https://github.com/eclipse-platform/eclipse.platform.ui/issues/1199 --- features/org.eclipse.e4.rcp/feature.xml | 28 ------------------------- 1 file changed, 28 deletions(-) diff --git a/features/org.eclipse.e4.rcp/feature.xml b/features/org.eclipse.e4.rcp/feature.xml index 98a262ed8bf..90fcfdd0b58 100644 --- a/features/org.eclipse.e4.rcp/feature.xml +++ b/features/org.eclipse.e4.rcp/feature.xml @@ -101,20 +101,6 @@ version="0.0.0" unpack="false"/> - - - - - - - - Date: Fri, 6 Oct 2023 10:16:53 +0200 Subject: [PATCH 3/5] Increase build duration timeout As more and more tests are running as part of this build, we need to increase the timeout. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index ffcd3048983..8aec932b473 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,6 +1,6 @@ pipeline { options { - timeout(time: 60, unit: 'MINUTES') + timeout(time: 80, unit: 'MINUTES') buildDiscarder(logRotator(numToKeepStr:'5')) disableConcurrentBuilds(abortPrevious: true) } From 938399a16df9b40130e103c4b298a4cb7fd97dfd Mon Sep 17 00:00:00 2001 From: Niklas Kellner Date: Mon, 9 Oct 2023 16:10:30 +0200 Subject: [PATCH 4/5] Null pointer thrown from addEditorOnboardingCommandId when keybinding without command exists (#1206) fixes https://github.com/eclipse-platform/eclipse.platform.ui/issues/1205 --- .../e4/compatibility/ModeledPageLayout.java | 6 +++++- .../ui/tests/api/ModeledPageLayoutTest.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java index c14682c9871..24dd2961e05 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java @@ -20,11 +20,13 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; import org.eclipse.core.runtime.IStatus; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.commands.MBindingTable; +import org.eclipse.e4.ui.model.application.commands.MCommand; import org.eclipse.e4.ui.model.application.commands.MKeyBinding; import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; import org.eclipse.e4.ui.model.application.ui.MElementContainer; @@ -644,7 +646,9 @@ public void addEditorOnboardingCommandId(String commandId) { if (numberOfOnboardingCommands >= 5) return; - Predicate commandWithEqualId = b -> b.getCommand().getElementId().equals(commandId); + Predicate commandWithEqualId = b -> Optional.of(b).map(MKeyBinding::getCommand) + .map(MCommand::getElementId).filter(elementId -> elementId.equals(commandId)).isPresent(); + Function toCommandText = b -> { try { return b.getCommand().getCommandName() + EDITOR_ONBOARDING_COMMAND_SEPARATOR diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/ModeledPageLayoutTest.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/ModeledPageLayoutTest.java index 03708e28327..5fc6170709a 100644 --- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/ModeledPageLayoutTest.java +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/ModeledPageLayoutTest.java @@ -124,6 +124,22 @@ public void addsUpToFiveEditorOnboardingCommandIds() throws Exception { assertThat(getNumberOfOnboardingCommands(perspective.getTags()), is(5)); } + @Test + public void addEditorOnboardingCommandWhenBrokenKeyBindingExsists() throws Exception { + MBindingTable bindingTable = MCommandsFactory.INSTANCE.createBindingTable(); + MKeyBinding binding = createBinding("unknownCommand", "Unknown", "M1+1+5"); + binding.setCommand(null); + bindingTable.getBindings().add(binding); + bindingTable.getBindings().add(createBinding("org.eclipse.ui.window.quickAccess", "Find Actions", "M1+3")); + + application.getBindingTables().add(bindingTable); + + pageLayout.addEditorOnboardingCommandId("org.eclipse.ui.window.quickAccess"); + + assertThat(perspective.getTags(), hasItem(ModeledPageLayout.EDITOR_ONBOARDING_COMMAND + "Find Actions$$$" + + KeySequence.getInstance("M1+3").format())); + } + private int getNumberOfOnboardingCommands(List commands) { return commands.stream().filter(t -> t.startsWith(EDITOR_ONBOARDING_COMMAND)).mapToInt(i -> 1).sum(); } From 985eb29b04788780f8afdc938ee9502337fd7335 Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Fri, 6 Oct 2023 13:03:33 +0200 Subject: [PATCH 5/5] Use pomless build for org.eclipse.e4.tools.test --- .../META-INF/MANIFEST.MF | 2 +- tools/tests/org.eclipse.e4.tools.test/pom.xml | 20 ------------------- 2 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 tools/tests/org.eclipse.e4.tools.test/pom.xml diff --git a/tools/tests/org.eclipse.e4.tools.test/META-INF/MANIFEST.MF b/tools/tests/org.eclipse.e4.tools.test/META-INF/MANIFEST.MF index ae80a325764..a1d43fe9bf4 100644 --- a/tools/tests/org.eclipse.e4.tools.test/META-INF/MANIFEST.MF +++ b/tools/tests/org.eclipse.e4.tools.test/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Test Bundle-SymbolicName: org.eclipse.e4.tools.test Bundle-Vendor: Eclipse.org -Bundle-Version: 1.3.0.qualifier +Bundle-Version: 1.3.100.qualifier Fragment-Host: org.eclipse.e4.tools;bundle-version="4.7.0" Bundle-RequiredExecutionEnvironment: JavaSE-17 Require-Bundle: org.junit;bundle-version="4.0.0", diff --git a/tools/tests/org.eclipse.e4.tools.test/pom.xml b/tools/tests/org.eclipse.e4.tools.test/pom.xml deleted file mode 100644 index 73443627500..00000000000 --- a/tools/tests/org.eclipse.e4.tools.test/pom.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - 4.0.0 - - org.eclipse.platform - eclipse.platform.ui.tools - 4.30.0-SNAPSHOT - ../../ - - - org.eclipse.e4.tools.test - 1.3.0-SNAPSHOT - - eclipse-test-plugin - - - true - -