Friday, October 31, 2008

New Resource Filters for the Eclipse Core Resources

Our customers have to work with large source trees, where creating projects with those trees can be cumbersome.

Often the user wants to deal only with a subset of files in those hierarchies, but each file system object gets created an a resource in the resource tree and causes performance and scalability problems.

To address those limitations, we implemented the "Resource Filter" feature which we provided a patch to the core.resources plugin today (UI to come shortly).

With this feature, the Core Resources plugin now support adding resource filters onto IFolder objects that limits at a low level which file system objects are available to the resource tree so that large source trees can scale easily when filters are used.

How does it work:

  • The .project file now contains tags that specify which filters exist on which folder.
  • A folder can contain a list of Filters (from 0 to n)
  • Filters can be optionally "inheritable", in which case they apply not only to the folder's children, but also to it's sub-folder children as well.
  • Each filter has the following attributes:

    1. The project relative path of the folder it applies.

    2. The id of the filter type provider (ex: "org.eclipse.core.resources.regexFilterProvider").

    3. The arguments of the filter. This is filter dependent. (ex: ".*\.c")

    4. The filter type. This is a integer that can contain any of the following flags:

      • Filters can be set to include only files or folders matching a criteria, or exclude all file and folders matching a criteria. The two following flags choose between the two modes:

        public static final int INCLUDE_ONLY = 1;
        public static final int EXCLUDE_ALL = 2;

        Note that multiple filters on the same folder can be of a mix of "include_only" and "exclude_all" types.

      • Filters can be applicable to files or folders or both, the following flags indicate the preference:

        public static final int FILES = 4;
        public static final int FOLDERS= 8;

      • Filters can be inheritable to sub-folders, the following flag indicate that:

        public static final int INHERITABLE = 16;

    Note that all those flags are declared in the org.eclipse.core.resources.IFilter interface.

Something important to realize is that only real files that are located under a folder and appear in the workspace tree by a local refresh can be filtered out. Linked resource explicitly added under a folder still appear no matter what filters are put.

This is by design, since linked resources and resource filters are complementary to each other. Where linked resources allow the user to build the project structure by explicitly including files and folders, resource filters allows the user to build the project structure by explicitly excluding files and folders.

One practical thing to do, though, is to put resource filters on linked resource folders, which work perfectly.

Some interesting behavior:
  • If the user creates a new file from the "File | New..." wizard that is actually filtered out by its parent resource filters, it will show up just after creation, but it will disappear from the resource tree when the user manually refreshes the view. I believe this is the proper behavior.

  • Deleting folders that contain filtered out children work as expected (hidden children are deleted with their parent), but might cause the user to delete files that he's not aware are present on the file system. This should be addressed by the UI showing a warning in such case.

  • Copying folders that have filters is interesting. While the filters get applied to the destination folder, only the visible objects are copied, which may or may not be what the user expects. Again, this issue should be resolved by having a UI giving the user the option (or at least the information) about what will happen

  • Moving folders with filters, on the other hand, moves the whole content, including the hidden files invisible from the resource tree. This is because the move operation moves the underlying directory, and then copy the resource tree. The filters are moved as expected as well.

How to try it out:
  1. Get the patch from:
    https://bugs.eclipse.org/bugs/show_bug.cgi?id=252996

  2. Apply the patch to the org.eclipse.core.resources project.

  3. Import the test project provided in this patch. The project contains two filters:
    • One filter on "folder" which "includes only" all files ending with ".c" (and is inheritable)
    • Another filter on "folder/sub_folder" that "excludes all" files matching "output.c".

  4. Observe that the following objects are hidden from the resource tree:

    • "folder/foo.h" (the include_only *.c filter on "folder")

    • "folder/bar.h" (the include_only *.c filter on "folder")

    • "folder/sub_folder/file.h" (the inherited include_only *.c filter on "folder")

    • "folder/sub_folder/output.c" (the exclude_all "output.c" on "sub_folder")


No comments: