Skip to content

Commit

Permalink
templating: (html)escaping
Browse files Browse the repository at this point in the history
  • Loading branch information
witek committed May 4, 2015
1 parent 2c60b00 commit 8326ecf
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 17 deletions.
8 changes: 8 additions & 0 deletions src/main/java/ilarkesto/templating/ATemplateElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ public final Context process(Context context) {
return context;
}

protected String format(Object o) {
return context.getTextFormater().format(o);
}

protected String escape(Object text) {
return context.getTextEscaper().escape(text.toString());
}

protected Object evalExpression(String expression) {
return context.getExpressionProcessor().eval(expression, context);
}
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/ilarkesto/templating/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
public class Context {

private ExpressionProcessor expressionProcessor = new ExpressionProcessor();
private TextFormater textFormater = new TextFormater();
private TextEscaper textEscaper = new HtmlTextEscaper();
private TemplateResolver templateResolver;

private StringWriter stringWriter;
Expand Down Expand Up @@ -80,6 +82,22 @@ public TemplateResolver getTemplateResolver() {
return templateResolver;
}

public void setTextEscaper(TextEscaper textEscaper) {
this.textEscaper = textEscaper;
}

public TextEscaper getTextEscaper() {
return textEscaper;
}

public void setTextFormater(TextFormater textFormater) {
this.textFormater = textFormater;
}

public TextFormater getTextFormater() {
return textFormater;
}

public String popOutput() {
if (stringWriter == null)
throw new IllegalStateException("Context was constructed with PrintWriter, peekOutput() not allowed");
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/ilarkesto/templating/HtmlTextEscaper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2011 Witoslaw Koczewsi <[email protected]>
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not,
* see <http://www.gnu.org/licenses/>.
*/
package ilarkesto.templating;

import ilarkesto.base.Str;

public class HtmlTextEscaper implements TextEscaper {

@Override
public String escape(String s) {
return Str.toHtml(s);
}

}
21 changes: 14 additions & 7 deletions src/main/java/ilarkesto/templating/MustacheLikeTemplateParser.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*
* Copyright 2011 Witoslaw Koczewsi <[email protected]>
*
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not,
* see <http://www.gnu.org/licenses/>.
*/
Expand All @@ -23,12 +23,12 @@ public class MustacheLikeTemplateParser extends ATemplateParser {

@Override
protected String[] getTokens() {
return new String[] { "{{" };
return new String[] { "{{{", "{{" };
}

@Override
protected void token(String token) {
pushState(new MustacheState());
pushState(new MustacheState(token.length() == 3));
}

@Override
Expand All @@ -46,9 +46,16 @@ public static Template parseTemplate(File templateFile) throws ParseException {

class MustacheState extends ASaxParserState {

private boolean triple;

public MustacheState(boolean triple) {
super();
this.triple = triple;
}

@Override
protected String[] getTokens() {
return new String[] { "}}" };
return new String[] { triple ? "}}}" : "}}" };
}

@Override
Expand All @@ -70,7 +77,7 @@ protected void text(String text) {
builder.startLoop(text.substring(1));
return;
}
builder.variable(text);
builder.variable(text).setEscape(!triple);
}
}

Expand Down
21 changes: 21 additions & 0 deletions src/main/java/ilarkesto/templating/TextEscaper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2011 Witoslaw Koczewsi <[email protected]>
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not,
* see <http://www.gnu.org/licenses/>.
*/
package ilarkesto.templating;

public interface TextEscaper {

String escape(String s);

}
25 changes: 25 additions & 0 deletions src/main/java/ilarkesto/templating/TextFormater.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2011 Witoslaw Koczewsi <[email protected]>
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not,
* see <http://www.gnu.org/licenses/>.
*/
package ilarkesto.templating;

import ilarkesto.core.base.Str;

public class TextFormater {

public String format(Object o) {
return Str.format(o);
}

}
26 changes: 22 additions & 4 deletions src/main/java/ilarkesto/templating/VariableElement.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*
* Copyright 2011 Witoslaw Koczewsi <[email protected]>
*
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not,
* see <http://www.gnu.org/licenses/>.
*/
Expand All @@ -18,6 +18,7 @@ class VariableElement extends ATemplateElement {

private String expression;
private String defaultValue;
private boolean escape = true;

// TODO formater

Expand All @@ -31,14 +32,31 @@ public void onProcess() {
Object value = evalExpression(expression);
if (value == null) value = defaultValue;
if (value == null) return;
print(value);

String formatedValue = format(value);

if (!escape) {
print(formatedValue);
return;
}

print(escape(formatedValue));
}

public VariableElement setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
return this;
}

public VariableElement setEscape(boolean escape) {
this.escape = escape;
return this;
}

public boolean isEscape() {
return escape;
}

public String getExpression() {
return expression;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*
* Copyright 2011 Witoslaw Koczewsi <[email protected]>
*
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not,
* see <http://www.gnu.org/licenses/>.
*/
Expand All @@ -30,6 +30,8 @@ public void templating() throws ParseException {
assertTemplateOutput("hello {{a}}", "hello a-value");
assertTemplateOutput("hello {{#rose}}existing{{/}}", "hello existing");
assertTemplateOutput("hello {{#rose}}{{color}}{{/}}", "hello red");
assertTemplateOutput("hello {{html}}", "hello &lt;html&gt;");
assertTemplateOutput("hello {{{html}}}", "hello <html>");
}

@Test
Expand Down Expand Up @@ -67,6 +69,25 @@ public void variable() throws ParseException {
assertNotEmpty(template.children);
VariableElement variable = (VariableElement) template.children.get(0);
assertEquals(variable.getExpression(), "a");
assertTrue(variable.isEscape());
}

@Test
public void variableUnescaped() throws ParseException {
Template template = MustacheLikeTemplateParser.parseTemplate("{{{html}}}");
assertNotEmpty(template.children);
VariableElement variable = (VariableElement) template.children.get(0);
assertFalse(variable.isEscape());
assertEquals(variable.getExpression(), "html");
}

@Test
public void variableEscaped() throws ParseException {
Template template = MustacheLikeTemplateParser.parseTemplate("{{html}}");
assertNotEmpty(template.children);
VariableElement variable = (VariableElement) template.children.get(0);
assertTrue(variable.isEscape());
assertEquals(variable.getExpression(), "html");
}

@Test
Expand All @@ -81,6 +102,7 @@ private static void assertTemplateOutput(String templateCode, String output) thr
Template template = MustacheLikeTemplateParser.parseTemplate(templateCode);
Context context = new Context();
context.put("a", "a-value");
context.put("html", "<html>");
context.put("rose", new Flower("rose", "red"));
context.put("flowers",
Arrays.asList(new Flower("rose", "white"), new Flower("rose", "red"), new Flower("tulip", "yellow")));
Expand Down
17 changes: 14 additions & 3 deletions src/test/java/ilarkesto/templating/TemplateTest.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*
* Copyright 2011 Witoslaw Koczewsi <[email protected]>
*
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not,
* see <http://www.gnu.org/licenses/>.
*/
Expand Down Expand Up @@ -117,6 +117,17 @@ public void scope() {
assertTemplateProcess("a-value");
}

@Test
public void escaping() {
context.put("html", "<html>");

template = new Template().add(new VariableElement("html"));
assertTemplateProcess("&lt;html&gt;");

template = new Template().add(new VariableElement("html").setEscape(false));
assertTemplateProcess("<html>");
}

@Test
public void expressions() {
context.put("a1", "a1-value");
Expand Down

0 comments on commit 8326ecf

Please sign in to comment.