| |
| <table border="0" cellspacing="5" cellpadding="2" width="100%"> |
| |
| <tr> |
| <td align="left" valign="top" bgcolor="#0080c0"> <b><font color="#ffffff" face="Arial,Helvetica"> |
| Eclipse 3.0 - Plan item</font></b> </td> |
| </tr> |
| </table> |
| <h1>Support Logical Resources</h1> |
| This document outlines the state of the Eclipse Platform <strong>Support Logical |
| Resources</strong> plan item. Interested parties should review this document and |
| verify that their use cases are reflected in the requirements then later that |
| the solution provided satisfies their needs. Feedback is strongly encouraged and |
| may be provided on the platform-vcm-dev mailing list or in the <a |
| href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37723">bug report</a> for this plan item. |
| <P></P> |
| <p class=MsoNormal>This is the plan item:</p> |
| |
| <blockquote> |
| <p>"<em>The Eclipse Platform supports a strong physical view of projects, |
| files, and folders in the workspace. However, there are many situations where |
| a physical view is not the most salient or useful for many purposes. In some |
| cases, multiple distinct objects happen to be stored in a single file, like |
| an archive. Conversely, in other cases, something that is logically a single |
| object is stored across multiple files. This discrepancy between logical and |
| physical creates problems for common operations such as searching, comparing, |
| and versioning, which need to work in the physical realm. Eclipse should support |
| some way of mapping between a logical view and the physical organization of |
| files on disk.</em>"</p> |
| <p>Last Modified: July 2nd, 2003</p> |
| </blockquote> |
| <h1>Motivation</h1> |
| <p>By definition Eclipse supports logical resources. It's a "an open extensible |
| IDE for anything and nothing in particular". The applications that are |
| built with it can be tailored to a particular problem domain and the workbench |
| extensions can be used to provide support for the logical model. What Eclipse |
| really doesn't support is integrating tools at the logical model. It's simple, |
| to integrate two plugins into Eclipse either plugin A and B have to know about |
| each other, or both plugins have to depend on some common plugin. While the |
| first option is satisfactory for a few cases, the second case is the most common |
| and the most problematic. To illustrate, the Eclipse SDK contains several plugins |
| that are based on the Resources plugin (e.g. Team, Search, Compare, JDT). When |
| an application is packaged based on the SDK, because the plugins in the SDK |
| are resource based it isn't possible to integrate plugins at the logical level.</p> |
| <p>As you will see later, even the users of the SDK (JDT+CVS+Resources) can observe |
| some of the problems associated with the lack of support for logical resources |
| and the implicit mapping to physical resources. The lack of a logical integration |
| point causes the co-existance of plugins in Eclipse to be error prone for the |
| user. The next sections will examine the relationships between logical and physical |
| resources and outline the visible problems with Eclipse 2.1. </p> |
| <h2>Existing Bugs</h2> |
| <p>Bug <A href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=32582">32582</a> |
| logical to physical mapping problem , 1 model element = 2 Files problem<br> |
| Bug <A href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=3979">3979</a> [CVS |
| Decorator] show version info works incorrectly for sub packages (1GFDIEB)</p> |
| <h2>Logical Resources</h2> |
| <p>Whereas logical resources are elements of the application that model the data/processes |
| of a particular problem domain, the physical resources are the file system resources |
| (e.g. files and folders) into which an application will eventually transform |
| their application model for storage. Applications that don't use file system |
| resources are not being considered as part of this plan item. For example, an |
| application that stores it's application data directly into a database.</p> |
| <p>The following table enumerates concrete examples of how logical and physical |
| resources are used in current applications integrated into Eclipse.</p> |
| <p><a name="#table1"></a>Table 1: Example logical to physical uses</p> |
| <table width="100%" border="1"> |
| <tr> |
| <td width="23%"><div align="center"><strong>Relationships</strong></div></td> |
| <td width="77%"><div align="center"><strong>Examples</strong></div></td> |
| </tr> |
| <tr> |
| <td><p>logical (1) <-> (*) physical</p> |
| <p>one logical to many physical</p></td> |
| <td valign="top"><p><a name="#1a"></a>(<strong>1a</strong>) EJB maps to several physical files: |
| (WSAD + XDE Tester). This is the most common case we have found. </p> |
| <blockquote> |
| <p>/src/org/app/bean.java<br> |
| /src/org/app/beanr.java<br> |
| /src/org/app/beanlocal.java</p> |
| </blockquote> |
| <p><em>Note: If one of the logical resource's files was deleted who would |
| remember that the file used to exist and is an outgoing deletion or that |
| there is an incoming addition to the logical resource?</em></p> |
| <p><a name="#1b"></a>(<strong>1b</strong>) Composite Object (logical) maps to several changed |
| physical resources. (Rational XDE)</p> |
| <p><em>Note</em>: <em>With 1 to many relationship there is always the complication |
| that arises if the logical element maps to files in an other project? This |
| would cause many problems in the current Team plugin.</em></p></td> |
| </tr> |
| <tr> |
| <td><p>logical (*) <-> (1) physical</p> |
| <p>many logical to one physical</p></td> |
| <td valign="top"><p><a name="#2a"></a>(<strong>2a</strong>) Methods in a class map to their |
| containing class file. (JDT)</p> |
| <p><a name="#2b"></a>(<strong>2b</strong>) Archive files (zip, jar) can be seen as a logical |
| and the contents of the archive all map to the same physical.(JTD + all)</p></td> |
| </tr> |
| <tr> |
| <td><p>logical (1) <-> (1) physical</p> |
| <p>one logical to one physical</p></td> |
| <td valign="top"><p><a name="#3a"></a>(<strong>3a</strong>) A Java Package maps to a folder |
| but a package does not include sub folders (e.g. they are shallow). (JDT)</p> |
| <p><a name="#3b"></a>(<strong>3b</strong>) A UML class maps to a file. For example, in a UML |
| application a class could be stored in a single file called 'x435dsds.umlclass'. |
| The reason it's a logical is that the user of the application will never |
| be concerned about the actual file name or even the folder it's stored |
| in. (XDE)</p></td> |
| </tr> |
| </table> |
| <h2>Not very adaptable</h2> |
| <p>Object contributions and decorators are key mechanisms for providing rich |
| integration between tools. Using object contributions and adaptable objects, |
| any plugin |
| |
| can provide actions and decorators that will show in another plugin's view. </p> |
| <p>Since IResource is the lowest common integration class and |
| is strongly mapped to its physical storage as files and folders, the integration |
| point for actions and decorators cannot be the logical types in the view. |
| The actions will consequently use the adaptable type from the selection |
| to perform the |
| action or the decorator the resource from the getImage request.</p> |
| <p>Here is an example to illustrate the problem with the CVS plugin. When running |
| a CVS commit action in the packages view the action doesn't know that the IFolder |
| is a Java package and is a shallow namespace. It will use the selection and |
| traverse the selected IContainer using IContainer.members() and commit all child |
| resources. This is the same when the CVS outgoing decorator is shown on a package. |
| It will reflect the deep outgoing state of the IContainer. This can lead to |
| unexpected behavior because the user expected the action to run on the model |
| that the action was displayed on.</p> |
| <p>Example object contribution for the CVS commit action:</p> |
| <pre> |
| <extension point="org.eclipse.ui.popupMenus"><br> <objectContribution<br> objectClass="org.eclipse.core.resources.IResource"<br> adaptable="true"<br> id="org.eclipse.team.ccvs.ui.IResourceContributions"><br> <filter<br> name="projectPersistentProperty"<br> value="org.eclipse.team.core.repository=org.eclipse.team.cvs.core.cvsnature"><br> </filter><br> <action<br> label="Commit"<br> tooltip="Commit resource to CVS repository"<br> class="org.eclipse.team.internal.ccvs.ui.actions.CommitAction"<br> menubarPath="team.main/group3"<br> id="org.eclipse.team.ccvs.ui.commit"><br> </action> |
| <objectContribution> |
| </extension> |
| </pre> |
| <p>Example code run in the commit action to calculate the resources to commit:</p> |
| <pre>public static Object[] getSelectedAdaptables(ISelection selection) { |
| ArrayList result = null; |
| if (!selection.isEmpty()) { |
| result = new ArrayList(); |
| Iterator elements = ((IStructuredSelection) selection).iterator(); |
| while (elements.hasNext()) { |
| Object adapter = getAdapter(elements.next(), IResource.class); |
| if (c.isInstance(adapter)) { |
| result.add(adapter); |
| } |
| } |
| } |
| if (result != null && !result.isEmpty()) { |
| return (Object[])result.toArray((Object[])Array.newInstance(IResource.class, result.size())); |
| } |
| return (Object[])Array.newInstance(IResource.class, 0); |
| }</pre> |
| <p>Example code for defining an IResource adaptable decorator:</p> |
| <pre><extension |
| point="org.eclipse.ui.decorators"> |
| <decorator objectClass="org.eclipse.core.resources.IResource" |
| adaptable="true" |
| label="%DecoratorStandard.name" |
| state="false" |
| lightweight= "true" |
| quadrant = "BOTTOM_RIGHT" |
| class="org.eclipse.team.internal.ccvs.ui.CVSLightweightDecorator" |
| id="org.eclipse.team.cvs.ui.decorator"> |
| <description> |
| %DecoratorStandard.desc |
| </description> |
| </decorator> |
| </extension></pre> |
| <h2> Decorators</h2> |
| <p>When the CVS decorator decorates a logical container in a view, the desire |
| is to decorate parents with the dirty indicator if one or more of their logical |
| children are dirty. To do this properly, the decorator would need to query the |
| dirty status of each of the logical children of the container. This can be a |
| costly operation as each child may itself be a logical container. We have optimized |
| the dirty decoration by caching folder dirty states. This optimization becomes |
| far more complicated with logical models where the caching must be based on |
| this alternate model (i.e. the state must be cached for each model).</p> |
| <p> |
| |
| |
| |
| In addition, often decorators rely on IResource change |
| events to re-calculate some new state. In the case of a |
| logical elements representing several physical resources there is no easy way of associated |
| a IResource change event to its files and the actual logical element.</p> |
| <h2>Views</h2> |
| <p>It would be nice to see the Java logical view in the Synchronize view or the |
| CVS Repositories View. However, the entries in these views may not be IResources |
| so an IResource independent mapping mechanism would be required. This could |
| be a considerable amount if work for anyone providing a logical model. This |
| problem is partly being addressed by the introduction of customizable content |
| providers as described in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-ui-home/navigator-proposal/general_purpose_navigator_proposal.html">Generic |
| Navigator</a> item.</p> |
| <p>Also if an action prompts the user, for example to add resources to CVS, what |
| icons and labels are used in the dialog? It would be nice to show those that |
| are most familiar to the user. </p> |
| <h2>Change Sets</h2> |
| <p>Consider a user's action as a logical change, for example, the user renames |
| a class using the JDT refactoring action. In the user's mind he 'renamed a class' |
| and as a result there has been many other file changes. Currently there is not |
| way of capturing these logical actions and associating the set of affected resources. |
| This problem manifests itself more in tools where almost every change to the |
| model has side effects.</p> |
| <h2>File based tools</h2> |
| <p>Some tools that integrate into Eclipse are file based and don't use IResources. |
| And thus wouldn't be able to operation logical elements.</p> |
| <h1>Proposed Solution</h1> |
| <p>Part of the solution is to introduce a logical resource element that can be |
| the basis for integration between plugins. Our proposed solution will attempt |
| to solve the most common uses described in <A href="#table1">Table1</a>, namely |
| examples <A href="#1a">1a</a>, <A href="1b">1b</a> and <A href="3a">3a</a>. |
| The <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-ui-home/navigator-proposal/general_purpose_navigator_proposal.html">generic |
| navigator</a> plan item should address the <A href="2b">2b</a> and <A href="3b">3b</a> |
| examples by providing extensions that would allow a logical model to be available |
| to other plugins for display purposes. Finally, <A href="2a">2a</a> is currently |
| solved with the existing IResource adapter mechanism.</p> |
| <p>Naturally another possible solution would be to change IResource to not be |
| analogous to file system resources. However this scope of change is beyond the |
| 3.0 timeframe and would cause, in my opinion, non-justifiable breaking changes |
| to all plugins.</p> |
| <h2>ILogicalResource</h2> |
| <p>An interface will be added to the Resources plugin that will allow binding |
| logical elements to physical ones. The interface is purposely simple with logical |
| model manipulations ommitted. A client can't use this interface to display logical |
| models or gain any interesting additional knowledge about it. In fact, the only |
| way that a plugin will be able to gain access to the model for those purposes, |
| would be via the navigator extensions proposed in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-ui-home/navigator-proposal/general_purpose_navigator_proposal.html">generic |
| nagivator</a> plan item.</p> |
| <p>Current plugins that add object contributions to IResource (CVS, Search, Compare) |
| would have to also add them to ILogicalResource and honour the biddings provided |
| by the logical resource. Moreover, the plugins that adapted to IResource to |
| these object contributions shown in the context menu should no longer adapt |
| the IResource and instead implement ILogicalResource.</p> |
| <pre> |
| |
| /** * A logical resource is an element of an application that |
| models the * data/processes of a particular problem domain. Eventually a |
| logical resource * must transform the application model for storage using a |
| file system |
| |
| * resource. * This class provides the bridge between a logical element and |
| the physical * resource(s) into which it is stored. On the other hand it |
| doesn't provide * hierarchical access to the |
| logical |
| model. * * |
| @see |
| IResource */ public interface ILogicalResource { |
| /** |
| * Returns the project which contains this logical resource. |
| |
| * This is a resource handle operation; neither the resource |
| * nor the resulting project need exist. |
| * |
| * |
| * @return the project handle |
| */ |
| public IProject getProject(); |
| |
| /** |
| * Returns the file system resource(s) for this logical resources. The |
| * returned resources must be contained within the same project. |
| * A logical element should return the same list of resources regardless |
| * of the existance of the files on the file system. For example, if a |
| * logical resource called "form" maps to "/p1/form.xml" and "/p1/form.java" |
| * then whether form.xml or form.java existed, they should be returned |
| * by this method. |
| * |
| * The traversal of the returned IResources should be done considering |
| * the <code>isDeep</code> flag. If a logical resource maps to a folder |
| * then the folder's child resources can only be visited if the folder is |
| * deep. |
| * |
| */ |
| public IResource[] getPhysicalResources(); |
| |
| /** |
| * Optimization check for tools that should not run operations that traverse |
| * into child folders. |
| * @return |
| */ |
| public boolean isDeep(); |
| } |
| </pre> |
| <h2>Issues</h2> |
| <p>- ObjectContributions have to be duplicated in the plugins that would like |
| to provide both contributions for IResource and ILogicalResource.</p> |
| <p>- Logical classes (e.g. java model, UML) have to implement the interface instead |
| of adapting to it. This is a limitation of the current objectContribution story |
| in the workbench.</p> |
| <p>- Plugins that add object contributions will have to modify their actions to |
| handle logical resources. There should be some standard UI components for showing |
| the mappings. For instance you could show the logical model at the top and in |
| a details part the physical files/folders that will be affected by the operation.</p> |
| </BODY> |
| </html> |