| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <title>Team Support for Logical Model Integration</title> |
| </head> |
| <body> |
| <table width="100%" cellpadding="2" cellspacing="5" border="0"> |
| <tbody> |
| <tr> |
| <td bgcolor="#0080c0" valign="top" align="left"> <b><font |
| face="Arial,Helvetica" color="#ffffff"> Eclipse 3.2 - Team Support for Logical |
| Model Integration</font></b></td> |
| </tr> |
| </tbody> |
| </table> |
| <h1>Team Support for Logical Model Integration</h1> |
| <p>Version 3.2 M4</p> |
| <p>The <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/docs/online/team3.2/model-integration-proposals.html">Proposed |
| Support for Logical Model Integration</a> document outlines all the areas that |
| are targeted to be addressed in 3.2 related to logical model integration support |
| in Eclipse. The purpose of this document is to outline the proposed solutions |
| relating to Team. Feedback is strongly encouraged and may be provided on the |
| platform-team-dev mailing list or in the <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37723">bug |
| 37723</a> for this plan item. The API described in this document is available |
| in builds but is not yet final and may undergo some revision before the end |
| of the Eclipse 3.2 development cycle. </p> |
| <p>This document is broken into the following sections:</p> |
| <ul> |
| <li><strong><a href="#ResourceMapping">Resource Mappings</a></strong>: API that |
| was introduced as provisional in 3.1</li> |
| <li><a href="#ModelProvider"><strong>Model Providers</strong></a>: This API |
| servers 2 purposes. It supports the grouping of resource mappings by model |
| for the purpose of performing batch operations and it supports the back-mapping |
| of file-system resources to resource mappings to ensure that team operations |
| include all relevant model elements in a team operation</li> |
| <li><strong><a href="#TeamInput">Team Operation Scope</a></strong>: API for |
| translating a set of selected model elements into the complete set of model |
| elements that should be included in a team operation.</li> |
| <li><a href="#AutoMerge"><strong>Model-based Merging</strong></a>: API for delegating |
| a merge operation (e.g. cvs update or merge) to a model so that model semantics |
| can be used to ensure model consistency and improve conflict resolution during |
| merge operations.</li> |
| <li><strong><a href="#FileHistory">File History</a></strong>: API for describing |
| the history of a file.</li> |
| </ul> |
| <p>It also contains a pointer to a download that contains a simple <a |
| href="#Example">Library example</a>.</p> |
| <h2>Overview of API</h2> |
| <p>The relationship between the APIs presented in this document can be described |
| in terms of a repository operation being performed on a logical model. Some |
| of the API relates to any repository operation while other parts are specific |
| to a merge operation (e.g. a CVS update). Here is a description of the steps |
| required to perform a CVS update on a logical model as it relates to the API |
| contained in this document.</p> |
| <ol> |
| <li>The user selects a set of model elements and chooses Team>Update from |
| the context menu. </li> |
| <ul> |
| <li>The <em>ResourceMapping API</em> is what makes it possible for repository |
| tooling to recognize that the selected elements are related to file-system |
| resources in some way.</li> |
| </ul> |
| <li>The selected elements may be part of a higher level model or may only represent |
| part of the contents of a file. The team operation needs to know the complete |
| set of model elements and resources that need to be operated on. </li> |
| <ul> |
| <li>The <em>ModelProvider API</em> supports the mapping of file-system resources |
| to model elements</li> |
| <li>The <em>Team Operation Scope API</em> provides a set of reusable classes |
| that determine the complete input (which we refer to as the scope) of the |
| team operation.</li> |
| </ul> |
| <li>Once the complete scope of the operation is determined (i.e. the complete |
| set of resources to be operated on), the operation can be performed. For a |
| merge, the semantics of the model may dictate in what order files need to |
| be merged or may be able to reduce the chances of conflicts by using model |
| semantics to perform the merge. |
| <ol> |
| <li>The <em>Model-based Merging API</em> allows the team operation to delegate |
| the merge to the model.</li> |
| <li>To do so, the team operation must communicate the synchronization state |
| of all the files involved to the model and give the model access to the |
| remote contents of those files so that the model can perform the merge</li> |
| </ol> |
| </li> |
| </ol> |
| <p>The following sections describe each of these API pieces in more detail.</p> |
| <h2><a name="ResourceMapping"></a>Resource Mappings</h2> |
| <h3>The Basic Resource Mapping API</h3> |
| <p>This solution involves adding API to the Resources plugin that maps logical |
| models elements to workspace (i.e. file system) resources. The API is purposely |
| simple with logical model manipulations omitted. A client can't use this interface |
| to display logical models or gain any interesting additional knowledge about |
| it. It's purpose is simply to map one or more model elements to workspace resources. |
| </p> |
| <p>The API consists of the following classes: </p> |
| <ul> |
| <li><strong>ResourceMapping</strong>: The Class to which logical model elements |
| adapt to indicate that the model corresponds to a set of resources in the |
| workspace. The complete <code>ResourceMapping</code> class can be viewed <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ResourceMapping.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">here</a>. |
| The methods of interest are: |
| <ul> |
| <li><code>Object getModelObject()</code>: The model object from which the |
| mapping was derived (or adapted).</li> |
| <li><code>ResourceTraversal[] getTraversals(ResourceMappingContext, IProgressMonitor)</code>: |
| The resource traversal that cover the resources that constitute the model |
| object.</li> |
| </ul> |
| </li> |
| <li><strong>ResourceTraversal</strong>: A <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ResourceTraversal.java?rev=HEAD&content-type=text/vnd.viewcvs-markup"><code>ResourceTraversal</code></a> |
| contains a set of resources and a depth flag that indicates the depth to which |
| the resources in the traversal are associated with the originating model object. |
| Resource traversals are provided to a client by a resource mapping in order |
| to describe the contents of a model in such a way that the client (e.g. a |
| repository provider) can perform its operations in as efficient a means as |
| possible. Methods of interest are: |
| <ul> |
| <li><code>getResources()</code></li> |
| <li><code>getDepth()</code></li> |
| </ul> |
| </li> |
| <li><strong>ResourceMappingContext</strong>: a context that is provided to the |
| resource mapping by the client when obtaining traversals. This context allows |
| the logical model to determine what the remote state of the model is so that |
| the proper resources can be covered by the resource traversals returned by |
| the resource mapping. The use of the<code> <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ResourceMappingContext.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">ResourceMappingContext</a></code> |
| and<code> <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/RemoteResourceMappingContext.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">RemoteResourceMappingContext</a></code> |
| is a bit more complicated and is described <a |
| href="#ResourceMappingContext">later</a>.</li> |
| </ul> |
| <p>There are two types of plugins that should be interested in resource mappings. |
| Those who provide a model that consists of, or is persisted in, resources in |
| the workspace and those that want to perform operations on resources. The following |
| two sections describe how to associate a resource mapping with a model object |
| and how to contribute menus to objects that adapt to resource mappings.</p> |
| <h4>Adapting a Model to a ResourceMapping</h4> |
| <p>Plugins that adapted their model objects to <code>IResource</code> in order |
| to get resource specific actions shown in the context menu can now adapt to |
| <code>ResourceMapping</code> if a richer description of how the object adapts |
| to resources is beneficial. However, they are not required to do so if there |
| is no benefit. For instance a Java compilation unit (i.e. *.java file shown |
| in a JDT view) that now currently adapts to <code>IFile</code> need not adapt |
| to <code>ResourceMapping</code> since nothing is gained. However, a Java package |
| should adapt to <code>ResourceMapping</code> in order to indicate that the package |
| consists of only the files in the corresponding folder and not the subfolders.</p> |
| <p>The preferred way to adapt model elements to a resource mapping is to use an |
| adapter factory. The following is the XML markup for contributing an adapter |
| factory in a plugin manifest. </p> |
| <pre style="background-color: rgb(204, 204, 255);"> <extension<br> point="org.eclipse.core.runtime.adapters"><br> <factory<br> class="org.eclipse.example.library.logical.AdapterFactory"<br> adaptableType="org.eclipse.example.library.Book"><br> <adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/><br> </factory><br> <factory<br> class="org.eclipse.example.library.logical.AdapterFactory"<br> adaptableType="org.eclipse.example.library.Library"><br> <adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/><br> </factory><br> ...<br> </extension></pre> |
| <p>The adapter factory implementation would look something like this:</p> |
| <pre style="background-color: rgb(204, 204, 255);">public class AdapterFactory implements IAdapterFactory {<br> public Object getAdapter(Object adaptableObject, Class adapterType) {<br> if((adaptableObject instanceof EObject) && adapterType == ResourceMapping.class) {<br> return new EObjectResourceMapping((EObject)adaptableObject);<br> }<br> return null;<br> }<br><br> public Class[] getAdapterList() {<br> return new Class[] {ResourceMapping.class};<br> }<br>}</pre> |
| <p>Model objects must implement the <code>IAdaptable</code> interface. When they |
| do so, they must ensure that the Platform adapter manager is consulted. This |
| can be done by either subclassing <code>PlatformObject</code> or by using the |
| following line of code:</p> |
| <blockquote> |
| <p><code>Platform.getAdapterManager().getAdapter(Object, Class)</code></p> |
| </blockquote> |
| <p>The above is the preferable approach. However, the model object can implement |
| the IAdaptable interface and provide a <code>getAdapter(Class)</code> implementation |
| that creates returns an instance of <code>ResourceMapping</code> explicitly |
| when asked for one. This is a more straightforward approach but the least desirable |
| as the model must have explicit knowledge of the adaptation to resources.</p> |
| <p>In some cases, the provider of a logical model may not want their model to |
| adapt to <code>IResource</code> in every context or may want the object to adapt |
| differently for object contributions than for other contexts. The workbench |
| UI provides a special intermediate adapter API, <code>IContributorResourceAdapter</code>, |
| for this purpose. When objects are being adapted to <code>IResource</code> in |
| the context of object contributions, the workbench first tries to adapt the |
| resource to <code>IContributorResourceAdapter</code> before trying to adapt |
| to <code>IResource</code> directly. A new sub-interface of this interface, <code>IContributorResourceAdapter2</code>, |
| has been added which provides the same capability for <code>ResourceMapping</code>. |
| The only difference is that the model provider should register a factory for<code> |
| IContributorResourceAdapter</code> since the Workbench does an <em>instanceof</em> |
| check to see if the contributed adapter is also an instance of <code>IContributorResourceAdapter2</code>.</p> |
| <p>The implementation of the <code>ResourceMapping</code> subclass for a Java |
| package would look something like this.</p> |
| <pre style="background-color: rgb(204, 204, 255);">public class JavaPackageResourceMapping extends ResourceMapping {<br> IPackageFragment package;<br> ...<br> public getModelObject() {<br> return package;<br> }<br> public ResourceTraversals[] getTraversals(<br> ResourceMappingContext context, <br> IProgressMonitor monitor) {<br> return new ResourceTraversal[] { <br> new ResourceTraversal(<br> new IResource[] { package.getCorrespondingResource() },<br> IResource.DEPTH_ONE, IResource.NONE)<br> }<br> }<br>}</pre> |
| <p>This is a fairly straightforward mapping so the implementation is not complex. |
| The complexity of the resource mapping implementation will, of course, vary |
| from model to model. The <code>EObjectResourceMapping</code> example used above |
| is implemented in the example and has a more complicated implementation.</p> |
| <h4>Contributing Menus to Resource Mappings</h4> |
| <p>Plug-ins that contribute extensions to adaptable extension points will have |
| to make two changes to support the new <code>ResourceMapping</code> APIs:</p> |
| <ol> |
| <li>Update their plugin.xml files to change the objectClass of their adaptable |
| contributions to <code>ResourceMapping</code> (for those for which this is |
| appropriate).</li> |
| <li>Update their actions to work on <code>ResourceMapping</code> instead of |
| <code>IResource</code> and respect the depth constraints provided in the traversals.</li> |
| <li>(Optional) provide a <code>ResourceMappingContext</code> if they manage |
| remote resources (more on this <a href="#ResourceMappingContext">below</a>)</li> |
| </ol> |
| <p>First of all, plugins that add object contributions to <code>IResource</code> |
| (CVS, Search, Compare) can now add them to <code>ResourceMapping</code> instead, |
| if the action can apply to multiple resources. Here is an XML snippet that contributes |
| a menu action to objects that adapt to resource mappings:</p> |
| <pre style="background-color: rgb(204, 204, 255);"> <extension<br> point="org.eclipse.ui.popupMenus"><br> <objectContribution<br> adaptable="true"<br> objectClass="org.eclipse.core.resources.mapping.ResourceMapping"<br> id="org.eclipse.example.library.ResourceMappingContributions"><br> <action<br> label="Show Resource Mappings"<br> class="org.eclipse.example.library.contributions.ShowResourceMappingsAction"<br> menubarPath="additions"<br> id="org.eclipse.example.library.showMappings"/> <br> </objectContribution><br> </extension></pre> |
| <p>Contributions to <code>ResourceMapping</code> will automatically apply to objects |
| that adapt to <code>IResource</code>. This transitive association is handled |
| by the Workbench.</p> |
| <p>Filtering of the contributions to resource mappings can be done using action |
| filters or expressions. An expression for filtering by project persistent property |
| has been added to allow repository providers to have their menus appear on projects |
| that are mapped to their repositories.</p> |
| <pre style="background-color: rgb(204, 204, 255);"> <extension<br> point="org.eclipse.ui.popupMenus"><br> <objectContribution<br> objectClass="org.eclipse.core.resources.mapping.ResourceMapping"<br> adaptable="true"<br> id="org.eclipse.team.ccvs.ui.ResourceMapperContributions"><br> <enablement><br> <adapt type="org.eclipse.core.resources.mapping.ResourceMapping"><br> <test <br> property="org.eclipse.core.resources.projectPersistentProperty" <br> args="org.eclipse.team.core.repository,org.eclipse.team.cvs.core.cvsnature" /><br> </adapt><br> </enablement><br> <action<br> label="%UpdateAction.label"<br> definitionId="org.eclipse.team.cvs.ui.update"<br> class="org.eclipse.team.internal.ccvs.ui.actions.UpdateAction"<br> tooltip="%UpdateAction.tooltip"<br> menubarPath="team.main/group2"<br> id="org.eclipse.team.cvs.ui.update"><br> </action><br> ...<br> </objectContribution><br> </extension></pre> |
| <p>Actions that have been contributed to the <code>ResourceMapping</code> class |
| will be given a selection that contains one or more <code>ResourceMappings</code>. |
| It is the actions responsibility to translate the resource mapping into a set |
| of resources to be operated on. This can be done by calling <code>getTraversals</code> |
| to get the traversals of the mapping. Traversals are used to allow the clients |
| of the traversal to optimize their operations based on the depth of the resources |
| being traversed. A client may traverse the resource manually or may use the |
| resource and the depth as input into an operation that the action delegates |
| to do the work. As an example, if the user performs a CVS update on a java package |
| and the java package resource mapping maps to a folder of depth one, CVS would |
| issue an appropriate command ("cvs update -l" for those who are curious) which |
| would perform a shallow update on the folder the package represents.</p> |
| <h3><a name="ResourceMappingContext"></a>Resource Mapping Context</h3> |
| <p>One of the advantages of a Resource Mapping API is that it allows plug-ins |
| to implement any operations they desire in terms of resource mappings (e.g. |
| CVS update, CVS commit, CVS tag, dirty decoration, etc.). However, the API that |
| has been introduced so far deals only with the local state of the model. When |
| working with a model that may be shared between developers, you end up in a |
| situation where the remote state of the model (i.e. the state of the model that |
| another user has checked-in to the repository) may differ from the state in |
| the workspace. If you performed a CVS update, you would want the local state |
| of the model to match the remote state even if it meant that additional files |
| needed to be included or some files needed to be removed.</p> |
| <p>This is not an issue for some logical models. For instance, a java package |
| is a container visited to a depth of one, regardless of the remote state of |
| the model. Given this, a repository provider can easily determine that outgoing |
| deletions should be included when committing or that incoming additions should |
| be included when updating. However, the resources that constitute some logical |
| models may change over time. For instance, the resources that constitute a model |
| element may depend of the contents of a manifest file (or some other similar |
| mechanism). In order for the resource mapping to return the proper traversal, |
| it must access the remote contents of the manifest file (if it differs from |
| the local contents) in order to see if there are additional resources that need |
| to be included. These additional resources may not exist in the workspace but |
| the repository provider would know how to make sure they did when the selected |
| action was performed.</p> |
| <p>In order to support these more complex models, a <code>RemoteResourceMappingContext</code> |
| can be passed to the <code>ResourceMapping#getTraversals</code> method. When |
| a context is provided, the mapping can use it to ensure that all the necessary |
| resources are included in the traversal. If a context is not provided, the mapping |
| can assume that only the local state is of interest. </p> |
| <h4>When does a ResourceMapping need to worry about the RemoteResourceMappingContext?</h4> |
| <p>A <code>ResourceMapping</code> need only worry about a context supplied to |
| the <code>getTraversals</code> method in cases were the resources that make |
| up a model change over time and the relationship between the model and resources |
| cannot be described by a simple traversal that is guaranteed to encompass those |
| resources (and only those resources) that constitute the model. For example, |
| although the resources of a Java package may change over time, the package can |
| be described as a folder of depth of one so a resource mapping for java packages |
| would not ned to make use of the resource mapping context. </p> |
| <p>As a more complicated example, consider an HTML file that contains several |
| images. Let's make the assumption that any images references from an HTML file |
| are part of the model of that file. When updating the local contents of the |
| HTML file from a repository, the user would expect that any new images would |
| be included. The <code>getTraversals</code> method for a <code>ResourceMapping</code> |
| for the HTML file model would look something like this:</p> |
| <pre style="background-color: rgb(204, 204, 255);">public class HTMLResourceMapping extends ResourceMapping {<br> private HTMLFile htmlFile;<br> public ResourceTraversal[] getTraversals(ResourceMappingContext context, <br> IProgressMonitor monitor)<br> IResource[] resources = htmlFile.getResources();<br> if (context instanceof RemoteResourceMappingContext) {<br> // Look for any additional resources on the server<br> RemoteResourceMappingContext remoteContext = (RemoteResourceMappingContext)context;<br> IFile file = htmlFile.getFile();<br> if (remoteContext.hasRemoteChange(file, monitor)) {<br> IStorage storage = remoteContext.fetchRemoteContents(file, monitor);<br> IResource[] additionalResources = getReferences(storage.getContents());<br> resources = combine(resources, additionalResources);<br> }<br> if (remoteContext.isThreeWay() && remoteContext.hasLocalChange(file, monitor)) {<br> IStorage storage = remoteContext.fetchBaseContents(file, monitor);<br> IResource[] additionalResources = getReferences(storage.getContents());<br> resources = combine(resources, additionalResources);<br> }<br> }<br> return new ResourceTraversal[] { <br> new ResourceTraversal(resources, IResource.DEPTH_ZERO, IResource.NONE)};<br> }<br>}</pre> |
| <p>Notice that there are two sets of resources included in the model: those derived |
| from the local contents of the HTML file in the workspace and those obtained |
| from the contents of the remote file and base file. In either of these two sets, |
| there may be resources that do not exist in the workspace. For instance, the |
| local HTML file may contain a relative link to an image that does not exist |
| in the workspace. This resource should be included so that it will be fetched |
| if it exists remotely. As for the remote file, it may contain a new copy that |
| references additional images that should be fetched when the new remote contents |
| are downloaded.</p> |
| <h4>When does a repository need to provide a RemoteResourceMappingContext?</h4> |
| <p>Any tool that is providing the ability of sharing workspace resources through |
| a repository and is supporting ResourceMappings should provide an appropriate |
| context for determining the relevant remote state of the model resources. The |
| context provides three basic queries:</p> |
| <ul> |
| <li>What type of comparison is being performed: two-way or three-way |
| <ul> |
| <li>for two-way, does the local contents differ from the remote contents</li> |
| <li>for three-way, are there local changes and are there remote changes</li> |
| </ul> |
| </li> |
| <li>What are the contents of the remote (and base for three-way) counterparts |
| of the file</li> |
| <li>What are the remote members of a folder</li> |
| </ul> |
| <p>The answer to the first question above depends on the type of operation that |
| is being performed. Typically, updates and merges are three-way while comparisons |
| and replace operations are two-way.</p> |
| <p>The Eclipse Team API includes a <code>Subscriber</code> class that defines |
| an API for providing the synchronization state between the local workspace and |
| a remote server. A <code><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/mapping/ResourceTraversal.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">SubscriberResourceMappingContext</a></code> |
| has been created that uses a <code>Subscriber</code> to access the necessary |
| remote state. Clients that have a <code>Subscriber</code> do not need to do |
| any additional work to get a resource mapping context.</p> |
| <h2><a name="ModelProvider"></a>Model Providers</h2> |
| <p>Model providers are a means to group related resource mappings together. Here |
| is a link to the <code><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ModelProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">ModelProvider</a></code><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.core.resources/src/org/eclipse/core/resources/mapping/ModelProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup"> |
| class</a>. This class serves two main purposes:</p> |
| <ol> |
| <li>From a model provider, clients can then obtain additional API pieces for |
| performing operations on a set of resource mappings.</li> |
| <li>Given a set of file-system resources, clients can query whether a model |
| provider has model elements persisted in those resources and, if it does, |
| obtain the set of resource mappings that describe the relationship.</li> |
| </ol> |
| <p>The following is an example of a modelProvider extension definition.</p> |
| <pre style="background-color: rgb(204, 204, 255);"> <extension<br> id="modelProvider"<br> name="Library Example"<br> point="org.eclipse.core.resources.modelProviders"><br> <modelProvider<br> class="org.eclipse.team.examples.library.adapt.LibraryModelProvider"<br> name="Library Example"/><br> <extends-model id="org.eclipse.core.resources.modelProvider"/><br> <enablement> |
| <test property="org.eclipse.core.resources.projectNature" |
| value="org.eclipse.team.examples.library.view.nature" /><br> </enablement><br> </extension><br></pre> |
| <p>The <code>LibraryModelProvider</code> is a subclass of <code>ModelProvider</code>. |
| The enablement rule is used to match resources that the Library model persists |
| its model in. In the above example, the model provider will match any resource |
| in a project that has the library nature. </p> |
| <p>Once the model provider is defined, the <code>ResourceMapping#getModelProviderId()</code> |
| method should be overridden to return the id of the model provider.</p> |
| <pre style="background-color: rgb(204, 204, 255);"> public String getModelProviderId() {<br> return "org.eclipse.team.examples.library.adapt.modelProvider";<br> }<br></pre> |
| <p>To get the proper inverse mapping of resources to resource mapping for those |
| resources that match your provider's enablement rule, you should also override |
| one or both of the <code>getMapping</code> methods. The method that you need |
| to override depends on whether your model has elements that contain multiple |
| resources or not. If your model elements map to a single resource, you can override |
| the method that accepts a single<code>IResource</code> argument. Otherwise, |
| you will need to override the method that accepts an array of resources. Here's |
| an example using the single resource case.</p> |
| <p>The following example method wraps a library model file in an appropriate resource |
| mapping. It also wraps folders that contain files that are of interest to the |
| model provider.<br> |
| </p> |
| <pre style="background-color: rgb(204, 204, 255);">public class LibraryModelProvider extends ModelProvider {<br> public ResourceMapping[] getMappings(IResource resource, <br> ResourceMappingContext context, IProgressMonitor monitor) {<br> if (isModelFile(resource)) {<br> // Return a resource mapping on the file<br> return new LibraryResourceMapping(resource);<br> } if (containsModelFiles(resource)) {<br> // Create a deep resource mapping on the container<br> return new LibraryContainerResourceMapping(resource);<br> }<br> // The resource is not of interest to this model provider<br> return null;<br> }<br>}</pre> |
| <p>Clients can then access the model provider to determine whether the model providers |
| cares about the resources that are about to be operated on. The next section |
| describes API that will be provided to team operations that use the model provider |
| API to determine the complete set of resource mappings to be operated on when |
| a team operation is performed on a set of selected resources or model elements.</p> |
| <h2><a name="TeamInput"></a>Team Operation Scope</h2> |
| <p>For team operations, the selected mappings need to be translated into the set |
| of mappings to be operated on. This process involves consulting all model providers |
| to ensure that they get included in operations on resources that match their |
| enablement rules. The term we use to describe the complete set of resource mappings |
| to be operated on is the operation <em>scope</em>. The following API has been |
| provided for this:</p> |
| <ul> |
| <li><code><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/IResourceMappingScope.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IResourceMappingScope</a></code>: |
| Interface that defines the API for accessing the scope of the operation. It |
| provides access to all the resource mappings being operated on and the traversals |
| for those mappings as they were calculated during the scope building process.</li> |
| <li><code><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/ScopeGenerator.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">ScopeGenerator</a></code>: |
| Class that is used to build a scope given a set of input mappings and a resource |
| mapping context.</li> |
| </ul> |
| <p>The code for creating an initializing an input would look something like this:</p> |
| <pre style="background-color: rgb(204, 204, 255);">ResourceMapping[] selectedMappings = getSelectedMappings();<br>ResourceMappingContext context = getResourceMappingContext();<br>ScopeGenerator builder = new ScopeGenerator();<br>IResourceMappingScope scope = builder.prepareScope(selectedMappings, context, monitor);<br>if (scope.hasAdditionalMappings()) {<br> // inform user of additional mappings<br>}<br>// Now get the set of mappings to be operated on<br>ResourceMapping[] operationMappings = scope.getMappings();<br>// Get the traversals that were cached during the input determination process<br>ResourceTraversal[] allTraversals = scope.getTraversals();</pre> |
| <p>Team operations will provide the set of selected resource mappings and a resource |
| mapping context. They will then call <code>buildScope</code> which calculates |
| all the resource mappings that need to be included in the operation. The scope |
| also caches the results so they do not need to be recalculated during the operation. |
| You can get all the traversals or only those for a particular mapping.</p> |
| <h2><a name="AutoMerge"></a>Model-based Merging</h2> |
| <p>This section offers a brief explanation of what model based merging involves |
| and provides pointers to example implementations in the SDK.</p> |
| <ul> |
| <li>The team provider needs to calculate the synchronization state of all the |
| resources involved in the merge. This is done by subclassing <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.ui/src/org/eclipse/team/ui/operations/ResourceMappingMergeOperation.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">ResourceMappingMergeOperation</a> |
| and overriding the <code>buildContext</code> method to return an <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/IMergeContext.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IMergeContext</a>. |
| The merge context provides the model access to the synchronization state of |
| the files involved (see the <code>getSyncInfoTree()</code> method) along with |
| access to the contents of the files (see <code>SyncInfo#getRemote()</code> |
| and <code>SyncInfo#getBase()</code>). The CVS UI plugin contains an a merge |
| operation subclass named <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/CVSMappingMergeOperation.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">CVSMappingMergeOperation</a>.</li> |
| <li>The model needs to adapt it's model provider to an instance of <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/IResourceMappingMerger.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IResourceMappingMerger</a>. |
| The merge operation delegates the merge to the registered merger. The platform |
| has a default implementation, <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/mapping/DefaultResourceMappingMerger.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">DefaultResourceMappingMerger</a>, |
| that performs a text-based merge on the files using the IStreamMerger registered |
| for that file type.</li> |
| </ul> |
| <h3>Synchronization and Merge Context</h3> |
| <p>An important aspect of model-based merging is the API used to communicate the |
| synchronization state of the resources involved to the model provider. There |
| are two interfaces of interest:</p> |
| <ul> |
| <li><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/ISynchronizationContext.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">ISynchronzationContext</a>: |
| provides access to the synchronization stat of all resources within the scope |
| of the operation. The following API pieces are used to describe the synchronization |
| state of resources. |
| <ul> |
| <li><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffTree.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IDiffTree</a>/<a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IResourceDiffTree.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IResourceDiffTree</a>: |
| data structure that contains the synchronization state for all resources |
| in the operation scope that are out-of-sync.</li> |
| <li><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IDiffNode.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IDiffNode</a>/<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/ITwoWayDiff.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">ITwoWayDiff</a>//<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IResourceDiff.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IResourceDiff</a>/<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/diff/IThreeWayDiff.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IThreeWayDiff</a>: |
| describes the synchronization of a single resource</li> |
| <li><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariant.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IResourceVariant</a>: |
| provides access to the base or remote file stat and contents that were |
| used to determine the synchronization state for a local resource. </li> |
| </ul> |
| </li> |
| <li><a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/mapping/IMergeContext.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IMergeContext</a>: |
| a synchronization context with additional methods that support merging.</li> |
| </ul> |
| <h3>Model Content in Team Operation Views</h3> |
| <p>API has been added in M4 that allows models to provide a team-aware content |
| provider that can be used by Team providers to display the effetcs of team operation |
| in termes of model elements and hierarchies. The CVS Team>Update context |
| menu action in Eclipse 3.2 Milestone 4 (M4) can be configured to display logical |
| model elements and hierarchies when previewing the effects of an update. You |
| must turn on the "Perform client side merges on update" preference |
| on the <strong>Team>CVS>Work In Progress</strong> preference page.</p> |
| <p><img src="updatePrefs.png" width="419" height="150"></p> |
| <p>In M4, Java implements a team-aware content provider which allows the effects |
| of an update to be shown with respect to the Java model.</p> |
| <p><img src="update.png" width="410" height="281"></p> |
| <p>There are three steps required to create a team-aware content provider</p> |
| <ol> |
| <li>Create a extension to the <em>org.eclipse.ui.navigator.navigatorContent</em> |
| extension point. Minimally, you will need to provide a content provider and |
| label provider and an enablement rule that matches the appropriate model elements. |
| The enablement sule should also match both <code>IResourceMappingScope</code> |
| and <code>ISynchronizationContext</code> as either of these could be used |
| as the input object to a Team viewer.</li> |
| <li>Associate your <em>navigatorContent</em> extension with the Team viewer |
| using the <em>org.eclipse.ui.navigator.viewer</em> extension point. The Team |
| viewer id is <em>org.eclipse.team.ui.navigatorViewer</em>.</li> |
| <li>Bind your content extension to your model provider using the <em>org.eclipse.team.ui.teamContentProviders</em> |
| extenson point.</li> |
| </ol> |
| <p>The following xml shows how the Java content provider is made team-aware.</p> |
| <pre style="background-color: rgb(204, 204, 255);"> <extension point="org.eclipse.ui.navigator.navigatorContent"><br> <navigatorContent<br> contentProvider="org.eclipse.jdt.internal.ui.model.JavaSynchronizationContentProvider"<br> id="org.eclipse.jdt.ui.resourceContent"<br> labelProvider="org.eclipse.jdt.internal.ui.model.JavaSynchronizationLabelProvider"<br> name="%JavaModelContent.name"><br> <enablement><br> <or><br> <instanceof value="org.eclipse.jdt.internal.ui.model.JavaModelProvider"/><br> <instanceof value="org.eclipse.jdt.core.IJavaElement"/><br> <instanceof value="org.eclipse.team.core.mapping.IResourceMappingScope"/><br> <instanceof value="org.eclipse.team.core.mapping.ISynchronizationContext"/><br> </or><br> </enablement><br> </navigatorContent><br> </extension> |
| |
| <extension point="org.eclipse.ui.navigator.viewer"><br> <viewerContentBinding viewerId="org.eclipse.team.ui.navigatorViewer"><br> <includes><br> <contentExtension isRoot="true"<br> pattern="org.eclipse.jdt.ui.resourceContent"/><br> </includes><br> </viewerContentBinding> |
| </extension> |
| |
| <extension> |
| id="jdtContentProvider"<br> point="org.eclipse.team.ui.teamContentProviders"><br> <teamContentProvider<br> contentExtensionId="org.eclipse.jdt.ui.resourceContent"<br> modelProviderId="org.eclipse.jdt.ui.modelProvider"/><br> </extension> |
| </pre> |
| <p>The <code><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/model/JavaSynchronizationContentProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">JavaSynchronizationContentProvider</a></code> |
| and <code><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/model/JavaSynchronizationLabelProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">JavaSynchronizationLabelProvider</a></code> |
| classes in the above example are subclasses of <code><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationContentProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">SynchronizationContentProvider</a></code> |
| and <code><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.ui/src/org/eclipse/team/ui/mapping/SynchronizationLabelProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">SynchronizationLabelProvider</a></code> |
| and make use of the synchronization context to provide filtering and label decoration.</p> |
| <h2><a name="FileHistory"></a>File History</h2> |
| <p>The proposed file history API consists of the following interfaces:</p> |
| <ul> |
| <li><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/filehistory/IFileHistoryProvider.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IFileHistoryProvider</a>: |
| Obtained from a RepositoryProvider, the file history provider allows clients |
| to obtain the file history of a particular file.</li> |
| <li><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/filehistory/IFileHistory.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IFileHistory</a>: |
| A data structure that allows access to the history of a file</li> |
| <li><a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.team.core/src/org/eclipse/team/core/filehistory/IFileRevision.java?rev=HEAD&content-type=text/vnd.viewcvs-markup">IFileRevision</a>: |
| The description of a single revision or state of a file at a particular poin |
| tin time in its history.</li> |
| </ul> |
| <p>Along with this API, a generic file history view is being proposed. A preview |
| version is available in M4.</p> |
| <p><img src="history.png" width="456" height="216"></p> |
| <h2><a name="Example"></a>EMF Library Example</h2> |
| <p>This example, available <a |
| href="libraryExample.html">here</a>, is built on a model that consists of libraries, |
| books and writers.</p> |
| <h2>What's Next</h2> |
| <p>See the <a href="plan.html">Eclipse Team/CVS 3.2 plan</a> for what is happening |
| in M5 and beyond.</p> |
| <h2>Conclusion</h2> |
| <p>This document contains a description of the API available so far in 3.2. This |
| is only a portion of the feature set described in the <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/docs/online/team3.2/model-integration-proposals.html">Proposed |
| Support for Logical Model Integration</a> document. Additional API for Team |
| support of logical model integration will be added to the document as it becomes |
| available. Also, the API described in this document may still undergo change |
| in the 3.2 release cycle. The document will be updated with any changes as well.</p> |
| <h2>Change History</h2> |
| <p>Changes in version 3.2 M4</p> |
| <ul> |
| <li>Updated to contain a brief description of the new API added in M4. This |
| includes |
| <ul> |
| <li>IDiffTree/IDiffNode API for describing changes</li> |
| <li>Use of Common Navigator framework to support the display of model elements |
| in views and dialogs associated with a Team operation</li> |
| <li>File history API</li> |
| </ul> |
| </li> |
| </ul> |
| <p>Changes in version 3.2 M3</p> |
| <ul> |
| <li>Updated 3.1 <a |
| href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/docs/online/team3.1/logical-physical-mappings.html">Resource |
| Mapping</a> document to reflect new support available in 3.2 M3.<br> |
| </li> |
| </ul> |
| </body> |
| </html> |