Two of the key points of DRAGOS are configurability and extensibility. We have invested a lot of time and thought to make the system as flexible as possible. As a result, there are a number of different points where extensions can plug in, and there is usually more than one way to implement a given requirement. This document is aimed at people who want to write their own extensions. Its study is not required for people who simply want to use any of the available extensions.
The Guide to Wrappers deals in detail with the Wrapper mechanism, one of the most popular ways to implement an extension.
While not required, it is highly recommended to provide an ExtensionDescriptor with your extension to allow uniform, error-resistant and intuitive initialization. Please refer to the API documentation of ExtensionDescriptor and GraphPoolFactory for more information.
Also, you should document how your extension may interact with other known extensions, and if possible give recommendations on the correct order (see our Best Practices for an example).
Many extensions will have to keep internal data, e.g. formulas for dynamically calculating attribute values. Two mechanisms are supported by DRAGOS: meta attributes and custom graph elements. An extension could also implement its own storage through database or file access, but this is not recommended: It reduces portability and network transparency, and can not be combined with other extensions like versioning.
This mechanism is pretty self-explanatory: You can store any type of additional information with a graph entity, graph entity class or attribute. Just take care that you use unique meta-attribute keys. Prefixing them with the Java package name should work fine. In contrast to the case above, references to the actual graph data will almost exclusively be stored in the form of IDs. There is one thing you must keep in mind when using meta attributes: The values must be serializable!
This method is especially recommended when you have to store complex data, and most easily implemented if you already wrap the graph pool or schema and/or use the GraphPool's Wrapper mechanism.
You should take a look at the FilteringGraphPool and the FilteringSchema classes in the core graph model. They allow you to store your internal data in the same data source the application uses, but hide it from any caller unless you explicitly deactivate filtering. Another option would be to store your data in a separate graph pool, but that might be more difficult to set up.
Since manipulating your internal data will result in DataEvents, you should also hide them, otherwise you will probably confuse the application. The EventManager offers a facility for this purpose, see EventManager.addPreFilter(EventFilter) for details. A hint on using this feature: Tag all your internal data with a meta attribute flag upon creation. Then write an EventFilter that rejects events if the source of the event has that meta attribute.
If you need to store references to the public graph data, there are two possibilities: Using edges relations or using IDs. The former would require changing the schema definition to allow these connections, keeping the edges updated whenever the target is modified to prevent consistency exceptions because of dangling edges, and carefully hiding all these changes and additional data. While basically possible, it is much easier to use IDs stored in attributes of your internal data to maintain such links.