Extending Omea with New Resource Types

Creating and Registering a Plugin

This article will discuss the main structure and responsibilities of a plugin which registers a new resource type. The example plugin discussed in the article is "Librarian" - a plugin which allows you to manage your book collection. It demonstrates a wide array of Omea interfaces that you will need to deal with when developing plugins, and at the same time does not involve any extra complexity related to integrating with external applications, protocols or data formats. The example implements only the bare minimum functionality, but you will be easily able to extend it if desired.

To create a new plugin in Visual Studio .NET, simply create a new project of type "Class Library" and add a reference to the OpenAPI.dll assembly from the Omea distribution. That assembly contains a set of classes and interfaces in the JetBrains.Omea.OpenAPI namespace which constitute the API available to the plugin developers. The documentation for the Open API is not included in the base Omea distribution and can be downloaded separately from our Web site.

In order for Omea to be able to load the plugin, it should implement the IPlugin interface. The interface consists of three methods - Register(), Startup() and Shutdown(). The plugin startup sequence is fully described in the OpenAPI documentation; here we will simply note that Register() is the first method called after a plugin has been loaded, and we will perform all the initialization in that method.

All services provided by the Omea core can be accessed through the static properties of the JetBrains.Omea.OpenAPI.Core class, which are available all the time a plugin is running. For example, to create a new resource, the method Core.ResourceStore.NewResource is used. Complete documentation of interfaces available through the Core class can be found in the Open API documentation.

After you have compiled the plugin for the first time, you'll need to add it to the system registry, so that Omea will know that it should be loaded. On your test machine you can use the "Add..." button in the Omea Plugins options page to add a plugin, but it is better to create an installer for the plugin that will add it to the registry automatically. The list of Omea plugins is stored in the registry under Software\JetBrains\Omea\Plugins for Omea Pro and under Software\JetBrains\Omea Reader\Plugins for Omea Reader. The contents of these keys is scanned both for HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER; plugins from either key are loaded.

Defining Resource and Property Types

In order to understand which resource and property types will be needed by the plugin, we need to decide on our requirements first. To keep the example simple, we will store only the minimum required information about each book.

Our plugin will allow the user to create, edit and view books. For every book, the user will be able to enter its name, authors, the year it was published and, optionally, its ISBN (which will serve as the unique identifier for the book). Every book can have several authors, and every person can be the author of several books.

To make the most use of the core features of Omea, it is recommended to reuse the resource and property types defined by the core and the standard plugins whenever it makes sense. In our example, we will need to create a new resource type to represent books (because that's the whole point of our plugin, after all). On the other hand, we do not need to create a separate resource type to represent book authors - we can reuse the standard Contact resource type to represent them. The openness of the Omea data model allows us to add any extra properties and links to Contact resources if we need to.

To represent the name of the book, we can also reuse an existing property type - Name, which is a string property type with no special features, and suits us just fine. We could represent the publication date of the book with the standard date property type Date, but it does not fit us quite well. It is usually not important to know the exact publication date of the book, and asking the user to enter that information will be an extra burden. Thus, we will create a new integer property type to represent the publication year. The ISBN will also be represented by a new string property type.

We will also define a new link type to represent the connection between a book and its authors. There is no inherent order for that connection, so we will not use a directed link type - the link will be completely symmetric.

To make sure the resource and property types defined by a third-party plugin do not conflict with the types defined by the Omea core or other third-party plugins, it is strongly recommended to use a prefix consisting of your company name and plugin name for every defined type. For example, our book resource type is called JetBrains.Librarian.Book, and the ISBN property type is JetBrains.Librarian.ISBN. The resource and property types defined by the Omea core do not have any dotted prefix. Display names are registered for the resource and property types, so that the user will see friendly-looking names, without any dotted prefixes.

The registration code for the resource and property types, along with the accessors for the registered property type IDs, is found in the classes PropTypes and ResourceTypes. Because the display name templates of some resource types may reference property types defined in the plugin, we register all property types before registering all resource types.

Note that the registration of resource and property types is completely separate - we do not need to tell Omea which properties we are going to use for the Book resource type. Any property can be applied to any resource type. However, to ensure data consistency, we register a link restriction specifying that the BookAuthor link of a book must point to a resource of type Contact. We could also specify restrictions on the link count (for example, specify that a book must have at least one author), but we want to allow the users to create books with unknown authors, so we don't restrict the link count.

The unique restriction on the ISBN property guarantees that the values of ISBN will be unique among all books. There can be any number of books for which the ISBN property is not defined, but if it is defined, there may exist no other Book resource with the same value of ISBN.

Page « Page 1 2 3 4 5 »
Dmitry's photo

Dmitry Jemerov
JetBrains

The youngest of JetBrains project leads, Dmitry got his job after working on Syndirella, an open-source RSS reader. Dmitry always carries with him a Tablet PC with Omea running, and is always eager to demo it to anyone willing to listen. When not at work, he sometimes finds the time to ride his bike, play his bass and meet his friends for a role-playing game.

Contact Dmitry via email: dmitry(.)jemerov
(at) jetbrains.com