Adapters
Some very astute readers may noticed a problem with the previous sections on views
and popup/context menus. In the view section that described the Accounts view
they may have noticed that the Accounts view is displaying a list of Account objects, that
is, objects that implement the org.jledger.model.IAccount interface.
Further more, these objects were obtained from a remote object store and
immediately added to the view widget's model.
The view also set the widget's selection provider to the site's selection provider.
The point is that the objects added to the Accounts view do not already implement the IOpenable interaface. These objects came from a remote object store that should have no reason to know anything about IOpenable and would have no reason to return objects to a client that implemented IOpenable. Yet, when one of these objects is selected the workbench obviously thinks that an IOpenable object is selected. How did that happen? The answer is that an adapter was defined by the org.jledger.ui plugin that added an implementation of the IOpenable interface to all IAccount accounts. JLense includes a facility for dynamically extending objects to provide different interfaces (or "adapters"). Adapters are created by adapter factories, which are in turn managed by type by adapter managers. See the IAdapterManager class for more details. To add the IOpenable interface to all IAccount objects the org.jledger.ui plugin registered an adapter factory with the Platform Adapter Manager when the plugin was started. Here is the code from the JLedger UI plugin that does that: public class JLedgerWorkbenchPlugin extends AbstractUIPlugin { public void startup() throws CoreException { registerAdapters(); } /** * Registers adapter factories for various object types. * Adapters are typically used to enable various workbench actions, like the * Open action for instance. */ public void registerAdapters() { IAdapterManager manager = Platform.getAdapterManager(); IAdapterFactory factory = new JLedgerWorkbenchAdapterFactory(); manager.registerAdapters(factory, IAccount.class); } } Here is the code for the JLedgerWorkbenchAdapterFactory. The JLedgerWorkbenchAdapterFactory is responsible for creating adpapter instances for IAccount objects: public class JLedgerWorkbenchAdapterFactory implements IAdapterFactory { public Object getAdapter(Object o, Class adapterType) { if (adapterType.isInstance(o)) { return o; } if (adapterType == IOpenable.class) { return getOpenable(o); } return null; } public Class[] getAdapterList() { return new Class[] { IOpenable.class }; } IOpenable getOpenable(final Object adaptable) { IOpenable adapter= null; if (adaptable instanceof IAccount) { adapter= new DefaultOpenableAdapter( "org.jledger.ui.accounts.OpenWizard", false /*not modal, open in window*/, (IAdaptable)adaptable); } return adapter; } } |