blob: 366c97e56263e21886dd209e4440f1dd8bd6b1ee [file] [log] [blame]
:jbake-type: page
:jbake-status: published
= Apache Tamaya -- Extension: Resolver
[[Core]]
== Tamaya Resolver (Extension Module)
=== Overview
Tamaya Resolver is an extension module. Refer to the
// @todo Fix the link to the modules documentation
link:modules.html[extensions documentation]
for further details about modules.
Tamaya Resolver provides a dynamic resolution mechanism, which allows to use UNIX-styled (+${...}+ placeholder
expressions in your configuration values. The resolver hereby supports transitive resolution and also prevents
cycles to loop endlessly.
=== 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, subs="verbatim,attributes"]
-----------------------------------------------
<dependency>
<groupId>org.apache.tamaya.ext</groupId>
<artifactId>tamaya-resolver</artifactId>
<version>{tamaya_version}</version>
</dependency>
-----------------------------------------------
The module automatically registers an according +PropertyFilter+ that is automatically called, whenever a value
is accessed.
=== Available Resolvers
Currently the module defined the following resolvers:
.Available Resolvers
[cols="<.1,<.2,<.1"]
|=======
| _Expression_
| _Description_
| _Example_
| +conf:<configKey>+
| Reads another configKey and replaces the expression with the value found.
| conf-ref=${conf:anotherConf.entryKey}
| +resource:<resourceRef>+
| Reads a resource from the current classpath and replaces the expression with the given text content.
| cp-ref=${resource:Testresource.txt}
| +file:<fileRef>+
| Reads a resource from the current classpath and replaces the expression with the given text content.
| file-ref=${file:c:\myFile.txt}
|+url:<url>+
|Reads an URL and replaces the expression with the given text content.
| url-ref=${url:http://www.google.com}
|=======
=== SPI: Implementing your own Resolvers
The module also provides an easy but powerful SPI for adding your own resolver implementations. Basically the
first and most important thing to do is implementing the +ExpressionResolver+ interface:
.Implementing a Custom Resolver
[source, java]
-----------------------------------------------
public class PwdDecrypter implements ExpressionResolver {
@Override
public String getResolverPrefix() {
return "decrypt:";
}
@Override
public String evaluate(String expression) {
return decrypt(expression);
}
private String decrypt(String s) {
...
}
}
-----------------------------------------------
Basically that is all you must do, after having registered the class with the +ServiceLoader+ it will be found
and loaded by the implementation. With that all expressions that start with the given prefix are passed to the
resolver, so all the following expressions will be sent to the implementation:
[source,listing]
-----------------------------------------------
blabla ${decrypt:myname}
blabla ${decrypt:myname} foo blabla ${decrypt:myname}
-----------------------------------------------
Hereby evaluation is repeated until no further change of values could be detetced. In case of a endless loop
the evaluation is broken after a (configurable) number of cycles.
Under the hood instances of +ExpressionResolver+ are managed by an implementation of the +ExpressionEvaluator+
interface:
[source, java]
-----------------------------------------------
public interface ExpressionEvaluator {
/**
* Evaluates the current expression.
* @param key the key, not null.
* @param value the value to be filtered/evaluated.
* @return the filtered/evaluated value, including null.
*/
String evaluateExpression(String key, String value);
}
-----------------------------------------------
Implementing and registering this interface gives you full control, but in most cases yhou should be fine with
the default implementation in place.