 -----
 Plexus Registry Component
 -----
 Brett Porter
 -----
 7 February 2007
 -----

~~ Licensed to the Apache Software Foundation (ASF) under one
~~ or more contributor license agreements.  See the NOTICE file
~~ distributed with this work for additional information
~~ regarding copyright ownership.  The ASF licenses this file
~~ to you under the Apache License, Version 2.0 (the
~~ "License"); you may not use this file except in compliance
~~ with the License.  You may obtain a copy of the License at
~~
~~   http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing,
~~ software distributed under the License is distributed on an
~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~~ KIND, either express or implied.  See the License for the
~~ specific language governing permissions and limitations
~~ under the License.

~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/guides/mini/guide-apt-format.html

Plexus Registry

    The Plexus registry is a single source of external configuration for Plexus components and applications.
    It can be used by components to source configuration, knowing that it can be used from within applications
    without the information being hard coded into the component.

    To facilitate a variety of providers, {{{http://jakarta.apache.org/commons/configuration/} Commons Configuration}}
    is used to implement the backing storage.

    This relies on a pull-based (or lookup) mechanism - the applications request specific pieces of configuration at
    the time they need them, and it is retrieved from the registry.

    The registry is configurable so that configuration can be placed in any location desired, and is shared container
    wide. A registry using the same file as other running VMs should operate correctly.

    <Note:> Inside the application server, this means that the scope is application wide as each application has it's
    own container. It may be feasible to provide a single registry for the whole server, but this has not yet been
    tested. This would only be necessary if the server was to dictate configuration locations that the registry was
    not already configured to use. Of course, such additional locations could be added to the application registry
    instances programmatically as well.

* Example Configuration

-----
<component>
  <role>org.codehaus.redback.components.registry.Registry</role>
  <implementation>org.codehaus.plexus.registry.CommonsConfigurationRegistry</implementation>
  <role-hint>commons-configuration</role-hint>
  <configuration>
    <properties>
      <system/>
      <jndi prefix="java:comp/env" config-optional="true"/>
      <xml fileName="${user.home}/.m2/archiva.xml" config-optional="true" config-name="org.apache.maven.archiva"
           config-at="org.apache.maven.archiva" config-forceCreate="true"/>
      <properties fileName="${user.home}/.m2/security.properties" config-optional="true"
                  config-at="org.codehaus.plexus.security"/>
    </properties>
  </configuration>
</component>
-----

  The configuration inside the outer <<<\<properties\>>>> element is equivalent to the
  {{{http://jakarta.apache.org/commons/configuration/howto_configurationbuilder.html#Using_DefaultConfigurationBuilder} builder syntax}}
  for Commons Configuration. This maps to similar concepts in the registry.

  In this example, the precedence is to first look in the system properties, then JNDI, then the given XML file, and
  finally the given properties file.

  Registries can have 'sections', which are declared as partitioned areas of the registry. This is done using the
  <<<config-name>>> attribute in Commons Configuration. While the sections behave normally as a part of the global
  registry, they can easily be retrieved independently. This is particularly useful for write-back operations so the
  file the section is stored in can be saved when the registry is modified.

  Each configuration source can be configured with a given mount-point in the registry using the <<<config-at>>>
  attribute. This will cause all of the properties to be stored with the given prefix.

* Using the Registry  

  The registry can be used as a simple directory, for example:

-----
int value = registry.getInt( "test.property" );
String text = registry.getString( "text.data" );
boolean enabled = registry.getBoolean( "system.enabled", true );
-----

  The first parameter is always a key. The registry is hierachical, so in the key, a <<<.>>> (period) represents a
  nested configuration, and can be traversed to any level.

  The second parameter specifies a default value. If it is not given, then <<<null>>> is returned for strings if the
  key is not found in the registry, and an exception is thrown for integers and booleans under the same circumstances.

** Subsets and Sections

  There are two ways to work with a portion of the registry at a time: subsets and sections.

  Sections were encountered earlier - and while they return a subset it may span a number of different base prefixes,
  depending on whether <<<config-at>>> was specified on the section or not. Even so, if it is a subset of the
  hierachy, some elements of the hierachy at the same level might not be returned because they come from a different
  section.

  On the other hand, subsets are reductions of the registry to keys descending from a given prefix.

  Once a subset (or section) is obtained, it behaves the same as the registry as a whole, however it will have fewer
  values, and looking up values will not have the prefix as a part of the key.

  For example:

-----
String value = registry.getString( "org.codehaus.plexus.registry.value" );
Registry subset = registry.getSubset( "org.codehaus.plexus.registry" );
value = subset.getString( "value" ); // this will equal the earlier value retrieved
-----

** Lists and Maps

  It is also possible to retrieve subsets of the registry as collections.

    * <<<getProperties(key)>>>: Maps and properties are straightforward - the subset is converted into key/value pairs
                                and returned as a map.

    * <<<getSubsetList(key)>>>: For lists of complex types that will still contain more than one key/value pair,
                                this method can be used to retrieve them as a list of subset registries.

    * <<<getList(key)>>>:       For lists of simple types, this method can be used to get a list of value objects.
                                
** Using Models

  To simplify the translation of configuration into reusable beans and to produce a self-documenting system, Modello
  can be used to generate registry I/O classes. The appropriate goals in the plugin are <<<registry-reader>>> and
  <<<registry-writer>>>.

** Saving Changes

  Saving changes to a registry is quite simple:

-----
registry.save();
-----

  Note that the registry must be a file-based section (saving the entire registry will not succeed). It will be saved
  to the same location that it was loaded from.

** Adding Change Listeners

  ~~TODO

