G2A Many GEOs
SHARE
TWEET

Templatron

a guest Mar 31st, 2015 224 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.io.File;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.Writer;
  6. import java.net.URL;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. import java.util.Map;
  10.  
  11. /**
  12.  * 'Templatron' template library. Quick Example Usage:
  13. <pre>Template template = Templatron.newTemplate("Hello, %{name=NULL}! How are you? I am %{feel}.");
  14.  
  15. HashMap<String, String> valueMap = new HashMap<>();
  16. valueMap.put("name", "Coder");
  17. valueMap.put("feel", "fine");
  18.  
  19. Templatron.render(template, valueMap, new PrintWriter(System.out));
  20.  * </pre>
  21.  * 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.
  22.  **/
  23. public class Templatron {
  24.         /**
  25.          * Creates a new template from a string.
  26.          * @param source The string to parse.
  27.          * @return A new template, generated from the given string.
  28.          **/
  29.         public static final Template newTemplate(String source) {
  30.                 if(source == null)
  31.                         throw new NullPointerException("'source' cannot be null!");
  32.                
  33.                 Template template = new Template();
  34.                 template.load(source);
  35.                 return template;
  36.         }
  37.        
  38.         /**
  39.          * Creates a new template from a string.
  40.          * @param file The file to parse.
  41.          * @return A new template, generated from the given string.
  42.          * @throws IOException If the file could not be opened/read.
  43.          **/
  44.         public static final Template newTemplate(File file) throws IOException {
  45.                 if(file == null)
  46.                         throw new NullPointerException("'file' cannot be null!");
  47.                
  48.                 StringBuilder bd = new StringBuilder();
  49.                 FileReader read = new FileReader(file);
  50.                 {
  51.                         int i = 0;
  52.                         while((i = read.read()) != -1)
  53.                                 bd.append((char)i);
  54.                 }
  55.                 read.close();
  56.                
  57.                 Template template = new Template();
  58.                 template.load(bd.toString());
  59.                 return template;
  60.         }
  61.        
  62.         /**
  63.          * Creates a new template from a string.
  64.          * @param url The url to parse.
  65.          * @return A new template, generated from the given string.
  66.          * @throws IOException If the url could not be opened/read.
  67.          **/
  68.         public static final Template newTemplate(URL url) throws IOException {
  69.                 if(url == null)
  70.                         throw new NullPointerException("'url' cannot be null!");
  71.                
  72.                 StringBuilder bd = new StringBuilder();
  73.                 InputStreamReader read = new InputStreamReader(url.openStream());
  74.                 {
  75.                         int i = 0;
  76.                         while((i = read.read()) != -1)
  77.                                 bd.append((char)i);
  78.                 }
  79.                 read.close();
  80.                
  81.                 Template template = new Template();
  82.                 template.load(bd.toString());
  83.                 return template;
  84.         }
  85.        
  86.         /**
  87.          * Instances of this class parse and store a template.
  88.          **/
  89.         public static class Template {
  90.                 List<Piece> pieces;
  91.                
  92.                 protected Template() {
  93.                         pieces = new ArrayList<>();
  94.                 }
  95.                
  96.                 @Override
  97.                 public String toString() {
  98.                         return "Template:{pieces.size="+pieces.size()+"}";
  99.                 }
  100.                
  101.                 /**
  102.                  * This is were the magic happens!
  103.                  * @param source The string to parse.
  104.                  **/
  105.                 public void load(String source) {
  106.                         StringBuilder buffer = new StringBuilder(source.length());
  107.                        
  108.                         for(int CHARINDEX = 0; CHARINDEX < source.length(); CHARINDEX++) {
  109.                                 char CHAR = source.charAt(CHARINDEX);
  110.                                
  111.                                 // IF %{ ... }
  112.                                 if(CHAR == '%' && peek(source, CHARINDEX+1, ' ') == '{') {
  113.                                         int start = CHARINDEX+2;
  114.                                         int end = findNext(source, CHARINDEX+1, '}');
  115.                                        
  116.                                         if(end == -1) {
  117.                                                 buffer.append(CHAR);
  118.                                                 continue;
  119.                                         }
  120.                                        
  121.                                         {
  122.                                                 // Flush buffer!
  123.                                                 String str = buffer.toString();
  124.                                                 buffer.setLength(0);
  125.                                                 TextPiece tp = new TextPiece();
  126.                                                 tp.data = str;
  127.                                                 pieces.add(tp);
  128.                                         }
  129.                                        
  130.                                         // Cut it out.
  131.                                         String link = source.substring(start, end);
  132.                                        
  133.                                         // Do your thing!
  134.                                         LinkPiece tp = new LinkPiece();
  135.                                         pieces.add(tp);
  136.                                        
  137.                                         // Has 'default' value embedded?
  138.                                         if(link.indexOf('=') != -1) {
  139.                                                 // Yes, so extract it!
  140.                                                 int i = link.indexOf('=');
  141.                                                 String k = link.substring(0, i);
  142.                                                 String d = link.substring(i+1);
  143.                                                 tp.data = k;
  144.                                                 tp.defaultdata = d;
  145.                                         } else {
  146.                                                 // No, just use all text as value link.
  147.                                                 tp.data = link;
  148.                                                 tp.defaultdata = "%{"+tp.data+"=null}";
  149.                                         }
  150.                                        
  151.                                         // skip forward
  152.                                         CHARINDEX = end;
  153.                                 } else {
  154.                                         // Just text!
  155.                                         buffer.append(CHAR);
  156.                                 }
  157.                         }
  158.                        
  159.                         // If there is something left in the buffer, finish it.
  160.                         if(buffer.length() > 0) {
  161.                                 String str = buffer.toString();
  162.                                 TextPiece tp = new TextPiece();
  163.                                 tp.data = str;
  164.                                 pieces.add(tp);
  165.                         }
  166.                 }
  167.                
  168.                 // Finds the next index of 'searched', then returns it. -1 if it cant be found.
  169.                 private final int findNext(String string, int start, char searched) {
  170.                         for(int i = start; i <= string.length(); i++) {
  171.                                 if(string.charAt(i) == searched)
  172.                                         return i;
  173.                         }
  174.                         return -1;
  175.                 }
  176.                
  177.                 // Safely peeking around in a string without getting IndexOutOfBoundsException's.
  178.                 private final char peek(String string, int index, char def) {
  179.                         if(index < 0)
  180.                                 return def;
  181.                         if(index >= string.length())
  182.                                 return def;
  183.                         return string.charAt(index);
  184.                 }
  185.         }
  186.        
  187.         /** A piece of the template. **/
  188.         public static abstract class Piece {
  189.                 // empty class
  190.         }
  191.        
  192.         /** A piece representing simple text. **/
  193.         public static class TextPiece extends Piece {
  194.                 String data;
  195.                
  196.                 @Override
  197.                 public String toString() {
  198.                         return "TextPiece:\""+data+"\"";
  199.                 }
  200.         }
  201.        
  202.         /** A piece that will be replaced by some value when the template is rendered. **/
  203.         public static class LinkPiece extends Piece {
  204.                 String data;
  205.                 String defaultdata;
  206.                
  207.                 @Override
  208.                 public String toString() {
  209.                         return "LinkPiece:\""+data+"\"|\""+defaultdata+"\"";
  210.                 }
  211.         }
  212.        
  213.         /**
  214.          * "renders" a template using the given data-map.
  215.          * @param template The template to render.
  216.          * @param data The data to insert into the template.
  217.          * @param writer The writer to output the template to.
  218.          * @throws IOException If something goes wrong.
  219.          **/
  220.         public static final void render(Template template, Map<String, String> data, Writer writer) throws IOException {
  221.                 // Go trough all pieces...
  222.                 for(Piece piece : template.pieces) {
  223.                         // If it is a text-piece...
  224.                         if(piece instanceof TextPiece) {
  225.                                 // Write it out!
  226.                                 writer.append(((TextPiece) piece).data);
  227.                         }
  228.                        
  229.                         // If it is a link-piece...
  230.                         if(piece instanceof LinkPiece) {
  231.                                 // Get the name of the 'link'...
  232.                                 String link = ((LinkPiece) piece).data;
  233.                                
  234.                                 // Get the value from the data-map...
  235.                                 String replace = data.get(link);
  236.                                
  237.                                 // Is the value NULL?
  238.                                 if(replace == null) {
  239.                                         // Yes, write the default value stored inside the LinkPiece.
  240.                                         writer.append(((LinkPiece) piece).defaultdata);
  241.                                 } else {
  242.                                         // No, write the actual data!
  243.                                         writer.append(replace);
  244.                                 }
  245.                         }
  246.                 }
  247.                
  248.                 // Flush! Note that we do NOT close the writer,
  249.                 // as one may want to append multiple templates.
  250.                 writer.flush();
  251.         }
  252.        
  253. }
RAW Paste Data
Ledger Nano X - The secure hardware wallet
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top