Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.File;
- import java.io.FileReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.Writer;
- import java.net.URL;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- /**
- * 'Templatron' template library. Quick Example Usage:
- <pre>Template template = Templatron.newTemplate("Hello, %{name=NULL}! How are you? I am %{feel}.");
- HashMap<String, String> valueMap = new HashMap<>();
- valueMap.put("name", "Coder");
- valueMap.put("feel", "fine");
- Templatron.render(template, valueMap, new PrintWriter(System.out));
- * </pre>
- * FOR THE SAKE OF SANITY: Do NOT use this library in production! This code was written to just work, without giving a f**k about anything.
- **/
- public class Templatron {
- /**
- * Creates a new template from a string.
- * @param source The string to parse.
- * @return A new template, generated from the given string.
- **/
- public static final Template newTemplate(String source) {
- if(source == null)
- throw new NullPointerException("'source' cannot be null!");
- Template template = new Template();
- template.load(source);
- return template;
- }
- /**
- * Creates a new template from a string.
- * @param file The file to parse.
- * @return A new template, generated from the given string.
- * @throws IOException If the file could not be opened/read.
- **/
- public static final Template newTemplate(File file) throws IOException {
- if(file == null)
- throw new NullPointerException("'file' cannot be null!");
- StringBuilder bd = new StringBuilder();
- FileReader read = new FileReader(file);
- {
- int i = 0;
- while((i = read.read()) != -1)
- bd.append((char)i);
- }
- read.close();
- Template template = new Template();
- template.load(bd.toString());
- return template;
- }
- /**
- * Creates a new template from a string.
- * @param url The url to parse.
- * @return A new template, generated from the given string.
- * @throws IOException If the url could not be opened/read.
- **/
- public static final Template newTemplate(URL url) throws IOException {
- if(url == null)
- throw new NullPointerException("'url' cannot be null!");
- StringBuilder bd = new StringBuilder();
- InputStreamReader read = new InputStreamReader(url.openStream());
- {
- int i = 0;
- while((i = read.read()) != -1)
- bd.append((char)i);
- }
- read.close();
- Template template = new Template();
- template.load(bd.toString());
- return template;
- }
- /**
- * Instances of this class parse and store a template.
- **/
- public static class Template {
- List<Piece> pieces;
- protected Template() {
- pieces = new ArrayList<>();
- }
- @Override
- public String toString() {
- return "Template:{pieces.size="+pieces.size()+"}";
- }
- /**
- * This is were the magic happens!
- * @param source The string to parse.
- **/
- public void load(String source) {
- StringBuilder buffer = new StringBuilder(source.length());
- for(int CHARINDEX = 0; CHARINDEX < source.length(); CHARINDEX++) {
- char CHAR = source.charAt(CHARINDEX);
- // IF %{ ... }
- if(CHAR == '%' && peek(source, CHARINDEX+1, ' ') == '{') {
- int start = CHARINDEX+2;
- int end = findNext(source, CHARINDEX+1, '}');
- if(end == -1) {
- buffer.append(CHAR);
- continue;
- }
- {
- // Flush buffer!
- String str = buffer.toString();
- buffer.setLength(0);
- TextPiece tp = new TextPiece();
- tp.data = str;
- pieces.add(tp);
- }
- // Cut it out.
- String link = source.substring(start, end);
- // Do your thing!
- LinkPiece tp = new LinkPiece();
- pieces.add(tp);
- // Has 'default' value embedded?
- if(link.indexOf('=') != -1) {
- // Yes, so extract it!
- int i = link.indexOf('=');
- String k = link.substring(0, i);
- String d = link.substring(i+1);
- tp.data = k;
- tp.defaultdata = d;
- } else {
- // No, just use all text as value link.
- tp.data = link;
- tp.defaultdata = "%{"+tp.data+"=null}";
- }
- // skip forward
- CHARINDEX = end;
- } else {
- // Just text!
- buffer.append(CHAR);
- }
- }
- // If there is something left in the buffer, finish it.
- if(buffer.length() > 0) {
- String str = buffer.toString();
- TextPiece tp = new TextPiece();
- tp.data = str;
- pieces.add(tp);
- }
- }
- // Finds the next index of 'searched', then returns it. -1 if it cant be found.
- private final int findNext(String string, int start, char searched) {
- for(int i = start; i <= string.length(); i++) {
- if(string.charAt(i) == searched)
- return i;
- }
- return -1;
- }
- // Safely peeking around in a string without getting IndexOutOfBoundsException's.
- private final char peek(String string, int index, char def) {
- if(index < 0)
- return def;
- if(index >= string.length())
- return def;
- return string.charAt(index);
- }
- }
- /** A piece of the template. **/
- public static abstract class Piece {
- // empty class
- }
- /** A piece representing simple text. **/
- public static class TextPiece extends Piece {
- String data;
- @Override
- public String toString() {
- return "TextPiece:\""+data+"\"";
- }
- }
- /** A piece that will be replaced by some value when the template is rendered. **/
- public static class LinkPiece extends Piece {
- String data;
- String defaultdata;
- @Override
- public String toString() {
- return "LinkPiece:\""+data+"\"|\""+defaultdata+"\"";
- }
- }
- /**
- * "renders" a template using the given data-map.
- * @param template The template to render.
- * @param data The data to insert into the template.
- * @param writer The writer to output the template to.
- * @throws IOException If something goes wrong.
- **/
- public static final void render(Template template, Map<String, String> data, Writer writer) throws IOException {
- // Go trough all pieces...
- for(Piece piece : template.pieces) {
- // If it is a text-piece...
- if(piece instanceof TextPiece) {
- // Write it out!
- writer.append(((TextPiece) piece).data);
- }
- // If it is a link-piece...
- if(piece instanceof LinkPiece) {
- // Get the name of the 'link'...
- String link = ((LinkPiece) piece).data;
- // Get the value from the data-map...
- String replace = data.get(link);
- // Is the value NULL?
- if(replace == null) {
- // Yes, write the default value stored inside the LinkPiece.
- writer.append(((LinkPiece) piece).defaultdata);
- } else {
- // No, write the actual data!
- writer.append(replace);
- }
- }
- }
- // Flush! Note that we do NOT close the writer,
- // as one may want to append multiple templates.
- writer.flush();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement