Step 6 of 10 Storing service and plugin preferences

Goal

Create a preferences class for your subject mapping service.

XNAT 1.7 stores most of its configuration and preferences data in the database. This provides a lot of advantages, but has a really big drawback by requiring developers to interact with the database in order to store their data. XNAT 1.7 provides a preferences bean framework to make it as easy as possible to transparently and safely store preferences and settings for your custom code.

"Bean" is a Java term that indicates a object that is just a collection of properties. In fact, the database entity you created in the last step is considered a bean. A pure bean class is one that has nothing other than property getters and setters (and a read-only or immutable bean would only have getters!). However, a bean class can have "decorations"–annotations or other indicators that help frameworks that handle the bean understand its contents–like the @Entity and @Table annotations on the last

It's really pretty easy to create your own preferences bean. Start by creating the bean class as you normally would. Let's create a bean that stores the preferences for the subject mapping framework. The only requirement right now would be a list of the source system IDs. This would look something like:

public class SubjectMappingPreferencesBean {
    public List<String> getSourceSystemIds() {
        return _sourceSystemIds;
    }
 
    public void setSourceSystemIds(final List<String> sourceSystemIds) {
        _sourceSystemIds.clear();
        _sourceSystemIds.addAll(sourceSystemIds);
    }
}

This is functional in that you can get and set a list of strings that contain the IDs of the external systems, but there's nothing here that saves or retrieves those values in the database. That's where the preferences bean framework comes in. There are three parts to turning this into a preferences bean:

  • Annotate the class with @NrgPreferenceBean and set some attributes on this annotation (more on this below)
  • Annotate your property with the @NrgPreference annotation
  • Make your bean class extend the AbstractPreferenceBean class
  • Implement the property to use AbstractPreferenceBean class methods for getting and setting property values

The code should look something like this:

@NrgPreferenceBean(toolId = "subjectMapping")
public class SubjectMappingPreferencesBean extends AbstractPreferenceBean {
    @NrgPreference(defaultValue = "['REDCap','PACS']")
    public List<String> getSourceSystemIds() {
        return getListValue("sourceSystemIds");
    }

    public void setSourceSystemIds(final List<String> sourceSystemIds) {
        try {
            setListValue("sourceSystemIds", sourceSystemIds);
        } catch (InvalidPreferenceName invalidPreferenceName) {
            //
        }
    }
} 

All of the functionality required to store and retrieve your preferences to and from the database are implemented in the base class. In fact, the base class also scans your preference class, finds all of the declared properties (i.e. those annotated with @NrgPreference), and creates them, populating each preference with a default value.

Completed!

You've created a new preference bean object for storing dynamic preference settings.

Go to the next step

Step 6 of 10 Storing service and plugin preferences



$label.name