20.5. Types Specified in an Extension Point
All plug-ins declaring an extension point use the IConfiguration-Element.createExecutable() method to instantiate types specified by other plug-ins (see Section 17.3.3, Creating executable extensions, on page 611). For example, given the following declaration, the org.eclipse.ui plug-in will instantiate the myPackage.MyActionDelegate class when necessary using the createExecutable() method.
<extension point="org.eclipse.ui.actionSets"> <action label="Open Favorites View" icon="icons/sample.gif" tooltip="Open the favorites view" menubarPath="myMenu/content" toolbarPath="Normal/additions" id="myProduct.openFavoritesView"> class="myPackage.MyActionDelegate" </action> </extension>
In the declaration above, only the fully qualified class name is specified, but there are a few hidden surprises that are explored in the following sections.
Types specified in a plug-in manifest are instantiated using their default no argument constructor, so how can they be parameterized? For example, let's suppose that you have two very similar functions in your menu. How should those functions be implemented? One approach is to have two different action delegates, one for each function, with a shared superclass containing all the common behavior. Another approach is to have a single action delegate, but somehow initialize each instance differently to perform a slightly different operation, but how? It is this second option being explored here.
Parameterizing a typepassing additional information to that type during its initialization phaseis accomplished by implementing the org.eclipse.core.runtime.IExecutableExtension interface. If additional information is provided in the plug-in manifest, then Eclipse passes the additional information to the type using the setInitializationData method. The information arrives via the setInitializationData method in different formats depending on how it is structured in the plug-in manifest.
One way to parameterize a type is to place a colon at the end of the type's class name followed by a string of information. This string is unstructured and has as much or as little information as desired. Eclipse parses the class attribute, using the information before the colon to determine the class to be instantiated, while the information after the colon is passed as a string to the type via the setInitializationData method.
For example, in the following declaration (see Figure 20-1), the action delegate myPackage.MyActionDelegate would be instantiated using its no argument constructor and then the setInitializationData method would be called with the string "one two three" as its third argument.
Figure 20-1. IExecutableExtension with unstructured parameters.
A second more structured approach is to define parameters formally. Rather than all parameters being declared in a single string, each parameter is declared separately as key/value pairs. Each key/value pair is placed into a java.util.Hashtable that is passed to the setInitializationData method.
For example, in the following IExecutableExtension declaration (see Figure 20-2), the action delegate myPackage.MyActionDelegate would be instantiated using its no argument constructor and then the setInitializationData method would be called with a Hashtable as its third argument. The Hashtable would contain the key/value pairs "p1"/"one", "p2"/"two", and "p3"/"three". All other aspects of this second approach are the same as those of the first.
Figure 20-2. IExecutableExtension with structured parameters.
Most of the time, the class being referenced in a plug-in's manifest resides in the same plug-in. But, what if one plug-in manifest references a class that is contained in a jar file of another plug-in? By default, if the fully qualified class name is specified, then Eclipse makes the assumption that the class resides in the plug-in making the declaration, so it will not find a class that resides in a different plug-in. In this case, precede the class name with the other plug-in's identifier followed by a slash.
For example, if plugin.A provides an action delegate class that can be parameterized (see Section 20.5.1, Parameterized types, on page 724) and plugin.B provides an action that launches a parameterized copy of that class, then the action declaration in plugin.B might look something like this:
<action id="com.qualityeclipse.favorites.showPartInfo" label="Show My View Info" menubarPath="myMenu/content" class="plugin.A/ plugin.A.actions.ShowPartInfoActionDelegate"> <parmeter name="partClass" value="plugin.B.view.myView"/> </action>