Step 2 of 10 Defining your XNAT plugin

Goal

In this step, you'll create a new class and declare it as an XNAT plugin.

The key to an XNAT plugin is a single Java class that is marked to indicate that it provides XNAT with information and metadata about your plugin. The XNAT framework library provides a Java annotation, @XnatPlugin, that provides a number of attributes you can use to define and configuration your XNAT plugin. To create your plugin definition class, just follow the steps below.

If you have an existing XNAT module or project overlay that consists of data-type schemas, Velocity templates, and possibly Java classes that just extend classes in the XNAT Turbine and Velocity frameworks, you may not need to use an @XnatPlugin-annotated Java class. If you'd prefer to avoid writing any (or any more) Java code, it's possible to migrate that kind of code structure to build with the XNAT Gradle plugin without any new classes. This practical session focuses on the full set of capabilities in XNAT 1.7 code. We will provide a migration guide for adapting existing code to work in 1.7 prior to the actual release of XNAT 1.7.

First, make sure you've imported the dependency org.nrg:framework:1.7.0-SNAPSHOT in your build.gradle. This dependency is already in the workshop version of this file, so if you started with that you'll have it. If not, find the dependencies block and add the dependency:

dependencies {
    compile("org.nrg:framework:1.7.0-SNAPSHOT") {
        transitive = false
    }
    // More dependencies may already be here...
} 

The transitive = false configuration helps reduce the number of extra dependencies referenced by your plugin.

You can run ./gradlew dependencies in your build folder to have Gradle generate a list of all of the dependencies referenced by your configuration.

Now create a new package for your plugin class under the folder src/main/java. This should be something indicative of your organization and the function of the plugin. For the sample plugin code, we used the package org.nrg.xnat.workshop for the overall package structure, then created another package under that for the plugin class named plugin.

 Once you've created your package, create a new class in it. Again, this should be named something relevant to the purpose of the plugin. We used the name WorkshopXnatPlugin. You should have something very simple like this:

package org.nrg.xnat.workshop.plugin;

public class WorkshopXnatPlugin {
} 

Now import the XnatPlugin annotation class and add it to the plugin class declaration:

package org.nrg.xnat.workshop.plugin;

import org.nrg.framework.annotations.XnatPlugin;

@XnatPlugin
public class WorkshopXnatPlugin {
} 

Annotations let you mark a class (and other things like parameters and fields and methods as well, but here we're mostly concerned about the class!) so that other code can recognize your class as having a particular function. That's useful in and of itself, but annotations also let you specify attributes, which are essentially properties that provide an even greater vocabulary to describe your plugin class. The @XnatPlugin annotation provides a number of attributes, including a few we'll use right now:

  • The value attribute provides a unique ID for the plugin
  • The name attribute provides a readable name for the plugin function
  • The description attribute provides a verbose description

Defining values for these attributes looks something like this:

package org.nrg.xnat.workshop.plugin;

import org.nrg.framework.annotations.XnatPlugin;

@XnatPlugin(value = "workshopPlugin", name = "XNAT 1.7 Workshop 2016 Plugin", 
            description = "This is our first plugin for XNAT 1.7. It's pretty OK, I guess.")
public class WorkshopXnatPlugin {
} 

Now you have a plugin class that defines some useful information about your plugin and makes it visible to the XNAT system. That's all there is to starting your plugin definition, but we'll return to this later to enable and configure other parts of the plugin implementation.

In addition to defining the @XnatPlugin annotation, the NRG framework library also includes a class that processes the annotation when you compile your code. It's not necessary to do anything to configure or invoke this processor: annotation processing is built into the javac compiler and is performed automatically. It's worth mentioning though because the processing of your plugin annotation generates some other effects, most importantly a properties file that's generated and included in the output jar file from your build. It's really this properties file that XNAT uses when loading your plugin code.

Completed!

You now have an XNAT plugin definition that you can build the rest of your plugin around.

Go to the next step

$label.name