Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 131105

Summary: [EFS] CopyFilesAndFoldersOperation does not handle null locations
Product: [Eclipse Project] Platform Reporter: Bert Vingerhoets <bert_vingerhoets>
Component: UIAssignee: Tod Creasey <Tod_Creasey>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: eclipse, john.arthorne, litrik_de_roy, Mike_Wilson
Version: 3.2   
Target Milestone: 3.1 RC2   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Bug Depends on: 130398    
Bug Blocks:    
Attachments:
Description Flags
Proposed patch
none
Updated patch
none
Team project set for the example none

Description Bert Vingerhoets CLA 2006-03-09 10:38:30 EST
Stumbled on this problem when copying/moving resources between local and remote filesystems. Copying or moving a file from a project on a remote filesystem to a project on a local filesystem results in a source does not exist error; vice-versa produces a destination does not exist; nonlocal to nonlocal produces a destination does not exist.

Partial stacktrace:
MoveFilesAndFoldersOperation(CopyFilesAndFoldersOperation).validateDestinationLocation(IContainer) line: 1428
MoveFilesAndFoldersOperation(CopyFilesAndFoldersOperation).validateDestination(IContainer, IResource[]) line: 1357
MoveFilesAndFoldersOperation.validateDestination(IContainer, IResource[]) line: 217
ResourceNavigatorMoveAction(CopyResourceAction).isValid(Object) line: 166
...

Remark that all destination validation in these UI classes use IResource.getLocation() which is only usable for resources on the local filesystem. Because of this, it is impossible to seamlessly integrate local and nonlocal resources.

I am using org.eclipse.ui.ide_3.2.0.I20060216-1200.jar but according to public CVS nothing has yet changed in the use of getLocation().
Comment 1 Tod Creasey CLA 2006-03-10 09:20:20 EST
Also see Bug 130398
Comment 2 Tod Creasey CLA 2006-03-17 15:07:02 EST
Bert would you mind checking in a build >20060317 (or with HEAD). I think Bug 130398 may have addressed this for you.

Thanks in advance
Comment 3 Bert Vingerhoets CLA 2006-03-20 05:29:47 EST
Verified with org.eclipse.ui.ide_3.2.0.N20060319-0010.jar
The problem is not solved: org.eclipse.ui.actions.MoveFilesAndFoldersOperation#validateDestination(IContainer, IResource[]) still uses IContainer#getLocation().
Comment 4 Tod Creasey CLA 2006-03-20 16:09:55 EST
Created attachment 36630 [details]
Proposed patch

Here is a proposed patch. I'll need a remote file system to verify this with before I release it - in the meantime if you could try it out Bert and let me know if I missed anything I would be most appreciative.
Comment 5 Tod Creasey CLA 2006-03-20 16:10:22 EST
Adding John for some insight in verifying this.
Comment 6 Bert Vingerhoets CLA 2006-03-21 04:33:09 EST
The problem is now shifted towards CopyFilesAndFoldersOperation#validateDestination(IContainer, IResource[]): this method calls validateDestinationLocation(IContainer) which in turn uses IResource#getLocation().

Another problem is the approach to construct a Path from the destination URI: this URI can (and in my case does) contain queries which are returned in the .toString() method. Hence, when appending the source filename to the destination Path, I get results similar to "http://host/sub1/sub2?option=value/filename.ext".

Note that using .getPath() instead of .toString() will not suffice: source and destination comparison must include scheme, host and port as well, as it must be possible to copy/move resources between hosts, even when source and destination path are the same; or between services running on the same host, using different ports; I cannot think of a usecase for the scheme part at the moment.
Comment 7 John Arthorne CLA 2006-03-29 10:53:10 EST
Tod: I have released a writable file system example to org.eclipse.ui.examples.filesystem - it is a file system that is stored completely in memory
Comment 8 Tod Creasey CLA 2006-03-31 10:17:17 EST
John I am still having the following problem with the zip example on validation


A URI from zip:/D:/temp/3.2M6-news.zip

generates 

!ENTRY org.eclipse.ui 4 0 2006-03-31 10:14:13.312
!MESSAGE java.lang.NullPointerException
!STACK 0
java.lang.NullPointerException
	at java.net.URI$Parser.parse(URI.java:2946)
	at java.net.URI.<init>(URI.java:574)
	at org.eclipse.core.internal.filesystem.zip.ZipFileSystem.getStore(ZipFileSystem.java:33)
	at org.eclipse.core.internal.filesystem.InternalFileSystemCore.getStore(InternalFileSystemCore.java:107)
	at org.eclipse.core.filesystem.EFS.getStore(EFS.java:296)
	at org.eclipse.core.filesystem.URIUtil.equals(URIUtil.java:42)
	at org.eclipse.core.internal.resources.LocationValidator.validateProjectLocationURI(LocationValidator.java:361)
	at org.eclipse.core.internal.resources.Workspace.validateProjectLocationURI(Workspace.java:2007)
	at org.eclipse.ui.dialogs.WizardNewProjectCreationPage.validatePage(WizardNewProjectCreationPage.java:307)
	at org.eclipse.ui.dialogs.WizardNewProjectCreationPage$2.reportError(WizardNewProjectCreationPage.java:128)
	at org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea$3.modifyText(ProjectContentsLocationArea.java:229)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:196)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:925)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:949)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:930)
	at org.eclipse.swt.widgets.Text.wmCommandChild(Text.java:2143)
	at org.eclipse.swt.widgets.Control.WM_COMMAND(Control.java:3375)
	at org.eclipse.swt.widgets.Control.windowProc(Control.java:3249)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:4023)
	at org.eclipse.swt.internal.win32.OS.CallWindowProcW(Native Method)
	at org.eclipse.swt.internal.win32.OS.CallWindowProc(OS.java:1803)
	at org.eclipse.swt.widgets.Text.callWindowProc(Text.java:131)
	at org.eclipse.swt.widgets.Control.windowProc(Control.java:3334)
	at org.eclipse.swt.widgets.Text.windowProc(Text.java:1841)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:4023)
	at org.eclipse.swt.internal.win32.OS.SetWindowTextW(Native Method)
	at org.eclipse.swt.internal.win32.OS.SetWindowText(OS.java:2583)
	at org.eclipse.swt.widgets.Text.setText(Text.java:1657)
	at org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.updateLocationField(ProjectContentsLocationArea.java:321)
	at org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.handleLocationBrowseButtonPressed(ProjectContentsLocationArea.java:311)
	at org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.access$6(ProjectContentsLocationArea.java:301)
	at org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea$2.widgetSelected(ProjectContentsLocationArea.java:204)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:90)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:925)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3346)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2966)
	at org.eclipse.jface.window.Window.runEventLoop(Window.java:820)
	at org.eclipse.jface.window.Window.open(Window.java:796)
	at org.eclipse.ui.actions.NewProjectAction.run(NewProjectAction.java:116)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:499)
	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:539)
	at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:488)
	at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:400)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:925)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3346)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2966)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1914)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1878)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:419)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:143)
	at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:95)
	at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:78)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:92)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:68)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:376)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:169)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:324)
	at org.eclipse.core.launcher.Main.invokeFramework(Main.java:336)
	at org.eclipse.core.launcher.Main.basicRun(Main.java:280)
	at org.eclipse.core.launcher.Main.run(Main.java:977)
	at org.eclipse.core.launcher.Main.main(Main.java:952)
Comment 9 Tod Creasey CLA 2006-03-31 10:18:04 EST
Sorry should have been in Bug 133867
Comment 10 Tod Creasey CLA 2006-04-06 13:48:20 EDT
Bert

John has written an in memory example and I am having no trouble with it in M6. The validation is done if there is no location only so it should be no problem for you.

Here is the code from MoveFilesAndFoldersOperation

if (destinationLocation != null) {
                IPath sourceLocation = sourceResource.getLocation();
                IPath destinationResource = destinationLocation
                        .append(sourceResource.getName());
                if (sourceLocation != null
                        && sourceLocation.isPrefixOf(destinationResource)) {
                    return NLS.bind(IDEWorkbenchMessages.MoveFilesAndFoldersOperation_sameSourceAndDest, sourceResource.getName());
                }
            }

I will attach a team project set with Johns example.
Comment 11 Tod Creasey CLA 2006-04-07 16:50:31 EDT
Marking as FIXED
Comment 12 Bert Vingerhoets CLA 2006-04-24 11:37:33 EDT
I'm sorry for it taking a while to get back to you, but it seems there is still an error.
Now I can copy/move any resource to a local location, but I can't copy/move anything to a remote location.

CopyFilesAndFoldersOperation#validateDestinationLocation(IContainer) still uses getLocation(), which returns null for a remote destination. As a result, an IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted message is returned ('destination does not exist'). This is the problem from Comment #6.

I have used a recently checked out version of org.eclipse.ui.ide (using CopyFilesAndFoldersOperation.java v1.22).
Comment 13 Tod Creasey CLA 2006-04-24 14:08:35 EDT
I can replicate Berts situation by doing the following

1) Create a regular project and a remote one (I used the in memory example - I'll attach a team project set here).

2) Copy something in the regular project and paste it into the in memory one.

I will attach a patch that I would like you to try Bert - basically I removed the calls to the method that checks for a null destination. I would feel better if you verified that this covers your case as well.

As this was (incompletely) fixed in RC1 I'll mark it RC2 and release the patch for tomorrows test pass.
Comment 14 Tod Creasey CLA 2006-04-24 14:09:19 EDT
Created attachment 39315 [details]
Updated patch
Comment 15 Tod Creasey CLA 2006-04-24 14:34:31 EDT
Marking FIXED
Comment 16 Bert Vingerhoets CLA 2006-04-25 05:57:18 EDT
Seems to be solved indeed.
remote->remote works
remote->local works
local->remote works
Comment 17 Tod Creasey CLA 2006-04-25 09:16:30 EDT
Cheers Bert.
Comment 18 Tod Creasey CLA 2006-04-25 11:20:58 EDT
Created attachment 39416 [details]
Team project set for the example
Comment 19 Tod Creasey CLA 2006-04-26 13:31:27 EDT
Verified in 20060426