| Class | Description |
|---|---|
| AbstractPropertiesBuilderDecorator<T extends Properties.PropertiesBuilder> | |
| AbstractPropertiesDecorator<T extends Properties> |
Decorates the provided
Properties and delegates method calls to them
Properties. |
| AbstractResourcePropertiesBuilder |
Implementation of the mutable
ResourceProperties.ResourcePropertiesBuilder interface. |
| AbstractResourcePropertiesBuilderDecorator<T extends ResourceProperties.ResourcePropertiesBuilder> | |
| AbstractResourcePropertiesDecorator<T extends ResourceProperties> |
Decorates the provided
ResourceProperties and delegates method calls
to them ResourceProperties. |
| EnvironmentProperties |
Extension of the
Properties type overwriting methods in order to
access the operating system's environment variables as of env on
Linux or Unix shells or set on Windows machines (e.g." |
| JavaProperties |
Implementation of the
ResourceProperties interface with support of so
called "Java properties" (or just "properties"). |
| JavaPropertiesBuilder |
Implementation of the
ResourceProperties.ResourcePropertiesBuilder interface with
support of so called "Java properties" (or just "properties"). |
| JsonProperties |
Implementation of the
ResourceProperties interface with support of so
called "JSON properties". |
| JsonPropertiesBuilder |
Implementation of the
ResourceProperties.ResourcePropertiesBuilder interface with
support of so called "JSON properties" (or just "properties"). |
| NormalizedPropertiesDecorator |
The
NormalizedPropertiesDecorator type decorates a Properties
instance and converts a path delimiter such as the full-stop (".") to the
Properties properties' path delimiter slash ("/", as of
AbstractPropertiesDecorator.getDelimiter()). |
| ProfilePropertiesDecorator |
The
ProfilePropertiesDecorator type decorates a Properties
instance and enriches it with profile support as of
ProfileProperties. |
| ProfilePropertiesProjection |
The
ProfilePropertiesProjection applies the profiles as of
ProfileProperties.getRuntimeProfiles() onto the encapsulated
Properties (ProfileProperties) and provides a view of them
Properties (ProfileProperties) from the profiles' point of
view e.g. as when profiles have been applied to them Properties
(ProfileProperties). |
| PropertiesBuilderImpl |
The Class PropertiesBuilderImpl.
|
| PropertiesImpl |
The Class PropertiesImpl.
|
| PropertiesPrecedenceComposite |
Retrieve properties from various different properties sources
(
Properties instances) by querying all the herein contained
Properties instances in the order of them being added. |
| PropertiesSugar |
Declarative syntactic sugar which may be statically imported in order to
allow declarative definitions for the construction of
Properties
precedences using ProfilePropertiesDecorator,
ProfilePropertiesProjection, ResourceProperties or
PropertiesPrecedenceComposite (and the like). |
| RuntimePropertiesComposite |
The
RuntimePropertiesComposite composite represent the system
properties as well as the environment variables (in that order) and Java
properties and are actually constructed from SystemProperties,
EnvironmentProperties and JavaProperties instances
(in that precedence). |
| ScheduledResourcePropertiesBuilderDecorator |
The
ScheduledResourcePropertiesBuilderDecorator decorates
ResourceProperties.ResourcePropertiesBuilder from which the properties are to be
reloaded periodically via AbstractResourcePropertiesBuilderDecorator.reload(ReloadMode). |
| ScheduledResourcePropertiesDecorator |
The
ScheduledResourcePropertiesDecorator decorates
ResourceProperties from which the properties are to be reloaded
periodically via AbstractResourcePropertiesDecorator.reload(ReloadMode). |
| StrictPropertiesDecorator |
The
StrictPropertiesDecorator type decorates a Properties
instance with all the getters to throw a KeyNotFoundRuntimeException
instead of returning null in case the key was not found. |
| SystemProperties |
Extension of the
Properties type overwriting methods in order to
access system properties as passed via the "-Dkey=value" when launching the
JVM (e.g.java -Dconsole.width=220)
The keys are transformed to a system properties by removing a prefixed "/"
path delimiter (as of PropertiesImpl.getDelimiter() and converting all other path
delimiters "/" to the system property's (de facto standard) separator ".". |
| TomlProperties |
Implementation of the
ResourceProperties interface with support of so
called "TOML properties". |
| TomlPropertiesBuilder |
Implementation of the
ResourceProperties.ResourcePropertiesBuilder interface with
support of so called "TOML properties". |
| XmlProperties |
Implementation of the
ResourceProperties interface with support of so
called "XML properties". |
| XmlPropertiesBuilder |
Implementation of the
ResourceProperties.ResourcePropertiesBuilder interface with
support of so called "XML properties" (or just "properties"). |
| YamlProperties |
Implementation of the
ResourceProperties interface with support of so
called "YAML properties". |
| YamlPropertiesBuilder |
Implementation of the
ResourceProperties.ResourcePropertiesBuilder interface with
support of so called "YAML properties" (or just "properties"). |
| Enum | Description |
|---|---|
| PropertiesPath |
Enumeration representing defined path values.
|
| ReloadMode |
Mode of operation regarding the
ResourceProperties.reload(ReloadMode)
method. |
| Exception | Description |
|---|---|
| ConfigurationRuntimeException |
Base exception for the configuration artifact.
|
import static org.refcodes.configuration.PropertiesSugar.*;
// ...
public class Foo {
public void bar() throws IOException, ParseException {
// ...
PropertiesBuilder theProperties = fromProperties( toProperty( "message", "Hello world!" ), toProperty( "foo", "bar" ) );
fileToTomlProperties( theProperties, "application.toml" );
// ...
Properties thePrecedence = toPrecedence( fromSystemProperties(), fromEnvironmentVariables(), seekFromTomlProperties( "application.toml" ) );
FooConfig theConfig = thePrecedence.toType( FooConfig.class );
// ...
}
// ...
public static class FooConfig {
String message;
int frequency;
TemperatureUnit unit;
int port;
}
// ...
}
See also the blog post Dead
simple Java application configuration.
pom.xml:
<dependencies>
...
<dependency>
<artifactId>refcodes-configuration</artifactId>
<groupId>org.refcodes</groupId>
<version>1.1.9</version>
</dependency>
...
</dependencies>
The artifact is hosted directly at
Maven Central. Jump
straight to the source codes at Bitbucket. Read
the artifact's javadoc at javadoc.io.
If you also want to observe your properties (e.g. listen for
create , update or delete operations),
you may instead add the following dependency to your pom.xml:
<dependencies>
...
<dependency>
<artifactId>refcodes-configuration-ext-observer</artifactId>
<groupId>org.refcodes</groupId>
<version>1.1.9</version>
</dependency>
...
</dependencies>
The artifact is hosted directly at
Maven Central. Jump
straight to the source codes at Bitbucket.
Read the artifact's javadoc at javadoc.io.
refcoces-configuration
features.
import static org.refcodes.configuration.PropertiesSugar.*; // ...Create some
properties and play around with them:
// ... PropertiesBuilder theProperties = fromProperties( toProperty( "/user/firstName", "Nolan" ), toProperty( "/user/lastName", "Bushnell" ), toProperty( "/commodore/user/firstName", "Jack" ), toProperty( "/commodore/user/lastName", "Tramiel" ) ); // ...The content of your
properties looks as follows:
/user/firstName=Nolan /user/lastName=Bushnell /commodore/user/lastName=Tramiel /commodore/user/firstName=JackThe
Properties.PropertiesBuilder inherits
from the Map interface, it is fully compatible with the
Java collections framework.
You may have noted that the keys in your properties
look like path declarations. This is no coincidence, you can now
manipulate your propertiesusing (sub-)paths. See
more in the article The
canonical model, an ace upon your sleeve. E.g. you may now retrieve the
commodore specific properties (the properties below
the /commodore path):
// ... Properties theCommodoreProperties = theProperties.retrieveFrom( "/commodore" ); // ...This results in your
commodore specific properties
to look as such:
/user/lastName=Tramiel /user/firstName=JackThere are many more features hidden in the
Properties type, just browse the Javadoc.
The Properties type is the
read-only super-type of the
Properties.PropertiesBuilder type. Common
functionality produces Properties
instances which easily can be converted into a mutable
Properties.PropertiesBuilder instance as
follows:
// ... PropertiesBuilder theBuilder = toPropertiesBuilder( theCommodoreProperties ); // ...
properties is as
easy as this:
// ... ResourcePropertiesBuilder theResourceProperties = saveToTomlProperties( theProperties, "/some/path/to/my/properties.toml" ); // ...You can make the
library choose a suitable place for you where
to save your properties to; being near the launcher
(JAR) of your application:
// ... ResourcePropertiesBuilder theResourceProperties = fileToTomlProperties( theProperties, "properties.toml" ); // ...See the
RuntimeUtility on how a suitable
location is determines by the library.
properties back
again is as easy as this:
// ... ResourcePropertiesBuilder theResourceProperties = loadFromTomlProperties( "/some/path/to/my/properties.toml" ): // ...You can make the
library seek for a suitable
properties for you to load; being near the launcher
(JAR) of your application:
// ... ResourcePropertiesBuilder theResourceProperties = seekFromTomlProperties( "properties.toml" ); // ...See the
RuntimeUtility on how a suitable
location is determines by the library.
refcodes-configuration
artifact:
Java based
properties
TOML based properties
XML based properties
YAMLbased properties
JSON based properties
profile is identified by the first level path hierarchy in
your originating properties. In the example above,
commodore represents a profile specific configuration which we
can use to get our profile view:
// ... Properties theProfile = fromProfile( theProperties, "commodore" ); // ...We can also specify a
property in our properties
for the path /runtime/profiles identifying the
profiles to be considered (comma separated).
See also the ProfilePropertiesProjection
type as well as the
ProfilePropertiesDecorator type on more
usages.
ResourceProperties.ResourcePropertiesBuilder
form above which we attached to a file, we now can schedule a *reload* of the
properties:
// ... ResourceProperties theScheduled = schedule( theResourceProperties, 5000, ReloadMode.ORPHAN_REMOVAL ); // ...We actually encapsulate the
properties with a *schedule*
decorator
which reloads the encapsulated properties accordingly: Reload
them each 5000 milliseconds and remove any
properties not found in the attached resource (e.g.
File ) from your properties instance.
create, update or
delete changes applied to your properties. To do so, you must
encapsulate your
ResourceProperties.ResourcePropertiesBuilder
instance with an observable
decorator
of type ObservableResourcePropertiesBuilder
This observable
fires a sub-type of the PropertyEvent
upon updates applied to the properties to each subscriber of
those events:
import static org.refcodes.configuration.ext.observer.ObservablePropertiesSugar.*;
// ...
PropertiesBuilder theProperties = toPropertiesBuilder();
ObservablePropertiesBuilder theObservable = observe( theProperties );
theObservable.subscribeObserver( aEvent -> {
if ( aEvent.getAction() == PropertyAction.PROPERTY_UPDATED ) {
System.out.println( aEvent.getClass().getSimpleName() + " (" + aEvent.getAction() + ") --> " + aEvent.getKey() + " := " + aEvent.getValue() );
}
} );
theObservable.put( "/user/firstName", "Nolan" );
theObservable.put( "/user/lastName", "Bushnell" );
theObservable.put( "/user/firstName", "Jack" );
theObservable.put( "/user/lastName", "Tramiel" );
theObservable.remove( "/user/firstName" );
theObservable.remove( "/user/lastName" );
// ...
For the example above to work, make sure to include the
refcodes-configuration-ext-observer
dependency (see at the beginning of this article) in your project's
pom.xml.
The lambda being subscribed acts as a listener
which is a FunctionalInterface of type PropertiesObserver
with which you explicitly may listen to the three event types PropertyCreatedEvent,
PropertyUpdatedEvent
and PropertyDeletedEvent
as well as to the super-type [PropertyEvent].
Observing just the PropertyEvent
type *catches* all of its sub-types (as we did in the example above).
Properties
instances behind a composite behaving just
like a Properties type:
// ... Properties theProperties = toPrecedence( fromSystemProperties(), fromEnvironmentVariables(), seekFromJavaProperties( "application.config" ) ); // ...Above we created a composite containing various various
properties instances, the first one overrules
the second one and the second one overrules the third one when accessing the
resulting Properties
composite.
Take a look at the SystemProperties as
well as at the EnvironmentProperties
instances we added: They provide means to access Java 's
system properties
or the operating system's environment variables
within your properties..
canonical model
pattern is an ace up your sleeve in order to open your libraries for
functionality otherwise to be implemented in a tiresome, error prone and
redundant way. As you settle upon a canonical model
within your library, your library's will be able to interact with any
existing and yet to be implemented functionality on top of your
canonical model,
making your bits and pieces work together magically.
The CanonicalMap is the super-type of the
Properties related types. Read more in the
blog post The
canonical model, an ace upon your sleeve.
Unit-Tests.
For examples and usage on the observable extensions, please take a look at
the according Unit-Tests.Copyright © 2018. All rights reserved.