| <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| <meta name="Author" content="Build"> |
| <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> |
| <title>Eclipse Platform Core RFC 0006 - Omnibus Resource Improvements</title> |
| </head> |
| <body> |
| |
| <h1> |
| Omnibus Resource Improvements</h1> |
| <i><font size=-1>Last revised 10:00 Wednesday February 27, 2002</font></i> |
| <p>This note summarizes a series of proposed additions and changes to Eclipse to improve the resource |
| story and address several Eclipse 2.0 plan items. |
| <h2> |
| Reify project description as project resource</h2> |
| A project's project description contains important information about the |
| project. |
| <p>The proposal is to reify the project description in a file, named |
| ".project", |
| in the root of each project's content area. The contents of the file would |
| be a well-specified XML format, and contain Core project description information: |
| project name, project description, list of project nature ids, list of |
| required project names, and the project build spec. |
| <p>The .project file in the root folder would be considered the master |
| copy. IProject.setDescription would overwrite this file. If a team provider |
| (or a user) changes the .project file through means other than IProject.setDescription, |
| this eventually affects the project much as if IProject.setDescription |
| had been called. The one exception is changes to the project name, which |
| would be disallowed [alternative: rename the project]. After the fact resource |
| change events are reported on the .project file resource as well as being |
| flagged as a description change on the project resource. |
| <p>Note that the location of the project's content directory is <i>not</i> |
| represented in the .project file. Rather, the .project file is found in |
| the project's content directory. |
| <p>As a consequence of this change, Core should drop its internal |
| .prj file. |
| <p>For open projects, core would keep the project description in memory |
| at all times. IProject.getDescription uses the in-memory information - |
| it does not access the local file system. Core would also remember a timestamp |
| for the .project file. When refreshLocal picks up a change to a .project |
| file, Core reads the modified .project file and changes the in-memory project |
| description. Resource change events are reported much as if the project |
| description had been changed via IProject.setDescription. |
| <p>Problems addressed: |
| <ul> |
| <li> |
| Projects are now more self-contained in the local file system. This means |
| it is easier to give a project to someone else simply by copying the project |
| content directory.</li> |
| |
| <li> |
| Meets Team (VCM) request for a real file containing project description. |
| Team would no longer need to treat project description as special in any |
| way; instead, it simply saves and restores the .project file exactly as |
| it would any other file.</li> |
| </ul> |
| New wrinkles created: |
| <ul> |
| |
| <li> |
| When a project's resources, which now might include a .project file, |
| already exist on disk but are not a part of a workspace, how does a user import this project to their workspace?<br> |
| When the designated directory contains a .project file, it should be read and |
| honored. When the designated directory does not contain a .project file, one |
| should be created (the user would normally supply crucial information as input, |
| including the project's list of capabilities/natures). This will require new Core |
| API, and a new Import wizard.</li> |
| <li> |
| What happens if a project's .project file gets deleted?<br> |
| This is a serious error which may cause the user to lose other important |
| data. If the project is to be opened (or remain open), Core should reconstruct |
| a .project file from available information. However, the user is in trouble, and |
| it is important that the facts be reported back to the user so that she can |
| rectify the situation.</li> |
| |
| <li> |
| What happens if a project's .project file is busy and cannot be read?<br> |
| The |
| Core operation that is causing the description to be read from disk fails. |
| If attempting to open a project, the open fails.</li> |
| |
| <li> |
| What happens if a project's .project file contains mangled XML?<br> |
| The Core |
| operation that is causing the description to be read from disk fails. If |
| attempting to open a project, the open fails.</li> |
| |
| <li> |
| What happens if a project's .project file is busy or something else prevents it |
| from being written |
| to disk?<br> |
| The Core operation that is causing the description to be written |
| to disk (IProject.setDescription) fails. (The alternative of proceeding with the |
| information held in memory was considered. It requires a more complex |
| interaction with the user to ensure that the changes eventually do get written |
| to disk after the user has rectified the situation.)</li> |
| |
| <li> |
| What happens when IFile.setContents is called on the .project file?<br> |
| This operation should overwrite the file in the local file system, and then |
| behave as if refresh local had just discovered the changed file.</li> |
| |
| <li> |
| What happens if there is a conflict on the .project file (user's outgoing |
| change being met by incoming change from team repository)?<br> |
| Ideally, there should be a specialized merge conflict viewer that would show |
| the user the changes in terms that they would understand and allow the |
| user to resolve the conflict. For 2.0, a standard text merge viewer on |
| the XML .project file contents would show the user the conflict (as it |
| does with conflicting .classpath files).</li> |
| |
| <li> |
| What is the relationship between operations that change the .project file and |
| the validateSave hook in IFile.setContents?<br> |
| Setting the project description via a Core operation should hit the validateSave |
| hook as it would if IFile.setContents were called to write out the .project |
| file. This hook would not be triggered when changes to the .project file (or any |
| other file) are discovered, as by refresh local.</li> |
| </ul> |
| |
| <h2> |
| Derived resources</h2> |
| Derived resources are regular files and folders in a project that are created |
| in the course of translating, compiling, copying, or otherwise processing other files. Derived resources are not original data, and can be recreated |
| from other resources. |
| <p>It is commonplace to exclude derived resources from VCM because they |
| clutter the repository with ever-changing files that each user appears |
| to modify regularly. Each team provider typically provides the user with |
| a way to include certain files under VCM and exclude others. If plug-ins |
| that create derived resources mark them as such, the team provider can |
| do a better job of excluding by default those resources that any user is |
| unlikely to want in the repository. |
| <p>The proposal is there be a way for non-Team-clients to provide hints |
| that certain resource subtrees are likely to contain derived resources. |
| This would be done by setting a mark bit on a folder or file; the mark |
| would mean that the resource, and any present or future descendents, should be considered derived |
| resources <i>by default</i>. Note that this is only a default. A user should |
| still be able to place any resource under management even if marked as, |
| or sits below, a derived resource. |
| <p>Example: JDT would set this bit on the project's output folder (or on |
| individual generated *.class files when the output folder coincides with the |
| project root). |
| <p>Example: An editor or utility that creates a backup copy of a file in |
| the same folder should mark the copy as a derived file. |
| <p>Derived marks would be recorded in the resource tree, and saved to disk |
| along with the in-memory resource tree. Derived marks would not be recorded |
| in a Team repository. |
| <p>To mark (or unmark) a resource as derived, the resource would need to |
| exist. There would be no resource delta for setting or resetting this bit; |
| default is off (i.e., not derived). |
| However, the fact that the bit would be retained in memory at all times |
| means that a Team provider can quickly discover whether a plug-in has marked |
| a resource or one of its ancestors as derived.<p>The user would be able see and change a resource's derived flag via |
| the Properties dialogs. It would not warrant anything more obvious since |
| users are unlikely to ever be interested in this property. However, letting the |
| user mark a resource as derived would allow them to indicate that certain files |
| (such as certain metadata files) are not prime candidates for version |
| management. |
| <p>In addition to this basic support for derived resources, the Team component |
| will maintain a list of excluded file and folder name patterns. Any files or |
| folders in the project |
| with names that match these patterns would be considered unmanaged (or unmanaged |
| by default).</p> |
| <p>Problems addressed: |
| <ul> |
| <li> |
| There is a simple way for client plug-ins to indicate that certain resource |
| which they create are derived resources that should not be put into a repository |
| by default. The mechanism is independent of any Team provider, and can be |
| used unconditionaly even when there is no Team provider for the project.</li> |
| |
| <li> |
| There is a simple way for Team providers to find out the whereabouts |
| of derived resources that should not be put into a repository by default.</li> |
| |
| <li> |
| Specifically, JDT would mark project output folders as derived. This would |
| hint that generated .class files and copied resource files should not be |
| placed in the repository.</li> |
| </ul> |
| |
| <h2> |
| Team-private resources</h2> |
| Some Team providers have extra files and folders that are created |
| in the project by the team provider to satisfy certain external requirements |
| of that provider. For example, CVS uses a CVS/ subfolder in each managed |
| folder to store CVS-specific information. Although these files are needed |
| by the team provider, they are of no interest to other plug-ins. Indeed, |
| other plug-ins should not even know of their existence. |
| <p>The proposal is to provide a way for a Team provider to hide certain resources in the resource |
| tree so that they are not seen by other plug-ins. This is achieved with a new <b>team-private |
| member</b> flag in the in-memory resource |
| tree. When a file or folder is marked as a team-private member, it is omitted |
| from the list of resources returned from IContainer.members (a variant method |
| includes team-private members upon request). In all other regards, a |
| team-private member is like any other file or folder resource that exists in the |
| workspace.</p> |
| <p>Team-private member marks are recorded in the resource tree, and saved to disk |
| along with the in-memory resource tree. Team-private member marks are not be recorded |
| in a Team repository. To mark (or unmark) a resource as a team-private member, the resource needs to |
| exist. The bit |
| defaults to off (i.e., not team-private).<p>Creations, deletions, and changes to |
| team-private member resources are reflected in resource deltas. Like IContainer.members, |
| the deltas seen by normal delta clients omit all mention of team-private member |
| resources (the unfiltered list of child deltas is available on request). A |
| change to the team-private member flag of a resource is reflected in the delta |
| (indicated as a change to the resource's team-private member property), and will |
| be seen by all delta clients (because the resource was a non-team-private member |
| either before or after the change).<p>The mechanism is intended to be used by Team providers. |
| Team providers are in the unique position of being able to set this flag to hide |
| any extra files or folders they might create. Team providers can do this without |
| needing to store additional metadata in the repository. |
| <p>Example: the CVS team provider would set this bit on the extra |
| "CVS" folders that it creates in most folders. By doing so at the time |
| a CVS folder first enters the workspace, the folder does not show up in the |
| normal resource delta, and therefore slips in to the workspace without other |
| plug-ins noticing. Since the CVS folders contain special metadata, the CVS team |
| provider may need to protect these files from being moved or deleted; the new |
| move/delete hook (described in a separate proposal) is useful in this regard.<p>Note |
| that other plug-ins are not is a similar position because team-private member marks |
| are not recorded |
| in team repositories. If a non-Team provider plug-in was to set this flag, the |
| resource does disappear from general view in the workspace. The hiding is only |
| for that workspace, however. When a resource propagates to another workspace via |
| a Team repository, the team-private member flag does not propagate along with |
| it. Thus, <i>this mechanism cannot be used by other plug-ins to hide their resources.</i> |
| <p>The workbench resource navigator does not show team-private members by |
| default, although the user can ask to see team-private members if they want |
| (similar to the way ".*" metadata resources are hidden from the user |
| by default). The user can see (but not change) a resource's team-private member flag via |
| the Properties dialogs. It does not warrant anything more obvious as users are unlikely to ever be interested in this property. |
| The user is not allowed to |
| change the setting is this flag.</p> |
| <p>Problems addressed: |
| <ul> |
| <li> |
| Team providers can include additional files and folders in a project without |
| impacting normal plug-in clients.</li> |
| |
| </ul> |
| |
| <h2> |
| Java builder resource file copying</h2> |
| The Java incremental project builder copies resource files from source |
| folders to the Java project's output folder. This allows the runtime classpath |
| to be shorter, and makes the output folder more closely resemble a typical |
| JAR contents used when deploying a Java program. |
| <p>However, this resource copying can have undesirable consequences when |
| it copies files willy-nilly to the output folder, and can create a situation |
| that confounds the user who peers into the project's output folder.<p>The proposal is for JDT to provide a mechanism for excluding certain |
| files from being copied. This would take the form of a list of file name |
| patterns to be excluded. This would make it easy to exclude files with certain names (e.g., |
| "*_EN_US.properties") or certain types of files (e.g., "*.antlr"). The list would be primed with |
| the pattern ".*", which would exclude all folders and files matching the |
| common Eclipse metadata naming convention. Through the UI, users would |
| be able to remove this pattern if it was too strong, and add additional |
| patterns to exclude other files. |
| <p>Note that the derived bit is unsuitable for controlling JDT copying behavior |
| (a derived resource file might very well need to be copied to the output folder). |
| <p>A global list of exclusion patterns would be persisted by JDT core. |
| This information would remembered with the workspace as JDT Core metadata |
| (it would not be in the .classpath file, and would not be shareable across |
| workspaces). |
| <p>Problems addressed: |
| <ul> |
| <li> |
| The JDT builder would no longer have to copy all resources to the output |
| folder. The user could better control this copying behavior.</li> |
| |
| <li> |
| The ".*" default pattern will prevent metadata files from being copied |
| into the output folder, thereby reducing one common source of user confusion.</li> |
| |
| <li> |
| Note that Team provider-specific files (e.g., "CVS" folders) would be invisible |
| under another proposal, so these would not be an issue.</li> |
| </ul> |
| |
| <h2> |
| Other issues</h2> |
| |
| <h3> |
| Project archive files</h3> |
| Given the project |
| description is reified as a file in the project, there is no longer as great a |
| need for a special form of project archive. Users can create a zip archive |
| containing the project's resources, which would now include its .project file. |
| After unzipping into the local file system, the project can be added to a |
| different workspace. |
| |
| <h3> |
| Read-only projects</h3> |
| No changes are planned to support read-only projects. |
| <p>The notion of a read-only Eclipse project is somewhat of an oxymoron. An |
| Eclipse project is for doing work, and must be located in a read-write |
| file system. The binary library projects employed by Java development tooling |
| are an admitted abberation to facilitate people working on large-scale |
| products spread across several related Eclipse projects. The idea is that |
| it is easy for the user to replace a binary library project in their workspace |
| with the real, source code project from a team repository if for some reason |
| they decide to do so. |
| <p>PDE uses binary library projects for plug-ins. For self-hosting convenience, |
| PDE provides the option to locate an Eclipse plug-in project directly in |
| the directory where the plug-in is installed. Doing so requires creating |
| additional files in that directory (including JDT's .classpath file), and |
| can only be done when the plug-ins are installed in a read-write directory. |
| For shared plug-in installs on, or plug-in installs on read-only drives, |
| there is no option but to have PDE create projects elsewhere and copy over |
| the necessary files from the plug-in. |
| </body> |
| </html> |