| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <meta http-equiv="content-type" |
| content="application/xhtml+xml; charset=utf-8"> |
| <meta name="generator" content="Windows Notepad"> |
| <link rel="stylesheet" href="http://dev.eclipse.org/default_style.css" |
| type="text/css"> |
| <link rel="stylesheet" type="text/css" |
| href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/layout.css" |
| title="Grey boxes stylesheet"> |
| <link rel="stylesheet" type="text/css" |
| href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/colors.css"> |
| <title>Eclipse Platform - Adaptable Contributions</title> |
| </head> |
| <body> |
| <h1>Support for adaptable contributions in Eclipse 3.1</h1> |
| Last Updated: February 10th, 2005<br> |
| by Jean-Michel Lemieux<br> |
| <br> |
| <span style="font-weight: bold;">Context</span><br> |
| <br> |
| All adaptable workbench contributions only support adapting to |
| IResource.<br> |
| <br> |
| <span style="font-weight: bold;">Problem</span> <br> |
| <br> |
| An adaptable flag was added to three workbench extension points to |
| allow contributions (e.g. popupMenus, property pages, decorators) to be |
| applied to |
| classes that do not share a common ancestor. For example, to enable CVS |
| contributions to appear in the Java Packages View. The CVS plug-in |
| defines adaptable contributions on IResource types and JDT would |
| provide adapters from Java elements to IResources. The problem is that <span |
| style="font-weight: bold;">adaptable contributions are |
| currently limited to IResource classes</span>.<br> |
| <br> |
| <span style="font-weight: bold;">Adapting models: the key to rich |
| integration</span><br> |
| <br> |
| In Eclipse plug-ins are free to model their application data using their model |
| of choice. A key to providing integration in Eclipse is to allow bridging of the |
| models. A model is a fairly generic term, but is known to most people as the actual |
| data representation for an application. But there are actually three types of |
| models:<font size="-1"><br> |
| <br> |
| </font> |
| <table cellpadding="2" cellspacing="2" border="1" |
| style="text-align: left; width: 100%;"> |
| <tbody> |
| <tr> |
| <td style="vertical-align: top; width: 15%;"><strong>Types</strong></td> |
| <td style="vertical-align: top;"><strong>Descirption</strong></td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top; width: 15%;">Meta-model</td> |
| <td style="vertical-align: top;">A model that includes types whose instances |
| are also types. Meta-models are often used to specify other models. For |
| example, EMF provides a meta-model (ECore) for describing models. </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top; width: 15%;">Model</td> |
| <td style="vertical-align: top;">A model of a specific application domain. |
| These instances are called meta-objects. A model is the actual data representation |
| for an application. For example, in JDT the model is composed of ICompilationUnit, |
| IJavaProject... The model can be instances of a meta-model or a standalone |
| model (e.g. simply a set of classes and interfaces).</td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top; width: 15%;">User Objects<br> |
| </td> |
| <td style="vertical-align: top;">Instances of the elements of a model.</td> |
| </tr> |
| </tbody> |
| </table> |
| <font size="2" face="Arial, Helvetica"><br> |
| </font>Figure 1 describes the common relationships between plug-ins and |
| models in Eclipse. In this example, Model A is defined as a base model; |
| an adapter is defined for elements from model B and C that will return |
| and element from model A. |
| Adaptable contributions is the mechanism that allows models to accept |
| contributions made to |
| base models without requiring the model implementation to inherit or |
| implement classes from the base model.<br> |
| <br> |
| <div style="text-align: center;"><img src="adapters.png" alt="" |
| style="width: 501px; height: 342px;"><br> |
| </div> |
| Figure 1: Plug-ins and models<br> |
| <br> |
| Currently the only base model supported in Eclipse is IResource. The |
| goal for opening this up is to allow other base models to exist and |
| thus allow bridging between other domain models.<br> |
| <br> |
| <span style="font-weight: bold;">Note</span>: When adapting to a base |
| model it is not fair to accept that all adapters represent a 1-1 |
| mapping between model elements. Consider providing a mapping interface |
| which allows a flexible representation of the mapping between two |
| models.<br> |
| <br> |
| <span style="font-weight: bold;">Adapters <span |
| style="font-weight: bold;"><br> |
| </span></span><br> |
| A historic problem with Adapters in Eclipse was that they were defined |
| at runtime. This meant that using them for contributions was not |
| possible since plug-in that were'nt loaded would not get a chance to |
| contribute adapters. The result was that contributions may not be |
| visible until a plug-in was loaded. This was solved in 3.0 with the |
| support for declarative specification of adapter factories.<br> |
| <br> |
| Contributions are adapted using the adapter factory to query the |
| supported adapters for a given type. This means that for adaptable |
| contributions to be supported plug-ins must move any runtime adapter |
| specification to use the new declarative extension point. There are two |
| distinct participants involved in supporting adaptable contributions:<br> |
| <ol> |
| <li>A plug-in that defines a model must define the adapters it |
| supports. <br> |
| </li> |
| <li>A plug-in that defines common contributions must define the base |
| model elements they apply to and ensure that the contributions are |
| marked adaptable.</li> |
| </ol> |
| <span style="font-weight: bold;">Defining the adapters</span><br> |
| <br> |
| A plug-in can define the adapters it supports by registering an |
| IAdapterFactory with the <span style="font-style: italic;">org.eclipse.runtime.adapters</span> |
| extension point as follows:<br> |
| <pre style="background-color: rgb(204, 204, 255);"><extension<br> point="org.eclipse.core.runtime.adapters"><br> <factory<br> class="logicalView.views.AdapterFactory"<br> adaptableType="logicalView.views.MyLogicalElement"><br> <adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/><br> </factory><br></extension><br></pre> |
| This plugin.xml snippet defines an adapter that can adapt instances of MyLogicalElement |
| to ResourceMapping. An adapter factory can adapt the same adaptableType to different |
| types. Simply add another <span |
| style="font-style: italic;">adapter </span>element to the extension point. The |
| adapter factory implementation would be:<br> |
| <pre style="background-color: rgb(204, 204, 255);">public class AdapterFactory implements IAdapterFactory {<br> public Object getAdapter(Object adaptable, Class adapterType) {<br> if(adaptableinstanceof MyLogicalElement && <br> adapterType == ResourceMapping.class) {<br> return new MyLogicalElementResourceMapping(<br> (MyLogicalElement)adaptable);<br> } <br> return null;<br> }<br><br> public Class[] getAdapterList() {<br> return new Class[] {IResourceMapper.class};<br> }<br>}<br></pre> |
| <span style="font-weight: bold;"><span style="font-weight: bold;"></span></span>A |
| rule of thumb when deciding what adapters to register, try and adapt to |
| the most specific type possible. For example, although it is |
| technically possible to return the IProject for a java IMethod (e.g. |
| the project that contains the method) the relationship is too vague and |
| would be best to return the IFile instead.<span |
| style="font-weight: bold;"><span style="font-weight: bold;"></span><br> |
| <br> |
| Definining the contributions</span><br> |
| <br> |
| The syntax for defining contributions hasn't changed simply, that the adaptable |
| attribute will be honoured even when the object class is not IResource. Here is |
| a snippet for defining a popup menu that should appear on ResourceMapping instances:<br> |
| <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="myaction.id"><br> <action<br> label="Do It"<br> class="myplug.actions.DoItAction"<br> menubarPath="additions"<br> id="myaction.id.doit"><br> </action><br></objectContribution></extension></pre> |
| The implementation of the action can assume the following:<br> |
| <ul> |
| <li>The selection is always converted to the type specified in |
| objectClass. This implies that <br> |
| </li> |
| <li>Filters (e.g IActionFilter, enablement rules) applied to a |
| contribution are given the type specified in objectClass.</li> |
| </ul> |
| <p><span style="font-weight: bold;">IContributorResourceAdapter</span><br> |
| <br> |
| An interface was added in Eclipse 2.0 to allow plug-ins to adapt IResource elements |
| differently when they were used for workbench contributions (see Bug <a |
| href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=6247">6247</a> for a background |
| discussion). This interface is still honnoured when adapting to IResource by |
| first checking if an objects adapts to IContributorResourceAdapter then to IResource. |
| In 3.1, a subinterface IContributorResourceAdapter2 has been added to support |
| context dependant adaptation to ResourceMappings.</p> |
| <p><span style="font-weight: bold;">Note: </span>This class is defined in the |
| IDE plug-in meaning that applications not including the IDE can't use this support.<br> |
| <br> |
| <span style="font-weight: bold;">Problems with IActionFilter</span><br> |
| <br> |
| Action filters are designed to allow contributions to filter their visibility |
| based on a filter queried at runtime. The workbench tries to find an IActionFilter |
| for an object in the selection by asking the adapted selection if it can adapt |
| to IActionFilter. This is restrictive since it allows only one implementation |
| of an IActionFilter per type. Another more flexible approach is to use the new |
| enablement attribute that was added in 3.0. The following enablement will show |
| the contribution only if it is shared with a CVS project. The enablement tester |
| is provived in the contribution instead of via the selection, which makes this |
| approach more flexible.<br> |
| </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="myaction.id"><br> <enablement><br> <test property="org.eclipse.ui.ide.projectPersistentProperty" |
| args="org.eclipse.team.core.repository=org.eclipse.team.cvs.core.cvsnature" /><br> </enablement><br> ...<br></objectContribution></extension></pre> |
| The property tester would is contributed as follows:<br> |
| <pre style="background-color: rgb(204, 204, 255);"><extension<br> point="org.eclipse.core.expressions.propertyTesters"><br> <propertyTester |
| namespace="org.eclipse.ui.ide" |
| type="org.eclipse.core.resources.mapping.ResourceMapping" |
| class="org.eclipse.ui.internal.ide.model.ProjectPersistentPropertyTester" |
| properties="projectPersistentProperty" |
| id="org.eclipse.ui.ide.projectPersistentPropertyTester" /><br></extension></pre> |
| <span style="font-weight: bold;">Related Bugs</span><br> |
| <br> |
| https://bugs.eclipse.org/bugs/show_bug.cgi?id=32436<br> |
| https://bugs.eclipse.org/bugs/show_bug.cgi?id=53217<br> |
| https://bugs.eclipse.org/bugs/show_bug.cgi?id=76599<br> |
| https://bugs.eclipse.org/bugs/show_bug.cgi?id=38041<br> |
| https://bugs.eclipse.org/bugs/show_bug.cgi?id=36968<br> |
| https://bugs.eclipse.org/bugs/show_bug.cgi?id=37084<br> |
| <br> |
| <span style="font-weight: bold;">Related problems not addressed</span><br> |
| <ul> |
| <li>Visibility of contributions is based on a homogenous selection |
| algorithm. This ensure that all objects in the selection have a common |
| class and/or adapter. Heterogenous selection is not yet supported.</li> |
| <li>The IAdapterManager is non-transitive. This implies that all |
| contributions must define direct adapters for each type.</li> |
| <li>IContributorResourceAdapter is in IDE, thus IDE must be |
| references |
| for IResource adaptables to work.<br> |
| </li> |
| </ul> |
| <br> |
| <br> |
| </body> |
| </html> |