HierarchicalMap Tutorial - Intermediate Level
HierarchicalMap is an interface. So anyone can implement it. This tutorial is based on BasicHierarchicalmap, a reference implementation of HierarchicalMap.
Following subjects are covered in this tutorial:
(Javascript must be enabled to allow syntax highlighting for source code snippets in this tutorial)
Advanced Level
11. Template FillingTemplate containing static content can be merged with HierarchicalMap to produce a new text document. There are two classes to handle template: org.dhmp.util.stylesheet.Script and org.dhmp.util.stylesheet.ScriptCollection.
A very simple language was defined to interact with HierarchicalMap.
Substitution
First, write down a text file with following content and name it "greetingTemplate.html" then place it on "/temp" directory:
<html> <body> <h>Hello <substitution name='greeting'/>!</h> </body> </html>
The following snippet of code will generate an html output "greeting.html" on "/temp" directory.
// parse template html ScriptCollection scripts = new ScriptCollection( new File("/temp")); Script script = scripts.get("greetingTemplate.html"); // prepare the data HierarchicalMap hmap = new BasicHierarchicalMap(); hmap.add("greeting", "world"); // fill out the template to generate final html Writer writer = new FileWriter("/temp/greeting.html"); script.eval(writer, hmap); writer.close();
The object ScriptCollection compiles the template into Script and keep it cached inside its structure. The constructor can receive a java.io.File object from where it will fetch the template. On the above example it will search for the template on "/temp" directory. There are another constructor which will accept an array of File or a java.net.URL.
Then the method get() will interprete the template language and compile it into Script Object. Note that compilation is not thread safe. Once Script is obtained, you can use it to generate a document replacing some tags with the content of HierarchicalMap and write down the result on writer object.
On the example above, substitution is a self-closing tag. But any text between opening and closing tag will be ignored.
<html> <body> <h>Hello <substitution name='familiar/greeting'> world </substitution>!</h> </body> </html>
Create a template with above content and save it as "/temp/greetingTemplate2.html". Then execute the code below:
// parse template html ScriptCollection scripts = new ScriptCollection( new File("/temp")); Script script = scripts.get("greetingTemplate2.html"); // prepare the data HierarchicalMap hmap = new BasicHierarchicalMap(); HierarchicalMap hmap2 = hmap.add("familiar"); hmap2.add("greeting", "my friends"); // fill out the template to generate final html Writer writer = new FileWriter("/temp/greeting2.html"); script.eval(writer, hmap); writer.close();
The result should be:
Condition If-Then-Else
Now, let's see the conditions. Create a document "/temp/conditionTemplate.html" with following content:
<html> <body> <h>Hello, <substitution name='greeting'/>!</h> <br> <if condition='flag'> <then>Flag exists</then> <else>Flag does not exist</else> </if> </body> </html>
Now, execute the code below:
// parse template html ScriptCollection scripts = new ScriptCollection( new File("/temp")); Script script = scripts.get("conditionTemplate.html"); // prepare the data HierarchicalMap hmap = new BasicHierarchicalMap(); hmap.add("greeting", "testing simple condition"); hmap.add("flag", ""); // fill out the template to generate final html Writer writer = new FileWriter("/temp/condition.html"); script.eval(writer, hmap); writer.close();
The result should be:
For the condition to met, the existence of node or leaf with key name same as condition name is enough regardless of its content.
If the same template is executed without setting the flag as in code below:.
// parse template html ScriptCollection scripts = new ScriptCollection( new File("/temp")); Script script = scripts.get("condition.html"); // prepare the data HierarchicalMap hmap = new BasicHierarchicalMap(); hmap.add("greeting", "testing simple condition " + "without flag"); //hmap.add("flag", ""); // fill out the template to generate final html Writer writer = new FileWriter("/temp/conditionFalse.html"); script.eval(writer, hmap); writer.close();
The result should be:
Iterarion
Nodes or leaves mapped to same key can be iterated with the following structure. Create a document "/temp/iterationTemplate.html" with following content:
<html> <body> <h>Hello, <substitution name='greeting'/>!</h> <br> <table border='1'> <tr><th>ISBN</th><th>Title</th></tr> <foreach in='order/item'> <tr> <td><substitution name='isbn'> 978-0321356680 </substitution> </td> <td><substitution name='title'> Effective Java </substitution> </td> </tr> </foreach> </table> </body> </html>
Now, execute the code below:
// parse template html ScriptCollection scripts = new ScriptCollection(new File("/temp")); Script script = scripts.get("iterationTemplate.html"); // prepare the data HierarchicalMap hmap = new BasicHierarchicalMap(); hmap.add("greeting", "testing iteration"); HierarchicalMap hmap2 = hmap.add("order/item"); hmap2.add("isbn","978-1861005618"); hmap2.add("title","Professional Java Servlets 2.3"); hmap2 = hmap.add("order/item"); hmap2.add("isbn","978-0130655677"); hmap2.add("title","Definitive XML Schema"); // fill out the template to generate final html Writer writer = new FileWriter("/temp/iteration.html"); script.eval(writer, hmap); writer.close();
The result should be:
ISBN | Title |
---|---|
978-1861005618 | Professional Java Servlets 2.3 |
978-0130655677 | Definitive XML Schema |
Condition Switch
Here is another type of condition. Create a document "/temp/switchTemplate.html" with following content:
<html> <head> <style type="text/css"> .javabook {background-color: #00FFFF;} .xmlbook {background-color: #CCFF66;} .book {background-color: #FFCC99;} </style> </head> <body> <h>Hello, <substitution name='greeting'>world</substitution>! </h> <br> <table border='1'> <tr><th>ISBN</th><th>Title</th></tr> <foreach in='order/item'> </* This is template comment */> <!-- Testing switch case --> <switch case='type'> <when is='xml' > <tr class='xmlbook'> </when> <when is='java'> <tr class='javabook'> </when> <default> <tr class='book'> </default> </switch> <td><substitution name='isbn'> 978-1423101475</substitution></td> <td><substitution name='title'> The Last Olympian</substitution></td> </tr> </* comment start> <tr class='xmlbook'> <td><substitution name='isbn'> 978-0470114872</substitution></td> <td><substitution name='title'> Beginning XML</substitution></td> </tr> <tr class='javabook'> <td><substitution name='isbn'> 978-0596008734</substitution></td> <td><substitution name='title'> Learning Java</substitution></td> </tr> <tr class='book'> <td><substitution name='isbn'> 978-1441412850</substitution></td> <td><substitution name='title'> Think and Grow Rich</substitution></td> </tr> <comment end */> </foreach> </table> </body> </html>
Note that "</*" indicates the start and "/*>" the end of the script comment. Any text between them are striped out by script during evaluation. This can be used to html author to check its page before runing java code, without disturbing the result after script evaluation.
Try opening the "/temp/switchTemplate.html" with some browser and the result would be like following:
ISBN | Title |
---|---|
Now, execute the code below:
// parse template html ScriptCollection scripts = new ScriptCollection(new File("/temp")); Script script = scripts.get("switchTemplate.html"); // prepare the data HierarchicalMap hmap = new BasicHierarchicalMap(); hmap.add("greeting", "testing switch case"); HierarchicalMap hmap2 = hmap.add("order/item"); hmap2.add("isbn","978-1861005618"); hmap2.add("title","Professional Java Servlets 2.3"); hmap2.add("type","java"); hmap2 = hmap.add("order/item"); hmap2.add("isbn","978-0130655677"); hmap2.add("title","Definitive XML Schema"); hmap2.add("type","xml"); hmap2 = hmap.add("order/item"); hmap2.add("isbn","978-1441408488"); hmap2.add("title","Treasure Island"); hmap2 = hmap.add("order/item"); hmap2.add("isbn","978-0060229351"); hmap2.add("title","Harold and the Purple Crayon"); hmap2.add("type","child"); // fill out the template to generate final html Writer writer = new FileWriter("/temp/switch.html"); script.eval(writer, hmap); writer.close();
The result should be:
ISBN | Title |
---|---|
978-1861005618 | Professional Java Servlets 2.3 |
978-0130655677 | Definitive XML Schema |
978-1441408488 | Treasure Island |
978-0060229351 | Harold and the Purple Crayon |
Continue to Advanced Level - .NET Interoperability