| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <title>Supporting Repository Operations on Logical Models</title> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| </head> |
| |
| <body> |
| <h1>Supporting Repository Operations on Logical Models</h1> |
| <p>The purpose of this document is to present details of the solutions for the |
| repository operation scenarios presented in <a href="logical-support.html">Enabling |
| Logical Model Integration in the Eclipse Platform</a>.</p> |
| <h2>Logical to Physical Mappings</h2> |
| <p>A well integrated development environment should support 3rd party operations, |
| such as repository provider operations, on UI model elements that map to the |
| underlying Platform Resource model. Eclipse currently does support this for |
| cases where there is a one-to-one mapping from a model element to a resource. |
| However, to get full integration, one-to-many, and many-to-one should also be |
| supported. </p> |
| <h3>Performing Resource Based Operations on Logical Models</h3> |
| <p>In order for resource based operations, such as repository operations, to be |
| performed on logical models, a means to communicate resources that constitute |
| the model elements is required. This is the purpose of the <code>ResourceMapping</code> |
| API introduced in Eclipse 3.1 M5. This mapping supports a "one model element |
| to many resource" mapping. The specifics of this support is outlined <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/docs/online/team3.1/logical-physical-mappings.html">here</a>.</p> |
| <p>The following points summarize how <code>ResourceMappings</code> are used to |
| communicate the resources of a model element to a repository provider.</p> |
| <ol> |
| <li>Repository providers contribute menu operations to model elements through |
| the Platform adaptable mechanism. The menu items will appear on any elements |
| that adapt to <code>ResourceMapping</code>.</li> |
| <li>When the user performs a repository operation on a model element, the contributed |
| operation is handed the <code>ResourceMappings</code> obtained from the model |
| elements.</li> |
| <li> What happens next depends on what operation was chosen. For instance, a |
| check-in (or commit) operation can use the resource mapping to check-in the |
| appropriate files. Other operations can similarly be performed on the resources |
| that constitute the model element.</li> |
| <li>In some cases, the remote state of the model may contain additional resources. |
| The <code>ResourceMappingContext</code> API is a way to allow the repository |
| provider to communicate to the model provider the means to determine the remote |
| state of the model so that all relevant resources can be included in the operation. |
| For instance, an html file model may include the images shown on a page. If |
| additional images are added to the remote state, operations such as update |
| or merge would want to include the new images.</li> |
| </ol> |
| <p>Once an operation is triggered, some operations may need to obtain additional |
| input from the user or show operation feedback. Ideally, the information shown |
| in dialogs or other views used to obtain information from or show information |
| to the user should be consistent with the model from which the operation was |
| launched or, in the very least, provide a link between the resources being operated |
| on and the originating model elements. The following list outlines some of the |
| different scenarios where this issue may occur:</p> |
| <ul> |
| <li>It may be desirable to provide the ability to exclude some of the model |
| elements from the operation due to resource state (e.g. may want to prompt |
| when replacing model elements that contain dirty files). When a single model |
| element maps to one or more resources, this is straight forward. However, |
| if many model elements are contained in the same file, the model elements |
| may need to be included/excluded as a group. This is further complicated by |
| the fact that all affected model elements may not be contained in the input |
| to the operation. This is covered in the "Handling Many-to-One Mappings" |
| section.</li> |
| <li>Repository operations often involve the merging of remote changes with local |
| changes. This involves fairly complicated interactions between the model and |
| the repository. This discussed in more detail in the next section.</li> |
| </ul> |
| <h3>Merging Logical Model Changes</h3> |
| <p>One of the more complicated scenarios involving repository providers is when |
| remote changes need to be merged with local changes. Here are the merge cases:</p> |
| <ul> |
| <li>When a merge is required, a headless merge may be possible at the file level |
| which means that it could be performed by the repository provider without |
| the involvement of the model (i.e. no knowledge of model semantics is needed). |
| </li> |
| <li>It is also possible that a headless merge is not possible at the file level |
| but is possible at the model level (i.e. the knowledge of the models semantics |
| makes a headless merge possible). </li> |
| <li>If a headless merge is not possible, the user will need to perform a manual |
| merge. </li> |
| </ul> |
| <p>The interesting cases are the last two (i.e. merge involving model semantics |
| and manual merge).</p> |
| <p>There are several complications that must be considered when formulating a |
| solution:</p> |
| <ul> |
| <li>The elements being merged may come from different model tooling and hence |
| are parts of different models. This is currently unlikely since there are |
| few generic views showing elements from different models but may become more |
| likely in the future as more generic views surface.</li> |
| <li>At the lowest level, merges happen on files. If the multiple model elements |
| are contained in a single file, it is highly possible that additional model |
| elements may be affected by the merge. This means that the scope of the merge |
| may be greater than what was originally indicated by the user when they launched |
| the operation that triggered the merge.</li> |
| <li>The model elements being merged may be contained by higher level models |
| or may involve files that are contained by other models. The challenge here |
| is to display the merge in a way that makes this obvious to the user and allows |
| them to decide which merge mechanism is more appropriate. In the case of layered |
| models, it may be appropriate to choose the highest level model as the default |
| merge mechanism.</li> |
| <li>In order for model tooling to display the merge in a form that is consistent |
| with the model, access to the ancestor and remote state for files needs to |
| be accessible.This would require API provided by the repository provider.</li> |
| <li>The merge happens as part of a repository operation. When the merge is complete, |
| the repository operation may then need to perform additional portions of the |
| operation (e.g. modify the synchronization state of local resources). This |
| is complicated by the fact that the merge may have been completed on a subset |
| of the elements included in the operation (and the other elements skipped).</li> |
| </ul> |
| <p>A solution for presenting model based merges could take several forms:</p> |
| <ul> |
| <li>A separate dialog or wizard page for each model type involved in the merge. |
| This is OK if the models are disjoint but may be a problem if there is overlap.</li> |
| <li>A single page that displays all the model elements being merged. Selecting |
| a model element will populate other portions of the page appropriately. The |
| advantage is that the user will see the entire scope of the operation at once. |
| However, it will still be difficult to highlight model overlap. This will |
| also require a more standardized presentation which may be more restrictive.</li> |
| </ul> |
| <p>The second approach is already supported by the compare framework and feels |
| like a better approach. Hence, we will concentrate on that solution for the |
| time being. Here is what this solution may involve:</p> |
| <ul> |
| <li>A mechanism is provided for obtaining a model specific <code>DiffNode</code> |
| (Compare component API) for each <code>ResourceMapping</code> that is being |
| operated on. This would allow the merge operation to convert the selection |
| into a form that could appear in a merge viewer. Each type of <code>DiffNode</code> |
| may have model specific operations that should appear in the context menu |
| or toolbar. |
| <ul> |
| <li>The mechanism for creating the <code>DiffNodes</code> will need access |
| to the remote and ancestor (or base) state of the model.</li> |
| <li>Need to be able to include additional <code>DiffNodes</code> from a |
| model for the case where one of the selected elements is contained in |
| a file with other model elements.</li> |
| <li>Ideally, <code>DiffNodes</code> could be obtained from other models |
| that are interested in the resources being merged.This becomes more complicated |
| as there may be relationships between multiple models (i.e. one may be |
| built on top of another) and you would want the display of the <code>DiffNodes</code> |
| to reflect this.</li> |
| </ul> |
| </li> |
| <li>A merge viewer that can contain <code>DiffNodes</code> from one or more |
| models. Operations appropriate to a selected node should appear in the context |
| menu and toolbar. Also, selecting a node should update the other portions |
| of the merge viewer (structured comparison and content comparison panes). |
| Expansion of <code>DiffNodes</code> should also be supported.</li> |
| </ul> |
| <p>The key here is that the model is in complete control of the merge of its model |
| elements (i.e. the user may not even need to be aware of the underlying files). |
| </p> |
| <h3>Handling Many-to-One Mappings</h3> |
| <p>Another interesting case involves the case where a single Platform resource |
| contains several model elements. If the user selects a single model element |
| and performs a repository operation on it, it will affect other model elements |
| as well. This will be confusing to the user if they see other model elements |
| being affected by an operation on one element. Here are some the scenarios involving |
| this case:</p> |
| <ul> |
| <li>The user wants to tag (i.e. label or version) a specific model element but |
| doing so will tag all the elements contained in the same file. It may be enough |
| to warn the user that more than one element will be tagged but ideally, the |
| user could be shown all the elements that will be tagged.</li> |
| <li>The user wants to merge a model element. If the model provides the merge |
| viewer, than this may be possible without involving the other elements. However, |
| the repository provider would need to be able to differentiate this from a |
| full file merge since the action taken upon merge completion may differ. For |
| some operations that start with a merge, such as check-in, all the elements |
| in the file would need to be merged.</li> |
| <li>The user wants to replace a model element with the contents from the repository. |
| The operation doesn't need a merge since local contents are being replaced. |
| However, like a merge, it may be possible for the model to perform the replace |
| on the specific element given the contents of the two files. Without this |
| capability, the user would need to be informed that additional elements will |
| be included in the operation.</li> |
| <li>Goto action on a file marker (https://bugs.eclipse.org/bugs/show_bug.cgi?id=87288). |
| If many elements are contained in a single file, it is possible that multiple |
| editors may be open on the same file. A mechanism to pcik the proper editor |
| is needed.</li> |
| </ul> |
| <p>Possible solutions to this problem are:</p> |
| <ul> |
| <li>Provide a hint on the resource mapping or traversals that the file is not |
| wholly contained by the model element. This would at least allow the repository |
| provider to warn the user that the operation will affect additional elements. |
| If the traversal also included the range within a file, this could be used |
| for linking operation such as the one involving the linking of markers to |
| editors mentioned above. This could also be used to perform replacement of |
| file sections but would require the the ability to obtain the corresponding |
| range from the remote contents as well.</li> |
| <li>Provide a means of obtaining the additional model elements that will be |
| affected. This will allow the repository provider to display all the elements |
| that will be affected but requires additional API.</li> |
| </ul> |
| <p>This problem has some overlap with the physical to logical problem which is |
| covered in the "Physical to Logical" section, in the sense that, if |
| a mechanism existed for finding all model elements from any model that are contained |
| within a resource, this could be used as the API for the second point mentioned |
| above.</p> |
| <h3>Decorations</h3> |
| <p>Decorating logical elements based on their resource mapping is problematic |
| is some cases. The most interesting case is decorating elements to indicate |
| that they have changed locally with respect to the repository. There are two |
| aspects of this that are problematic:</p> |
| <ol> |
| <li>When a file contains many logical elements, only a few may be dirty when |
| the file is dirty. However, they will all appear dirty if the file dirty state |
| is used to determine the decoration. This can be overcome by allowing the |
| model provider to determine model element dirty state by comparing the modified |
| local file contents with that of the unmodified contents from the repository. |
| Unfortunately, this requires that either the unmodified contents are cached |
| or fetched from the server.</li> |
| <li>When elements are shown in a tree, the resource mapping of a parent may |
| not contain all the resource mappings of its children. This is due to the |
| use of content providers in tree views that determine what the children of |
| an element are in the tree. The only solution to this is to use model elements |
| that contain the logic of determining their children and use a simple content |
| provider that obtains the children from the model element. The problem with |
| this approach is that it leads to model wrapping when alternate views are |
| used (which is something the content provider API was supposed to solve).</li> |
| </ol> |
| <h2> </h2> |
| <h2>Status</h2> |
| <p>Here is the status of this work as of 3.1 M5</p> |
| <ul> |
| <li><a href="logical-physical-mappings.html">ResourceMapping/ResourceMappingContext</a>: |
| Initial cut is available in 3.1 M5 and will be in 3.1 as provisional API.</li> |
| <li>Merge Support: Although work has not begun, this area is well bounded and |
| well understood. </li> |
| </ul> |
| <h2>Open Issues</h2> |
| <p>Here are the list of open issues:</p> |
| <ul> |
| <li><strong>Transaction support</strong>: Some repository may have transaction |
| support. It is unclear how this fits in with logical model support.</li> |
| </ul> |
| <p> </p> |
| </body> |
| </html> |