Eclipse Platform Core RFC 0001
Case Variant Collisions During Resource Creation.
Summary
The Eclipse workspace is always case-sensitive, but some filesystems are not.
This causes a problem when trying to create a file using the Core API, in
the case where a file already exists at the target location that differs only
in case from the file being created. This document discusses the problem and
evaluates various approaches to solving it.
By John Arthorne, OTI.
Created: November 26, 2001
Last Modified: November 26, 2001
</Greg>
What is the resulting behavior when move files from
case sensitive local files system, to case sensitive server, to a case-insensitive
local file system.
Playing devils advocate
- In the past core has indicated that certain behavior/api
is a reasonable (e.g. related to project creation & move) because core
is just plain folders, files. However this is not the case since core is case
sensitive independent of what the native file system supports.
- Each project can be associated with a different repository
& the versioning abilities of that project are governed by the target
repository (adapter). It seems strange that we would not argue that a project's
case sensitive behavior wouldn't be based on the target file system it was
stored on.
The solution seems to indicate the error on create stays
the same, but that a new unreliable/fuzzy status code is added. Unless status
codes are gauranteed I don't understand how this helps.
<Greg>
The ProblemLet us define three resource handles: IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("Project");
IFile abc = project.getFile("abc.txt");
IFile ABC = project.getFile("ABC.txt");
The initial state of the problem is when project and abc
already exist. If a Core API method is used to create ABC (using either
create, copy, or move API methods), an exception is
thrown. The exception detail states that the file could not be created because
it already exists. The contradiction is that ABC.exists()will return
false, since the case sensitive workspace does not recognize the collision with
abc. Likewise, lookup methods such as
project.findMember("ABC.txt") will also fail to locate the existing
file abc, leading the API user to believe that it is ok to go ahead and
create ABC.
Note that this is not quite the same as when a case variant already exists in
the file system, but not in the workspace. Following the above example, say a
local file "abc.txt" does not exist in the workspace, but is created externally
in the filesystem. In this case, the current behaviour when a client calls
ABC.create() is consistent; it throws an exception stating that the
workspace is out of sync with the local filesystem.
Proposed Solution
The proposal is to add a new core status code, IResourceStatus.CASE_VARIANT_EXISTS.
This status code would be included in exceptions from all create, copy,
or move API methods in the IResource hierarchy, when a case variant already
exists at the target location. The exception will also include an appropriate
error message describing why the creation couldn't continue.
Pros:
- This solution allows clients to recognize the situation and act accordingly.
Core cannot determine the appropriate behaviour for all cases when this problem
occurs, so the decision must be left to the caller. For example, say a resource
"/Project/abc/myfile.txt" already exists. A client wants to create a file
called "/Project/ABC/anotherfile.txt". When they attempt to create folder
ABC, a failure occurs because of the case variant collision. In this situation,
the caller may know that the case of the folder isn't important, and they'll
just go ahead and create "/Project/abc/anotherfile.txt". In another situation,
the caller may decide it is better to delete the existing "abc" folder, and
create the new "ABC" folder in its place. In a third situation, the client
may decide to defer the question to the user.
<Greg>
* Are clients actually asking to be able to do this???
* In he case above of anotherfile.txt what exactly does the error indicate
& provide.
</Greg>
- Minimal impact on downstream clients. This fix requires no breaking API
changes, and the new behaviour is similar to the old behaviour. In both new
and old approaches, an exception is thrown -- the only thing that has changed
is the status code.
Cons:
- Status codes are fuzzy API. API methods do not formally guarantee what status
codes will be returned for a given error condition. The status codes could
theoretically change at any time without warnings or deprecations.
<Greg>
Technically we still have an inconsistency between the create and the exists.
The only "helping" factor is you knew the status hint saying the
create failed due to case sensitivity.
It also means any ui operations for goto file (for example) must support a
case insensitive variant. This is not unreasonable to expect as a user I would
want this anyways.
</Greg>
Alternative SolutionsThis section describes proposed alternative
solutions, and some comments on them. More alternative solutions will be added
as they are raised during discussion. Please feel free to add to or dispute any
pros and cons already listed.
Make the Workspace Case-Sensitivity Match the FilesystemWith this
approach, when the Eclipse workspace is run on a case-insensitive operating
system, the workspace would never be case-sensitive. On case-sensitive operating
systems, the workspace would always be case-sensitive.
Pros:
- Behaviour is consistent with the underlying filesystem
- Core API methods are always consistent with each other. If there is a
failure to create because the target already exists, then exists and
findMember methods will also find the target in all cases.
Cons:
- Performance. This approach would have a huge performance cost. The critical
performance path for the workspace is lookups in the resource tree. This lookup
is based on a high performance binary search in the resource tree. This search
cannot be performed as efficiently when ignoring case.
<Greg> You won't convince clients with this arguement-
we'll just ask you to go make it faster<g> </Greg>
- Inconsistency gets pushed up to higher layers. In many cases this approach
merely moves the file-system inconsistency problems up to other plugins. Callers
of Core API can currently rely on it always being case-sensitive, and can
act accordingly. Core is able to handle some of these inconsistent situations
without involving client plug-ins.
<Greg> see discussion about re: repo. You could
argue that providing a case sensentive workspace in the absence of a case
sensitive file system is also pushing up an inconsistency to layers above
that may also need to deal with external tools? </Greg>
- Inconsistencies still possible when workspace spans filesystems. If the
user has a workspace where some projects are mounted on a case-sensitive filesystem,
and others are mounted on a case-insensitive filesystem, there would still
be an inconsistency. Such a setup would undoubtedly case widespread problems
for downstream plug-ins trying to manage such an inconsistent workspace.
<Greg> This could also be viewed as pro like repo
story. </Greg>
Related Bugs:
RFC Status
<Greg> Although this is non voting (and I am not a
committer) I would give this a +1 provided the status values are guaranteed -
not fuzzy. If they are fuzzy then we are not much further ahead and hence its
a -1. I would also request that the error message itself be clearer to indicate
the cause of failure without requiring looking at the status bit.
Overall I don't have a problem with the workspae being case sensitive but I find
it odd that we are presenting something not actually supported. This implicitily
means we can't really argue that we are justified in a given api because we are
just exposing the file system.
</Greg>
This proposal is currently soliciting comments. Please provide comments by
4-DEC-2001
In particular, if you have a suggestion for another way this problem could be
addressed, or have reservations about the proposed approach, let us know!
Comments should be directed to the core mailing list: platform-core-dev@xxxxxxxxxxx
(post, archives).
|