View Javadoc
1   package org.melati.template;
2   
3   import java.io.IOException;
4   import java.util.Enumeration;
5   import java.util.List;
6   
7   import org.melati.Melati;
8   import org.melati.poem.Persistent;
9   import org.melati.poem.PoemLocale;
10  import org.melati.template.AbstractMarkupLanguage;
11  import org.melati.template.AttributeMarkupLanguage;
12  import org.melati.template.MarkupLanguage;
13  import org.melati.template.TemplateIOException;
14  import org.melati.template.TempletLoader;
15  import org.melati.util.MelatiWriter;
16  
17  /**
18   * A representation of JSON such that Java objects can be serialised 
19   * to it.
20   *  
21   * @author timp
22   * @since 09 Nov 2012
23   *
24   */
25  public class JSONMarkupLanguage extends AbstractMarkupLanguage implements MarkupLanguage {
26  
27    public JSONMarkupLanguage(Melati melati, TempletLoader templetLoader, PoemLocale locale) {
28      super("json", melati, templetLoader, locale);
29    }
30  
31    @Override
32    public AttributeMarkupLanguage getAttr() {
33      throw new RuntimeException("Not expected to be called in JSON");
34    }
35  
36    @Override
37    public String escaped(String s) {
38      return escape(s);
39    }
40    public static String escape(String s) { 
41      return s
42          .replace("\"", "\\\"")
43          .replace("\\", "\\\\")
44          .replace("/", "\\/");    
45    }
46    @Override
47    public String escaped(Persistent o) {
48      throw new RuntimeException("Not implemented yet");
49    }
50  
51    @Override
52    public String encoded(String s) {
53      throw new RuntimeException("Not expected to be called in JSON");
54    }
55  
56    @Override
57    public String decoded(String s) {
58      throw new RuntimeException("Not expected to be called in JSON");
59    }
60  
61    /**
62     * Where all content Strings are actually escaped and written out.
63     * @see org.melati.template.AbstractMarkupLanguage#render(java.lang.String, org.melati.util.MelatiWriter)
64     */
65    @Override
66    public void render(String s, MelatiWriter writer) {
67      try {
68        writer.write(escaped(s));
69      } catch (IOException e) {
70        throw new TemplateIOException("Problem writing " + s, e);
71      }      
72    }
73    @Override
74    protected void renderMarkup(String s, MelatiWriter writer) {
75      throw new RuntimeException("Not expected to be called in JSON");
76    }
77  
78    /**
79     * Render an Object in a MarkupLanguage specific way, rendering to
80     * a supplied Writer.
81     *
82     * NOTE The context always contains objects with the names melati, object and  ml  
83     *
84     * @param o - the Object to be rendered
85     * @param writer - the MelatiWriter to render this Object to
86     */
87    protected void render(Object o, MelatiWriter writer) {
88      if (o == null)
89        writer.output("null");
90      else if (o instanceof String) { 
91          writer.output("\"" + o + "\"");
92      } else if (o instanceof Boolean) { 
93        if (((Boolean)o).booleanValue())
94          writer.output("true");
95        else
96          writer.output("false");
97      } else if (o instanceof List) { 
98          List<?> l = (List<?>)o;
99          writer.output("[");
100         boolean seenOne = false;
101         for (int i = 0; i < l.size(); i++) { 
102           if (seenOne)
103             writer.output(",");            
104           render(l.get(i), writer);
105           seenOne = true;
106         }
107         writer.output("]\n");
108     } else if (o instanceof Enumeration) { 
109       Enumeration<?> e = (Enumeration<?>) o;
110       writer.output("[");
111       boolean seenOne = false;
112       while (e.hasMoreElements()) { 
113         if (seenOne)
114           writer.output(",");            
115         render(e.nextElement(), writer);
116         seenOne = true;        
117       }
118       writer.output("]\n");
119     } else {
120         Template templet =
121           templetLoader.templet(melati.getTemplateEngine(), this, o.getClass());
122         TemplateContext vars =
123             melati.getTemplateEngine().getTemplateContext();
124         vars.put("object", o);
125         vars.put("melati", melati);
126         vars.put("ml", melati.getMarkupLanguage());
127         expandTemplet(templet, vars, writer);
128     }
129   }
130 
131   
132 }