com.ibm.wbi.protocol.http.beans
Class HtmlTemplateGenerator

com.ibm.wbi.Meg
  |
  +--com.ibm.wbi.Generator
        |
        +--com.ibm.wbi.protocol.http.HttpGenerator
              |
              +--com.ibm.wbi.protocol.http.beans.FourStepHttpGenerator
                    |
                    +--com.ibm.wbi.protocol.http.beans.HtmlGenerator
                          |
                          +--com.ibm.wbi.protocol.http.beans.HtmlTemplateGenerator
All Implemented Interfaces:
SetClassLoader

public class HtmlTemplateGenerator
extends HtmlGenerator
implements SetClassLoader

HttpGenerator that produces an HTML page using a page template and a set of variables. An HTML template is an object that allows filling out variables in html files. The html file is written with special tags that are replaced with values from the template. There are two forms for the special tags, and each one takes optional-formatting-flags that correspond to the MessageFormat modifiers.

  1. simple variables, as in ${var,optional-formatting-flags}.
  2. iterator tags for arrays, as in ${iterate i to bound,optional-formatting-flags}...${enditerate}.
  3. iterator tags for enumerations, as in ${iterate i on enum,optional-formatting-flags}...${enditerate}.
  4. conditional tags , as in ${if [obj1] [operator] [obj2]}...${endif}

    The parameter [obj1] is an object, string, or integer. [obj2] is an object of the same type as [obj1], and may not be present depending on [operator]. Valid operators for Integers are: ==, !=, >, <. >=, <=, odd, even. The odd and even operators do not need the [obj2] argument. If [obj1] is a String, then valid operators are: ==, equals, !=, isNot, equalsIgnoreCase, notEqualsIgnoreCase, isNull, isNotNull. If [obj1] is a Boolean, then valid operators are isTrue, isFalse, and isNotTrue. For all other types of [obj1], the only valid operators are: ==, !=, isNull, isNotNull.

When a Vector, Hashtable, or Dictionary is used in an iteration, then an enumeration of its elements is automatically created by calling the elements() method.

By default, the output strings are HTML-escaped, which means that the symbols less than, greater than, double quote, and ampersand are replaced with the appropriate escape sequence so that they will be displayed properly. If a string is to be interpreted literally, then rather than referencing a variable as ${myvariable}, you should prepend a '#' to the name; for instance, ${#myvariable}. If you wish to HTML-escape a string, you should prepend a '%', for instance, ${%myvariable}. If you wish to generate no output from a command, prepend a '!'. This can be useful in calling methods that have should no output.

Because bound variables may have methods associated with them, we support the ability to call those methods, including calling methods with arguments. For example,

     ${city.getZipCode("San Jose, CA")}
     ${city.getZipCode(localCity.getName())}
 
Method arguments themselves may be the results of function calls, or they can be double-quoted strings (such as "example string"), integers, or single-quoted characters (such as 'Z'). When iterating through enumerations, a special index variable, the index name appended with "-index" can be used to get the current iteration index. This index starts counting from 0, and thus can be useful in printing lists, or in conditional operations on alternating lines, such as changing the background cell color in a table.

When a variable is expanded, its value is obtained by first checking to see if it is a regular variable (set with addVariable()), and if that fails, the global variable list is checked. The global variable list is static to the HtmlTemplateGenerator class and is useful for things like variables that occur in the headers and footers.

Notice that there are three special rules for the substitution tags:

  1. a variable cannot be named "iterate" or "enditerate", as these are reserved keywords,
  2. to output literally the string ${a}, the $ must be escaped using another $.
  3. an enumeration can be reused multiple places in the template, and so can an array (see below).

If a is a variable with value "Value of A", "A=${a}" will be expanded to "A=Value of A", but "A=$${a}" will not be expanded. In the latter case, the string "A=${a}$ will emerge from the template.

A simple example

    FileReader readr = new FileReader("intro.html");
    HtmlTemplateGenerator template = new HtmlTemplateGenerator();
    template.setTemplateFromReader( (Reader)readr );
    template.addVariable( "result", "success" );
    template.setup( "TemplateGenerator", "host _test & path /test", 1 );
    addMeg( template );
 
If the file intro.html looks like:
    Your form submission resulted in ${result}.
 
then the resulting output would be
    Your form submission resulted in success.
 

A realistic example

  class PageFilterGenerator extends HttpGenerator {
    // template string
    final static String template =
        "<html><head><title>Starting Points</title></head>\n" +
        "<body>\n" +
         "<h1>PageFilter</h1>\n" +
        ">h2>Possible starting pages</h2>\n" +
        "<table>\n" +
        "${iterate i on pageList}" +
        "<tr>lt;tdgt;<a href='${i.sample}'>${i.title}</a>\n" +
        "</td><td>${i.pattern.pattern}</td>lt;/tr>\n" +
        "${enditerate}\n" +
        "</table>\n" +
        "<p><a href='http://_wbipagefilter/setupPage'>Add Pages to List</a>\n" +
        "</body></html>";

    // when handling a request, create new template generator and set its varibles at run time
    public void handleRequest( RequestEvent e ) throws RequestRejectedException, IOException {
      HtmlTemplateGenerator htg = new HtmlTemplateGenerator();
      htg.setTemplate( template );
      htg.addVariable( "pageList", pageList );
      forwardRequest( htg, e );
    }
  }
 

A Complicated Example Using Iterators

Suppose that the file sample.html contains
    This is a test of array operations:

    Arg 0 = ${args[0]}
    Arg 1 = ${args[1]}
    Arg 2 = ${args[2]}

    Here are member operations: { ${example1.name}, ${example1.number}}

    Here are member operations with array operations:

    Example2 is {
      { ${example2[0].name}, ${example2[0].number}}
      { ${example2[1].name}, ${example2[1].number}}
    }

    A bit more complex:
    ${example2[example1.number].name}

    Here is an error:

      ${example2[5].name}

    Okay, now for the iterators:

    This tests the counting iterator and the length field on arrays
      ${iterate i to args.length}
        Arg ${i} is ${args[i]}
      ${enditerate}

    This test the enumeration iterator
      ${iterate i on enumeration1}
        ${if i-index even}
          ++++ ${i.number}, ${i.name}
        ${endif}
        ${if i-index odd}
          oooo ${i.number}, ${i.name}
        ${endif}
      ${enditerate}

    Now we nest them:
      ${iterate i on enumeration2}
        ${i.number}, ${i.name}
        Here are the args again:
        ${iterate j to args.length}
          Arg ${j} is ${args[j]}
        ${enditerate}

      ${enditerate}

    Watch, when we try and use an enumeration again, it fails!
      ${iterate i on enumeration1}
        ${i.number}, ${i.name}
      ${enditerate}
 
Now suppose we have code with the following:
  class exampleClass {
   String name;
   int number;

   public exampleClass( String name, int number ) {
	 this.name = name;
	 this.number = number;
   }
  }

   ...

	HtmlTemplate.setHeader(new StringReader( "<title>${title}</title>\n" ) );

	// Now the footer
	HtmlTemplate.setFooter(new StringReader( "<footer>${bye}</footer>\n" ) );

	// All footers are to have the same message, so we make it a global
	// variable
	HtmlTemplate.addGlobalVariable( "bye", "See ya" );
	
	// Now instantiate the body from a resource
	HtmlTemplate template = new HtmlTemplate( "sample.html" );

   // Set up the header and footer variables
   template.addVariable( "title", "This is the title" );
 		
   // Now setup the variables that are going to be used in the body
   template.addVariable( "example1", new exampleClass( "First", 1 ) );
   exampleClass example2[] = new exampleClass[2];
   example2[0] = new exampleClass( "Element 1", 0 );
   example2[1] = new exampleClass( "Element 2", 1 );
   template.addVariable( "example2", example2 );
   template.addVariable( "args", args );
   Vector vector = new Vector();
   vector.addElement( new exampleClass( "Vector element 1", 1 ) );
   vector.addElement( new exampleClass( "Vector element 2", 2 ) );
   vector.addElement( new exampleClass( "Vector element 3", 3 ) );
   template.addVariable( "enumeration1", vector.elements() );
   template.addVariable( "enumeration2", vector.elements() );

   // Dump out the page
   OutputStreamWriter ow = new OutputStreamWriter( System.out );
   template.doHeader( ow );
   template.outputTemplate( ow );
   template.doFooter( ow );
 
When this code is run, it produces the following output:
  <title>This is the title</title>
  This is a test of array operations:

  Arg 0 = first
  Arg 1 = second
  Arg 2 = thurd

  Here are member operations: { First, 1}

  Here are member operations with array operations:

  Example2 is {
  { Element 1, 0}
  { Element 2, 1}
  }

  A bit more complex:
  Element 2

  Here is an error:

  !****** 5 out of range ***!

  Okay, now for the iterators:

  This tests the counting iterator and the length field on arrays
  Arg 0 is first
  Arg 1 is second
  Arg 2 is thurd

  This test the enumeration iterator
  ++++ 1, Vector element 1
  oooo 2, Vector element 2
  ++++ 3, Vector element 3

  Now we nest them:
  1, Vector element 1
  Here are the args again:
     Arg 0 is first
     Arg 1 is second
     Arg 2 is thurd

  2, Vector element 2
  Here are the args again:
     Arg 0 is first
     Arg 1 is second
     Arg 2 is thurd

  3, Vector element 3
  Here are the args again:
     Arg 0 is first
     Arg 1 is second
     Arg 2 is thurd


 Watch, when we try and use an enumeration again, it fails!
  1, Vector element 1
  2, Vector element 2
  3, Vector element 3

  <footer>See ya</footer>
 
If a variable in the html file is not supplied, then it will result in an error message included in the output stream.

See Also:
java.text.MessageFormat

Fields inherited from class com.ibm.wbi.protocol.http.beans.HtmlGenerator
COPYRIGHT
 
Fields inherited from class com.ibm.wbi.protocol.http.HttpGenerator
http
 
Fields inherited from class com.ibm.wbi.Meg
EDITOR, GENERATOR, MONITOR, REQUEST_EDITOR, UNDEFINED
 
Constructor Summary
HtmlTemplateGenerator()
          default constructor
 
Method Summary
static void addGlobalVariable(java.lang.String name, java.lang.Object value)
          Add a global variable to be used when expanding tags.
 void addVariable(java.lang.String name, java.lang.Object value)
          Add a variable to be used when expanding tags.
protected  java.lang.String getHtmlString(RequestEvent e)
          Builds the HTML from the Template and variable definitions (overrides the method from HtmlGenerator)
static void removeGlobalVariable(java.lang.String name)
          Remove a global variable definition
 void removeVariable(java.lang.String name)
          Remove a variable definition
static void resetGlobalVariables()
          Remove all global variable definitions
 void resetVariables()
          Remove all variable definitions
 java.lang.ClassLoader setClassLoader(java.lang.ClassLoader ldr)
          If loading the template from a resource, then this hook is invoked to ensure that the appropriate classloader is used to load the resource.
 void setFooter(java.io.Reader reader)
          Sets the standard footer that will be output to all subsequent pages when the doFooter() method is called.
 void setFooter(java.lang.String footer)
          Sets the standard footer that will be output to all subsequent pages when the doFooter() method is called.
 void setHeader(java.io.Reader reader)
          Sets the standard header that will be output to all subsequent pages when the doHeader() method is called.
 void setHeader(java.lang.String header)
          Sets the standard header that will be output to all subsequent pages when the doHeader() method is called.
 void setTemplate(java.lang.String templateString)
          set the Template property with the given string
 void setTemplateFromReader(java.io.Reader reader)
          set the Template property based on what is read from the given Reader
 void setTemplateFromResource(java.lang.String resourceName)
          set the Template property from resources without header and footer.
 
Methods inherited from class com.ibm.wbi.protocol.http.beans.HtmlGenerator
writeContent
 
Methods inherited from class com.ibm.wbi.protocol.http.beans.FourStepHttpGenerator
getHeader, handleRequest, initialize, verify
 
Methods inherited from class com.ibm.wbi.protocol.http.HttpGenerator
add, addCookie, getContentType, getHttpResponse, getHttpResponseString, getResponseCode, getResponseText, isCache, produceHeader, set, setCache, setContentLength, setContentType, setResponseCode, setResponseText, setServer, writeHeader
 
Methods inherited from class com.ibm.wbi.Generator
getType
 
Methods inherited from class com.ibm.wbi.Meg
forwardRequest, getCondition, getEnabled, getMegProperty, getMegProperty, getMegPropertyKeys, getName, getPlugin, getPriority, getSystemContext, initialize, initialize, isEnabled, isMegApplicable, loadMegResources, run, setCondition, setEnabled, setMegProperty, setName, setPriority, setSystemContext, setup, setup, setup, setup
 

Constructor Detail

HtmlTemplateGenerator

public HtmlTemplateGenerator()
default constructor
Method Detail

setTemplate

public void setTemplate(java.lang.String templateString)
set the Template property with the given string

setTemplateFromResource

public void setTemplateFromResource(java.lang.String resourceName)
set the Template property from resources without header and footer.
Parameters:
resourceName - The name of the resource. The package elements should be delimited by /'s
See Also:
ClassLoader.getSystemResourceAsStream(String)

setTemplateFromReader

public void setTemplateFromReader(java.io.Reader reader)
set the Template property based on what is read from the given Reader

setHeader

public void setHeader(java.lang.String header)
               throws java.io.IOException
Sets the standard header that will be output to all subsequent pages when the doHeader() method is called. to be set for use with this header.
Parameters:
header - a reader that contains the header

setHeader

public void setHeader(java.io.Reader reader)
Sets the standard header that will be output to all subsequent pages when the doHeader() method is called. to be set for use with this header.
Parameters:
header - a reader that contains the header

setFooter

public void setFooter(java.lang.String footer)
               throws java.io.IOException
Sets the standard footer that will be output to all subsequent pages when the doFooter() method is called. When using it is important to make know the variables that will need to be set for use with this footer.
Parameters:
footer - The name of the resource to retreive from the CLASSPATH

setFooter

public void setFooter(java.io.Reader reader)
Sets the standard footer that will be output to all subsequent pages when the doFooter() method is called. When using it is important to make know the variables that will need to be set for use with this footer.
Parameters:
footer - a reader that contains the footer

addVariable

public void addVariable(java.lang.String name,
                        java.lang.Object value)
Add a variable to be used when expanding tags. (If the variable is already defined, the old definition will be deleted.)
Parameters:
String - name - the name of the variable, which will be used in the Template to reference this variable.
Object - value - the variable itself. This variable is saved in the variable table. If it is an Enumeration, it is actually turned into a Vector, so the Enumeration can be regenerated. When a Vector, Hashtable, or Dictionary is added, if it happens to be used in an iteration, then an enumeration of its elements is automagically created by calling the elements() method.

resetVariables

public void resetVariables()
Remove all variable definitions

removeVariable

public void removeVariable(java.lang.String name)
Remove a variable definition

addGlobalVariable

public static void addGlobalVariable(java.lang.String name,
                                     java.lang.Object value)
Add a global variable to be used when expanding tags. (If the variable is already defined, the old definition will be deleted.) Global variables are used if a regular variable with the same name does not exist.

resetGlobalVariables

public static void resetGlobalVariables()
Remove all global variable definitions

removeGlobalVariable

public static void removeGlobalVariable(java.lang.String name)
Remove a global variable definition

getHtmlString

protected java.lang.String getHtmlString(RequestEvent e)
Builds the HTML from the Template and variable definitions (overrides the method from HtmlGenerator)
Overrides:
getHtmlString in class HtmlGenerator
See Also:
HtmlGenerator

setClassLoader

public java.lang.ClassLoader setClassLoader(java.lang.ClassLoader ldr)
If loading the template from a resource, then this hook is invoked to ensure that the appropriate classloader is used to load the resource.
Specified by:
setClassLoader in interface SetClassLoader