Skip to content

atteo/dollarbrace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status Coverage Status Maven Central Apache 2

Overview

DollarBrace library provides a mechanisms to filter strings, files and XML trees to perform property resolution for a common dollar-brace expressions. For instance, given document

<name>${name}</name>

and properties file

name=Stephan

The filtering result will be

<name>Stephan</name>

Changes

2.0 (2015-07-17) Change name to DollarBrace Better error reporting for recursive property resolution

1.3 (2014-11-30) fix: PropertyFilter returned from getFilter was not thread-safe

1.2 (2014-04-06) Added file filtering

1.1 (2014-03-12) fix: incorrectly returning circular dependencies for missing properties

1.0 (2014-02-13) Splitted from evo-config Separated filtering (PropertyFilter) from property resolution (PropertyResolver)

Usage

First add the following dependency to your POM file:

<dependency>
    <groupId>org.atteo.dollarbrace</groupId>
    <artifactId>dollarbrace</artifactId>
    <version>2.0</version>
</dependency>

Then create a property resolver instance:

Properties properties = new Properties();
properties.putProperty("name", "Stephan");
PropertyResolver propertyResolver = new PropertiesPropertyResolver(properties);

Finally create a property filter and use it to interpolate dollar-brace expression within a string:

PropertyFilter propertyFilter = DollarBrace.getFilter(propertyResolver);

// will print 'His name is Stephan'
System.out.println(propertyFilter.filter("His name is ${name}"));

Property filter

DollarBrace.getFilter(...) returns a PropertyFilter instance. It contains several methods which allow you to interpolate dollar-brace expressions:

  • filter(String) - filters given string interpolating dollar-brace expressions inside
  • filter(Element) - filters given XML subtree interpolating tag content and attribute values
  • filter(Path source, Path destination) - filters source file and stores the result in the destination file
  • getProperty(String) - returns the value of the given property

Property resolvers

DollarBrace.getFilter(resolver1, resolver2, ...) method takes a number of property resolvers. Each resolver will be tried in turn to get the values for dollar-brace expressions.

There are several PropertyResolvers already available for your convenience:

EnvironmentPropertyResolver

Resolves ${env.NAME} with the value of environment variable named NAME.

SystemPropertyResolver

Resolves ${NAME} from the Java system property provided with -DNAME="value"

PropertiesPropertyResolver

Resolves property from the provided Properties object.

XmlPropertyResolver

Takes XML DOM tree as an input and resolves any ${tag.tag.tag} as a dot-separated path to the XML element. For instance, given document:

<a>
	<b>test</b>
</a>

"${a.b}" will resolve to "test".

OneOfPropertyResolver

Matches any name prefixed with 'oneof:' and formatted as comma separated list of values - 'oneof:value1,value2,value3'. It returns first of the values which is correctly defined.

For instance

'${oneof:${env.HOME},~/}'

will return the value of the environment variable 'HOME' or '~/' if the 'HOME' variable is undefined

RawPropertyResolver

Matches any name prefixed with 'raw:' and returns the same string without 'raw:' prefix. This is handy in case some special characters would otherwise trigger recursive filtering.

For instance

'${raw:${a}}'

will return exactly '${a}' (without trying to resolve dollar brace inside it).

JaninoPropertyResolver

Matches any name prefixed with 'java:'. It treats the following string as Java expression which is executed to obtain the value.

For instance '${java:2+2}'

will return '4' and

'${java:new java.util.Date()'}

will return current date and time.

If the returned Java object is not a String type, 'toString()' method is automatically executed.

To use this resolver you need to add additional Maven dependency:

<dependency>
    <groupId>org.atteo.dollarbrace</groupId>
    <artifactId>janino</artifactId>
    <version>1.3</version>
</dependency>

Custom property resolver

Basics

You can easily prepare your own property resolvers by implementing PropertyResolver interface.

public interface PropertyResolver {
	String resolveProperty(String name, PropertyFilter filter) throws PropertyNotFoundException;
}

For instance here is the resolver which matches on a "date" string and always returns current date and time:

public class DatePropertyResolver implements PropertyResolver {
	String resolveProperty(String name, PropertyFilter filter) throws PropertyNotFoundException() {
		if ("date".equals(name)) {
			return new Date().toString();
		}
		throw new PropertyNotFoundException(name);
	}
}

Recursive resolution

PropertyResolvers can support recursive resolution. That is one dollar-brace expression can be itself built using several other dollar-brace expressions like this:

properties.putProperty("name1", "John");
properties.putProperty("number", "1");
PropertyFilter propertyFilter = DollarBrace.getFilter(new PropertiesPropertyResolver(properties));

System.out.println(propertyFilter.filter("My name is ${name${number}}"));

To support recursive resolution your custom property resolver must execute extra step to filter property name using the provided PropertyFilter. Here is the example:

public class DatePropertyResolver implements PropertyResolver {
	String resolveProperty(String name, PropertyFilter filter) throws PropertyNotFoundException() {
		// filter the name to support recursive resolution
		name = filter.filter(name);

		if ("date".equals(name)) {
			return new Date().toString();
		}
		throw new PropertyNotFoundException(name);
	}
}