Added support for negative condition and comments

This commit is contained in:
Ziver Koc 2015-03-26 23:01:38 +00:00
parent 70a051be3d
commit 9f5922a0be
2 changed files with 79 additions and 28 deletions

View file

@ -41,16 +41,18 @@ import java.util.logging.Logger;
* <ul> * <ul>
* <li><b> {{key}} </b><br> * <li><b> {{key}} </b><br>
* <b> {{obj.attr}} </b><br> * <b> {{obj.attr}} </b><br>
* will be replaced with the string from the key</li> * Will be replaced with the string from the key.</li>
* <li><b> {{#key}}...{{/key}} </b><br> * <li><b> {{#key}}...{{/key}} </b><br>
* will display content between the tags if key is defined</li> * Will display content between the tags if key is defined.</li>
* <li><b>{{^key}}</b><br>
* A negative condition, will display content if key is not set.</li>
* <li><b>{{! ignore me }}</b><br>
* Comment, will be ignored.</li>
* </ul> * </ul>
* *
* TODO: * TODO:
* * {{! ignore me }}: Comment
* * {{^key}}: negative condition
* * {{#person}}: support for boolean * * {{#person}}: support for boolean
* * {{#person}}: support for loops * * {{#person}}: support for iterators
* * {{> file}}: include file * * {{> file}}: include file
* * {{=<% %>=}}: change delimiter * * {{=<% %>=}}: change delimiter
* @author Ziver koc * @author Ziver koc
@ -65,7 +67,7 @@ public class Templator {
parseTemplate(tmpl); parseTemplate(tmpl);
} }
public void setData(String key, Object data){ public void set(String key, Object data){
this.data.put(key, data); this.data.put(key, data);
} }
@ -98,7 +100,7 @@ public class Templator {
String d = ""+ c + (m.i+1<tmpl.length() ? tmpl.charAt(m.i+1) : ' '); String d = ""+ c + (m.i+1<tmpl.length() ? tmpl.charAt(m.i+1) : ' ');
switch( d ){ switch( d ){
case "{{": case "{{":
root.add(new TmplStaticString(data.toString())); root.add(new TemplateStaticString(data.toString()));
data.delete(0, data.length()); data.delete(0, data.length());
tagOpen = true; tagOpen = true;
++m.i; ++m.i;
@ -113,25 +115,30 @@ public class Templator {
String tagName = data.toString(); String tagName = data.toString();
data.delete(0, data.length()); data.delete(0, data.length());
switch(tagName.charAt(0)) { switch(tagName.charAt(0)) {
case '#': case '#': // Condition
++m.i; ++m.i;
root.add(parseTemplate(new TemplateCondition(tagName), root.add(parseTemplate(new TemplateCondition(tagName.substring(1)),
tmpl, m, tagName)); tmpl, m, tagName));
break; break;
case '/': case '^': // Negative condition
++m.i;
root.add(parseTemplate(new TemplateNegativeCondition(tagName.substring(1)),
tmpl, m, tagName));
break;
case '/': // End tag
// Is this tag closing the parent? // Is this tag closing the parent?
if(parentTag != null && tagName.endsWith(parentTag.substring(1))) if(parentTag != null && tagName.endsWith(parentTag.substring(1)))
return root; return root;
log.severe("Closing non-opened tag: {{"+tagName+"}}"); log.severe("Closing non-opened tag: {{" + tagName + "}}");
root.add(new TmplStaticString("{{"+tagName+"}}")); root.add(new TemplateStaticString("{{"+tagName+"}}"));
break;
case '!': // Comment
break; break;
default: default:
root.add(new TmplDataAttribute(tagName)); root.add(new TemplateDataAttribute(tagName));
} }
break; break;
default: default:
if(Character.isWhitespace(c)) // Not a valid tag if it contains whitespace
tagOpen = false;
data.append(c); data.append(c);
break; break;
} }
@ -139,20 +146,23 @@ public class Templator {
if(tagOpen) // Incomplete tag, insert it as normal text if(tagOpen) // Incomplete tag, insert it as normal text
data.insert(0, "{{"); data.insert(0, "{{");
if(data.length() > 0) // Still some text left, add to node if(data.length() > 0) // Still some text left, add to node
root.add(new TmplStaticString(data.toString())); root.add(new TemplateStaticString(data.toString()));
// If we get to this point means that this node is incorrectly close // If we get to this point means that this node is incorrectly close
// or this is the end of the file, so we convert it to a normal node // or this is the end of the file, so we convert it to a normal node
if(parentTag != null) { if(parentTag != null) {
root = new TemplateNode(root); root = new TemplateNode(root);
String tagName = "{{"+parentTag+"}}"; String tagName = "{{"+parentTag+"}}";
log.severe("Missing closure of tag: "+tagName); log.severe("Missing closure of tag: " + tagName);
root.addFirst(new TmplStaticString(tagName)); root.addFirst(new TemplateStaticString(tagName));
} }
return root; return root;
} }
/**************************** Utility functions *************************************/
public static Object getFieldValue(Object obj, String attrib){ public static Object getFieldValue(Object obj, String attrib){
try { try {
for (Field field : obj.getClass().getDeclaredFields()) { for (Field field : obj.getClass().getDeclaredFields()) {
@ -200,7 +210,7 @@ public class Templator {
private String key; private String key;
public TemplateCondition(String key){ public TemplateCondition(String key){
this.key = key; this.key = key.trim();
} }
public void compile(StringBuilder str) { public void compile(StringBuilder str) {
@ -209,10 +219,23 @@ public class Templator {
} }
} }
protected class TmplStaticString implements TemplateEntity { protected class TemplateNegativeCondition extends TemplateNode {
private String key;
public TemplateNegativeCondition(String key){
this.key = key.trim();
}
public void compile(StringBuilder str) {
if( ! data.containsKey(key))
super.compile(str);
}
}
protected class TemplateStaticString implements TemplateEntity {
private String text; private String text;
public TmplStaticString(String text){ public TemplateStaticString(String text){
this.text = text; this.text = text;
} }
@ -221,12 +244,12 @@ public class Templator {
} }
} }
protected class TmplDataAttribute implements TemplateEntity { protected class TemplateDataAttribute implements TemplateEntity {
private String key; private String key;
private String attrib; private String attrib;
public TmplDataAttribute(String key){ public TemplateDataAttribute(String key){
String[] s = key.split("\\.", 2); String[] s = key.trim().split("\\.", 2);
this.key = s[0]; this.key = s[0];
if(s.length > 1) if(s.length > 1)
this.attrib = s[1]; this.attrib = s[1];

View file

@ -43,7 +43,7 @@ public class TemplatorTest {
@Test @Test
public void simpleAttributeTest() { public void simpleAttributeTest() {
Templator tmpl = new Templator("<HTML>{{test}}</HTML>"); Templator tmpl = new Templator("<HTML>{{test}}</HTML>");
tmpl.setData("test", "1234"); tmpl.set("test", "1234");
assertEquals("<HTML>1234</HTML>", tmpl.compile()); assertEquals("<HTML>1234</HTML>", tmpl.compile());
} }
@Test @Test
@ -51,7 +51,7 @@ public class TemplatorTest {
Templator tmpl = new Templator("<HTML>{{test.attr}}</HTML>"); Templator tmpl = new Templator("<HTML>{{test.attr}}</HTML>");
TestClass obj = new TestClass(); TestClass obj = new TestClass();
obj.attr = "1234"; obj.attr = "1234";
tmpl.setData("test", obj); tmpl.set("test", obj);
assertEquals("<HTML>1234</HTML>", tmpl.compile()); assertEquals("<HTML>1234</HTML>", tmpl.compile());
} }
@Test @Test
@ -87,9 +87,9 @@ public class TemplatorTest {
public void simpleConditionTest(){ public void simpleConditionTest(){
Templator tmpl = new Templator( Templator tmpl = new Templator(
"<HTML>{{#key}}123456789{{/key}}</HTML>"); "<HTML>{{#key}}123456789{{/key}}</HTML>");
tmpl.setData("key", true); tmpl.set("key", "set");
assertEquals( assertEquals(
"<HTML></HTML>", "<HTML>123456789</HTML>",
tmpl.compile()); tmpl.compile());
} }
@Test @Test
@ -104,4 +104,32 @@ public class TemplatorTest {
new Templator("<HTML>{{#key}}{{/key}}</HTML>").compile()); new Templator("<HTML>{{#key}}{{/key}}</HTML>").compile());
} }
@Test
public void emptyNegativeConditionTest(){
Templator tmpl = new Templator(
"<HTML>{{^key}}123456789{{/key}}</HTML>");
assertEquals(
"<HTML>123456789</HTML>",
tmpl.compile());
}
@Test
public void setNegativeConditionTest(){
Templator tmpl = new Templator(
"<HTML>{{^key}}123456789{{/key}}</HTML>");
tmpl.set("key", "set");
assertEquals(
"<HTML></HTML>",
tmpl.compile());
}
@Test
public void commentTest(){
Templator tmpl = new Templator(
"<HTML>{{! This is a comment}}</HTML>");
assertEquals(
"<HTML></HTML>",
tmpl.compile());
}
} }