| <!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("my.plugin.namespace", "widget");<br> |
| IExtension[] extensions = point.getExtensions();<br> |
| // initial population<br> |
| for (int i = 0; i < 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 < 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> |