{title:'SVL Variables', updated:'9.0.0'}

In the previous examples, there were several cases where embedded variables were contained within annotation values:

| @Rest( | title="$L{my.label}" | )

Variables take the form $X{contents} where X can consist of zero or more ASCII characters and contents can be virtually anything. This is called Simple Variable Language, or SVL, and is defined here: {@doc jm.SimpleVariableLanguage Simple Variable Language}.

##### Features

- Variables can be nested arbitrarily deep (e.g. "$X{$Y{foo}}").
- Variables can contain arguments (e.g. "$L{my.label,arg1,arg2}").
- Variables are recursively resolved.
  i.e., if a variable results to a value with another variable in it, that variable will also be resolved (restricted for security reasons on variables that involve user input).

There are two distinct groups of variables:

- Initialization-time variables
  These are variables that can be used in many of the annotations in {@link oajr.annotation.Rest @Rest}.
  The {@link oajr.RestContext#getVarResolver()} method returns initialization-time variables only.
- Request-time variables
  These are variables that are available during HTTP-requests and can be used on annotation such as {@del oajr.annotation.HtmlDoc @HtmlDoc}.
  {@link oajr.RestRequest#getVarResolverSession()} method returns initialization and request-time variables.

The following is the default list of supported variables.

##### Default REST SVL Variables:

Module | Class | Pattern | Initialization time | Request time | Examples
--- | --- | --- | --- | --- | ---
juneau-svl | {@link oaj.svl.vars.EnvVariablesVar} | $E{key[,default]} | yes | yes | $E{PATH}
{@link oaj.svl.vars.SystemPropertiesVar} | $S{key[,default]} | yes | yes | $S{java.home}
{@link oaj.svl.vars.ArgsVar} | $A{key[,default]} | yes | yes | $A{foo,null}
{@link oaj.svl.vars.ManifestFileVar} | $MF{key[,default]} | yes | yes | $MF{Main-Class}
{@link oaj.svl.vars.IfVar} | $IF{arg,then[,else]} | yes | yes | $IF{$S{my.boolean.property},foo,bar}
{@link oaj.svl.vars.SwitchVar} | $SW{arg,p1:then1[,p2:then2...]} | yes | yes | $SW{$S{os.name},*win*:Windows,*:Something else}
{@link oaj.svl.vars.CoalesceVar} | $CO{arg1[,arg2...]} | yes | yes | $CO{$S{my.property},$E{my.property},n/a}
{@link oaj.svl.vars.PatternMatchVar} | $PM{arg,pattern} | yes | yes | $PM{$S{os.name},*win*}
{@link oaj.svl.vars.NotEmptyVar} | $NE{arg} | yes | yes | $NE{$S{foo}}
{@link oaj.svl.vars.UpperCaseVar} | $UC{arg} | yes | yes | $UC{$S{foo}}
{@link oaj.svl.vars.LowerCaseVar} | $LC{arg} | yes | yes | $LC{$S{foo}}
juneau-config | {@link oaj.config.vars.ConfigVar} | $C{key[,default]} | yes | yes | $C{REST/staticFiles}
juneau-rest-server | {@link oajr.vars.FileVar} | $F{path[,default]}} | yes | yes | $F{resources/MyAsideMessage.html, Oops not found!}
{@link oajr.vars.ServletInitParamVar} | $I{name[,default]} | yes | yes | $I{my.param}
{@link oajr.vars.LocalizationVar} | $L{key[,args...]} | no | yes | $L{MyMessage,foo,bar}
{@link oajr.vars.RequestAttributeVar} | $RA{key1[,key2...]} | no | yes | $RA{attrName}
{@link oajr.vars.RequestFormDataVar} | $RF{key1[,key2...]} | no | yes | $RF{paramName}
{@link oajr.vars.RequestHeaderVar} | $RH{key1[,key2...]} | no | yes | $RH{Header-Name}
{@link oajr.vars.RequestPathVar} | $RP{key1[,key2...]} | no | yes | $RP{pathVAr}
{@link oajr.vars.RequestQueryVar} | $RQ{key1[,key2...]} | no | yes | $RQ{paramName}
{@link oajr.vars.RequestSwaggerVar} | $RS{key} | no | yes | $RS{title}
{@link oajr.vars.RequestVar} | $R{key1[,key2...]} | no | yes | $R{contextPath}
{@link oajr.vars.SerializedRequestAttrVar} | $SA{contentType,key[,default]} | no | yes | $SA{application/json,$RA{foo}}
{@link oajr.vars.UrlVar} | $U{uri}> | no | yes | $U{servlet:/foo}
{@link oajr.vars.UrlEncodeVar} | $UE{uriPart} | yes | yes | $U{servlet:/foo?bar=$UE{$RA{bar}}
{@link oajr.widget.Widget} | $W{name} | no | yes | $W{MenuItemWidget}

Custom variables can be defined on resources via the following API:

- {@link oajr.RestContext.Builder}
  - {@link oajr.RestContext.Builder#createVarResolver(BeanStore,Class) createVarResolver(BeanStore,Class)}
  - {@link oajr.RestContext.Builder#varResolver() varResolver()}
  - {@link oajr.RestContext.Builder#varResolver(Consumer) varResolver(Consumer)}

##### Example:

| // Defined a variable that simply wrapps all strings inside [] brackets. | // e.g. "$BRACKET{foobar}" -> "[foobar]" | public class BracketVar extends SimpleVar { | | public BracketVar() { | super("BRACKET"); | } | | @Override /* Var */ | public String resolve(VarResolverSession session, String arg) { | return '[' + arg + ']'; | } | } | | // Register it with our resource. | @Rest(...) | public class MyResource { | | public MyResource(RestContext.Builder builder) { | builder.varResolver().vars(BracketVar.class); | } | }

The methods involved with variables are:

- {@link oajr.RestContext}
  - {@link oajr.RestContext#getVarResolver() getVarResolver()}
- {@link oajr.RestRequest}
  - {@link oajr.RestRequest#getVarResolverSession() getVarResolverSession()}