<commit_before>
[[_introduction]]
= 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

[source,groovy,linenumbers,options="nowrap"]
----
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)

[source,json,linenumbers,options="nowrap"]
----
{
    "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 sincey with their
`PrefernceNode` 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

[source,java,linenumbers,options="nowrap"]
----
preferencesManager.save(model)
----

Griffon version: {griffon-version}
<commit_msg>Fix typo in guide. Relates to #1<commit_after>
[[_introduction]]
= 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

[source,groovy,linenumbers,options="nowrap"]
----
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)

[source,json,linenumbers,options="nowrap"]
----
{
    "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 synched 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

[source,java,linenumbers,options="nowrap"]
----
preferencesManager.save(model)
----

Griffon version: {griffon-version}

{'fraction_non_alphanumeric': 0.07621214275558083, 'fraction_numerical': 0.013792122849424143, 'mean_word_length': 4.538582677165354, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1373779', 'n_tokens_mistral': 1979, 'n_tokens_neox': 1857, 'n_words': 836}