Saturday, May 17, 2008

Open BD Plugin Architecture

Alan Williamson said he needed to document and blog about the plugin architecture of Open BlueDragon, after all it is his baby. Being the huge proponent of it, I decided to go poke around the source and figure some of this out on my own. What follows is my interpretation of the plugin architecture after messing with it this this morning. I'm sure Alan will have better documentation in the wiki.

Firstly since I didn't really feel like writing a hello world function I took the code Andrew Scott posted the other day and turned it into a plugin. Since the plugin stuff has not got much press Andrew did what he knew he could do and added his function to the core, something that has gotten some criticism already. This type of functionality is perfect for the plugin architecture so i figured it would be perfect for my example. In an effort to keep this entry from getting too long I am going to focus in on the com.bluedragon.plugin package and how to use the plugin architecture and I will leave out how to create a tag or method till later. Besides others have already figured it out so you can too right?

The Plugin package contains only 2 concrete classes and for now we only need to worry about one of them, and an interface; the PluginManager (concrete) and Plugin (interface). We'll be using the PluginManager to register our functions and tags, on a side note it looks like this is also Java's interface to CFCs. On start up the PluginManager is called and it uses a node in bluedragon.xml to know what plugins to load. The node is <plugin> and the path is (found on line 67 of PluginManager): server.system.plugin. Here is a snippet example:
<server>

<system>

<plugin>com.bluedragon.extra.ExtraPackPlugIn</plugin>

</system>

</server>

The classes specified in the plugin node should be in the classpath, on launch, and each should implement the Plugin interface (the other class in the package mentioned earlier). One of the methods you have to implement is pluginStart. This method takes an instance of the PluginManager which you can then use to register all your addin methods and tags. To add a tag it would lok something like this:

manager.registerFunction("QueryGetRow", "com.cfinnovate.example.QueryGetRow");
(or registerTag, for tags).

The first argument will be the name used inside of your CFML and the second is the class that implements the functionaity for your method/tag. Generally they'll extend functionBase or cfTag. NOTE: you can override builtin functions and tags with the PluginManager's methods.

The important thing to call out here is your methods and tags can be written exactly as if they were built into the core, just put them in your own package. The end result is a, 100% portable to the core, extension to Open BlueDragon. As far as eclipse setup I created a new resource folder inside of my openbd project called plugins and put the plugin code in my own package and it worked perfectly. This also allows for easy export to a jar to distribute to others. Here is a recap:
  1. Create a Class that implements Plugin
  2. Place that class (and your actual method/tag classes) in the classpath
  3. Put the plugin implementing class in the server.system.plugin node
  4. Start the server and enjoy
If you would like to see a working example check out this example jar (which contains the source as well). Please note that the function itself is Andrew's which he shared with OpenBD and this is example code. An entire example project can be found in my SADHaTS project. Please note that to make it easier to share I put it in its own project. If you want to test out building the way I explained earlier just copy the package into a new resource tree in your openBD project. Happy coding!

Update: Alan has blogged about it now here

No comments: