JSONMarkupLanguage.java
package org.melati.template;
import java.io.IOException;
import java.util.Enumeration;
import java.util.List;
import org.melati.Melati;
import org.melati.poem.Persistent;
import org.melati.poem.PoemLocale;
import org.melati.template.AbstractMarkupLanguage;
import org.melati.template.AttributeMarkupLanguage;
import org.melati.template.MarkupLanguage;
import org.melati.template.TemplateIOException;
import org.melati.template.TempletLoader;
import org.melati.util.MelatiWriter;
/**
* A representation of JSON such that Java objects can be serialised
* to it.
*
* @author timp
* @since 09 Nov 2012
*
*/
public class JSONMarkupLanguage extends AbstractMarkupLanguage implements MarkupLanguage {
public JSONMarkupLanguage(Melati melati, TempletLoader templetLoader, PoemLocale locale) {
super("json", melati, templetLoader, locale);
}
@Override
public AttributeMarkupLanguage getAttr() {
throw new RuntimeException("Not expected to be called in JSON");
}
@Override
public String escaped(String s) {
return escape(s);
}
public static String escape(String s) {
return s
.replace("\"", "\\\"")
.replace("\\", "\\\\")
.replace("/", "\\/");
}
@Override
public String escaped(Persistent o) {
throw new RuntimeException("Not implemented yet");
}
@Override
public String encoded(String s) {
throw new RuntimeException("Not expected to be called in JSON");
}
@Override
public String decoded(String s) {
throw new RuntimeException("Not expected to be called in JSON");
}
/**
* Where all content Strings are actually escaped and written out.
* @see org.melati.template.AbstractMarkupLanguage#render(java.lang.String, org.melati.util.MelatiWriter)
*/
@Override
public void render(String s, MelatiWriter writer) {
try {
writer.write(escaped(s));
} catch (IOException e) {
throw new TemplateIOException("Problem writing " + s, e);
}
}
@Override
protected void renderMarkup(String s, MelatiWriter writer) {
throw new RuntimeException("Not expected to be called in JSON");
}
/**
* Render an Object in a MarkupLanguage specific way, rendering to
* a supplied Writer.
*
* NOTE The context always contains objects with the names melati, object and ml
*
* @param o - the Object to be rendered
* @param writer - the MelatiWriter to render this Object to
*/
protected void render(Object o, MelatiWriter writer) {
if (o == null)
writer.output("null");
else if (o instanceof String) {
writer.output("\"" + o + "\"");
} else if (o instanceof Boolean) {
if (((Boolean)o).booleanValue())
writer.output("true");
else
writer.output("false");
} else if (o instanceof List) {
List<?> l = (List<?>)o;
writer.output("[");
boolean seenOne = false;
for (int i = 0; i < l.size(); i++) {
if (seenOne)
writer.output(",");
render(l.get(i), writer);
seenOne = true;
}
writer.output("]\n");
} else if (o instanceof Enumeration) {
Enumeration<?> e = (Enumeration<?>) o;
writer.output("[");
boolean seenOne = false;
while (e.hasMoreElements()) {
if (seenOne)
writer.output(",");
render(e.nextElement(), writer);
seenOne = true;
}
writer.output("]\n");
} else {
Template templet =
templetLoader.templet(melati.getTemplateEngine(), this, o.getClass());
TemplateContext vars =
melati.getTemplateEngine().getTemplateContext();
vars.put("object", o);
vars.put("melati", melati);
vars.put("ml", melati.getMarkupLanguage());
expandTemplet(templet, vars, writer);
}
}
}