Created
September 12, 2013 11:12
-
-
Save williamhogman/6535878 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Map; | |
public class Template { | |
private List<String> tokens; | |
private String simple; | |
public Template(String template) { | |
this.tokens = tokenize(template); | |
// If the length is zero, it can only be the empty string. | |
// If the length is one, it cannot be a variable. | |
// Hence, if the is lesser than 2, we return the template. | |
if(template.length() < 2) { | |
simple = template; | |
} | |
} | |
private String expandToken(String token, Map<String, String> variables) { | |
if(token.charAt(0) == '$') { | |
return variables.get(token.substring(1)); | |
} else { | |
return token; | |
} | |
} | |
private int findWhitespace(String in, int start) { | |
for(int i = start; i < in.length(); i++) { | |
char c = in.charAt(i); | |
if(c == ' ' || c == '\n' || c == '\t') { | |
return i; | |
} | |
} | |
return -1; | |
} | |
private List<String> tokenize(String template) { | |
List<String> tokens = new ArrayList<String>(); | |
int start = 0; | |
int end = -1; | |
while((end = template.indexOf("$", start)) != -1 && start <= template.length()) { | |
// If there is something before the $-sign then add it | |
if (start != end) { | |
tokens.add(template.substring(start, end)); | |
} | |
// find the end of the variable name | |
//int endOfVar = template.indexOf(" ", end); | |
int endOfVar = findWhitespace(template, end); | |
// If we can't find a space that means that the variable is at the end of the input string | |
if(endOfVar == -1) { | |
tokens.add(template.substring(end)); | |
return tokens; | |
} | |
// Add the variable token | |
tokens.add(template.substring(end, endOfVar)); | |
// Move forward | |
start = endOfVar; | |
} | |
// If there is anything left then add that | |
if(end < template.length()) { | |
tokens.add(template.substring(start)); | |
} | |
return tokens; | |
} | |
public String evaluate(Map<String, String> variables) { | |
if(simple != null) { | |
return simple; | |
} | |
StringBuffer buffer = new StringBuffer(); | |
for(String token : tokens) { | |
buffer.append(expandToken(token, variables)); | |
} | |
return buffer.toString(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static org.junit.Assert.*; | |
import java.util.HashMap; | |
import java.util.Map; | |
import junit.framework.Assert; | |
import org.junit.Test; | |
public class TemplateTest { | |
private Map<String, String> emptyMap = new HashMap<String, String>(); | |
@Test | |
public void testStaticString() { | |
Template t = new Template("hej"); | |
String s = t.evaluate(emptyMap); | |
assertEquals("Should return the exacty same string", "hej", s); | |
} | |
@Test | |
public void testEmptyString() { | |
Template t = new Template(""); | |
String s = t.evaluate(emptyMap); | |
assertEquals("Should return the empty string", "", s); | |
} | |
@Test | |
public void testOneVariable() { | |
Template t = new Template("$x"); | |
Map<String, String> map = new HashMap<String, String>(); | |
map.put("x", "foo"); | |
String s = t.evaluate(map); | |
assertEquals("Should insert the correct value", "foo", s); | |
} | |
@Test | |
public void testTwoVariables() { | |
Template t = new Template("$x $y"); | |
Map<String, String> map = new HashMap<String, String>(); | |
map.put("x", "foo"); | |
map.put("y", "bar"); | |
String s = t.evaluate(map); | |
assertEquals("Should insert the correct value", "foo bar", s); | |
} | |
@Test | |
public void testSpace(){ | |
Template t = new Template(" "); | |
String s = t.evaluate(emptyMap); | |
assertEquals("Should return a string with just a space", " ", s); | |
} | |
@Test | |
public void testMixed() { | |
Template t = new Template("Foo $x lol"); | |
Map<String, String> map = new HashMap<String, String>(); | |
map.put("x", "bar"); | |
String s = t.evaluate(map); | |
assertEquals("Foo bar lol", s); | |
} | |
@Test | |
public void testTwoSpaces() { | |
Template t = new Template(" "); | |
String s = t.evaluate(emptyMap); | |
assertEquals(" ", s); | |
} | |
@Test | |
public void testNewLineVars() { | |
Template t = new Template("$x\n$x"); | |
Map<String, String> map = new HashMap<String, String>(); | |
map.put("x", "bar"); | |
String s = t.evaluate(map); | |
assertEquals("bar\nbar", s); | |
} | |
@Test | |
public void testTabVars(){ | |
Template t = new Template("$x\t$x"); | |
Map<String, String> map = new HashMap<String, String>(); | |
map.put("x", "bar"); | |
String s = t.evaluate(map); | |
assertEquals("bar\tbar", s); | |
} | |
@Test | |
public void testDollahDollahBillYall() { | |
Template t = new Template("$$x $$x"); | |
Map<String, String> map = new HashMap<String, String>(); | |
map.put("$x", "foo"); | |
String s = t.evaluate(map); | |
assertEquals("foo foo", s); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment