<- Compilation and Installation of JWIG Services Contents Services and Sessions ->

Constructing XHTML Documents

All output from a JWIG service has the form of XHTML documents, which are sent to the client to be shown in a browser window. These XHTML documents are constructed in the JWIG program by means of XML templates. An XML template is a fragment of XML syntax that may contain unspecified pieces called gaps. These gaps can be filled with strings or other templates to construct larger templates.

XML templates are represented in the JWIG program by values of the XML type. XML values are immutable. All operations that manipulate XML templates create new values.

XML template constants are written as plain XML text enclosed in double square brackets, [[ ... ]]. For example, the following piece of code declares a variable to contain XML template values and initializes it to Hello <i>World</i>!:

    XML hello = [[Hello <i>World</i>!]];

XML template constants must be well-formed, that is, the tags must be balanced and nest properly. Implicitly, the default namespace is set to http://www.w3.org/1999/xhtml (the XHTML 1.0 namespace).

Gaps and Plugs

XML template constants can contain named gaps, using the syntax <[name]>. The gap name must be a legal Java identifier. These gaps can be placed within text and tags, as if they were themselves tags. Gaps placed like this are called template gaps.

Gaps can also be placed inside tags, as the values of attributes. The syntax for this is to write the name of the gap enclosed in square brackets where you would normally write an attribute value enclosed in single or double quotes. For example, <a href=[link]> is an anchor start tag whose href attribute is a gap named link. Gaps placed like this are called attribute gaps.

Gaps are filled using the plug operator. This is an expression of type XML with the syntax exp1 <[name = exp2], where exp1 is an expression of type XML, name is an identifier indicating a gap name, and exp2 is an expression of type XML or String. The result of this expression is a copy of exp1 where all occurrences of gaps named name are replaced by a copy of exp2. All gaps in exp1 with names different from name will still be present in the result, and all gaps in exp2 are copied into the result as well, regardless of their name. Note that neither exp1 nor exp2 are modified in the operation.

Example:

    XML hello1 = [[<p align=[alignment]>Hello <[what]>!</p>]];
    XML hello2 = hello1 <[what = [[<i><[thing]></i>]]];
    XML hello3 = hello2 <[thing = "World"] <[alignment = "left"];

After executing this code, the values of the variables will be:

hello1:<p align=[alignment]>Hello <[what]>!</p>
hello2:<p align=[alignment]>Hello <i><[thing]></i>!</p>
hello3:<p align="left">Hello <i>World</i>!</p>

As can be seen from the example, both strings and XML templates can be plugged into template gaps. Attribute gaps, however, can only contain strings, since plugging an XML template into an attribute gap would result in malformed XML. Attempting this will result in an exception being thrown at runtime, as described later.

As a shorthand, the plug operator allows the plugging of any object or simple value. This will plug the corresponding string representation into the gap, as if the plugged value was passed through String.valueOf(). An exception to this is when the plugged object is a Class object representing a session class (described in the next section). This will plug the URL of the session (as described in the previous section) into the gap as a string. This is convenient for making links that start new sessions.

When a document is shown, as explained in the next section, all remaining template gaps in the shown document are replaced by empty strings. For all remaining attribute gaps, the whole attribute is removed. This can be used to control, dynamically, which attributes will be present in a given tag.

Code Gaps

In addition to template gaps and attribute gaps, which are filled using the plug operator, XML templates can contain inlined pieces of code, called code gaps. The syntax for a code gap is <{code}>, where code is Java code as it would appear in a normal Java method body. This code will be executed when the document is shown, and its result (indicated by return statements) is inserted at the point in the document where the code gap was.

Example:

    XML date = [[The current date is now <i><{ return new Date(); }></i>]];

When a document containing the value given to the date variable above is shown, the current date and time (as returned by new Date().toString()) will appear in place of the code gap. Note that any value can be returned by a code gap. It is treated as if it was plugged into a template gap.

Code gaps are executed in the order they appear in the document. If a code gap returns an XML template which itself contains code gaps, these will be executed as they appear, before processing subsequent code gaps in the original document.

External XML Templates

Instead of being written inlined in the JWIG program, an XML template constant can be placed in an external file and loaded into the program at runtime using the construct get url, where url is a string constant indicating the location of the template constant. This file should be a plain XML fragment (without the double square brackets).

Example:

    XML doc = get "http://www.brics.dk/JWIG/test.xml";

When this code is executed, the designated file will be fetched and parsed, and the resulting XML template will be pointed to by doc.

The retrieval of the document will happen every time the get url expression is evaluated. This makes it possible to change the appearance of a running service simply by changing the external templates. (If this behavior is not needed or not desired, the get url expression should be used in such a way that the template is not fetched every time its value is needed, since this could drastically impair the performance of the service.)

An external XML template can contain template gaps and attribute gaps just like an inlined one. However, it cannot contain code gaps, since this would require runtime compilation of code into the running service.

Exceptions

A number of exceptions can be thrown as a result of XML template manipulation. These are:

PlugException:
Thrown when an attempt is made to plug into a gap that does not occur in the given document or when an XML template is plugged into an attribute gap.
XMLException:
Thrown when a syntax error is encountered in an XML template constant. For inline template constants, the exception is thrown when the constant expression is evaluated. For external templates, it is thrown when the get url expression is evaluated, during parsing of the loaded file. A code gap in an external XML template will also cause this exception to be thrown.
IOException:
Thrown by the get url expression if the specified file could not be found, or if some other I/O error occurred during the fetching.

The JWIG static analysis is able to verify statically for a given JWIG program, that none of the two first of these exceptions can occur at runtime, provided that no external XML templates have been changed since the time of the analysis. In addition, the analysis also checks that all documents being constructed are valid XHTML 1.0, which is the XML variant of HTML 4.01.


<- Compilation and Installation of JWIG Services Contents Services and Sessions ->