Introduction
The goal of this tutorial is to extend Nomad PIM by using extension points. We define additional data, create an editor field and add some functionality to views.
If there are problems with the tutorial, feel free to ask in the Developer Mailing List .
Preconditions
This tutorial requires a project that is set up according to the tutorial Creating the basic entity UI .
Tutorial project access
The project that is the result of the tutorial is available in the subversion repository:
extendAnEntityType tutorial project | The project created in this tutorial |
tutorial/extendAnEntityType/trunk |
You can use it to quickly access the tutorial results. Please refresh the project after generating the model code.
Extending the entity type Task of the schedule module
In this tutorial, you create an entity type Task which extends the Task of the schedule module with a new field. See the Entity types section of the Creating an entity type tutorial.
The first step is to add the module of the extended entity to the file "META-INF/MANIFEST.MF".
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: TutorialProject Plug-in Bundle-SymbolicName: TutorialProject; singleton=true Bundle-Version: 1.0.0 Bundle-Localization: plugin Require-Bundle: org.nomadpim.core, org.nomadpim.core.ui,org.nomadpim.module.schedule,org.eclipse.swt, org.eclipse.core.commands, org.eclipse.ui.forms, org.eclipse.core.runtime, org.eclipse.ui.workbench, org.eclipse.ui
After that, change the file "source/model/Entities.xml" as follows:
...<entity name="Task" package="org.nomadpim.tutorial"> <attribute name="Url" type="String" /> </entity></entities>
The entity name Task refers to the existing type of the schedule module. The generated Task source contains the new URL field only. For now, if the module is installed, every created Task will have a field "url", in the persistence file "net.sourceforge.nomadpim.tasks.xml".
<?xml version="1.0" encoding="UTF-8"?> <data version="6"> <task id="0"> <finished xml:space="preserve">false</finished> <plannedTimes /> <description xml:space="preserve"></description> <workTimes /><url xml:space="preserve"></url><date xml:space="preserve">2009-02-15</date> <note xml:space="preserve"></note> </task> </data>
But, it's empty at the moment, of course. The persistence and UI components of the Task entity are defined in the schedule module. We will use it here, too.
User Interface integration
To extend the User Interface, we have to define an editor page in the file "source/model/Entities.xml".
... <entity name="Task" package="org.nomadpim.tutorial"> <attribute name="Url" type="String" /><ui:editorPage name="Url"/></entity> </entities>
The additional editor page should be named, since the standard page exists. This means, our editor page configuration in the "src/java" source folder, have to be named "TaskEditorConfigurationUrl" and contained in the package "org.nomadpim.tutorial". This code will not be generated. To create this class simply copy this code and paste it directly on the "java/src" source folder. Eclipse will create the necessary package fragments and files for you.
package org.nomadpim.tutorial; import java.util.List; import org.nomadpim.core.ResourceFacade; import org.nomadpim.core.ui.component.Section; import org.nomadpim.core.ui.component.SectionBuilder; import org.nomadpim.core.ui.editor.IEntityEditorConfiguration; public class TaskEditorConfigurationUrl implements IEntityEditorConfiguration { public List<Section> createPropertyFieldConfigurations() { SectionBuilder builder = new SectionBuilder(new ResourceFacade( "TutorialProject"), Task.TYPE_NAME); builder.addTextField(Task.URL); return builder.getSections(); } }
Finally add descriptions in the "plugin.properties" file.
... wizard.new.notification.description=Creates a new notification entityobject.task.fields.url.name=URL editor.task.pages.Url=URL
Now, we have a simple user interface to enter values in our additional field. Please, compare to the Creating the editor page section of the Creating the basic entity UI tutorial.
Extend behaviour with a module
Often, it's not only an extension of data with a standard user interface, but an extension of behavior, a new action, in context to an entity or without. Nomad PIM is an Eclipse RCP application, which provides entry points for menu bar, task bar, popup menus and more, but this is not part of this tutorial. The file "src/model/plugin.xml" is combined with generated code to the file "plugin.xml", which is overwritten. So remember to modify "src/model/plugin.xml" instead of "plugin.xml" if you want to extend some extension points.
To create an action in context with an entity, we have to publish a type adapter factory and a context action to the Nomad PIM core. Edit the file "src/model/plugin.xml" in the TutorialProject.
...<extension point="org.nomadpim.core.typeAdapterFactory"> <configuration typeName="task" adapterFactory="org.nomadpim.tutorial.TaskUrlProviderAdapterFactory" /> </extension> <extension point="org.nomadpim.core.ui.contextAction"> <configuration icon="resources/icons/action_ShowUrl.png" label="%action.context.ShowUrl.label" tooltip="%action.context.ShowUrl.tooltip" class="org.nomadpim.tutorial.ui.ShowUrlContextAction" /> </extension></plugin>
The type adapter factory needs a provider type interface first. Create it in "src/java".
package org.nomadpim.tutorial; public interface IUrlProvider { String getUrl(); }
Second is the type adapter, created it in "src/java".
package org.nomadpim.tutorial; import org.nomadpim.core.entity.IEntity; import org.nomadpim.core.entity.adapter.AbstractEntityAdapter; public class TaskUrlProviderAdapter extends AbstractEntityAdapter implements IUrlProvider { public TaskUrlProviderAdapter(IEntity s) { super(s); } public String getUrl() { return getEntity().get(Task.URL); } }
Third the type adapter factory, created it in "src/java".
package org.nomadpim.tutorial; import org.nomadpim.core.entity.IEntity; import org.nomadpim.core.entity.adapter.AbstractEntityAdapterFactory; public class TaskUrlProviderAdapterFactory extends AbstractEntityAdapterFactory<IUrlProvider> { public IUrlProvider createAdapter(IEntity s) { return new TaskUrlProviderAdapter(s); } public Class<IUrlProvider> getAdapterClass() { return IUrlProvider.class; } }
The content action have to be created manually in "src/java", too.
package org.nomadpim.tutorial.ui; import org.nomadpim.core.ui.actions.ContextAction; import org.nomadpim.tutorial.IUrlProvider; public class ShowUrlContextAction extends ContextAction<IUrlProvider> { public ShowUrlContextAction() { super(IUrlProvider.class); } @Override public boolean isEnabled() { final String url = getFirstContext().getUrl(); return url != null && url.length() > 0; } @Override public void run() { } }
To launch a browser with the Eclipse org.eclipse.help.ui Plug-in, change the file "META-INF/MANIFEST.MF".
... org.eclipse.ui,org.eclipse.help.ui
And implement the run method like this.
package org.nomadpim.tutorial.ui;import java.util.Hashtable; import org.eclipse.core.runtime.CoreException; import org.eclipse.help.ui.browser.LaunchURL;... @Override public void run() {LaunchURL launch = new LaunchURL(); Hashtable<String, String> data = new Hashtable<String, String>(); data.put("url", getFirstContext().getUrl()); try { launch.setInitializationData(null, null, data); launch.run(null); } catch (CoreException e) { // @tag see: IScheduleModuleConstants.LOG.log(e); }} }
After this, we have an additional button on the top of a task editor and a new pop-up menu entry in the task list view, handled by the Nomad PIM framework.
Please refer to the Creating the basic entity UI tutorial and consider the sections Adding descriptions and Adding icons.
Congratulations!
You just extended an existing entity type with data and behavior. Further tutorials will be available soon.