• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.testng.mustache;
2 
3 import org.testng.collections.Lists;
4 
5 import java.io.IOException;
6 import java.util.List;
7 import java.util.Map;
8 
9 public class Mustache {
10 
run(String template, Map<String, Object> m)11   public String run(String template, Map<String, Object> m) throws IOException {
12     return run(template, new Model(m));
13   }
14 
run(String template, Model model)15   String run(String template, Model model) throws IOException {
16     int lineNumber = 0;
17 
18     List<BaseChunk> chunks = Lists.newArrayList();
19     int ti = 0;
20     while (ti < template.length()) {
21       int start;
22       int end;
23       if (template.charAt(ti) == '\n') lineNumber++;
24 
25       if (template.charAt(ti) == '{' && ti + 1 < template.length()
26           && template.charAt(ti + 1) == '{') {
27         int index = ti + 2;
28         start = index;
29         boolean foundEnd = false;
30         while (index < template.length() && ! foundEnd) {
31           index++;
32           foundEnd = template.charAt(index) == '}' && index + 1 < template.length()
33               && template.charAt(index + 1) == '}';
34         }
35 
36         if (foundEnd) {
37           end = index;
38           String variable = template.substring(start, end);
39           p("Found variable:" + variable);
40           if (variable.startsWith("#")) {
41             // Complex variable {{#foo}}.
42             String conditionalVariable = variable.substring(1);
43             Value value = model.resolveValue(conditionalVariable);
44             int endIndex = findClosingIndex(template, ti, conditionalVariable);
45             Object v = value.get();
46             if (v == null) {
47               // Null condition, do nothing
48             } else if (v instanceof Iterable) {
49               // Iterable, call a sub Mustache to process this chunk in a loop
50               // after pushing a new submodel
51               Iterable it = (Iterable) v;
52               String subTemplate = template.substring(ti + variable.length() + 4, endIndex);
53               for (Object o : it) {
54                 model.push(conditionalVariable, o);
55                 String r = new Mustache().run(subTemplate, model);
56                 model.popSubModel();
57                 chunks.add(new StringChunk(model, r));
58               }
59             } else {
60               // Scope, call a sub Mustache to process this chunk
61               // after pushing a new submodel
62               String subTemplate = template.substring(ti + variable.length() + 4, endIndex);
63               model.push(conditionalVariable, v);
64               String r = new Mustache().run(subTemplate, model);
65               model.popSubModel();
66               chunks.add(new StringChunk(model, r));
67             }
68             ti = endIndex + variable.length() + 4;
69           } else {
70             // Regular variable {{foo}}
71             chunks.add(new VariableChunk(model, variable));
72             ti += variable.length() + 4;
73           }
74         } else {
75           throw new RuntimeException("Unclosed variable at line " + lineNumber);
76         }
77       } else {
78         chunks.add(new StringChunk(model, "" + template.charAt(ti)));
79         ti++;
80       }
81     } // while
82 
83     p("******************** Final composition, chunks:");
84     StringBuilder result = new StringBuilder();
85     p("*** Template:" + template);
86     for (BaseChunk bc : chunks) {
87       p("***  " + bc);
88     }
89 
90     for (BaseChunk bc : chunks) {
91       String c = bc.compose();
92       result.append(c);
93     }
94     p("*** Final result:" + result);
95     return result.toString();
96   }
97 
98   private int findClosingIndex(String template, int ti,
99       String conditionalVariable) {
100     int result = template.lastIndexOf("{{/" + conditionalVariable);
101     return result;
102   }
103 
104   private void p(String string) {
105     if (false) {
106       System.out.println(string);
107     }
108   }
109 
110   public static void main(String[] args) throws IOException {
111   }
112 }
113