Merge from existing repo
This commit is contained in:
parent
649512ba39
commit
99c7704f83
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
classes/*
|
||||||
|
doc/*
|
30
LICENSE
Normal file
30
LICENSE
Normal file
@ -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.
|
112
README.md
Normal file
112
README.md
Normal file
@ -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>
|
||||||
|
```
|
46
build.xml
Normal file
46
build.xml
Normal file
@ -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>
|
10
res/test.html
Normal file
10
res/test.html
Normal file
@ -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>
|
184
src/com/binarythought/picotemplate/Template.java
Normal file
184
src/com/binarythought/picotemplate/Template.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
162
src/com/binarythought/picotemplate/TemplateDictionary.java
Normal file
162
src/com/binarythought/picotemplate/TemplateDictionary.java
Normal file
@ -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());
|
||||||
|
}
|
||||||
|
}
|
48
src/com/binarythought/picotemplate/TemplateNode.java
Normal file
48
src/com/binarythought/picotemplate/TemplateNode.java
Normal file
@ -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
Block a user