Community
Participate
Working Groups
If a user has an existing file called "abc.txt", then tries to create a new file called "ABC.txt" using IFile.create with force=true, it throws an exception. The API contains the sentence: * However, if <code>true</code> is specified, this method will * attempt to write a corresponding file in the local file system, * overwriting any existing one if need be. This suggests that if force=true we should just wipe out case variants. The problem is, if we don't do this, clients have NO OTHER option but to do the following: - create a java.io.File on the parent folder - call list() to get names of children - do an equalsIgnoreCase test against every child - delete the child that is in the way - call IFile.create again. Which is really not nice to have to do.
Note that the API for force says "local file system" all the time. In the current case, the user DOES have a file in the workspace with the same name and that's why it is failing. I would say that if the file didn't exist in the workspace it would overwrite it.
It's open to interpretation. I can argue that since Eclipse is always case sensitive, it DOES NOT already have a file in the workspace with the exact same name. If they call IFile.exists(), it says false... then when they try to create, it says, "Sorry, that file exists". Now they're stuck. I admit I'm trying to stretch the API definition a little bit, but the what it comes down to is that IFIle.create and IFile.exists use different definitions of existence. Maybe IFile.exists() should check if the OS is case-sensitive, and act accordingly?
I agree with you that the two APIs IFile.exists() and IFile.create() can have different semantics on case insensitive file systems. I agree as well that we need to improve it. I just disagree about the "It's open to interpretation." part. Solving this problem using the current APIs could end up in extra and/or unecessary overhead. Maybe an extra API (like out internal Resource.findExistingResourceVariant() ) or the same APIs with extra flags could solve. I just think the client should have the option of having the overhead or not.
Exposing new API just moves the problem up to the ISV level. The API user would then have to decide whether to use the case-sensitive or insensitive approach, meaning their code probably doesn't work right for one case or the other. Elsewhere in core we query the OS to determine if it's case sensitive, and then act appropriately, all handled under the covers without the ISV having to care about the platform's case sensitivity. However, I agree that it would be dangerous to add anything to IResource.exists() that makes it significantly slower. I don't know what to recommend here...
I will try a simple compromise solution to see how it flies with the UI people. The compromise is that methods that create files and folders on disk will return a special status constant in the CoreException if a case variant collision is detected. This constant is IResourceStatus.CASE_VARIANT_EXISTS. The idea is that at least this allows the programmatic detection of this case, so appropriate handling can be written: -call IFile.create - if exception constant is CASE_VARIANT_EXISTS, notify the user if necessary - then get list of children of parent resource, and find the case variant, and delete it - call IFile.create again.
Fixed in v208