You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by po...@apache.org on 2016/12/18 22:39:51 UTC
[07/10] incubator-tamaya-site git commit: TAMAYA-178: Fix menu
structure
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_etcd.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_etcd.adoc b/content/documentation/extensions/mod_etcd.adoc
new file mode 100644
index 0000000..149d843
--- /dev/null
+++ b/content/documentation/extensions/mod_etcd.adoc
@@ -0,0 +1,189 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: Integration with etcd (Core OS)
+
+toc::[]
+
+
+[[Optional]]
+== Integration with etcd (Extension Module)
+=== Overview
+
+The Tamaya etcd integration module provides different artifacts which allows integration of Apachae Tamaya
+configuration with etcd. Basically the module supports read-only integration (as a +EtcdPropertySource+ as well
+as a support for +MutableConfiguration+ as defined by the +tamaya-mutable-config+ extension module.
+
+
+=== Compatibility
+
+The module is based on Java 7, so it will not run on Java 7 and beyond.
+
+
+=== Installation
+
+To benefit from configuration builder support you only must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-etcd</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+
+=== The Extensions Provided
+
+ETcd integration comes basically with 2 artifacts:
+
+* The +org.apache.tamaya.etcd.EtcdAccessor+ can be configured with a an url targeting an etcd server's REST endpoint root.
+ (+org.apache.tamaya.etcd.EtcdAccessor+). The accessor basically provides a simple Java API for communicating
+ with etcd server. The accessor hereby allows reading of single properties, or whole subtrees. Also the basic non
+ atomic write methods are implemented.
+* The +org.apache.tamaya.etcd.EtcdPropertySource+ is a +PropertySource+ with a default ordinal of 100 and the name
+ 'etcd', which is automatically registered.
+* If the +tamaya-mutable-config+ module is loaded it is possible to write property values back into the etcd cluster,
+ by accessing a +MutableConfiguration+ using the URI +config:etcd+.
+
+=== The EtcdAccessor
+
+The accessor mentioned implements the basic read and write API for communicating with an etcd configuration cluster.
+Hereby the accessor also provides etcd specific data such as +createdIndex, modifiedIndex, ttl+ in the +Map+
+returned. Hereby the concept of etcd is used where keys starting with an '_' will be hidden from the overall
+properties map, being only directly/explicitly accessible:
+
+[source, java]
+-----------------------------------------------
+public class EtcdAccessor {
+
+ /**
+ * Creates a new instance with the basic access url.
+ * @param server server url, e.g. {@code http://127.0.0.1:4001}.
+ * @throws MalformedURLException
+ */
+ public EtcdAccessor(String server) throws MalformedURLException;
+
+ /**
+ * Get the etcd server version.
+ * @return the etcd server version, never null.
+ */
+ public String getVersion();
+
+ /**
+ * Ask etcd for s aingle key, value pair. Hereby the response returned from etcd:
+ * <pre>
+ * key=value
+ * _key.source=[etcd]http://127.0.0.1:4001
+ * _key.createdIndex=12
+ * _key.modifiedIndex=34 // optional
+ * _key.ttl=300 // optional
+ * _key.expiration=... // optional
+ * </pre>
+ * @param key the requested key
+ * @return the mapped result, including meta-entries.
+ */
+ public Map<String,String> get(String key);
+
+ /**
+ * Creates/updates an entry in etcd without any ttl set.
+ * The response is as follows:
+ * <pre>
+ * key=value
+ * _key.source=[etcd]http://127.0.0.1:4001
+ * _key.createdIndex=12
+ * _key.modifiedIndex=34 // optional
+ * _key.prevNode.createdIndex=12 // optional
+ * _key.prevNode.modifiedIndex=34 // optional
+ * </pre>
+ * @param key the property key, not null
+ * @param value the value to be set
+ * @return the result map as described above.
+ */
+ public Map<String,String> set(String key, String value);
+
+ /**
+ * Creates/updates an entry in etcd. The response is as follows:
+ * <pre>
+ * key=value
+ * _key.source=[etcd]http://127.0.0.1:4001
+ * _key.createdIndex=12
+ * _key.modifiedIndex=34 // optional
+ * _key.ttl=300 // optional
+ * _key.expiry=... // optional
+ * _key.prevNode.createdIndex=12 // optional
+ * _key.prevNode.modifiedIndex=34 // optional
+ * _key.prevNode.ttl=300 // optional
+ * _key.prevNode.expiration=... // optional
+ * </pre>
+ * @param key the property key, not null
+ * @param value the value to be set
+ * @param ttlSeconds the ttl in seconds (optional)
+ * @return the result map as described above.
+ */
+ public Map<String,String> set(String key, String value, Integer ttlSeconds);
+
+
+ /**
+ * Deletes a given key. The response is as follows:
+ * <pre>
+ * _key.source=[etcd]http://127.0.0.1:4001
+ * _key.createdIndex=12
+ * _key.modifiedIndex=34
+ * _key.ttl=300 // optional
+ * _key.expiry=... // optional
+ * _key.prevNode.createdIndex=12 // optional
+ * _key.prevNode.modifiedIndex=34 // optional
+ * _key.prevNode.ttl=300 // optional
+ * _key.prevNode.expiration=... // optional
+ * _key.prevNode.value=... // optional
+ * </pre>
+ * @param key the key to be deleted.
+ * @return the response mpas as described above.
+ */
+ public Map<String,String> delete(String key);
+
+
+ /**
+ * Access regular Tamaya properties map as follows:
+ * <pre>
+ * key1=myvalue
+ * _key1.source=[etcd]http://127.0.0.1:4001
+ * _key1.createdIndex=12
+ * _key1.modifiedIndex=34 // optional
+ * _key1.ttl=300 // optional
+ * _key1.expiration=... // optional
+ *
+ * key2=myvaluexxx
+ * _key2.source=[etcd]http://127.0.0.1:4001
+ * _key2.createdIndex=12
+ *
+ * key3=val3
+ * _key3.source=[etcd]http://127.0.0.1:4001
+ * _key3.createdIndex=12
+ * _key3.modifiedIndex=2
+ * </pre>
+ */
+ public Map<String,String> getProperties(String directory, boolean recursive);
+
+}
+-----------------------------------------------
+
+
+=== The EtcdPropertySource
+
+The +EtcdPropertySource+ is automatically registered and allows to configure the etcd servers to be used. This
+enables to use e.g. in Docker environments the docker environment configuration mechanisms to configure Tamaya running
+in microservice containers to connect with the according etcd cluster:
+
+* The property source reads the +tamaya.etcd.server.urls+ system and environment property to evaluate possible etcd servers
+ (comma separated), which can be connected to. On error the API just performs a Round-Robin through the list of
+ configured servers. Without any configuration +http://127.0.0.1:4001+ is used. If no connection to any etcd
+ server can be established a warning will be logged, but deployment will not fail.
+* Additinoally also the
+ accessor allows to configure the socket/connection timeouts by setting +tamaya.etcd.timeout+ in seconds either as
+ system or environment property.
+* The +EtcdPropertySource+ finally also allows the values read from the etcd cluster to be mapped to prefixed
+ context. This can be activated by setting the +-Dtamaya.etcd.prefix=<PREFIX>+ system property. E.g. when the prefix is
+ set to +cluster-config.+ a etcd key of +host:known/all+ is mapped to +cluster-config.host:known/all+.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_events.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_events.adoc b/content/documentation/extensions/mod_events.adoc
new file mode 100644
index 0000000..c0a3809
--- /dev/null
+++ b/content/documentation/extensions/mod_events.adoc
@@ -0,0 +1,278 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: Events
+
+toc::[]
+
+
+[[Core]]
+== Tamaya Events (Extension Module)
+=== Overview
+
+Tamaya Events is an extension module. Refer to the link:modules.html[extensions documentation] for further details
+about modules.
+
+Tamaya Events provides an abstraction for events like change events, when configuration has been changed.
+
+=== Compatibility
+
+The module is based on Java 7, so it can be used with Java 7 and beyond.
+
+=== Installation
+
+To benefit from configuration event support you only must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-events</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+=== Core Architecture
+
+The core of the module are the +ConfigEventListener+ interface and the +ConfigEvent+ class, which defines an abstraction
+for event handling and observation:
+
+[source,java]
+.ConfigEvent
+--------------------------------------------
+public final interface ConfigEvent<T> {
+
+ Class<T> getResourceType();
+ T getResource();
+ String getVersion();
+ long getTimestamp();
+}
+
+// @FunctionalInterface
+public interface ConfigEventListener {
+
+ void onConfigEvent(ConfigEvent<?> event);
+
+}
+--------------------------------------------
+
+This mechanism can now be used to propagate configuration changes to all interested stakeholders. Hereby the payload
+can be basically arbitrary as long as it implements the +ConfigEvent+ interface. The next sections
+give more details on the the provided event types and their usage.
+
+
+=== Modelling Configuration Changes
+
+This module provides a serializable and thread-safe abstraction modlling a configuration change. A change hereby may
+be
+
+* additional configuration entries
+* removed configuration entries
+* changes on entries
+
+
+The most important event modelled is the +ConfigurationChange+ class, which implements the event sent for a changed
++Configuration+:
+
+[source,java]
+-------------------------------------------------------
+public final class ConfigurationChange implements ConfigEvent<Configuration>, Serializable{
+
+ public static ConfigurationChange emptyChangeSet(Configuration configuration);
+
+ @Override
+ public Configuration getResource();
+ @Override
+ public Class<Configuration> getResourceType();
+ @Override
+ public String getVersion();
+ @Override
+ public long getTimestamp();
+
+ // Event specific methods
+
+ public Collection<PropertyChangeEvent> getChanges();
+ public int getRemovedSize();
+ public int getAddedSize();
+ public int getUpdatedSize();
+
+ public boolean isKeyAffected(String key);
+ public boolean isRemoved(String key);
+ public boolean isAdded(String key);
+ public boolean isUpdated(String key);
+ public boolean containsKey(String key);
+ public boolean isEmpty();
+}
+
+-------------------------------------------------------
+
+New instances of this class hereby can be created using a fluent builder:
+
+[source,java]
+-------------------------------------------------------
+Configuration config = ...;
+ConfigurationChange change = ConfigurationChangeBuilder.of(config)
+ .addChange("MyKey", "newValue")
+ .removeKeys("myRemovedKey").build();
+-------------------------------------------------------
+
+Also it is possible to directly compare 2 instances of configurations to create +ConfigurationChange+ that
+reflect the differences between the two configurations:
+
+[source,java]
+Comparing 2 configurations
+-------------------------------------------------------
+Configuration config = ...;
+Configuration changedConfig = ...;
+ConfigurationChange change = ConfigurationChangeBuilder.of(config)
+ .addChanges(changedConfig).build();
+-------------------------------------------------------
+
+So a +ConfigurationChange+ allows you to evaluate the changes on a configuration. This allows you to listen to changes
+and react in your client code as useful, once you encounter changes that are relevant to you, e.g. by reconfiguring
+your component. For listening to configuration changes you must implement the
++ConfigEventListener+ functional interface:
+
+[source,java]
+.Implementing a ConfigChangeListener
+-------------------------------------------------------
+public final class MyConfigChangeListener implements ConfigChangeListener<ConfigurationChange>{
+
+ private Configuration config = ConfigurationProvider.getConfiguration();
+
+ public void onConfigEvent(ConfigEvent<?> event){
+ if(event.getResourceTspe()==Configuration.class){
+ if(event.getConfiguration()==config){
+ // do something
+ }
+ }
+ }
+
+}
+-------------------------------------------------------
+
+You can *register* your implementation in 2 ways:
+
+. Manually by calling +ConfigEventManager.addListener(new MyConfigChangeListener())+
+. Automatically by registering your listener using the +ServiceLoader+ under
+ +META-INF/services/org.apache.tamaya.events.ConfigEventListener+
+
+
+=== Modelling PropertySource Changes
+
+Beside that a whole configuration changes, also +PropertySource+ instances can change, e.g. by a configuration file
+edited on the fly. This is similarly to a +ConfigurationChange+ reflected by the classes +PropertySourceChange,
+PropertySourceChangeBuilder+.
+
+
+=== The ConfigEventManager Singleton
+
+Main entry point of the events module is the +ConfigEventManager+ singleton class, which provides static accessor
+methods to the extension's functionality:
+
+* Adding/removing of +ConfigChangeListener+ instances, either globally or per event type.
+* Firing configuration events synchronously or asyncronously (mostly called by framework code).
+* Configuring the monitor that periodically checks for changes on the global +Configuration+ provided
+ by +ConfigurationProvider.getConfiguration()+.
+
+[source,java]
+-------------------------------------------------------
+public final class ConfigEventManager {
+
+ private ConfigEventManager() {}
+
+ public static void addListener(ConfigEventListener l);
+ public static <T extends ConfigEvent> void addListener(ConfigEventListener l, Class<T> eventType);
+ public static void removeListener(ConfigEventListener l);
+ public static <T extends ConfigEvent> void removeListener(ConfigEventListener l, Class<T> eventType);
+ public static <T extends ConfigEvent>
+ Collection<? extends ConfigEventListener> getListeners();
+ public static <T extends ConfigEvent>
+ Collection<? extends ConfigEventListener> getListeners(Class<T> type);
+
+ public static <T> void fireEvent(ConfigEvent<?> event);
+ public static <T> void fireEventAsynch(ConfigEvent<?> event);
+
+ public static void enableChangeMonitoring(boolean enable);
+ public static boolean isChangeMonitoring();
+ public long getChangeMonitoringPeriod();
+ public void setChangeMonitoringPeriod(long millis);
+
+}
+-------------------------------------------------------
+
+
+==== Monitoring of configuration changes
+
+The +ConfigEventManager+ also supports active monitoring of the current configuration to trigger corresponding change
+events to listeners registered. This feature is deactivated by default, but can be enabled by calling
++ConfigEventManager.enableChangeMonitoring(true);+. This feature avoids regularly polling your local +Configuration+ for
+any kind of changes. If a change has been encountered Tamaya identifies it and triggers corresponding
++ConfigurationChange+ events automatically.
+
+
+=== Freezing Configurations and PropertySources
+
++Configuration+ instances as well as +PropertySources+ are explicitly not required to be serializable. To enable easy
+serialization of these types a +Configuration+'s *current state can be frozen* (e.g. for later comparison with a newly
+loaded version). Freezing hereby means
+
+* all key/values are read-out by calling the +getProperties()+ method.
+* a meta data entry is added of the form +_frozenAt=223273777652325677+, whichdefines the UTC timestamp in
+ milliseconds when this instance was frozen.
+* if not already defined an +_id+ property will be added to the +Configuration+ containing the
+ identifier of the configuration.
+
+In code freezing is a no-brainer:
+
+[source,java]
+.Freezing the current Configuration
+--------------------------------------------------
+Configuration config = ConfigurationProvider.getConfiguration();
+Configuration frozenConfig = FrozenConfiguration.of(config);
+--------------------------------------------------
+
+... and similarly for a +PropertySource+:
+
+[source,java]
+.Freezing the current Configuration
+--------------------------------------------------
+PropertySource propertySource = ...;
+PropertySource frozenSource = FrozenPropertySource.of(propertySource);
+--------------------------------------------------
+
+
+
+=== SPIs
+
+This component also defines an additional SPI, which allows to adapt the implementation of the main +ConfigEventManager+
+singleton. This enables, for example, using external eventing systems, such as CDI, instead of the default provided
+simple SE based implementation. As normal, implementation must be registered using the current +ServiceContext+
+active, by default using the Java +ServiceLoader+ mechanism.
+
+[source,java]
+.SPI: ConfigEventSpi
+--------------------------------------------------
+public interface ConfigEventManagerSpi {
+
+ <T> void addListener(ConfigEventListener l);
+ <T extends ConfigEvent> void addListener(ConfigEventListener l, Class<T> eventType);
+ void removeListener(ConfigEventListener l);
+ <T extends ConfigEvent> void removeListener(ConfigEventListener l, Class<T> eventType);
+ Collection<? extends ConfigEventListener> getListeners();
+ Collection<? extends ConfigEventListener> getListeners(Class<? extends ConfigEvent> eventType);
+
+ void fireEvent(ConfigEvent<?> event);
+ void fireEventAsynch(ConfigEvent<?> event);
+
+ long getChangeMonitoringPeriod();
+ void setChangeMonitoringPeriod(long millis);
+ boolean isChangeMonitorActive();
+ void enableChangeMonitor(boolean enable);
+}
+--------------------------------------------------
+
+
+Summarizing with the events module you can easily observe configuration changes, record the
+state of any configuration and compare configuration states to create and publish related
+change events.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_filter.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_filter.adoc b/content/documentation/extensions/mod_filter.adoc
new file mode 100644
index 0000000..670faa0
--- /dev/null
+++ b/content/documentation/extensions/mod_filter.adoc
@@ -0,0 +1,119 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: User Filtering
+
+toc::[]
+
+
+[[Optional]]
+== User Filtering (Extension Module)
+=== Overview
+
+The Tamaya filter module provides a simple singleton accessor that allows to explicitly add +PropertyFilter+ instances
+active on the current thread only. This can be very useful in many scenarios. Additionally this module adds
+standard filters that hide metadata entries when the full configuration map is accessed. When keys are accessed
+explicitily no filtering is applied and everything is visible.
+
+=== Compatibility
+
+The module is based on Java 7, so it will not run on Java 7 and beyond.
+
+
+=== Installation
+
+To benefit from configuration builder support you only must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-filter</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+
+=== The Extensions Provided
+
+Tamaya Filter comes basically with 3 artifacts:
+
+* The +org.apache.tamaya.filter.ConfigurationFilter+ provides several static methods to register +PropertyFilter+
+instances on the current thread.
+* The +org.apache.tamaya.filter.DefaultMetdataFilter+ is a +PropertyFilter+ with hides all entries starting with
+ an underscore ('_'), when a full property map is accessed.
+
+
+=== The ConfigurationFilter
+
+The accessor mentioned implements the API for for adding +PropertyFilters+ to the current thread (as thread local):
+
+[source, java]
+-----------------------------------------------
+public final class ConfigurationFilter implements PropertyFilter{
+
+ ...
+
+ /**
+ * Seactivates metadata filtering also on global map access for this thread.
+ * @see #clearFilters()
+ * @param active true,to enable metadata filtering (default).
+ */
+ public static void setFilterMetadata(boolean active);
+
+ /**
+ * Access the filtering configuration that is used for filtering single property values accessed.
+ * @return the filtering config, never null.
+ */
+ public static FilterContext getSingleFilterContext();
+
+ /**
+ * Access the filtering configuration that is used for filtering configuration properties accessed as full
+ * map.
+ * @return the filtering config, never null.
+ */
+ public static FilterContext getMapFilters();
+
+ /**
+ * Removes all programmable filters active on the current thread.
+ */
+ public static void clearFilters();
+
+ ...
+
+}
+-----------------------------------------------
+
+For using regular expression when filtering configuration keys a corresponding implementation of a +PropertyFilter+
+is part of this module, So you can add a customized filter as follows:
+
+[source, java]
+-----------------------------------------------
+try {
+ ConfigurationFilter.getMapFilters().addFilter(new myFilter());
+
+ // do your code with filtering active
+}
+finally {
+ // cleanup
+ ConfigurationFilter.clearFilters();
+}
+-----------------------------------------------
+
+The +FilterContext+ is a simple structure just providing some handy accessors to the dynamic thread-local
+managed filters:
+
+[source, java]
+-----------------------------------------------
+public final class FilterContext implements PropertyFilter {
+
+ public void addIncludes(PropertyFilter filter);
+ public void addExcludes(int pos, PropertyFilter filter);
+ public PropertyFilter removeFilter(int pos);
+ public void clearFilters();
+ public void setIncludes(PropertyFilter... filters);
+ public void setExcludes(Collection<PropertyFilter> filters);
+ public List<PropertyFilter> getFilters();
+
+}
+-----------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_formats.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_formats.adoc b/content/documentation/extensions/mod_formats.adoc
new file mode 100644
index 0000000..401a755
--- /dev/null
+++ b/content/documentation/extensions/mod_formats.adoc
@@ -0,0 +1,206 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: Formats
+
+toc::[]
+
+
+[[Core]]
+== Tamaya Formats (Extension Module)
+=== Overview
+
+Tamaya Formats is an extension module. Refer to the link:modules.html[extensions documentation] for further details.
+
+Tamaya Formats provides an abstraction for configuration formats provding the following benefits:
+
+* Parsing of resources in can be implemented separately from interpreting the different aspects/parts parsed. As an
+ example a file format can define different sections. Depending on the company specific semantics of the sections
+ a different set of +PropertySource+ instances must be created.
+* Similarly the configuration abstraction can also be used as an interface for integrating Tamaya with alternate
+ frameworks that provide logic for reading configuration files, such as Apache commons.configuration.
+
+=== Compatibility
+
+The module is based on Java 7, so it can be used with Java 7 and beyond.
+
+=== Installation
+
+To benefit from dynamic value resolution you only must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-formats</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+
+=== The Idea
+
+Formats should be reusable, meaning you should have to write a format parser only once and then be able to map the data read into whatever
+data structure (in our cases: property sources).
+
+==== ConfigurationData
+
+Configuration formats can be very different. Some are simple key/value pairs, whereas other also consist of multiple sections (e.g. ini-files) or
+hierarchical data (e.g. yaml, xml). This is solved in Tamaya by mapping the configuration read into a normalized intermediary format called
++ConfigurationData+:
+
+[source,java]
+.ConfigurationData
+-------------------------------------------------------
+public final class ConfigurationData {
+
+ public ConfigurationFormat getFormat();
+ public String getResource();
+
+ public Set<String> getSectionNames();
+ public Map<String,String> getSection(String name);
+
+ public boolean hasDefaultProperties();
+ public Map<String,String> getDefaultProperties();
+ public Map<String,String> getCombinedProperties();
+
+ public boolean isEmpty();
+}
+-------------------------------------------------------
+
+In detail the data read from a file is organized into _sections_ as follows:
+
+* with +getResource()+ and +getFormat()+ the underlying resource and the format that read this data can be accessed.
+* properties can be owned by
+ ** named sections
+ ** an (unnamed) default section
+* each section section contains a map of properties. Hereby the same key can be part of the default section and multiple
+ named sections, depending on the configuration format.
+* The method +getSectionNames()+ returns a set of all section names.
+* With +getSection(String name)+ a named section can be accessed.
+* With +getDefaultSection()+ the 'default' section can be accessed. This is a convenience method.
+* With +getCombinedProperties()+ a flattened entry map can be accessed built up (by default) out of
+ ** all entries from the default section, without any changes.
+ ** all entries from named sections, where the key for each entry is prefix with the section name and a '::' separator.
+* The configuration format used determines the mapping of configuration data read into this structure. The format
+ implementation can as well provide alternate implementations of how the data read should be mapped into the
+ combined properties map.
+
+
+==== ConfigurationFormat
+
+A ConfigurationFormat is basically an abstraction that reads a configuration resource (modelled by an InputStream) and
+creates a corresponding +ConfigurationData+ instance.
+
+[source,java]
+-------------------------------------------------------
+public interface ConfigurationFormat {
+
+ String getName();
+ boolean accepts(URL url);
+ ConfigurationData readConfiguration(String resource, InputStream inputStream);
+}
+-------------------------------------------------------
+
+
+=== How to tranform ConfigurationData into a PropertySource
+
+For for the conversion of +ConfigurationData+ into a +PropertySource+ different approaches can be useful:
+
+. The +ConfigurationFormat+ that reads the data can provides all properties read either as sectioned properties
+ or/and as default properties. The most simple cases is, where all properties have been added as 'default'
+ properties. In this case the default properties can be used as the property sources properties without any change.
+. If the format did also add section based properties, the combined properties returned can be used, hereby
+ replacing the '::' separator with a '.' separator.
+. In all other cases a custom mapping is useful, which can be acomplished by using the +MappedConfigurationDataPropertySource+
+ and overriding the +Map<String,String> populateData(ConfigurationData data)+ method.
+
+In most cases the usage of a +FlattenedDefaultPropertySource+, is a good choice to start. This class
+provides a convenient default mapping and also allows to customized the mapping easily:
+
+[source,java]
+-------------------------------------------------------
+ConfigurationData data = ...;
+FlattenedDefaultPropertySource ps = new FlattenedDefaultPropertySource(data){
+ protected Map<String, String> populateData(ConfigurationData data) {
+ ...
+ }
+};
+-------------------------------------------------------
+
+Nevertheless, depending on the context, where a configuration source was read (classloader, time, source etc.) the
+resulting properties can have different semnatics, especially different priorities. Also section
+names may be mapped into different ordinals instead of using them as key prefixes (e.g. imagine configuration formats
+with a 'default', 'main', and 'overrides' sections). For such more complex or custom cases no simple mapping
+can be defined. Consequently the functionality mapping the normalized +ConfigurationData+ read to the
+appropriate collection of +PropertySource+ instances must be implemented.
+
+
+=== Examples
+
+==== Mapping ini-Files
+
+Consider the following ini-file:
+
+[source,listing]
+.Example.ini
+-------------------------------------------------------
+a=valA
+a.b=valB
+
+[section1]
+aa=sectionValA
+aa.b.c=SectionValC
+
+[section2]
+a=val2Section2
+-------------------------------------------------------
+
+This file content coud be mapped to the following structure:
+
+[source,listing]
+.Mapping of Example.ini
+-------------------------------------------------------
+a=valA
+a.b=valB
+section1::valA=sectionValA
+section1::a.b.c=SectionValC
+section2::a=val2Section2
+-------------------------------------------------------
+
+Nevertheless from the +ConfigurationData+ instance a more complex algorithm can access all the different parts:
+
+* the_default_ properties (a, a.b)
+* the section +section1+, with properties +aa, aa.b.c+
+* the section +section2+, qith properties +a+
+
+
+==== Mapping xml-Files
+
+The same concept can also be applied to xml-files. Consider the following configuration file:
+
+[source,xml]
+.Example.conf
+-------------------------------------------------------
+<config>
+ <default>
+ <a>valA</a>
+ <a.b>valB</a.B>
+ </default>
+
+ <section id="section1">
+ <param id="aa">sectionValA</aa>
+ <param id="aa.b.c">SectionValC</aa.b.c>
+ </section>
+ <section id="section2">
+ <param id="a">val2Section2</aa>
+ </section>
+</config>
+-------------------------------------------------------
+
+This file basically describes the same configuration as the ini-based version we have seen before. The formats
+module hereby ships with 3 format classes:
+
+* +PropertiesFormat+ providing support for .properties files.
+* +PropertiesXmlFormat+ providing support for xml.property files.
+* +IniConfiguratonFormat+ providing support for xml.property files.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_functions.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_functions.adoc b/content/documentation/extensions/mod_functions.adoc
new file mode 100644
index 0000000..6e2c172
--- /dev/null
+++ b/content/documentation/extensions/mod_functions.adoc
@@ -0,0 +1,108 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: Functions
+
+toc::[]
+
+[[Core]]
+== Tamaya Functions (Extension Module)
+=== Overview
+
+Tamaya Functions is an extension module. Refer to the link:modules.html[extensions documentation] for further details.
+
+Tamaya Functions provides several functional extensions using the +ConfigOperator,ConfigQuery+ extension points. Most
+functional extension are accessible from the +ConfigurationFunction+ singleton. When importing its methods statically
+one can use the methods to achieve some interesting effects, e.g.
+
+[source,java]
+-------------------------------------------------------------------
+import static org.apache.tamaya.functions.ConfigurationFunctions.*;
+
+Set<String> sections = ConfigurationProvider.getConfiguration().with(areas("a", false).with(transitiveAreas());
+-------------------------------------------------------------------
+
+The expression above returns all fully qualified section names that are child sections of the root section 'a'.
+So given the entries +a.b.entry1, a.b.entry2, a.a.entry3, a.b.c.entry4+ the reult would be +a, a.a, a.b, a.b.c+.
+
+=== Compatibility
+
+The module is based on Java 7, so it can be used with Java 7 and beyond.
+
+=== Installation
+
+For using the functionality shown in this document you only must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-functions</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+
+=== The Provided Functions
+
+==== Functions on +ConfigurationFunctions+
+
+The following sections explain the provided functions defined by +ConfigurationFunctions+ singleton.
+
+* *ConfigOperator filter(PropertyMatcher matcher)* creates a +ConfigOperator+ that creates a +Configuration+
+ containing only keys that are selected by the given _matcher predicate_. The +PropertyMatcher+ hereby allows to evaluate not only
+ the _key_, but also the _value_.
+* *ConfigOperator map(KeyMapper keyMapper)* creates a +ConfigOperator+ that maps the keys as defined
+ by the given _keyMapper_.
+* *ConfigOperator section(String section)* creates a +ConfigOperator+ that creates a +Configuration+ containing only
+ entries that are direct or indirect members of the given section.
+* *ConfigOperator section(String areaKey, boolean stripKeys)* creates a +ConfigOperator+ that creates a +Configuration+
+ containing only entries that are direct or indirect members of the given section. Hereby _stripKeys_ allows to determine
+ if the returned entries should be relative to the search criteria {{stripKeys=true}} or absolute keys.
+* *isKeyInSection(String section, String sectionKey)* allows to easily determine if a given _key_ is a direct or indirect member
+ of a given section.
+* *boolean isKeyInSections(String key, String... sectionKeys)* allows to easily determine if one key of given
+ _key_ is a direct or indirect member of at least one of the given _sectionKeys_.
+* *ConfigQuery<Set<String>> sections()* allows to query all the contained fully qualified section names (the ones that
+ also have parameters present).
+* *ConfigQuery<Set<String>> transitiveSections()* allows to query all the contained fully qualified section names,
+ including the transitive closure of sections.
+* *ConfigQuery<Set<String>> sections(final Predicate<String> predicate)* allows to query all the contained fully
+ qualified section names that are selected by the given _predicate_.
+* *ConfigQuery<Set<String>> sections(final Predicate<String> predicate)* allows to query all the contained fully
+ qualified section names that are selected by the given _predicate_, including the transitive closure of sections
+ identified.
+* *ConfigOperator sectionsRecursive(String... sectionKeys)* provides a +ConfigOperator+ that filters all sections identified
+ by the given _sectionKeys_ and its child sections.
+* *ConfigOperator sectionRecursive(final boolean stripKeys, final String... sectionKeys)* provides a +ConfigOperator+
+ that filters all sections identified by the given _sectionKeys_ and its child sections. _stripKeys_ allows to
+ determine if the resulting configuration should be relative to the selected areas ({{stripKeys=true}}) or
+ absolute (filtering only).
+* *ConfigQuery<String> jsonInfo()* returns a query that converts a +Configuration+ into a JSON formatted +String+
+ representation.
+
+
+==== Functions on +PropertySourceFunctions+
+
+The following sections explain the provided functions defined by +PropertySourceFunctions+ singleton.
+
+* *PropertySource addMetaData(PropertySource propertySource, Map<String,String> metaData)* Creates a new +PropertySource+
+ with the given metadata added.
+* *boolean isKeyInSection(String key, String sectionKey)* Checks if the given _key_ is a direct or indirect member of
+ one of the given _sectionKey_.
+* *boolean isKeyInSections(String key, String... sectionKeys)* Checks if the given _key_ is a direct or indirect member of
+ one of one of the given _sectionKeys_.
+* *Set<String> sections(Map<String, String> properties)* Extracts the sections from the given properties.
+* *Set<String> transitiveSections(Map<String, String> properties)* Extracts the transitive sections from the given
+ properties.
+* *Set<String> sections(Map<String, String> properties, final Predicate<String> predicate)* Extracts the sections
+ from the given properties, also filtering with the given predicate.
+* *Set<String> transitiveSections(Map<String, String> properties, Predicate<String> predicate)* Extracts the transitive
+ sections from the given properties, also filtering with the given predicate.
+* *Map<String,String> sectionsRecursive(Map<String, String> properties, String... sectionKeys)* Creates w +PropertySource+
+ only containing the sections that a direct or indirect children of the given _sectionKeys_.
+* *Map<String,String> sectionRecursive(Map<String, String> properties, boolean stripKeys, String... sectionKeys)* Creates w +PropertySource+
+ only containing the sections that a direct or indirect children of the given _sectionKeys_. With _stripKeys_ one can
+ select of the returned values should be relative to its selection of be fully qualified.
+* *String stripSectionKeys(String key, String... sectionKeys)* This function strips away the matching section key as given
+ in _sectionKeys_ from a given _key_.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_injection.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_injection.adoc b/content/documentation/extensions/mod_injection.adoc
new file mode 100644
index 0000000..941351e
--- /dev/null
+++ b/content/documentation/extensions/mod_injection.adoc
@@ -0,0 +1,430 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: Injection
+
+toc::[]
+
+
+[[Core]]
+== Tamaya Injection (Extension Module)
+=== Overview
+
+Tamaya Injection is an extension module. Refer to the link:modules.html[extensions documentation] for further details
+about modules.
+
+Tamaya Injection provides functionality for injecting configured values into beans, or creating configuration
+template instances.
+
+Inversion of Control (aka IoC/the Hollywood Principle) has proven to be very useful and effective in avoiding boilerplate
+code. In Java there are different frameworks available that all provide IoC mechanisms. Unfortunately IoC is not a
+built-in language feature. So for a portable solution that works also in Java SE Tamaya itself has to provide the
+according injection services. This module adds this functionality to Tamaya.
+
+=== Compatibility
+
+The module is based on Java 7, so it can be used with Java 7 and beyond.
+
+=== Installation
+
+Basically Tamaya's injection API is deployed as API artifact:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection-api</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+To use injection with Java SE you must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+Similarly there are other injection implementations available, targetig platforms such as
+
+* Spring, Spring Boot
+* Java EE/CDI
+* OSGI, Apache Felix/Apache Karaf
+
+
+=== Core Concepts
+
+Basically you annotate fields or methods in your beans with +@Config+ to enable configuration injection. Tamaya
+additionally defines further annotations that allo you to define additional aspects such as default values, custom
+converters etc. The following example illustrates the basic functionality:
+code snippet:
+
+[source,java]
+.Annotated Example Class
+--------------------------------------------
+package foo.bar;
+
+public class ConfiguredClass {
+
+ // resolved by default, using property name, class and package name: foo.bar.ConfiguredClass.testProperty
+ private String testProperty;
+
+ // Trying to resolve mutiple keys, with a default value, if none could be resolved
+ @Config({"a.b.c.key1","a.b.legacyKey",area1.key2"}, defaultValue="The current \\${JAVA_HOME} env property is ${env:JAVA_HOME}.")
+ String value1;
+
+ // Typical case
+ @Config("a.b.c.key2")
+ private int value2;
+
+ // resolved by default as foo.bar.ConfiguredClass.accessUrl
+ // Using a (default) String -> URL converter
+ @Config(defaultValue="http://127.0.0.1:8080/res/api/v1/info.json")
+ private URL accessUrl;
+
+ // Config injection disabled for this property
+ @NoConfig
+ private Integer int1;
+
+ // Overriding the String -> BigDecimal converter with a custom implementation.
+ @Config("BD")
+ @WithPropertyConverter(MyBigDecimalRoundingAdapter.class)
+ private BigDecimal bigNumber;
+
+ ...
+}
+--------------------------------------------
+
+
+When configuring data or configuration classes it is also possible to auto-inject the fields identified. For activating
+this feature a class must be annotated with +@ConfigAutoInject+:
+
+[source, java]
+. An autoinjected bean class
+--------------------------------------------
+package a.b;
+
+@ConfigAutoInject
+public final class Tenant {
+ private int id;
+ private String name;
+ private String description;
+ @NoConfig // prevents auto injection for this field
+ private String id2;
+
+ public int getId(){
+ return id;
+ }
+ public String getName(){
+ return name;
+ }
+ public String getDescription(){
+ return description;
+ }
+}
+--------------------------------------------
+
+These examples do not show all possibilities provided. Configuring instance of these
+class using Tamaya is very simple: Just pass the instance to Tamaya to let
+Tamaya inject the configuration (or throw a +ConfigException+, if this is not possible):
+
+[source,java]
+.Configuring the +ConfiguredClass+ Instance
+--------------------------------------------
+ConfiguredClass classInstance = new ConfiguredClass();
+ConfigurationInjector.configure(configuredClass);
+
+Tenant tenant = new Tenant();
+ConfigurationInjector.configure(tenant);
+--------------------------------------------
+
+NOTE: Configuration injection works similarly, when used with other integration modules, e.g. when Tamaya is used
+with CDI, Spring or within an OSGI container. For further details refer also to the corresponding integration module's
+documentation.
+
+
+=== The Annotations in detail
+==== The ConfigurationInjector
+
+The +ConfigurationInjector+ interface provides methods that allow any kind of instances to be configured
+by passing the instances to +T ConfigurationInjector.getInstance().configure(T);+. The classes passed
+hereby must not be annotated with +@Config+ for being configurable. By default Tamaya
+tries to determine configuration for each property of an instance passed, using the following resolution policy:
+
+Given a class +a.b.MyClass+ and a field +myField+ it would try to look up the following keys:
+[source, listing]
+--------------------------------------------
+a.b.MyClass.myField
+a.b.MyClass.my-field
+MyClass.myField
+MyClass.my-field
+myField
+my-field
+--------------------------------------------
+
+So given the following properties:
+
+[source, properties]
+--------------------------------------------
+a.b.Tenant.id=1234
+Tenant.description=Any kind of tenant.
+name=<unnamed>
+--------------------------------------------
+
+
+==== Accessing Supplier instances
+
+In many cases you want to create a supplier that simply creates instances that are correctly configured as defined
+by the current context. This can be done using +Suppliers+:
+
+[source, java]
+--------------------------------------------
+Supplier<Tenant> configuredTenantSupplier = ConfigurationInjector.getInstance().getConfiguredSupplier(
+ new Supplier<Tenant>(){
+ public Tenant get(){
+ return new Tenant();
+ }
+});
+--------------------------------------------
+
+With Java 8 it's even more simple:
+
+[source, java]
+--------------------------------------------
+Supplier<Tenant> configuredTenantSupplier = ConfigurationInjector.getInstance().getConfiguredSupplier(
+ Tenant::new);
+--------------------------------------------
+
+Hereby this annotation can be used in multiple ways and combined with other annotations such as
++@WithLoadPolicy+, +@WithConfigOperator+, +@WithPropertyConverter+.
+
+==== Minimal Example
+
+To illustrate the mechanism below the most simple variant of a configured class is given:
+
+[source,java]
+.Most simple configured class
+--------------------------------------------
+pubic class ConfiguredItem{
+ @Config
+ private String aValue;
+}
+--------------------------------------------
+
+When this class is configured, e.g. by passing it to +ConfigurationInjector.getInstance().configure(Object)+,
+the following is happening:
+
+* The current valid +Configuration+ is evaluated by calling +Configuration cfg = ConfigurationProvider.getConfiguration();+
+* The current property value (String) is evaluated by calling +cfg.get("aValue");+ for each possible key (mutliple
+ keys are possible).
+* if not successful, an error is thrown (+ConfigException+)
+* On success, since no type conversion is involved, the value is injected.
+
+==== Using @DefaultValue
+
+In the next example we explicitly define the property value:
+[source,java]
+--------------------------------------------
+pubic class ConfiguredItem{
+
+ @Config(value={"aValue", "a.b.value","a.b.deprecated.value"}, defaultValue="${env:java.version}")
+ private String aValue;
+}
+--------------------------------------------
+
+==== Inject a DynamicValue Property
+
+Within this example we evaluate a dynamic value. This mechanism allows you to listen for configuration changes and to
+commit new values exactly, when convenient for you.
+
+[source,java]
+--------------------------------------------
+pubic class ConfiguredItem{
+
+ @Config(value={"aValue", "a.b.value","a.b.deprecated.value"}, defaultValue="${env:java.version}")
+ private DynamicValue aValue;
+}
+--------------------------------------------
+
+The +DynamicValue+ provides you the following functionality:
+
+[source,java]
+--------------------------------------------
+public interface DynamicValue<T> {
+
+ enum UpdatePolicy{
+ IMMEDIATE,
+ EXPLCIT,
+ NEVER,
+ LOG_AND_DISCARD
+ }
+
+ T get();
+ T getNewValue();
+ T evaluateValue();
+ T commitAndGet();
+ void commit();
+ void discard();
+ boolean updateValue();
+
+ void setUpdatePolicy(UpdatePolicy updatePolicy);
+ UpdatePolicy getUpdatePolicy();
+ void addListener(PropertyChangeListener l);
+ void removeListener(PropertyChangeListener l);
+
+ boolean isPresent();
+ T orElse(T other);
+ // Enabled with Java 8
+ // T orElseGet(ConfiguredItemSupplier<? extends T> other);
+ // <X extends Throwable> T orElseThrow(ConfiguredItemSupplier<? extends X> exceptionSupplier) throws X;
+
+}
+--------------------------------------------
+
+Summarizing this class looks somehow similar to the new +Optional+ class added with Java 8. It provides
+a wrapper class around a configured instance. Additionally this class provides functionality that gives
+active control, to manage a configured value based on a ++LoadingPolicy+:
+
+* +IMMEDEATE+ means that when the configuration system detects a change on the underlying value, the new value
+ is automatically applied without any further notice.
+* +EXPLICIT+ means that a new configuration value is signalled by setting the +newValue+ property. if +getNewValue()+
+ returns a non null value, the new value can be applied by calling +commit()+. You can always access the newest value,
+ hereby implicitly applying it, by accessing it via +commitAndGet()+. Also it is possible ti ignore a change by calling
+ +discard()+.
+* +NEVER+ means the configured value is evaluated once and never updated. All changes are silently discarded.
+* +LOG_AND_DISCARD+ similar to +NEVER+, but changes are logged before they are discarded.
+
+Summarizing a +DynamicValue+ allows you
+
+* to reload actively updates of configured values.
+* update implicitly or explicitly all changes on the value.
+* add listeners that observe changes of a certain value.
+
+Dynamic values also allow on-the-fly reevaluation of the value by calling +evaluateValue()+. Hereby the value of the
+instance is not changed.
+
+
+==== Ommitting Injection using @NoConfig
+
+Adding the @NoConfig annotation prevents a field or method to be auto-injected from
+configuration. This is especially useful, if a type is annotated as @ConfigAutoInject with auto-confiuration
+turned on as follows:
+
+[source,java]
+--------------------------------------------
+@ConfigAutoInject
+pubic class ConfiguredItem{
+
+ @NoConfig
+ private transient int sum;
+
+ private String a;
+ private String b;
+ Private String c;
+}
+--------------------------------------------
+
+In this case the fields +a,b,c+ are configured, whereas the field +sum+ is ignored regarding
+configuration.
+
+==== Adding custom operators using @WithConfigOperator
+
+The @WithConfigOperator annotation allows you define a class of type +ConfigOperator+, to being applied
+to the final +Configuration+, BEFORE the value is injected. This can be used for various use cases, e.g.
+filtering or validating the visible properties for a certain use case.
+
+[source,java]
+--------------------------------------------
+
+@WithConfigOperator(MyConfigView.class)
+pubic class ConfiguredItem{
+
+ @Config
+ private String a;
+
+}
+--------------------------------------------
+
+
+==== Adding custom property converters using @WithPropertyConverter
+
+The @WithPropertyConverter annotation allows you to define a class of type +PropertyConverter+, to be applied
+on a property configured to convert the String value to the expected injected type. This can be used for
+various use cases, e.g. adding custom formats, config models, decryption.
+
+[source,java]
+--------------------------------------------
+
+pubic class ConfiguredItem{
+
+ @WithPropertyConverter(MyPropertyConverter.class)
+ @Config
+ private String a;
+
+}
+--------------------------------------------
+
+
+==== Defining the loading policy to be applied to configured values using @WithLoadPolicy
+
+The @WithLoadPolicy annotation allows to define the loading behaviour to be applied. The +LoadPolicy+
+enum hereby defines the various loading modes.
+
+[source,java]
+--------------------------------------------
+
+@WithLoadPolicy(LoadPolicy.NEVER)
+pubic class BootTimeStableConfig{
+
+ @WithPropertyConverter(MyPropertyConverter.class)
+ @Config
+ private String a;
+
+}
+--------------------------------------------
+
+
+=== Configuration Events
+
+Similar to CDI Tamaya publishes Configuration events, when instances were configured. It depends on the effective
+event backend in use, if and how events are published:
+
+* when you have the CDI extension active events are published using the default CDI event mechanism.
+* in all other scenarios events are delegated to the +tamaya-events+ module, if available,
+* if no event delegation is available no events are published.
+
+The event published is very simple:
+
+[source,java]
+--------------------------------------------
+public interface ConfiguredType {
+ Class getType();
+ String getName();
+ Collection<ConfiguredField> getConfiguredFields();
+ Collection<ConfiguredMethod> getConfiguredMethods();
+ void configure(Object instance, Configuration config);
+}
+
+
+public interface ConfiguredField {
+ Class<?> getType();
+ Collection<String> getConfiguredKeys();
+ String getName();
+ String getSignature();
+ Field getAnnotatedField();
+ void configure(Object instance, Configuration config);
+}
+
+public interface ConfiguredMethod {
+ Collection<String> getConfiguredKeys();
+ Class<?>[] getParameterTypes();
+ Method getAnnotatedMethod();
+ String getName();
+ String getSignature();
+ void configure(Object instance, Configuration config);
+}
+----------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_jodatime.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_jodatime.adoc b/content/documentation/extensions/mod_jodatime.adoc
new file mode 100644
index 0000000..4ebae7a
--- /dev/null
+++ b/content/documentation/extensions/mod_jodatime.adoc
@@ -0,0 +1,48 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: JodaTime
+
+toc::[]
+
+[[Core]]
+== Tamaya JodaTime (Extension Module)
+
+=== Overview
+
+Tamaya JodaTime is an extension module to support the usage of http://www.joda.org/joda-time/[Joda-Time]
+in conjunction with Tamaya. Tamaya JodaTime defines some additional property
+converters to retrieve Joda-Time types from a given configuration.
+
+Refer to the link:modules.html[extensions documentation] for further details
+about modules.
+
+tools to locate resources in your classpath or file system based on descriptive
+ant-styled resource patterns. To use this module add the following dependency:
+
+[source, listing]
+-----------------------------------------------
+<dependency>
+ <grooupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-jodatime</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+After adding this dependency to your project you can retrieve
+Joda-Time based values directly from a given configuration.
+
+[source,java]
+-----------------------------------------------
+Configuration configuration = ConfigurationProvider.getConfiguration();
+
+DateTime pit = configuration.get("pointInTime", DateTime.class)
+-----------------------------------------------
+
+=== Specifying date and time values
+
+To be written.
+
+=== Specifing periods and durations
+
+To be written.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_json.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_json.adoc b/content/documentation/extensions/mod_json.adoc
new file mode 100644
index 0000000..66c12fa
--- /dev/null
+++ b/content/documentation/extensions/mod_json.adoc
@@ -0,0 +1,62 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: Builder
+
+toc::[]
+
+
+[[BuilderCore]]
+== Tamaya JSON (Extension Module)
+=== Overview
+
+The Tamaya json module provides support for reading configuration using JSON format:
+
+
+=== Compatibility
+
+The module is based on Java 7, so it will run on Java 7 and beyond.
+
+
+=== Installation
+
+To benefit from configuration builder support you only must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-json</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+This extension also transitively requires the +tamaya.formats+ module.
+
+=== Reading configuration in JSON
+
+For reading JSON based onfiguration most easily a +JSONFormat+ can be provided:
+
+[source, java]
+-----------------------------------------------
+ConfigurationData dataRead = ConfigurationFormats.readConfig(
+ getClassLoader().getResource("myFileConfig.json"), new JSONFormat()));
+-----------------------------------------------
+
+=== Examples
+
+The JSON module adds instances of +ConfigurationFormat+ so JSON configuration can be read and mapped to the
+according property maps. E.g. the following file is a simple and correct JSON configuration:
+
+[source,listing]
+----------------------------------------------------------------
+{
+ "a" : "A",
+ "b" : "B",
+ "c" : "C",
+ "d" : {
+ "o" : "O",
+ "p" : "P"
+ }
+}
+----------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_management.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_management.adoc b/content/documentation/extensions/mod_management.adoc
new file mode 100644
index 0000000..b912747
--- /dev/null
+++ b/content/documentation/extensions/mod_management.adoc
@@ -0,0 +1,92 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: JMX Management Access
+
+toc::[]
+
+
+[[ExtModel]]
+== Tamaya Management (JMX Support) (Extension Module)
+=== Overview
+
+The Tamaya management module provides support for registering a JMX management bean for accessing configuration.
+
+=== Compatibility
+
+The module is based on Java 7, so it will run on Java 7 and beyond.
+
+
+=== Installation
+
+To benefit from configuration builder support you only must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-management</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+
+=== The ManagedConfigMBean bean
+
+The management model defines the MBean of type +ManagedConfigMBean+ as follows:
+
+
+[source,java]
+-----------------------------------------------------------------------------
+public interface ManagedConfigMBean {
+ String getJsonConfigurationInfo();
+ String getXmlConfigurationInfo();
+ Map<String, String> getConfiguration();
+ Map<String, String> getSection(String area, boolean recursive);
+ Set<String> getSections();
+ Set<String> getTransitiveSections();
+ boolean isSectionExisting(String area);
+ default boolean isSectionEmpty(String area);
+}
+-----------------------------------------------------------------------------
+
+* +getJsonConfigurationInfo,getXmlConfigurationInfo+ return a JSON or XML representation of the
+current configuration.
+* +getConfiguration+ access the current configuration properties.
+* +getSection+ allows to extract all entries below a certain subkey. With _recursive_ the query
+ will not only return direct children, but also recursively walk down all subsection of the
+ given section key.
+* +getSections+ returns all current known section names.
+* +getTransitiveSections+ return all sections, but also adds all transitive subsection as single
+ entries to the set as well.
+* +isSectionExisting+ and +isSectionEmpty+ allow for quering if entries are present under the given
+ section keys.
+
+=== Registering the ManagedConfigMBean
+
+For registering the current +ManagedConfigMBean+ instance to the current MBean platform server, the
+following static methods are available:
+
+[source,java]
+-----------------------------------------------------------------------------
+public final class ConfigManagementSupport{
+
+ private JMXSupport(){}
+
+ public static ObjectName registerMBean();
+ public static ObjectName registerMBean(String context);
+ public static ObjectName unregisterMBean();
+ public static ObjectName unregisterMBean(String context);
+}
+-----------------------------------------------------------------------------
+
+* +registerMBean+ creates a new +ManagedConfigMBean+ instance using the +ServiceContextManager+
+ and registers it. Optionally an additional _context_ parameter can be passed, which allows
+ to register the management bean for different classloaders, e.g. for different
+ ears.
+* +unregisterMBean+ does the oppsite than registering obviously.
+
+NOTE: The instance of +ManagedConfigMBean+ to be created and registered is evaluated by use og the
+ +ServiceContextManager+. So you can replace the bean implementation by registering your
+ overriding implementation using the current +ServiceContext+ (by default using
+ +java.util.ServiceLoader+ and +@Priority+ annotation.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_metamodel-staged.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_metamodel-staged.adoc b/content/documentation/extensions/mod_metamodel-staged.adoc
new file mode 100644
index 0000000..cf02806
--- /dev/null
+++ b/content/documentation/extensions/mod_metamodel-staged.adoc
@@ -0,0 +1,58 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: Staged PropertySources
+
+toc::[]
+
+
+[[Remote]]
+== Tamaya Metamodel: Staged PropertySources (Extension Module)
+=== Overview
+
+The Tamaya Staged PropertySources extension provides a base class and default implementation for loading
+multistaged configuration easily from a common configuration location.
+
+
+=== Compatibility
+
+The module is based on Java 7, so it will run on Java 7 and beyond.
+
+
+=== Installation
+
+To benefit from Tamaya CDI integration you only must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext.metamodels</groupId>
+ <artifactId>tamaya-metamodel.staged</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+The component will not register any components. The component basically provides the following options:
+
+* Use it as default configuration extension. Hereby you should define your stages in use by setting the
+ +env.STAGE+ system property with the stages to be loaded in order of precedence (most significant last),
+ e.g. +sys-env,DEFAULTS,TEST,DEVELOPMENT. _Additionally_ you must register
+ +org.apache.tamaya.staged.StagedConfigPropertiesProvider+ as in
+
+--------------------------------------------------------------
+META-INF
+|_service
+ |_org.apache.tamaya.spi.PropertySourceProvider
+--------------------------------------------------------------
+
+Tamaya will then load .properties files from +System.getenv(),
+classpath:DEFAULTS.properties, classpath:TEST.properties+ and
++classpath:DEVELOPMENT.properties+
+
+* For more advanced requirements, such as alternate locations, patterns or formats, you can also extend one of the
+ provided classes (+org.apache.tamaya.staged.StagedConfigPropertiesProvider+,
+ ** +BaseStagedPropertySourceProvider+). Extending provides features such as:
+
+ ** Defining a prefix for all entries provided/loaded.
+ ** Using alternate locations or formats.
+ ** Defining the ordinals used.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_model.adoc
----------------------------------------------------------------------
diff --git a/content/documentation/extensions/mod_model.adoc b/content/documentation/extensions/mod_model.adoc
new file mode 100644
index 0000000..e454eb1
--- /dev/null
+++ b/content/documentation/extensions/mod_model.adoc
@@ -0,0 +1,451 @@
+:jbake-type: page
+:jbake-status: published
+
+= Apache Tamaya -- Extension: Model Documentation and Validation
+
+toc::[]
+
+
+[[ExtModel]]
+== Tamaya Model Documentation and Validation (Extension Module)
+=== Overview
+
+The Tamaya model module provides support for documenting configuration and validating configuration read and processed
+against this model. Documentation and config models can be provided in different ways:
+
+* as separate meta-model documents
+* by providers that check classes/packages for configuration annotations (planned)
+
+
+=== Compatibility
+
+The module is based on Java 7, so it will not run on Java 7 and beyond.
+
+
+=== Installation
+
+To benefit from configuration builder support you only must add the corresponding dependency to your module:
+
+[source, xml]
+-----------------------------------------------
+<dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-model</artifactId>
+ <version>{tamaya_version}</version>
+</dependency>
+-----------------------------------------------
+
+
+=== Describing the Configuration Meta-Model
+
+Basically configuration is modelled using key, value-pairs. Looking at a keys
++a.b.c.param1+ and +a.b.c.param2+ the following concepts can be used to defined/describe
+configuration:
+
+. the _configuration section:_ In our case this equals to +a.b.c+, which itself also includes the
+ transitive entries +a.b+ and +a+.
+. the _configuration parameter:_ Basically parameters are adressed using their fully qualified names,
+ which equals to the containing section name and the relative parameter name, separated by the dor separator.
+ In the above example +a.b.c.param1+ and +a.b.c.param2+ are the fully qualified parameter names.
+
+Now with only these 2 concepts a simple configuration meta-model can be defined as
+
+* a meta-model's name, used just for grouping different meta-models and entries to better separate
+ descriptions, e.g. in a management console or generated configuration documentation site.
+* a set of sections.
+* a set of parameters.
+* Both, sections (+.model.target=Section+) as well as parameter models (+.model.target=Parameter+)
+ ** can be modelled by a meta-data entry, by default +_my.config.key.model+.
+ ** may be required, or optional (+.model.required=true|false+)
+ ** may have an optional description
+* Parameters additionally have
+ ** a _type_ (+.model.type=Classname+), described by the fully qualified class name, into which any configured (String)
+ value must be convertable into. If no type is configured +java.ui.lang.String+ is assumed as default.
+ ** an optional regular expression that can be used to validate the +String+ values returned from a
+ configuration (+.model.expression=regexpression+).
+
+Given these concepts a configuration can be fully described. Entries that are not contained in one of the given
+sections (or its children), or parameters not described or marked as valid (e.g. for dynamic configModels of
+a section), are called _undefined_. Undefined parameters should be grouped with its parent section. Each section, as
+well as all parent sections, including transitive) of any parametet read, should similarly marked as undefined, if and
+only if
+
+. the section itself is (directly) _undefined_
+. the section is not a _super section_ of a defined section.
+
+As en example the section definition of +a.b.c+ also implicitly includes the sections +a.b+ and +a+ to be defined
+sections, despite the fact that section properties, such as description and custom configModels are not inherited to
+its parent, or child section.
+
+
+=== Defining Meta-Configuration Model
+
+The configuration meta-model is defined by simple configuration meta-data entries. The section for all model
+configuration by default is called +model+, which results in entries such as +_my.config.key.model.target=Section+.
+Within this section fully qualified configuration keys defines
+which part of the configuration is targeted by certain entries.
+
+==== Defining Sections
+
+First we start to define some configuration sections, the example below starts with the most important
+variants supported:
+
+[source,listing]
+-------------------------------------------------------------------------------
+# Metamodel information
+_model.provider=ConfigModel Extension
+
+# org.mycompany.root (optional section)
+_org.mycompany.root.model.target=Section
+_org.mycompany.root.model.description=Root section defining my company configuration.
+
+# org.mycompany.security (required section)
+_org.mycompany.security.model.target=Section
+_org.mycompany.security.model.required=true
+_org.mycompany.security.model.description=Security related settings.\
+ refer for further details to XXX.
+
+# minmal section
+_minimal.model.target=Section
+
+# custom validated section
+_validated.model.target=Section
+_validated.model.validator=org.apache.tamaya.model.TestValidator
+-------------------------------------------------------------------------------
+
+Above +org.mycompany.root+ transitively defines 3 sections:
+
+* org
+* org.mycompany
+* org.mycompany.root
+
+All sections are optional. Additionally the model above also defines a required section +org.mycompany.security+.
+Required sections are checked so the section is not empty. It is not checked for any specific parameter hereby,
+only the existance of any child parameter is validated.
+
+The _class_ attribute has to be defined for any section definition, because if not set a model entry is, by default,
+defined to be a parameter configModel entry. Given above the entry for the section +minimal+ shows such a minimal
+entry.
+
++validated+ defines a section, which is validated through a customizable validator. Hereby an ordered list of validators
+can be provided, separated by commas.
+
+
+==== Defining Parameters
+
+Similarly parameters also can be defined:
+
+[source,listing]
+-------------------------------------------------------------------------------
+# org.mycompany.root.name (required parameter)
+_org.mycompany.root.name.model.target=Parameter
+_org.mycompany.root.name.model.required=true
+_org.mycompany.root.name.model.description=The company's name, also used in the application's main header.
+
+# org.mycompany.security (required parameters)
+_org.mycompany.security.uid.model.required=true
+_org.mycompany.security.uid.model.description=The user id.
+_org.mycompany.security.realm.model.required=true
+_org.mycompany.security.realm.model.validator=org.apache.tamaya.model.RealmValidator
+_org.mycompany.security.realm.model.description=The security realm required.
+_org.mycompany.security.tokenid.model.description=The token id, if the token service is used (optional).
+
+# A minmal parameter
+_minimalClass.model.target=Class
+-------------------------------------------------------------------------------
+
+Similarly as when defining section also parameter entries define transitively its containing sections. E.g.
+the entry above for +org.mycompany.security.realm+ also defines the following sections (as optional).
+
+* org
+* org.mycompany
+* org.mycompany.security
+
+Additional entries for section, e.g. configModels to be done, can be added as described in the previous section,
+but are optional.
+
+Since the parameter is the default type for model entries, a minmal parameter model entry only only needs it's
+parameter type to be defined. In the example above we define a parameter +minimalClass+ of type +Class+.
+Types hereby are fully qualified class names, whereas as 'java.ui.lang' for built-in language types can be
+ommitted.
+
+==== Model Locations
+
+By default the configuration model can be defined at the following locations:
+
+* +classpath*:META-INF/configmodel.properties+, separate to the current +Configuration+. This functionality is enabled
+ by default, but can be disabled by adding +org.apache.tamaya.model.default.enabled=false+ to your current
+ +Configuration+.
+* +implicitly as part of the current +Configuration+. THis can be disabled by setting
+ the +org.apache.tamaya.model.integrated.enabled+ configuration poarameter to +false+.
+* customized by configuring the +org.apache.tamaya.model.resources+ in the current +Configuration+. This
+ parameter allows to define the locations from where the model extension is trying to read the
+ model configuration. If the _resources extension_ is available in your system it is used to
+ evaluate the locations. If not the default +Classloader.getResources+ command is issued. Also it
+ is required that the _formats extension_ is available, since this is used to effectively read the
+ data. This extension also allows you to use alternate representation formats such as +ini, xml, yml, json+.
+
+
+=== Tracking Configuration Access
+
+The model module also allows tracking which code accesses configuration properties or configuration parameters.
+It checks the stacktrace to evaluate the calling code location, hereby any unwanted packages can be implicitly
+ommitted from the stacktrace. Also the maximal length of the stacktrace retained can be constraint in length.
+The usages are recorded as +Usage+ instances. Hereby for each parameter accessed a corresponding +Usage+
+instance is created. It can be accessed by calling +Usage ConfigUsageStats.getUsage(String key)+. Usage
+statistics for calling +Configuration.getProperties()+ can be obtained calling +Usage getUsageAllProps();+.
+
+Usage tracking is disabled by default. It can be enabled by calling +ConfigUsageStats.enableUsageTracking(true);+.
++ConfigUsageStats.isUsageTrackingEnabled()+ returns the current tracking status.
+
+The +Usage+ class itself provides access to further fainer grained usage data (+AccessDetail+) containing:
+
+* the access point (+fqn.ClassName#method(line: xxx)+).
+* the number of accesses
+* the first an last access
+* the values read
+* the access stacktrace (filtered by ignored packages).
+
+[source,java]
+-----------------------------------------------------------
+public final class Usage {
+ [...]
+ public String getKey();
+ public void clearMetrics();
+ public int getReferenceCount();
+ public int getUsageCount();
+ public Collection<AccessDetail> getAccessDetails(Class type);
+ public Collection<AccessDetail> getAccessDetails(Package pack);
+ public Collection<AccessDetail> getAccessDetails(String lookupExpression);
+ public Collection<AccessDetail> getAccessDetails();
+ public void trackUsage(String value);
+ public void trackUsage(String value, int maxTraceLength);
+
+
+ public static final class AccessDetail {
+ [...]
+ public void clearStats();
+ public long trackAccess(String value);
+ public long getAccessCount();
+ public String getAccessPoint();
+ public long getFirstAccessTS();
+ public long getLastAccessTS();
+ public String[] getStackTrace();
+ public Map<Long, String> getTrackedValues();
+ }
+
+}
+-----------------------------------------------------------
+
+With +ConfigUsageStats.clearUsageStats()+ the collected statistics can be reset at any time. Summarizing the main
+singleton for configuration statistics is defined as follows:
+
+[source,java]
+-----------------------------------------------------------
+public final class ConfigUsageStats{
+ public static Set<String> getIgnoredUsagePackages();
+ public static void addIgnoredUsagePackages(String... packageName);
+ public static void enableUsageTracking(boolean enabled);
+ public static Usage getUsage(String key);
+ public static Collection<Usage> getUsages();
+ public static void clearUsageStats();
+ public static Usage getUsageAllProperties();
+ public static boolean isUsageTrackingEnabled();
+ public static String getUsageInfo();
+}
+-----------------------------------------------------------
+
+==== Customizing the Stacktrage for Usage Reporting
+
+The stacktrace tracked by the system can be customized in several ways:
+
+* +ConfigUsageStats.addIgnoredPackageNames(String...)+ allows to add additional ignored package names.
+* With +Usage.setMaxTraceLength(int)+ the maximal size of the stacktraces logged can be set. Setting a
+ negative value will disable stacktrace logging completelely.
+
+
+=== Accessing Usage Statistics
+
+Bascially usage statistics are available in two forms:
+
+* The +Usage/AccessDetail+ object tree can be accessed programmatically from the +ConfigUsageStats+
+ singleton.
+* With +ConfigUsageStats.getUsageInfo()+ also a textual representation of the usage statistics
+ can be obtained, as illustrated below (a snipped from the current test output):
+
+[source,listing]
+-----------------------------------------------------------
+Apache Tamaya Configuration Usage Metrics
+=========================================
+DATE: Sat Apr 30 21:51:09 CEST 2016
+
+220 <<all>>:
+ - 220 <unknown/filtered/internal> , first=Sat Apr 30 21:51:09 CEST 2016, last=Sat Apr 30 21:51:09 CEST 2016
+3 java.version:
+ - 2 test.model.TestConfigAccessor#readProperty(line:43), first=Sat Apr 30 21:51:09 CEST 2016, last=Sat Apr 30 21:51:09 CEST 2016
+ - 1 <unknown/filtered/internal> , first=Sat Apr 30 21:51:09 CEST 2016, last=Sat Apr 30 21:51:09 CEST 2016
+
+-----------------------------------------------------------
+
+
+==== Programmatic API
+
+Basically the configModel module provides a simple API to access the defined +ConfigModel+ instances and
+validating the current +Configuration+ against the models as follows:
+
+[source,java]
+-----------------------------------------------------------
+public final class ConfigModelManager {
+
+ private ConfigModelManager() {}
+
+ public static Collection<ConfigModel> getModels();
+ public static Collection<ConfigModel> findModels(ModelType type, String namePattern);
+ public static <T extends ConfigModel> T getModel(String name, Class<T> modelType);
+ public static Collection<ConfigModel> findModels(String namePattern);
+
+ public static Collection<ValidationResult> validate();
+ public static Collection<ValidationResult> validate(boolean showUndefined);
+ public static Collection<ValidationResult> validate(Configuration config);
+ public static Collection<ValidationResult> validate(Configuration config, boolean showUndefined);
+
+ public static void registerMBean();
+ public static void registerMBean(String context);
+
+}
+-----------------------------------------------------------
+
+This singleton allows to validate the current or any +Configuration+ instance. All the ConfigModels read also are
+available from the +getModels+ method. This models can be used to provide documentation, e.g. as part of a CLI interface
+or shown on a documentation web server.
+
+A +ConfigModel+ hereby is defined as one single part of configuration, typically corresponding to a specific concern
+of your system. As an example you can define different models for different modules or products plugged together.
+With resolution mechanism in place you can also define a shared module that is targeted by multiple modules as a
+single configuration source (e.g. for configuring the machine's IP address and subnet settings only once.
+
+[source,java]
+-----------------------------------------------------------
+public interface ConfigModel {
+
+ ModelTarget getType();
+ String getName();
+ String getProvider();
+ boolean isRequired();
+ String getDescription();
+ Collection<ValidationResult> validate(Configuration config);
+}
+-----------------------------------------------------------
+
+
+Hereby +ModelTarget+ defines more details on the kind of model:
+
+[source,java]
+-----------------------------------------------------------
+public enum ModelTarget {
+ /**
+ * A configuration section.
+ */
+ Section,
+ /**
+ * A configuration paramter.
+ */
+ Parameter,
+ /**
+ * ConfigModel that is a container of other validations.
+ */
+ Group
+}
+-----------------------------------------------------------
+
+A +ValidationResult+ models one validation executed by a +ConfigModel+ on a certain +Configuration+ instance:
+
+[source,java]
+-----------------------------------------------------------
+public final class ValidationResult {
+
+ public static ValidationResult ofValid(ConfigModel configModel);
+ public static ValidationResult ofMissing(ConfigModel configModel);
+ public static ValidationResult ofMissing(ConfigModel configModel, String message);
+ public static ValidationResult ofError(ConfigModel configModel, String error);
+ public static ValidationResult ofWarning(ConfigModel configModel, String warning);
+ public static ValidationResult ofDeprecated(ConfigModel configModel, String alternateUsage);
+ public static ValidationResult ofDeprecated(ConfigModel configModel);
+ public static ValidationResult ofUndefined(final String key);
+ public static ValidationResult of(ConfigModel configModel, ValidationState result, String message);
+
+ public ConfigModel getConfigModel();
+ public ValidationState getResult();
+ public String getMessage(),
+}
+-----------------------------------------------------------
+
+The result of a complete validation on a concrete +Configuration+ instance finally is mapped as a
++Collection<ValidationResult>+, refer to the methods on +ConfigModelManager+.
+
+
+=== Auto-Documentation of Classes with Configuration Injection
+
+A special feature of this module is that it observes +ConfigEvent+ published through Tamaya'as event channel
+(+tamaya-events+ module). If no metaconfiguration model is found the model manager by default automatically creates
+models for all injected instances on the fly. In the case of CDI integration this happens typically during deployment
+time, since CDI initializes during deployment time. Other runtime platforms, such as OSGI, may have rather different
+behaviour. Nevertheless this means that after your system has been started you should have access to a complete
+set of +ConfigModel+ instances that automatically document all the classes in your system that consume configuration
+(through injection).
+
+
+== Model SPI
+=== Registering Configuration Models
+
+The model extension also provides an SPI where customized functionality can be added. The main abstraction hereby is
+the +ModelProviderSpi+ interface, which allows any kind of additional config models to be added to the system:
+
+[source,java]
+-----------------------------------------------------------
+public interface ModelProviderSpi {
+
+ Collection<ConfigModel> getConfigModels();
+
+}
+-----------------------------------------------------------
+
+New instances implementing this interface must be registered into the current +ServiceContext+, by default the
++ServiceLoader+ is used.
+
+
+=== The ConfigUsageStatsSpi
+
+The methods for managing and tracking of configuration changes are similarly delegated to an
+implementation of the +org.apache.tamaya.model.spi.ConfigUsageStatsSpi+ SPI.
+By implementing this SPI and registerting it with the +ServiceContext+ the usage tracking
+logic can be adapted or replaced.
+
+=== Other Utility Classes
+
+The module also provides further utility classes that may be useful for implementing models or testing:
+
+* +AbstractModel+ provides a base class that can be extended, when implementing +ConfigModel+.
+* +AreaConfigModel+ provides a +ConfigModel+ implementation (with a corresponding +Builder+) to model the
+ requirement of certain configuration sections being present, or opionally present, in the model.
+* +ParameterModel+ provides an implementation base class for validating parameters on existence and compliance
+ with a regular expression.
+* +ConfigDocumentationMBean+ is the MBean registered that models similar functionality as +ConfigModelManager+.
+* +ConfigModelGroup+ provides a +ConfigModel+ that groups several child models.
+* +ConfigModelReader+ allows to read +ConfigModels+ from properties files as described at the beginning of this
+ document.
+
+
+=== Switches to enable/disable functionality
+
+The model module provides different switches that can be used to activate or deactivate features:
+
+* +tamaya.model.integrated.enabled+ allows to deactivate reading inline metaconfiguration delivered with
+ the normal Tamaya Configuration. By default inline entries (+_.abcd.model.*+) are evaluated.
+* +tamaya.model.default.enabled+ allows to deactivate reading metamodel information from
+ +classpath:META-INF/configmodel.properties+. By default it is active.
+* +tamaya.model.resources+ allows to define additional resources (loaded through the resources extension),
+ that can be used to read metamodel information in any format using Tamaya's format module.
+* the system property +tamaya.model.autoModelEvents+ allows to activate/deactivate the automatic
+ documentation of classes configured and published by Tamaya +ConfiguredType+ event instances (e.g. published by
+ Tamaya's injection modules).