The org.apache.juneau.svl
package defines an API for a language called "Simple Variable Language".
In a nutshell, Simple Variable Language (or SVL) is text that contains variables of the form "$varName{varKey}".
Variables can be recursively nested within the varKey (e.g. "$FOO{$BAR{xxx},$BAZ{xxx}}").
Variables can also return values that themselves contain more variables.
The {@link org.apache.juneau.svl.VarResolver} class is used to resolve variables.
The {@link org.apache.juneau.svl.VarResolver#DEFAULT} resolver will resolve "$S{systemProperty}" and "$E{envVariable}"
variables.
// Use the default variable resolver to resolve a string that contains $S (system property) variables
String myProperty = VarResolver.DEFAULT.resolve("The Java home directory is $S{java.home}");
The following shows how variables can be arbitrarily nested...
// Look up a property in the following order:
// 1) MYPROPERTY environment variable.
// 2) 'my.property' system property if environment variable not found.
// 3) 'not found' string if system property not found.
String myproperty = VarResolver.DEFAULT.resolve("$E{MYPROPERTY,$S{my.property,not found}}");
1.1 - Vars
Variables are defined through the {@link org.apache.juneau.svl.Var} API.
// Create a var resolver that extends the default resolver and appends our own "$URLEncode{...}" variable
// First create our var.
public class UrlEncodeVar extends SimpleVar {
// Must have a no-arg constructor!
public UrlEncodeVar() {
super("URLEncode");
}
// The method we must implement
@Override
public String resolve(VarResolverSession session, String varVal) {
return URLEncoder.encode(varVal, "UTF-8");
}
}
// Next create a var resolver that extends the existing DEFAULT resolver
// that supports resolving system properties.
VarResolver r = VarResolver.DEFAULT.builder().vars(UrlEncodeVar.class).build();
// Retrieve a system property and URL-encode it if necessary.
String myProperty = r.resolve("$URLEncode{$S{my.property}}");
The following shows the class hierarchy of the {@link org.apache.juneau.svl.Var} class and all current
predefined implementations.
- {@link org.apache.juneau.svl.Var} - Superclass of all vars.
- {@link org.apache.juneau.svl.SimpleVar} - Superclass of all vars that return strings.
- {@link org.apache.juneau.svl.DefaultingVar} - Variables that define a default value if the resolve method returns null.
- {@link org.apache.juneau.svl.MapVar} - Variables that pull values from maps.
- {@link org.apache.juneau.svl.vars.SystemPropertiesVar} - Resolves system properties.
- {@link org.apache.juneau.svl.vars.ArgsVar} - Resolves variables from an {@link org.apache.juneau.utils.Args} object.
- {@link org.apache.juneau.svl.vars.ConfigFileVar} - Resolves variables from a {@link org.apache.juneau.ini.ConfigFile} object.
- {@link org.apache.juneau.svl.vars.EnvVariablesVar} - Resolves environment variables.
- {@link org.apache.juneau.svl.vars.ManifestFileVar} - Resolves variables from a {@link org.apache.juneau.utils.ManifestFile} object.
- {@link org.apache.juneau.rest.vars.ServletInitParamVar} - Resolves servlet initialization parameters.
- {@link org.apache.juneau.svl.MultipartVar} - Variables that consist of 2 or more comma-delimited arguments.
- {@link org.apache.juneau.rest.vars.LocalizationVar} - Resolves localized strings for an HTTP request.
- {@link org.apache.juneau.rest.vars.RequestVar} - Resolves specialized HTTP request values.
- {@link org.apache.juneau.rest.vars.UrlEncodeVar} - URL-encodes the value inside the variable.
- {@link org.apache.juneau.svl.StreamedVar} - Superclass of all vars that stream their value to writers.
- {@link org.apache.juneau.rest.vars.SerializedRequestAttrVar} - Resolves HTTP request attribute values passed through a {@link org.apache.juneau.serializer.Serializer}.
1.2 - VarResolvers and VarResolverSessions
The main class for performing variable resolution is {@link org.apache.juneau.svl.VarResolver}.
Two methods are provided for resolving variables:
- {@link org.apache.juneau.svl.VarResolver#resolve(String)} - Resolves variables and returns the results as a simple string.
- {@link org.apache.juneau.svl.VarResolver#resolveTo(String,Writer)} - Resolves variables and sends results to a writer.
Var resolvers can have zero or more context objects associated with them.
Some {@link org.apache.juneau.svl.Var Vars} rely on the existence of some other object, such as an {@link org.apache.juneau.utils.Args} object
for {@link org.apache.juneau.svl.vars.ArgsVar} or a {@link org.apache.juneau.ini.ConfigFile} for a {@link org.apache.juneau.svl.vars.ConfigFileVar}.
These object dependencies are made by setting context objects on the var resolver.
Context objects are set through the {@link org.apache.juneau.svl.VarResolverBuilder#contextObject(String,Object)} method.
They can be any class type.
Context objects are used by {@link org.apache.juneau.svl.Var Vars} by calling the {@link org.apache.juneau.svl.VarResolverSession#getSessionObject(Class, String)} method.
In addition to context objects, there are also session objects.
Session objects are considered more ephemeral than context objects.
While a context object is unlikely to ever change, a session object may change on every use of the var resolver.
For example, the server API defines various Var
objects that use the RestRequest
object as a session object for the duration of a single HTTP request.
Session objects are used by calling the {@link org.apache.juneau.svl.VarResolver#createSession()} or {@link org.apache.juneau.svl.VarResolver#createSession(Map)} methods to create an instance
of a {@link org.apache.juneau.svl.VarResolverSession} object that contains {@link org.apache.juneau.svl.VarResolverSession#resolve(String)} and {@link org.apache.juneau.svl.VarResolverSession#resolveTo(String,Writer)} methods
that are identical to {@link org.apache.juneau.svl.VarResolver#resolve(String)} and {@link org.apache.juneau.svl.VarResolver#resolveTo(String, Writer)} except that the Var
objects
have access to the session objects through the {@link org.apache.juneau.svl.VarResolverSession#getSessionObject(Class, String)} method.
Session objects are specified through either the {@link org.apache.juneau.svl.VarResolver#createSession(Map)} method or the {@link org.apache.juneau.svl.VarResolverSession#sessionObject(String, Object)} methods.
Like Context object, Session objects are used by {@link org.apache.juneau.svl.Var Vars} by calling the {@link org.apache.juneau.svl.VarResolverSession#getSessionObject(Class, String)} method.
Var resolvers can be cloned and extended by using the {@link org.apache.juneau.svl.VarResolver#builder()} method.
Cloning a resolver will copy it's {@link org.apache.juneau.svl.Var} class names and context objects.
Example:
// Create a resolver that copies the default resolver and adds $C and $ARG vars.
VarResolver myVarResolver = VarResolver.DEFAULT.builder().vars(ConfigFileVar.class, ArgsVar.class).build();
1.3 - Other Notes
- The escape character '\' can be used when necessary to escape the following characters:
$ , { }
- WARNING: It is possible to cause {@link java.lang.StackOverflowError StackOverflowErrors} if your nested variables result in
a recursive loop (e.g. the environment variable
'MYPROPERTY'
has the value '$E{MYPROPERTY}'
).
So don't do that!
- As a general rule, this class tries to be as efficient as possible by not creating new strings when not needed.
For example, calling the resolve method on a string that doesn't contain variables (e.g. resolver.resolve("foobar")
)
will simply be a no-op and return the same string.