Wednesday, February 13, 2013

oXygen, Scala and plugin repository

Introduction

I am looking at Scala for future development, and wondered a bit about its integration abilities for edge cases. Writing a plugin for oXygen looked like a good candidate to investigate this: oXygen has no specific support for Scala, it is written in Java, there is a JAR library containing classes to use for developing the plugin, which has to implement some specific classes and use others, then be bundled as a plugin JAR file, loaded dynamically by oXygen and called from the description in the plugin.xml descriptor. If Scala did not support that scenario, it would probably not be worth having a look at for me.

So I don't know anything about Scala. I downloaded it, tried to sketch a Hello World kind of plugin for oXygen, and the result was impressively simple! So here are the few steps I've done, if you want to make your own at home.

Setup

First, download and install Scala. I went to Scala download area, downloaded the latest version for Mac OS X, unzip it in /usr/local/scala-2.10.0 and added the sub-directory bin/ to my $PATH. I assume you also have the oXygen SDK, with the file oxygen.jar to use for plugin development.

The Scala sources

The following two classes are the implementation of a very simple plugin for oXygen that displays a message when you start oXygen up, and another one when you are about to shut it down. They both must be in a directory called org/fgeorges/test in order to match the package name (exactly like in Java). First the plugin class itself, in org/fgeorges/test/MyPlugin.scala:
package org.fgeorges.test

import ro.sync.exml.plugin.{Plugin, PluginDescriptor}

class MyPlugin(desc: PluginDescriptor) extends Plugin(desc)
{
    // empty plugin
}
Here is the extension class, in org/fgeorges/test/MyExtension.scala:
package org.fgeorges.test

import ro.sync.exml.plugin.workspace.WorkspaceAccessPluginExtension
import ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace

class MyExtension() extends WorkspaceAccessPluginExtension
{
    var myws: StandalonePluginWorkspace = null
    override def applicationStarted(ws: StandalonePluginWorkspace) {
        myws = ws
        ws.showInformationMessage("F., yeah!")
    }
    override def applicationClosing(): Boolean = {
        myws.showInformationMessage("We're closing guys...")
        true
    }
}

Compiling

In order to compile those, and build the JAR file, go to the top directory (the one containing the sub-directory org/), and use the following command. Note that the -Y is necessary because of some conflicts in the oXygen JAR file when used from Scala. You also might have to adapt the path to the oXygen JAR, of course.
> scalac \
    -Yresolve-term-conflict:error \
    -cp .:oxygen.jar \
    org/fgeorges/test/*.scala
> jar cf my-plugin.jar org/fgeorges/test/*.class

Deploying

From now on, you have your plugin as a JAR file, like any other plugin for oXygen. So the next required step is to deploy the plugin like any other plugin. Create a new directory in the oXygen plugins/ sub-directory (right under the install directory), and create a plugin descriptor at, say, plugins/my-plugin/plugin.xml:
<!DOCTYPE plugin SYSTEM "../plugin.dtd">

<plugin name="MyPlugin"
        description="Test plugin with Scala..."
        version="0.0.1"
        vendor="fgeorges.org"
        class="org.fgeorges.test.MyPlugin">

   <runtime>
      <library name="my-plugin.jar"/>
   </runtime>

   <extension type="WorkspaceAccess" class="org.fgeorges.test.MyExtension"/>

</plugin>
All you have to do now to test the plugin is to (re)start oXygen!

Add-ons repository

A new feature in oXygen 14 (which is not related at all with Scala), is the ability to create an online repository for add-ons (including plugins and frameworks), so a user can point oXygen to it and install add-ons through a graphical interface:

All you have to do in order to create such a repository is to publish a repository descriptor, which links to the JAR files for your add-ons, and give that URL to your users, like you can see on the EXPath oXygen area. The descriptor looks like the following:
<xt:extensions xmlns:xt="http://www.oxygenxml.com/ns/extension"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="
                  http://www.oxygenxml.com/ns/extension
                    http://www.oxygenxml.com/ns/extension/extensions.xsd">
   <xt:extension id="xproject">
      <xt:location href="http://expath-pkg.googlecode.com/files/xproject-oxygen-plugin-0.5.1.zip"/>
      <xt:version>0.5.1</xt:version>
      <xt:oxy_version>14.0+</xt:oxy_version>
      <xt:type>plugin</xt:type>
      <xt:author>Florent Georges</xt:author>
      <xt:name>XProject</xt:name>
      <xt:description>XProject, the XML project manager.</xt:description>
      <xt:license>Bla bla...</xt:license>
   </xt:extension>
</xt:extensions>
Conclusion: Scala is sooo easy to setup to be used to write a plugin for oXygen, and the new oXygen add-on repository is sooo easy to create and to install plugins from!

Labels: ,