The Registry API provides unified access to settings.

## API Overview

The API has the concept of context which consists of a set of name-to-object bindings. It contains methods for examining and updating these bindings. The contexts are composed into hierarchical collection which form configuration system. The configuration system allows applications to store and retrieve data. How data are stored is implementation detail of backing storage.

## Learn by example

For API clients it in practice means:
1.) Decide on the unique name of the context for a group of related settings, eg:
`String ctxName = "/Settings/org/netbeans/modules/fooModule/barSettings";
`
It is recommended to use the module's code name base in the name of the context to ensure uniqueness.
2.) Create the context for this unique name:
`Context ctx = Context.getDefault().createSubcontext(ctxName);`
or you can retrieve context if you know it exists:
`Context ctx = Context.getDefault().getSubcontext(ctxName);
`
3.) Read and/store settings in the context as needed:
You have two choices. First is to read/store only primitivy data types:
`String proxyServer = ctx.getString("proxyServer", "");
int proxyPort = ctx.getInt("proxyPort", 8080);
boolean proxyInUse = ctx.getBoolean("proxyInUse", false);
`
The last parameters in all calls is default value which will be returned if there is no value stored in the registry or if for some reason operation of reading of stored data failed. It is up to client to provide some reasonable default which will allow application to still work although there is no default configured.
Similarly writing could look like:
`ctx.putString("proxyServer", "someproxy.com");
ctx.putInt("proxyPort", 1080``);
ctx.putBoolean("proxyInUse", true``);
`
The second choice is to read/store directly Objects in registry:
`ProxyConfiguration proxy = (ProxyConfiguration)ctx.getObject("proxy", defaultInstance);
`
and writting:
`ctx.putObject("proxy", new ProxyConfiguration("someproxy.com", 1080, true));
`
However in this case the client must also solve how the object will be persisted. The object persistence is not in the scope of Registry API. It is up to implementation of backing storage and its documentation must be consulted. It is expected that backing storage should by default handle all common types of objects like String, Integer, Long, Color, Font, URL, etc. and for client's objects it should provide a way how to persist them, e.g. Java Serialization or other mechanism.

## Registry API in detail

The API classes can be split into these categories:

- The Context class. This is the heart of the Registry API. Clients will use the class to manipulate the settings. The Context class contains getters and setters for most of the common data types including the primitivy data types. All method signatures contain defaultValue parameter which is returned if no value was found in registry. Besides that there are methods for enumerating subcontexts, bindings and attributes; methods for manipulation with them; support for ordered listing of context items and their sorting; support for reverting of modifications to default state if Registry backend has concept of defaults; method for obtaining default context on top of the default filesystem; etc.
- The ContextListener (and its events: SubcontextEvent, BindingEvent and AttributeEvent) can be used to learn about changes on the context.
- The Registry API is thread save. It can be called form arbitrary threads and it will internally properly synchronize them. The API has getter for Mutex which clients can used to do several changes in one step.

## Distinguishing events

It might be needed to distinguish events resulted from your context modifications and events results from foreign modifications. The events are fired synchronously from the write mutex. That means that at time when your code is leaving write mutex are all listeners already notified about the change(s). Following code snippet illustrate the typical usage how to take advantage of this to distinguish the events:
`private static boolean doingMyChanges = false;
Context myContext = ... ;
myContext.getMutex().writeAccess( new Runnable() {
public void run() {
doingMyChanges = true;
try {
doMyChangeHere();
} finally {
doingMyChanges = false;
}
}
});
// in implementation of your ContextListener you then do
// ...
public void bindingChanged(...) {
if (doingMyChanges) {
return;
}
// handle foreign changes...
}
` `// ...
`