blob: 9303fa9787fbd0e73efb450a9a42685de5a9a70b [file]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML>
<HEAD>
<meta name="copyright" content="Copyright (c) IBM Corporation and others 2000, 2005. This page is made available under license. For full details see the LEGAL in the documentation book that contains this page." >
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
<LINK REL="STYLESHEET" HREF="../book.css" CHARSET="ISO-8859-1" TYPE="text/css">
<TITLE>
Dynamic Plug-ins
</TITLE>
<link rel="stylesheet" type="text/css" HREF="../book.css">
</HEAD>
<BODY BGCOLOR="#ffffff">
<H2> Dynamic Plug-ins</H2>
<p>Dynamic Plug-ins provide the ability to insert and remove
plug-ins into a running instance of Eclipse. A reusable component with the potential
to be unloaded, Dynamic Plug-ins provide an easy way to help you track the comings
and goings of plug-ins. </p>
<p> A dynamic plug-in may not remain for the life of the
application, as such, it is essential to ensure that when the component goes
away everything is cleaned up. When listeners are
hooked on the Workbench and items are registered, they remain there after shut
down, these plug-ins must be aware that they need to clean up.</p>
<p>The assumption that on start up, a read through of all
the implementations of the extension point will be sufficient for the life of
the application is false as that will not work. You must ensure that either
the listener is hooked or that nothing is ever cached, so that registry changes
are listened for. It is important to understand that items in the workbench
are not necessarily static, they are in fact transient and could go away at
any time. If you're writing a plug-in for a specific view first ensure that
the view is still there.</p>
<p>As a plug-in developer you need to ensure that any extensions
you may utilize are allowed to appear and disappear at any given point. When
they disappear you should acknowledge their disappearance by cleaning up any
internal structures that may represent the extensions and remove any UI artifacts
that they may drive. When they appear you should augment your internal structures
and possibly create new UI artifacts. Assume that
your application is reading from the registry and has an extension, you create
a record for it and assign its location. Upon its conclusion, you would be notified
that a clean up is required. In addition, a listener will announce when new
items come in and create them. </p>
<p>The org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker and associated
interfaces provide a mechanism by which plug-in developers can easily track
the coming and going of extensions and manage the resources generated by such
actions.</p>
<p>The following example assumes that you have an extension point in your plug-in
called widgets and that you are using IExtensionTracker. Internally, you have
WidgetDescriptors that encapsulate widget extensions and a WidgetRegistry to
manage them. </p>
<pre>
public class WidgetRegistry implements IExtensionChangeHandler {
public WidgetRegistry() {
IExtensionTracker tracker = PlatformUI.getWorkbench()
.getExtensionTracker();<br>
IExtensionPoint point = Platform.getExtensionRegistry()
.getExtensionPoint(&quot;my.plugin.namespace&quot;, &quot;widget&quot;);<br>
IExtension[] extensions = point.getExtensions();<br>
// initial population<br>
for (int i = 0; i &lt; extensions.length; i++) {
addExtension(tracker, extensions[i]);<br>
}
tracker<br>
.registerHandler(this, tracker<br>
.createExtensionPointFilter(point));
}
public void addExtension(IExtensionTracker tracker, IExtension extension){
WidgetDescriptor descriptor = new WidgetDescriptor(extension);
tracker.registerObject(extension, descriptor,<br>
IExtensionTracker.REF_STRONG);
addToInternalStructure(descriptor)
}
private void addToInternalStructure(WidgetDescriptor descriptor) {
// registry specific logic
}
public void removeExtension(IExtension extension, Object[] objects) {
for (int i = 0; i &lt; objects.length; i++) {
WidgetDescriptor descriptor = (WidgetDescriptor) objects[i];<br>
removeFromInternalStructure(descriptor);<br>
}<br>
}
private void removeFromInternalStructure(WidgetDescriptor
descriptor) {
// registry specific logic
}<br>
}
public void dispose() {
PlatformUI.getWorkbench()
.getExtensionTracker().unregisterHandler(this)<br>
}
}<br>
</pre>
<p>In this example Platform UI provides IExtensionTracker instances at various
levels of the Workbench. If you're tracking objects that live for the life of
the workbench you should use the tracker provided by IWorkbench.getExtensionTracker().
If your objects are relevant to particular workbench windows or pages, you should
use the trackers provided by IWorkbenchWindow.getExtensionTracker() or IWorkbenchPage.getExtensionTracker().
For instance, Workbench tracks view descriptors at the Workbench level but tracks
actual view instances at the workbench page level. Your handlers may be registered
against particular extension points via providing an IFilter instance to IExtensionTracker.registerHandler().
Your handler will only be called when extensions matching the IFilter object
are added or removed. </p>
<p>When an extension enters the runtime this method will be called. Your handler
then has the opportunity to incorporate the new extension into its associated
model. Any objects created based on the IExtension provided to this interface
should be registered against the tracker via IExtensionTracker.registerObject().
When an extension leaves the runtime this method will be called. Any objects
previously registered against the extension will be passed as arguments. Your
handler may then clean up and dispose of the objects as necessary. It's good
practice to unregister your handlers so that your registries are not leaked.</p>
</BODY>
</HTML>