1. Introduction
Preferences
are represented by a tree of nodes. Each node has a name (may not
be unique) and a path (always unique). The root node has "/" as name and path.
No other node may have the character '/' in its name. Nodes may contain
key-value entries.
Preferences
trigger events whenever a node changes value or nodes are
added/removed. You may register a griffon.plugins.preferences.PreferenceChangeListener
to handle the first type of event, and a griffon.plugins.preferences.NodeChangeListener
to handle the second one.
Preferences
may be resolved at any time given a PreferencesManager
; this
plugin will automatically instantiate a manager given the default configuration.
Preference values may also be injected following a naming convention. Classes
that participate in preferences injection have their properties annotated with
@Preference
. Only classes annotated with @PreferencesAware
will be notified
of updates whenever preferences change value. The @Preference
annotation
defines additional parameters such as key
, args
, defaultValue
and format
;
these parameters work exactly as shown by @InjectedResource
.
Here’s an example of a Model class defining a preference for a title and a custom format for a Date property
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package sample
import griffon.core.artifact.GriffonModel
import griffon.metadata.ArtifactProviderFor
import griffon.plugins.preferences.Preference
import griffon.plugins.preferences.PreferencesAware
@griffon.transform.Observable
@PreferencesAware
@ArtifactProviderFor(GriffonModel)
class SampleModel {
@Preference(defaultValue='Sample')
String title
@Preference(defaultValue='08.04.2013 2:30 PM', format='dd.MM.yyyy h:mm a')
Date date
private String isbn
@Preference(defaultValue='9781935182238')
void setIsbn(String isbn) { this.isbn = isbn }
String getIsbn() { this.isbn }
}
When the application is run for the first the title
property will have "Sample"
as its value. Preferences will be written to disk when the application is shutdown.
Here are the contents of the default.json
file (JSON support is enabled if the
griffon-preferences-json
dependency is added to the classpath)
1
2
3
4
5
6
7
8
9
{
"sample": {
"SampleModel": {
"isbn": "9781935182238",
"title": "Sample",
"date": "08.04.2013 2:30 PM"
}
}
}
If that file is edited so that the title property has a different value then the new value will be shown the next time the application is launched.
It’s worth noting that if a preference cannot be resolved a
griffon.plugins.preferences.NoSuchPreferenceException
is thrown.
The @Preference
annotation may be applied to methods too, as long as the method
represents a property getter or setter. Both read and write methods must exist.
The annotation may be applied to any of the property accessors. The setter has
precedence in the event of both accessors being annotated.
Values of properties annotated with @Preference
are not automatically synchronized with their
PreferenceNode
counterpart. This is to ensure only valid preference values are stored.
Thus developers must manually invoke the save()
method on an instance of PreferencesManager
,
such as
1
preferencesManager.save(model)
Version 1.4.0 and earlier computed the value of a preference key based on the declaring class of
the matching annotated field or method. You can change this behavior since version 1.5.0 by defining
a configuration flag in Config.groovy
and/or Config.properties
.
preferences.key.resolution.strategy = instance_class
Valid values are: declaring_class
, instance_class
. Although instance_class
is more aligned with
the inheritance model of members in Java, declaring_class
remains the default value to keep backward
compatibility with existing applications.
Griffon version: 2.14.0
2. Build Configuration
2.1. Gradle
You have two options for configuring this plugin: automatic and manual.
2.1.1. Automatic
As long as the project has the org.codehaus.griffon.griffon
plugin applied to it you
may include the following snippet in build.gradle
dependencies {
griffon 'org.codehaus.griffon.plugins:griffon-preferences-plugin:2.1.0'
}
The griffon
plugin will take care of the rest given its configuration.
2.1.2. Manual
You will need to configure any of the following blocks depending on your setup
dependencies {
compile 'org.codehaus.griffon.plugins:griffon-preferences-core:2.1.0'
}
dependencies {
compile 'org.codehaus.griffon.plugins:griffon-preferences-jackson:2.1.0'
}
dependencies {
compile 'org.codehaus.griffon.plugins:griffon-preferences-json:2.1.0'
}
dependencies {
compile 'org.codehaus.griffon.plugins:griffon-preferences-yaml:2.1.0'
}
2.2. Maven
First configure the griffon-preferences-plugin
BOM in your POM file, by placing the following
snippet before the <build>
element
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.codehaus.griffon.plugins</groupId>
<artifactId>griffon-preferences-plugin</artifactId>
<version>2.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Next configure dependencies as required by your particular setup
<dependency>
<groupId>org.codehaus.griffon.plugins</groupId>
<artifactId>griffon-preferences-core</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.griffon.plugins</groupId>
<artifactId>griffon-preferences-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.griffon.plugins</groupId>
<artifactId>griffon-preferences-json</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.griffon.plugins</groupId>
<artifactId>griffon-preferences-yaml</artifactId>
</dependency>
3. Modules
The following sections display all bindings per module. Use this information to successfully override a binding on your own modules or to troubleshoot a module binding if the wrong type has been applied by the Griffon runtime.
3.1. Preferences
Module name: preferences
bind(PreferencesManager.class)
.to(DefaultPreferencesManager.class)
.asSingleton();
bind(PreferencesPersistor.class)
.to(SerializingPreferencesPersistor.class)
.asSingleton();
bind(GriffonAddon.class)
.to(PreferencesAddon.class)
.asSingleton();
3.2. Preferences Jackson
Module name: preferences-jackson
Depends on: preferences
bind(PreferencesPersistor.class)
.to(JacksonPreferencesPersistor.class)
.asSingleton();
You must define a binding for Jackson’s com.fasterxml.jackson.databind.ObjectMapper type.
|