9 changed files with 642 additions and 0 deletions
-
2.gitignore
-
30LICENSE
-
112README.md
-
46build.xml
-
10res/test.html
-
184src/com/binarythought/picotemplate/Template.java
-
162src/com/binarythought/picotemplate/TemplateDictionary.java
-
48src/com/binarythought/picotemplate/TemplateNode.java
-
48src/com/binarythought/picotemplate/example/TemplateExample.java
@ -0,0 +1,2 @@ |
|||||
|
classes/* |
||||
|
doc/* |
@ -0,0 +1,30 @@ |
|||||
|
Copyright (c) 2009,2011 Christopher Ramey |
||||
|
All rights reserved. |
||||
|
|
||||
|
Redistribution and use in source and binary forms, with or without |
||||
|
modification, are permitted provided that the following conditions |
||||
|
are met: |
||||
|
|
||||
|
Redistributions of source code must retain the above copyright |
||||
|
notice, this list of conditions and the following disclaimer. |
||||
|
|
||||
|
Redistributions in binary form must reproduce the above copyright |
||||
|
notice, this list of conditions and the following disclaimer in the |
||||
|
documentation and/or other materials provided with the distribution. |
||||
|
|
||||
|
Neither the name of the picotemplate nor the names of its |
||||
|
contributors may be used to endorse or promote products derived |
||||
|
from this software without specific prior written permission. |
||||
|
|
||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
||||
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
||||
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY |
||||
|
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
||||
|
OF SUCH DAMAGE. |
@ -0,0 +1,112 @@ |
|||||
|
picotemplate |
||||
|
============ |
||||
|
|
||||
|
`picotemplate` is a simple, tiny C-Template workalike written in java |
||||
|
with the intention of being as high performance as possible. |
||||
|
`picotemplate` is very small, only three class files and is BSD licensed. |
||||
|
|
||||
|
basic usage |
||||
|
----------- |
||||
|
|
||||
|
First, create your template: |
||||
|
```html |
||||
|
<html> |
||||
|
<body> |
||||
|
This is my template. My favorite food is {{FOOD}}. |
||||
|
</body> |
||||
|
</html> |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
Import the required classes: |
||||
|
```java |
||||
|
import com.binarythought.picotemplate.Template; |
||||
|
import com.binarythought.picotemplate.TemplateDictionary; |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
Create your template and template dictionary: |
||||
|
```java |
||||
|
Template template = new Template(new File("mytemplate.tpl")); |
||||
|
TemplateDictionary dict = new TemplateDictionary(); |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
Assign a value to the "food" variable (Unassigned variables are not shown): |
||||
|
```java |
||||
|
dict.put("food", "cookies"); |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
And parse your template: |
||||
|
```java |
||||
|
String result = template.parse(dict); |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
And the result: |
||||
|
```html |
||||
|
<html> |
||||
|
<body> |
||||
|
This is my template. My favorite food is cookies. |
||||
|
</body> |
||||
|
</html> |
||||
|
``` |
||||
|
|
||||
|
advanced usage |
||||
|
-------------- |
||||
|
|
||||
|
picotemplate can selectively show areas of static content, called "sections". |
||||
|
It can also loop over these sections using child dictionaries. Consider the |
||||
|
following example: |
||||
|
```html |
||||
|
<html> |
||||
|
<body> |
||||
|
{{FAVORITE_SHOW}} is probably my favorite show. |
||||
|
{{#GOODSHOWS}} |
||||
|
{{SHOW}} is pretty good, too.. |
||||
|
{{/GOODSHOWS}} |
||||
|
</body> |
||||
|
</html> |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
Create your template and template dictionary as usual: |
||||
|
```java |
||||
|
Template template = new Template(new File("mytemplate.tpl")); |
||||
|
TemplateDictionary dict = new TemplateDictionary(); |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
Define our favorite show: |
||||
|
```java |
||||
|
dict.put("favorite_show", "Happy Days"); |
||||
|
``` |
||||
|
|
||||
|
Now show the section called "goodshows" (Sections are by default hidden, and |
||||
|
must be explicitly told to be shown): |
||||
|
```java |
||||
|
dict.show("goodshows"); |
||||
|
``` |
||||
|
|
||||
|
And add some shows for it to loop over: |
||||
|
```java |
||||
|
TemplateDictionary child1 = dict.createChild("goodshows"); |
||||
|
child1.put("show", "M.A.S.H"); |
||||
|
TemplateDictionary child2 = dict.createChild("goodshows"); |
||||
|
child2.put("show", "A-Team"); |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
And the result: |
||||
|
```html |
||||
|
<html> |
||||
|
<body> |
||||
|
Happy Days is probably my favorite show. |
||||
|
|
||||
|
M.A.S.H is pretty good, too.. |
||||
|
|
||||
|
A-Team is pretty good, too.. |
||||
|
</body> |
||||
|
</html> |
||||
|
``` |
@ -0,0 +1,46 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<project name="picotemplate" default="compile"> |
||||
|
<property name="version.num" value="1.0" /> |
||||
|
|
||||
|
<target name="clean"> |
||||
|
<delete file="${ant.project.name}-${version.num}.jar" /> |
||||
|
<delete includeemptydirs="true"> |
||||
|
<fileset dir="doc" includes="**/*" /> |
||||
|
<fileset dir="classes" includes="**/*" /> |
||||
|
</delete> |
||||
|
</target> |
||||
|
|
||||
|
<target name="compile"> |
||||
|
<mkdir dir="classes" /> |
||||
|
<javac includeantruntime="false" target="1.5" |
||||
|
srcdir="src" destdir="classes" /> |
||||
|
</target> |
||||
|
|
||||
|
<target name="jar" depends="compile"> |
||||
|
<delete file="${ant.project.name}-${version.num}.jar" /> |
||||
|
<jar destfile="${ant.project.name}-${version.num}.jar"> |
||||
|
<fileset dir="classes"> |
||||
|
<exclude name="**/example/**" /> |
||||
|
</fileset> |
||||
|
</jar> |
||||
|
</target> |
||||
|
|
||||
|
<target name="run" depends="compile"> |
||||
|
<java classname="com.binarythought.picotemplate.example.TemplateExample" |
||||
|
fork="true" maxmemory="64M"> |
||||
|
<classpath> |
||||
|
<dirset dir="classes" /> |
||||
|
</classpath> |
||||
|
</java> |
||||
|
</target> |
||||
|
|
||||
|
<target name="doc"> |
||||
|
<mkdir dir="doc" /> |
||||
|
<javadoc destdir="doc"> |
||||
|
<fileset dir="src"> |
||||
|
<exclude name="**/example/**" /> |
||||
|
</fileset> |
||||
|
</javadoc> |
||||
|
</target> |
||||
|
|
||||
|
</project> |
@ -0,0 +1,10 @@ |
|||||
|
<html> |
||||
|
<head> |
||||
|
<title>Pico Template</title> |
||||
|
</head> |
||||
|
<body> |
||||
|
This is my {{OBJECT1}}, this is my gun.<br/> |
||||
|
{{#SECTION}} This is for {{OBJECT2}}!<br/> |
||||
|
{{/SECTION}} |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,184 @@ |
|||||
|
package com.binarythought.picotemplate; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.Stack; |
||||
|
import java.util.regex.Pattern; |
||||
|
import java.util.regex.Matcher; |
||||
|
import java.io.FileReader; |
||||
|
import java.io.File; |
||||
|
|
||||
|
/** |
||||
|
* Template is the base class for picotemplate. It it used to generate |
||||
|
* html or text from a supplied template and dictionary. |
||||
|
* <p>Basic usage: |
||||
|
* <p><code>Template template = new Template("I like {{FOOD}}.");<br> |
||||
|
* TemplateDictionary dictionary = new TemplateDictionary();<br> |
||||
|
* dictionary.put("food", "cookies");<br> |
||||
|
* String result = template.parse(dictionary);</code> |
||||
|
* <p>Value of result : <code>I like cookies.</code> |
||||
|
*/ |
||||
|
public class Template { |
||||
|
private static final Pattern pattern = Pattern.compile( |
||||
|
"\\{\\{(#|/){0,1}(\\w+)\\}\\}", Pattern.CANON_EQ |
||||
|
); |
||||
|
|
||||
|
private TemplateNode parsedTemplate[]; |
||||
|
private String originalTemplate; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Instantiate and compile a new template with the template provided. |
||||
|
* @param template String containing the template. |
||||
|
*/ |
||||
|
public Template(String template) throws Exception |
||||
|
{ |
||||
|
this.originalTemplate = template; |
||||
|
this.parsedTemplate = initTemplate(template); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Instantiate and compile a new template with the template provided. |
||||
|
* @param file File containing the template. |
||||
|
*/ |
||||
|
public Template(File file) throws Exception |
||||
|
{ |
||||
|
if(file == null || !file.canRead()){ |
||||
|
throw new Exception("Cannot read "+file.getName()); |
||||
|
} |
||||
|
|
||||
|
FileReader reader = new FileReader(file); |
||||
|
StringBuilder b = new StringBuilder(); |
||||
|
|
||||
|
char buf[] = new char[1024]; |
||||
|
for(int i=0; (i = reader.read(buf)) != -1;){ |
||||
|
b.append(buf, 0, i); |
||||
|
} |
||||
|
|
||||
|
reader.close(); |
||||
|
this.originalTemplate = b.toString(); |
||||
|
this.parsedTemplate = initTemplate(this.originalTemplate); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private static TemplateNode[] initTemplate(String template) throws Exception |
||||
|
{ |
||||
|
ArrayList<TemplateNode> parsedTemplate = new ArrayList<TemplateNode>(); |
||||
|
Stack<String> sections = new Stack<String>(); |
||||
|
Matcher match = pattern.matcher(template); |
||||
|
int lastpos = 0; |
||||
|
|
||||
|
while(match.find()){ |
||||
|
String segment = template.substring(lastpos,match.start()); |
||||
|
if(segment.length() > 0){ |
||||
|
parsedTemplate.add(new TemplateNode(TemplateNode.PLAIN, segment)); |
||||
|
} |
||||
|
|
||||
|
if("#".equals(match.group(1))){ |
||||
|
sections.push(match.group(2)); |
||||
|
parsedTemplate.add( |
||||
|
new TemplateNode(TemplateNode.SECTION_START, match.group(2)) |
||||
|
); |
||||
|
} else if("/".equals(match.group(1))){ |
||||
|
parsedTemplate.add( |
||||
|
new TemplateNode(TemplateNode.SECTION_END, match.group(2)) |
||||
|
); |
||||
|
if(sections.empty() || !sections.pop().equals(match.group(2))){ |
||||
|
throw new Exception("Out of turn section termation at "+match.start()); |
||||
|
} |
||||
|
} else { |
||||
|
parsedTemplate.add( |
||||
|
new TemplateNode(TemplateNode.VARIABLE, match.group(2)) |
||||
|
); |
||||
|
} |
||||
|
lastpos = match.end(); |
||||
|
} |
||||
|
|
||||
|
String segment = template.substring(lastpos, template.length()); |
||||
|
if(segment.length() > 0){ |
||||
|
parsedTemplate.add(new TemplateNode(TemplateNode.PLAIN, segment)); |
||||
|
} |
||||
|
|
||||
|
if(!sections.empty()){ |
||||
|
throw new Exception("Unterminated section in template"); |
||||
|
} |
||||
|
|
||||
|
return parsedTemplate.toArray(new TemplateNode[0]); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Parse this template with the provided dictionary and output it to a string. |
||||
|
* <p><b>This method is threadsafe.</b> |
||||
|
* @param dict Template dictionary to parse against. |
||||
|
* @return String containing the parsed result of the template. |
||||
|
*/ |
||||
|
public String parse(TemplateDictionary dict) |
||||
|
{ |
||||
|
StringBuilder b = new StringBuilder(); |
||||
|
|
||||
|
if(dict != null){ parseTemplate(dict, b, parsedTemplate, 0); } |
||||
|
else { parseTemplate(b, parsedTemplate); } |
||||
|
|
||||
|
return b.toString(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private static int parseTemplate(StringBuilder output, TemplateNode template[]) |
||||
|
{ |
||||
|
for(int i = 0; i < template.length; i++){ |
||||
|
if(template[i].getNodeType() == TemplateNode.PLAIN){ |
||||
|
output.append(template[i].getContent()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private static int parseTemplate(TemplateDictionary dict, StringBuilder output, TemplateNode template[], int i) |
||||
|
{ |
||||
|
for(;i < template.length; i++){ |
||||
|
switch(template[i].getNodeType()){ |
||||
|
case TemplateNode.PLAIN: |
||||
|
output.append(template[i].getContent()); |
||||
|
break; |
||||
|
|
||||
|
case TemplateNode.VARIABLE: |
||||
|
output.append(dict.get(template[i].getContent())); |
||||
|
break; |
||||
|
|
||||
|
case TemplateNode.SECTION_START: |
||||
|
if(dict.isShown(template[i].getContent())){ |
||||
|
List<TemplateDictionary> l = ( |
||||
|
dict.getParent() == null ? dict.getChild(template[i].getContent()) : |
||||
|
dict.getParent().getChild(template[i].getContent()) |
||||
|
); |
||||
|
|
||||
|
if(l == null){ |
||||
|
i = parseTemplate(dict, output, template, i+1); |
||||
|
} else { |
||||
|
int last = 0; |
||||
|
for(TemplateDictionary d : l){ |
||||
|
last = parseTemplate(d, output, template, i+1); |
||||
|
} |
||||
|
i = last; |
||||
|
} |
||||
|
} else { |
||||
|
for(int c=1; c > 0;){ |
||||
|
i++; |
||||
|
switch(template[i].getNodeType()){ |
||||
|
case TemplateNode.SECTION_START: c++; break; |
||||
|
case TemplateNode.SECTION_END: c--; break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case TemplateNode.SECTION_END: return i; |
||||
|
} |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
} |
@ -0,0 +1,162 @@ |
|||||
|
package com.binarythought.picotemplate; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
import java.util.Set; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.HashSet; |
||||
|
import java.util.List; |
||||
|
import java.util.LinkedList; |
||||
|
import java.util.Collections; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* TemplateDictionary is used to assign variables and show sections |
||||
|
* inside templates. It is functionally similar to a HashMap, although |
||||
|
* not a decendent. <b>All methods that use identifying keys under this object |
||||
|
* are case-insensitive.</b> This means that "MY_VAR" is the same as "my_var" |
||||
|
* for both section names and variable names. |
||||
|
* <p>At the most basic level, TemplateDictionary can be used with |
||||
|
* Template to create simple fill-in-the-blank style templates. |
||||
|
* <p>More advanced functionality is available, allowing developers |
||||
|
* to toggle shown sections and loop over sections using child dictionaries. |
||||
|
* @see Template |
||||
|
*/ |
||||
|
public class TemplateDictionary |
||||
|
{ |
||||
|
private Map<String,String> dictionary; |
||||
|
private Map<String,List<TemplateDictionary>> children; |
||||
|
private Set<String> sections; |
||||
|
private TemplateDictionary parent; |
||||
|
|
||||
|
/** |
||||
|
* Instantiate an empty TemplateDictionary. |
||||
|
*/ |
||||
|
public TemplateDictionary(){ this(null); } |
||||
|
|
||||
|
|
||||
|
private TemplateDictionary(TemplateDictionary parent) |
||||
|
{ |
||||
|
this.parent = parent; |
||||
|
|
||||
|
dictionary = new HashMap<String,String>(); |
||||
|
children = new HashMap<String,List<TemplateDictionary>>(); |
||||
|
sections = new HashSet<String>(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Get the parent dictionary to this one, or null if one does not exist. |
||||
|
* @return This dictionary's parent dictionary. |
||||
|
*/ |
||||
|
public TemplateDictionary getParent(){ return parent; } |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Show a specific section. This method is case-insensitive. |
||||
|
* @param name The section to show. |
||||
|
*/ |
||||
|
public void show(String name){ sections.add(name.toUpperCase()); } |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Hide a specific section. This method is case-insensitive. |
||||
|
* @param name The section to hide. |
||||
|
*/ |
||||
|
public void hide(String name){ sections.remove(name.toUpperCase()); } |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Checks if a section is hidden. This method is case-insensitive. |
||||
|
* @param name The section name checking against. |
||||
|
* @return True if a section is hidden, false if it is not. |
||||
|
*/ |
||||
|
public boolean isHidden(String name){ return !sections.contains(name.toUpperCase()); } |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Checks if a section is shown. This method is case-insensitive. |
||||
|
* @param name The section name checking against. |
||||
|
* @return True if this section is shown, false if it is not. |
||||
|
*/ |
||||
|
public boolean isShown(String name){ return sections.contains(name.toUpperCase()); } |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Provides a list of children identified by a case-insensitive section name. |
||||
|
* @param name The section name checking against. |
||||
|
* @return List of children dictionaries identified by specific section name or null if there are none. |
||||
|
*/ |
||||
|
public List<TemplateDictionary> getChild(String name){ |
||||
|
if(children.containsKey(name.toUpperCase())){ |
||||
|
return children.get(name.toUpperCase()); |
||||
|
} else { return null; } |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Remove all of the child dictionaries under this one identified by |
||||
|
* a specific section name. |
||||
|
* @param name Case-insensitive section name's children to remove. |
||||
|
*/ |
||||
|
public void removeChildren(String name){ |
||||
|
children.remove(name.toUpperCase()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Create a child dictionary underneath this one for use with a specific |
||||
|
* section. |
||||
|
* @param name Case-insensitive section name for the new dictionary. |
||||
|
* @return TemplateDictionary for specific section. |
||||
|
*/ |
||||
|
public TemplateDictionary createChild(String name){ |
||||
|
TemplateDictionary child = new TemplateDictionary(this); |
||||
|
|
||||
|
if(!children.containsKey(name.toUpperCase())){ |
||||
|
List<TemplateDictionary> list = new LinkedList<TemplateDictionary>(); |
||||
|
children.put(name.toUpperCase(), list); |
||||
|
} |
||||
|
|
||||
|
children.get(name.toUpperCase()).add(child); |
||||
|
return child; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Gets the value of a variable by key. This method also ascends into parent |
||||
|
* dictionaries looking for the key. |
||||
|
* @param key Case-insensitive Key to look for. |
||||
|
* @return Value of key as string, or an empty string if the key is not found. |
||||
|
*/ |
||||
|
public String get(String key) |
||||
|
{ |
||||
|
if(dictionary.containsKey(key.toUpperCase())){ |
||||
|
return dictionary.get(key.toUpperCase()); |
||||
|
} else if(parent != null){ |
||||
|
return parent.get(key); |
||||
|
} else { |
||||
|
return ""; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Set the value of a variable. |
||||
|
* @param key Case-insensitive key that identifies this variable. |
||||
|
* @param val Value of this variable. |
||||
|
*/ |
||||
|
public void put(String key, String val) |
||||
|
{ |
||||
|
dictionary.put(key.toUpperCase(), val); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Remove a variable. |
||||
|
* @param key Case-insensitive key to remove. |
||||
|
*/ |
||||
|
public void remove(String key) |
||||
|
{ |
||||
|
dictionary.remove(key.toUpperCase()); |
||||
|
} |
||||
|
} |
@ -0,0 +1,48 @@ |
|||||
|
package com.binarythought.picotemplate; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Groups of TemplateNodes compose a template once it's compiled. |
||||
|
* This class shouldn't be used directly. |
||||
|
* @see Template |
||||
|
*/ |
||||
|
public class TemplateNode |
||||
|
{ |
||||
|
/** Plain node type */ |
||||
|
public static final int PLAIN = 0; |
||||
|
/** Variable node type */ |
||||
|
public static final int VARIABLE = 1; |
||||
|
/** Start of section node type */ |
||||
|
public static final int SECTION_START = 2; |
||||
|
/** End of section node type */ |
||||
|
public static final int SECTION_END = 3; |
||||
|
|
||||
|
private int nodeType; |
||||
|
private String content; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Instantiate new node. |
||||
|
* @param nodeType Type of node |
||||
|
* @param content Content of this node. |
||||
|
*/ |
||||
|
public TemplateNode(int nodeType, String content) |
||||
|
{ |
||||
|
this.nodeType = nodeType; |
||||
|
this.content = content; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Get the type of this node |
||||
|
* @return Type of this node. |
||||
|
*/ |
||||
|
public int getNodeType(){ return nodeType; } |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Get the content of this node. |
||||
|
* @return Content of this node. |
||||
|
*/ |
||||
|
public String getContent(){ return content; } |
||||
|
} |
@ -0,0 +1,48 @@ |
|||||
|
package com.binarythought.picotemplate.example; |
||||
|
|
||||
|
import com.binarythought.picotemplate.Template; |
||||
|
import com.binarythought.picotemplate.TemplateDictionary; |
||||
|
import java.io.File; |
||||
|
|
||||
|
|
||||
|
public class TemplateExample { |
||||
|
public static void main(String args[]) throws Exception |
||||
|
{ |
||||
|
Template template = new Template(new File("res/test.html")); |
||||
|
|
||||
|
TemplateDictionary dict = new TemplateDictionary(); |
||||
|
dict.put("object1", "rifle"); |
||||
|
|
||||
|
dict.show("section"); |
||||
|
TemplateDictionary d1 = dict.createChild("section"); |
||||
|
d1.put("object2", "fighting"); |
||||
|
TemplateDictionary d2 = dict.createChild("section"); |
||||
|
d2.put("object2", "fun"); |
||||
|
|
||||
|
System.out.println("*** Parsed Template: "); |
||||
|
System.out.println(template.parse(dict)); |
||||
|
|
||||
|
long t = System.currentTimeMillis(); |
||||
|
template.parse(dict); |
||||
|
System.out.println("1 Template: "+(System.currentTimeMillis()-t)+"ms"); |
||||
|
|
||||
|
t = System.currentTimeMillis(); |
||||
|
for(int i=0;i < 1000; i++){ |
||||
|
template.parse(dict); |
||||
|
} |
||||
|
System.out.println("1000 Templates: "+(System.currentTimeMillis()-t)+"ms"); |
||||
|
|
||||
|
t = System.currentTimeMillis(); |
||||
|
for(int i=0;i < 10000; i++){ |
||||
|
template.parse(dict); |
||||
|
} |
||||
|
System.out.println("10000 Templates: "+(System.currentTimeMillis()-t)+"ms"); |
||||
|
|
||||
|
t = System.currentTimeMillis(); |
||||
|
for(int i=0;i < 100000; i++){ |
||||
|
template.parse(dict); |
||||
|
} |
||||
|
System.out.println("100000 Templates: "+(System.currentTimeMillis()-t)+"ms"); |
||||
|
} |
||||
|
|
||||
|
} |
Reference in new issue