<!DOCTYPE HTML> | |
<!-- | |
/*************************************************************************************************************************** | |
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations under the License. | |
* | |
***************************************************************************************************************************/ | |
--> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
<style type="text/css"> | |
/* For viewing in Page Designer */ | |
@IMPORT url("../../../../../../javadoc.css"); | |
/* For viewing in REST interface */ | |
@IMPORT url("../htdocs/javadoc.css"); | |
body { | |
margin: 20px; | |
} | |
</style> | |
<script> | |
/* Replace all @code and @link tags. */ | |
window.onload = function() { | |
document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>'); | |
document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>'); | |
} | |
</script> | |
</head> | |
<body> | |
<p>Simple Variable Language</p> | |
<script> | |
function toggle(x) { | |
var div = x.nextSibling; | |
while (div != null && div.nodeType != 1) | |
div = div.nextSibling; | |
if (div != null) { | |
var d = div.style.display; | |
if (d == 'block' || d == '') { | |
div.style.display = 'none'; | |
x.className += " closed"; | |
} else { | |
div.style.display = 'block'; | |
x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' ); | |
} | |
} | |
} | |
</script> | |
<a id='TOC'></a><h5 class='toc'>Table of Contents</h5> | |
<ol class='toc'> | |
<li><p><a class='doclink' href='#SimpleVarLanguage'>Simple Variable Language</a></p> | |
<ol> | |
<li><p><a class='doclink' href='#Vars'>Vars</a></p> | |
<li><p><a class='doclink' href='#VarResolvers'>VarResolvers and VarResolverSessions</a></p> | |
<li><p><a class='doclink' href='#OtherNotes'>Other Notes</a></p> | |
</ol> | |
</li> | |
</ol> | |
<!-- ======================================================================================================== --> | |
<a id="SimpleVarLanguage"></a> | |
<h2 class='topic' onclick='toggle(this)'>1 - Simple Variable Language</h2> | |
<div class='topic'> | |
<p> | |
The <code>org.apache.juneau.svl</code> 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 <js>"$varName{varKey}"</js>. | |
</p> | |
<p> | |
Variables can be recursively nested within the varKey (e.g. <js>"$FOO{$BAR{xxx},$BAZ{xxx}}"</js>). | |
Variables can also return values that themselves contain more variables. | |
</p> | |
<p> | |
The {@link org.apache.juneau.svl.VarResolver} class is used to resolve variables. | |
The {@link org.apache.juneau.svl.VarResolver#DEFAULT} resolver will resolve <js>"$S{systemProperty}"</js> | |
and <js>"$E{envVariable}"</js> variables. | |
</p> | |
<p class='bcode'> | |
<jc>// Use the default variable resolver to resolve a string that contains $S (system property) variables</jc> | |
String myProperty = VarResolver.<jsf>DEFAULT</jsf>.resolve(<js>"The Java home directory is $S{java.home}"</js>); | |
</p> | |
<p> | |
The following shows how variables can be arbitrarily nested... | |
</p> | |
<p class='bcode'> | |
<jc>// 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.</jc> | |
String myproperty = VarResolver.<jsf>DEFAULT</jsf>.resolve(<js>"$E{MYPROPERTY,$S{my.property,not found}}"</js>); | |
</p> | |
<!-- ======================================================================================================== --> | |
<a id="Vars"></a> | |
<h3 class='topic' onclick='toggle(this)'>1.1 - Vars</h3> | |
<div class='topic'> | |
<p> | |
Variables are defined through the {@link org.apache.juneau.svl.Var} API. | |
</p> | |
<p class='bcode'> | |
<jc>// Create a var resolver that extends the default resolver and appends our own "$URLEncode{...}" variable</jc> | |
<jc>// First create our var.</jc> | |
<jk>public class</jk> UrlEncodeVar <jk>extends</jk> SimpleVar { | |
<jc>// Must have a no-arg constructor!</jc> | |
<jk>public</jk> UrlEncodeVar() { | |
<jk>super</jk>(<js>"URLEncode"</js>); | |
} | |
<jc>// The method we must implement</jc> | |
<ja>@Override</ja> | |
<jk>public</jk> String resolve(VarResolverSession session, String varVal) { | |
<jk>return</jk> URLEncoder.<jsm>encode</jsm>(varVal, <js>"UTF-8"</js>); | |
} | |
} | |
<jc>// Next create a var resolver that extends the existing DEFAULT resolver | |
// that supports resolving system properties.</jc> | |
VarResolver r = VarResolver.<jsf>DEFAULT</jsf>.builder().vars(UrlEncodeVar.<jk>class</jk>).build(); | |
<jc>// Retrieve a system property and URL-encode it if necessary.</jc> | |
String myProperty = r.resolve(<js>"$URLEncode{$S{my.property}}"</js>); | |
</p> | |
<p> | |
The following shows the class hierarchy of the {@link org.apache.juneau.svl.Var} class and all current | |
predefined implementations. | |
</p> | |
<ul class='doctree'> | |
<li class='jac'> | |
{@link org.apache.juneau.svl.Var} | |
- Superclass of all vars. | |
<ul> | |
<li class='jac'> | |
{@link org.apache.juneau.svl.SimpleVar} | |
- Superclass of all vars that return strings. | |
<ul> | |
<li class='jac'> | |
{@link org.apache.juneau.svl.DefaultingVar} | |
- Variables that define a default value if the resolve method returns null. | |
<ul> | |
<li class='jac'> | |
{@link org.apache.juneau.svl.MapVar} | |
- Variables that pull values from maps. | |
<ul> | |
<li class='jc'> | |
{@link org.apache.juneau.svl.vars.SystemPropertiesVar} | |
- Resolves system properties. | |
</ul> | |
</li> | |
<li class='jc'> | |
{@link org.apache.juneau.svl.vars.ArgsVar} | |
- Resolves variables from an {@link org.apache.juneau.utils.Args} object. | |
<li class='jc'> | |
<code>ConfigFileVar</code> | |
- Resolves variables from a {@link org.apache.juneau.ini.ConfigFile} object. | |
<li class='jc'> | |
{@link org.apache.juneau.svl.vars.EnvVariablesVar} | |
- Resolves environment variables. | |
<li class='jc'> | |
{@link org.apache.juneau.svl.vars.ManifestFileVar} | |
- Resolves variables from a {@link org.apache.juneau.utils.ManifestFile} object. | |
<li class='jc'> | |
{@link org.apache.juneau.rest.vars.ServletInitParamVar} | |
- Resolves servlet initialization parameters. | |
</ul> | |
</li> | |
<li class='jac'> | |
{@link org.apache.juneau.svl.MultipartVar} | |
- Variables that consist of 2 or more comma-delimited arguments. | |
<ul> | |
<li class='jc'> | |
{@link org.apache.juneau.rest.vars.LocalizationVar} | |
- Resolves localized strings for an HTTP request. | |
</ul> | |
</li> | |
<li class='jc'> | |
{@link org.apache.juneau.rest.vars.RequestVar} | |
- Resolves specialized HTTP request values. | |
<li class='jc'> | |
{@link org.apache.juneau.rest.vars.UrlEncodeVar} | |
- URL-encodes the value inside the variable. | |
</ul> | |
</li> | |
<li class='jac'> | |
{@link org.apache.juneau.svl.StreamedVar} | |
- Superclass of all vars that stream their value to writers. | |
<ul> | |
<li class='jc'> | |
{@link org.apache.juneau.rest.vars.SerializedRequestAttrVar} | |
- Resolves HTTP request attribute values passed through a | |
{@link org.apache.juneau.serializer.Serializer}. | |
</ul> | |
</li> | |
</ul> | |
</li> | |
</ul> | |
</div> | |
<!-- ======================================================================================================== --> | |
<a id="VarResolvers"></a> | |
<h3 class='topic' onclick='toggle(this)'>1.2 - VarResolvers and VarResolverSessions</h3> | |
<div class='topic'> | |
<p> | |
The main class for performing variable resolution is {@link org.apache.juneau.svl.VarResolver}. | |
Two methods are provided for resolving variables: | |
</p> | |
<ul class='doctree'> | |
<li class='jm'> | |
{@link org.apache.juneau.svl.VarResolver#resolve(String)} | |
- Resolves variables and returns the results as a simple string. | |
<li class='jm'> | |
{@link org.apache.juneau.svl.VarResolver#resolveTo(String,Writer)} | |
- Resolves variables and sends results to a writer. | |
</ul> | |
<p> | |
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 | |
<code>ConfigFileVar</code>. | |
These object dependencies are made by setting context objects on the var resolver. | |
</p> | |
<p> | |
Context objects are set through the {@link org.apache.juneau.svl.VarResolverBuilder | |
#contextObject(String,Object)} method. | |
They can be any class type. | |
</p> | |
<p> | |
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. | |
</p> | |
<p> | |
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 <code>Var</code> objects that use the <code>RestRequest</code> | |
object as a session object for the duration of a single HTTP request. | |
</p> | |
<p> | |
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 <code>Var</code> 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. | |
</p> | |
<p> | |
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. | |
</p> | |
<p> | |
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. | |
</p> | |
<h6 class='topic'>Example:</h6> | |
<p class='bcode'> | |
<jc>// Create a resolver that copies the default resolver and adds $C and $ARG vars.</jc> | |
VarResolver myVarResolver = VarResolver.<jsf>DEFAULT</jsf>.builder().vars(ConfigFileVar.<jk>class</jk>, | |
ArgsVar.<jk>class</jk>).build(); | |
</p> | |
</div> | |
<!-- ======================================================================================================== --> | |
<a id="OtherNotes"></a> | |
<h3 class='topic' onclick='toggle(this)'>1.3 - Other Notes</h3> | |
<div class='topic'> | |
<ul class='spaced-list'> | |
<li> | |
The escape character <js>'\'</js> can be used when necessary to escape the following characters: | |
<code>$ , { }</code> | |
<li> | |
<b>WARNING:</b> It is possible to cause {@link java.lang.StackOverflowError StackOverflowErrors} if | |
your nested variables result in a recursive loop (e.g. the environment variable | |
<code>'MYPROPERTY'</code> has the value <code>'$E{MYPROPERTY}'</code>). | |
So don't do that! | |
<li> | |
As a general rule, this class tries to be as efficient as possible by not creating new strings when not | |
needed. | |
<br>For example, calling the resolve method on a string that doesn't contain variables (e.g. | |
<code>resolver.resolve(<js>"foobar"</js>)</code>) will simply be a no-op and return the same string. | |
</ul> | |
</div> | |
</div> | |
</body> | |
</html> |