sunlabs.brazil.template
Class BSLTemplate

java.lang.Object
  extended by sunlabs.brazil.template.Template
      extended by sunlabs.brazil.template.BSLTemplate (view source)
All Implemented Interfaces:
Serializable, TemplateInterface

public class BSLTemplate
extends Template
implements Serializable

The BSLTemplate takes an HTML document with embedded "BSL" markup tags in it and evaluates those special tags to produce a standard HTML document.

BSL stands for Brazil Scripting Language. BSL can be used to substitute data from the request properties into the resultant document. However, rather than simple property substitution as is provided by the SetTemplate, this class provides the ability to iterate over and choose amongst the values substituted with a set of simple flow-control constructs.

BSL uses the following special tags as its language constructs:

This template recursively evalutes the bodies/clauses of the BSL commands, meaning that they may contain nested BSL and/or other tags defined by other templates.

The following configuration parameter is used to initialize this template.

debug
If this configuration parameter is present, this template replaces the BSL tags with comments, so the user can keep track of where the dynamically generated content is coming from by examining the comments in the resultant HTML document. By default, the BSL tags are completely eliminated from the HTML document rather than changed into comments.

<if> TAG

The <if> tag evaluates one of its clauses dependant upon the value of the provided conditions. The other clauses are not evaluated and do not appear in the resultant HTML document. The general format of the <if> tag is as follows:
 <if [not] condition>
     clause
 <elseif [not] condition>
     clause
 <else>
     clause
 </if> 
The <elseif> and <else> tags are optional, and multiple <elseif> tags may be present. <elseif> may also be spelled <elif> or <else if>. The optional parameter not reverses the sense of the specified condition.

Following are the formats of the condition:

<if name=var>
Test if the value of property var is set and is not "", "false", "no", "off", or the number 0.

<if name=var value=string>
Test if the value of property var is equal to the given string.

<if name=pattern any>
Test if any property exists that matches matches the given glob pattern. Note: This may be expensive if there are large numbers of properties.

<if name=var glob=pattern>
Test if the value of property var matches the given glob pattern.

<if name=var match=pattern>
Test if the value of property var matches the given regular expression pattern.

if the attribute nocase is present, then a case insensitive match is performed.

<if expr=numeric expression>
The numeric expression is evaluated. If the result is "1", then the condition is satisfied. This uses Calculator to evaluate the expression. Any vaiable that is defined, but not "0"m "off" or "no" is considered to have a value of "1" for the purposes of the expression evaluation. This allows (as an example) the expression "x && y && ! z" to evaluate to "true" only if the variables "x" and "y", but not "z" are defined *(and not "0", "no" or "false".
Normally, the variable is look-up in the Properties Stack, starting with the Request Properties. The attribute "namespace" may be used to look-up the variable in the specified namespace.

<foreach> TAG

The <foreach> tag repeatedly evaluates its body a selected number of times. Each time the body is evaluated, the provided named property is set to the next word in the provided list of words. The body is terminated by the </foreach> tag. This tag is especially useful for dynamically producing lists and tables. All the temporary properties that this tag creates are visible only within the body for the duration of the <foreach>.

if the attribute nocase is present, then a case insensitive match is performed.

When either glob or match is specified, then the "namespace" attribute may be used to restrict the name lookups to start with that namespace. However, the values aren't restricted to being in the specified namespace.

BUG: You must only specify a "namespace" if it has already been imported.

Sorting using foreach

The <foreach> tag contains a feature to change the order of iteration. This facility is intended for common sorting operations. For general purpose manipulation of the iteration order, the order should be defined either in another handler, or by using the <server> directive.

The four additional parameters used to control sorting are:

reverse
The list of items is iterated in the reverse order.

sort[=key]
The items to be iterated over are sorted. If no key is supplied, the items are sorted by the property name. If a key is supplied, its value is used as the sort key for the iteration. For this to be meaningful, the key should contain variable substitutions (e.g. ${...}, see getProperty). A sample use of the sort key would be:
 <foreach name=id property=employee.ids sort="${employee.${id}.last}, ${employee.${id}.first}">
This option can be tricky to use correctly. The following example will not sort employees by last name:
 1. <foreach name=id property=employee.ids sort="employee.${id}.last">
Why? Because another level of ${...} needs to be inserted in the sort key:
 2. <foreach name=id property=employee.ids sort="${employee.${id}.last}">
Example (1) will just sort the literal strings "employee.1234.last", "employee.5678.last", etc. while example (2) will do the correct thing and sort the values "Stevens" and "Johnson". Remember that BSL sorts based on exactly what you pass it and does not know that the provided string should be treated as another variable itself.

numeric
When used in conjunction with the sort parameter, it causes the items to be interpreted as numbers (or zero if the item doesn't look like a number).

nocase
When used in conjunction with the sort parameter, it causes the items to be sorted in a case-insensitive fashion.

Note that when used with "glob=..." or "match=...", it does NOT cause the glob or regular expression to be case insensitive. It causes the results of the glob or regexp to be sorted in a case-insensitive fashion. There is currently no way to specify a case-insensitive glob or regular expression.


<abort> TAG

The <abort> tag terminates processing of the current HTML page at the point it is evaluated. All HTML on the page after the <abort> tag is discarded, and the HTML processed up to that point is returned. This tag can be placed anywhere on a page, including within a <foreach> or <if> construct.

The following is an example usage of this tag:

 <foreach name=x list="0 1 2 3">
   <if name=x value=3>
     <abort>
   </if>
   <get name=x>
 </foreach> 
 Testing
 
This example produces the output:

 0 1 2
 

<break> TAG

The <break> tag terminates processing within a <foreach> construct. The processing of HTML continues immediately after the </foreach>. This tag can only be used inside of a <foreach> tag.

The following is an example usage of this tag:

 <foreach name=x list="0 1 2 3">
   <if name=x value=3>
     <break>
   </if>
   <get name=x>
 </foreach> 
 Testing
 
This example produces the output:

 0 1 2 Testing
 

<continue> TAG

The <continue> tag continues processing at the top of a <foreach> construct. This skips any HTML after the <continue> tag and before the </foreach>. This tag can only be used inside of a <foreach> tag.

The following is an example usage of this tag:

 <foreach name=x list="0 1 2 3">
   <if name=x value=2>
     <continue>
   </if>
   <get name=x>
 </foreach> 
 Testing
 
This example produces the output:

 0 1 3 Testing
 

<extract> TAG

The <extract> tag permits portions of a property's value to be extracted into additional properties, based on either glob or regular expression patterns. The extract tag takes the following tag parameters:
name=var
The name of the property whose value will be split up and extracted.

prepend=base
Optional parameter that specifies the base string to prepend to the extracted properties. The default value for base is the specified property name var.

glob=pattern
The glob pattern to match against. In turn, the following properties are set:
base.1, base.2, ... are the substrings that matched the wildcard characters in the pattern.

match=pattern
The regular expression pattern to match against. In turn, the following properties are set:
base.0 is the substring that matched the whole pattern.
base.1, base.2, ... are the substrings that matched the parenthesized subexpressions in pattern, if any.

If the attribute all is present, then all matches and submatches are extracted into properties. The properties base.0, base.1, etc., are set to the 1st matched expression, the 2nd matched expression, etc. The properties base.0.0, base.0.1... are set to the sub-matches of the first full match, and so forth. If any matches are found the following additional properties are set:

basematches
The number of times the regular expression was matched.
basesubmatches.
The number of sub-expressions for this regular expression.
basematchelist.
The list of matches (e.g. "1 2 3 ...").
replace=substitution
If specified (with match), then no portions of the value are extracted. Instead, a regular expression substitution is performed (see substitution). The resultant substituted value is placed in the property: prefix.replace.
map
A white space separated list of names that will be used to name sub-matches, instead of .1, .2, ... etc. See tag_extract(sunlabs.brazil.template.RewriteContext) for more detail.
One of glob or match must be specified.

In addition, the property base.matches is set to a value indicating the number of matches and submatches stored. This property can be examined and compared with 0 to determine if the <extract> tag matched at all. If there was no match, the numbered properties base.N are not set or changed from their previous value.


Anytime an argument is specified to one of the BSL tags, variable substitution as described in getProperty may be used.

Any time a boolean parameter (XXX) is allowed (nocase, not, numeric, or reverse) it is considered false if it takes any of the forms: XXX=0, XXX=no, XXX=false XXX="". If it takes the forms XXX or XXX="anything else", the value is true.

see a sample HTML page that contains some BSL markup.

See Also:
SetTemplate, Serialized Form

Field Summary
static int ABORT
           
static int BREAK
           
static int CONTINUE
           
 
Fields inherited from class sunlabs.brazil.template.Template
debug
 
Constructor Summary
BSLTemplate()
           
 
Method Summary
 boolean init(RewriteContext hr)
          Called before this template processes any tags.
 void tag_abort(RewriteContext hr)
          Handles the "abort" tag.
 void tag_break(RewriteContext hr)
          Handles the "break" tag.
 void tag_continue(RewriteContext hr)
          Handles the "continue" tag.
 void tag_extract(RewriteContext hr)
          Handle the [experimental] "extract" tag.
 void tag_foreach(RewriteContext hr)
          Handles the "foreach" tag.
 void tag_if(RewriteContext hr)
          Handles the "if" tag.
 
Methods inherited from class sunlabs.brazil.template.Template
done
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ABORT

public static final int ABORT
See Also:
Constant Field Values

BREAK

public static final int BREAK
See Also:
Constant Field Values

CONTINUE

public static final int CONTINUE
See Also:
Constant Field Values
Constructor Detail

BSLTemplate

public BSLTemplate()
Method Detail

init

public boolean init(RewriteContext hr)
Description copied from class: Template
Called before this template processes any tags.

Specified by:
init in interface TemplateInterface
Overrides:
init in class Template

tag_abort

public void tag_abort(RewriteContext hr)
Handles the "abort" tag.


tag_break

public void tag_break(RewriteContext hr)
Handles the "break" tag.


tag_continue

public void tag_continue(RewriteContext hr)
Handles the "continue" tag.


tag_foreach

public void tag_foreach(RewriteContext hr)
Handles the "foreach" tag.


tag_if

public void tag_if(RewriteContext hr)
Handles the "if" tag.


tag_extract

public void tag_extract(RewriteContext hr)
Handle the [experimental] "extract" tag. This permits parts of a property's value to be extracted into additional properties, based on either glob or regular expression patterns.
<extract name= prepend= glob= match=>
name
The name of the property to extract
prepend
The base name for all extracted properties (defaults to "name"). If it doesn't end with a ".", one is added.
glob
The glob pattern to use for extraction. The text matching each wildcard in the pattern is extracted.
match
The regular expression pattern to use for extraction. The text matching each sub-expression is extracted. If "glob" is specified, then "match" is ignored.
null
the value to return if there was no match [or sub-match] (defaults to "").
map
a white space separated list of names that will be used to name sub-matches, instead of .1, .2, ... etc. If there are more sub expressions than names, then the indeces are used after the names run out. The example:
                <set name=entry value="joe:211A:x3321">
                <extract name=entry glob=*:*:* map="name room phone">
                
Will return the values:
          entry.name=joe
          entry.room=211A
          entry.phone=x3321
          
In "glob" extraction, each wildcard in the glob pattern is assigned the next token in "map". in Regular expression extractions, when "all" is specified, the map names are used to name the sub-expressions. Without "all" the names are assigned like "glob", only the first name gets the entire match (e.g. you need one more name for "match" than for "glob". namespace
Normally, results are extracted into the current request namespace. If namespace is specified, then the results are placed into the named namespace. The names "server" and "local" are special (see SetTemplate).

NOTE: The namespace will be accessable by any other templates associated with the same TemplateRunner, using the default sessionTable (see SetTemplate).


Version Kenai-svn-r24, Generated 08/18/09
Copyright (c) 2001-2009, Sun Microsystems.