package siena.remote; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.List; import java.util.Set; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import siena.Json; public class JsonSerializer implements Serializer { public Document deserialize(InputStream in) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); Json json = Json.load(reader); return fromJson(json); } public void serialize(Document document, OutputStream out) throws IOException { Json json = toJson(document); json.write(new OutputStreamWriter(out)); } private static Json toJson(Document doc) { Json json = Json.map(); Element root = doc.getRootElement(); Json map = Json.map(); json.put(root.getName(), map); toJson(root, map); return json; } @SuppressWarnings("unchecked") private static void toJson(Element element, Json e) { List<Element> elements = element.elements(); if(elements.isEmpty()) { if(element.hasContent()) { e.put("@", element.getText()); // } else { // e.put("@", null); } } else { Json map = Json.map(); e.put("@", map); for (Element elem : elements) { Json j = Json.map(); map.put(elem.getName(), j); toJson(elem, j); } } List<Attribute> attributes = element.attributes(); for (Attribute attr : attributes) { e.put(attr.getName(), attr.getValue()); } } private static Document fromJson(Json json) { String root = json.keys().iterator().next(); Document doc = DocumentHelper.createDocument(); fromJson(json.get(root), doc.addElement(root)); return doc; } private static void fromJson(Json json, Element element) { Set<String> keys = json.keys(); for (String key : keys) { if("@".equals(key)) { Json value = json.get(key); if(value.isString()) { element.setText(value.str()); } else { Set<String> ks = value.keys(); for (String k : ks) { Element child = element.addElement(k); fromJson(value.get(k), child); } } } else { element.addAttribute(key, json.get(key).str()); } } } public static void main(String[] args) { Document doc = DocumentHelper.createDocument(); doc.addElement("root") .addAttribute("foo", "bar") .addAttribute("foobar", "baz") .addElement("child") .addAttribute("x", "y") .addElement("grandchild") .addAttribute("a", "b") .setText("foo bar"); System.out.println("Original document"); System.out.println(doc.asXML()); System.out.println(); Json json = toJson(doc); System.out.println("As Json"); System.out.println(json); System.out.println(); Document result = fromJson(json); System.out.println("Back to document"); System.out.println(result.asXML()); System.out.println(); } }