From c677e2d443ff8bc3b8268d691e5ab605dbbb4941 Mon Sep 17 00:00:00 2001 From: benfry Date: Sun, 16 Dec 2012 20:36:40 +0000 Subject: [PATCH] fix indents with XML writing, finalize toString() and format() syntax --- core/src/processing/data/JSONArray.java | 17 +++--- core/src/processing/data/JSONObject.java | 21 +++----- core/src/processing/data/XML.java | 67 +++++++++++++++++++----- core/todo.txt | 23 ++++---- 4 files changed, 79 insertions(+), 49 deletions(-) diff --git a/core/src/processing/data/JSONArray.java b/core/src/processing/data/JSONArray.java index 4ce4dbf48..8f9c17ce8 100644 --- a/core/src/processing/data/JSONArray.java +++ b/core/src/processing/data/JSONArray.java @@ -847,21 +847,16 @@ public class JSONArray { // } + /** - * Make a JSON text of this JSONArray as a single line. For compactness, - * no unnecessary whitespace is added. If it is not possible to produce - * a syntactically correct JSON text then null will be returned instead. - * This could occur if the array contains an invalid number. - *

- * Warning: This method assumes that the data structure is acyclic. - * - * @return a printable, displayable, transmittable - * representation of the array. + * Return the JSON data formatted with two spaces for indents. + * Chosen to do this since it's the most common case (e.g. with println()). + * Same as format(2). Use the format() function for more options. */ @Override public String toString() { try { - return toString(-1); + return format(2); } catch (Exception e) { return null; } @@ -878,7 +873,7 @@ public class JSONArray { * with [ (left bracket) and ending * with ] (right bracket). */ - public String toString(int indentFactor) { + public String format(int indentFactor) { StringWriter sw = new StringWriter(); synchronized (sw.getBuffer()) { return this.write(sw, indentFactor, 0).toString(); diff --git a/core/src/processing/data/JSONObject.java b/core/src/processing/data/JSONObject.java index cdb970b36..4f9980b08 100644 --- a/core/src/processing/data/JSONObject.java +++ b/core/src/processing/data/JSONObject.java @@ -690,7 +690,7 @@ public class JSONObject { * @param key A key string. * @return true if the key exists in the JSONObject. */ - public boolean has(String key) { + public boolean hasKey(String key) { return this.map.containsKey(key); } @@ -1419,21 +1419,14 @@ public class JSONObject { /** - * Make a JSON text of this JSONObject. For compactness, no whitespace - * is added. If this would not result in a syntactically correct JSON text, - * then null will be returned instead. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, portable, transmittable - * representation of the object, beginning - * with { (left brace) and ending - * with } (right brace). + * Return the JSON data formatted with two spaces for indents. + * Chosen to do this since it's the most common case (e.g. with println()). + * Same as format(2). Use the format() function for more options. */ @Override public String toString() { try { - return this.toString(-1); + return format(2); } catch (Exception e) { return null; } @@ -1452,7 +1445,7 @@ public class JSONObject { * with } (right brace). * @throws JSONException If the object contains an invalid number. */ - public String toString(int indentFactor) { + public String format(int indentFactor) { StringWriter w = new StringWriter(); synchronized (w.getBuffer()) { return this.write(w, indentFactor, 0).toString(); @@ -1578,7 +1571,7 @@ public class JSONObject { * @return The writer. * @throws JSONException */ - public Writer write(Writer writer) { + protected Writer write(Writer writer) { return this.write(writer, 0, 0); } diff --git a/core/src/processing/data/XML.java b/core/src/processing/data/XML.java index 8b0316641..f18724474 100644 --- a/core/src/processing/data/XML.java +++ b/core/src/processing/data/XML.java @@ -189,7 +189,7 @@ public class XML implements Serializable { public boolean save(PrintWriter output) { - output.print(toString(2)); + output.print(format(2)); output.flush(); return true; } @@ -756,20 +756,30 @@ public class XML implements Serializable { } - public String toString(int indent) { + /** + * Format this XML data as a String. + * @param indent -1 for a single line (and no declaration), >= 0 for indents and newlines + */ + public String format(int indent) { try { - DOMSource dumSource = new DOMSource(node); // entities = doctype.getEntities() - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer transformer = tf.newTransformer(); - // if this is the root, output the decl, if not, hide it + TransformerFactory factory = TransformerFactory.newInstance(); + if (indent != -1) { + factory.setAttribute("indent-number", indent); + } + Transformer transformer = factory.newTransformer(); + + // Add the XML declaration at the top if this node is the root and we're + // not writing to a single line (indent = -1 means single line). if (indent == -1 || parent != null) { transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); } else { transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); } // transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "sample.dtd"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + // transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "yes"); // huh? // transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, @@ -783,18 +793,45 @@ public class XML implements Serializable { // transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS // indent by default, but sometimes this needs to be turned off if (indent != 0) { - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent)); + //transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent)); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + } else { + transformer.setOutputProperty(OutputKeys.INDENT, "no"); } // Properties p = transformer.getOutputProperties(); // for (Object key : p.keySet()) { // System.out.println(key + " -> " + p.get(key)); // } - StringWriter sw = new StringWriter(); - StreamResult sr = new StreamResult(sw); - transformer.transform(dumSource, sr); - return sw.toString(); + // If you smell something, that's because this code stinks. No matter + // the settings of the Transformer object, if the XML document already + // has whitespace elements, it won't bother re-indenting/re-formatting. + // So instead, transform the data once into a single line string. + // If indent is -1, then we're done. Otherwise re-run and the settings + // of the factory will kick in. If you know a better way to do this, + // please contribute. I've wasted too much of my Sunday on it. But at + // least the Giants are getting blown out by the Falcons. + + StringWriter tempWriter = new StringWriter(); + StreamResult tempResult = new StreamResult(tempWriter); + transformer.transform(new DOMSource(node), tempResult); + String[] tempLines = PApplet.split(tempWriter.toString(), '\n'); + if (tempLines[0].startsWith(" default to 2 params +X fix this across the other items +X look into json and how it would work wrt XML +o 1) we bring back getFloatAttribute() et al., +o and make getFloat() be equivalent to parseFloat(xml.getContent()) +o 2) we keep getFloat() like it is, and add getFloatContent(), etc. +o 3) we deprecate our nice short getFloat/getInt/etc and go with +o getXxxxAttribute() and getXxxxContent() methods. +X not gonna do getFloatContent() since it's not really any shorter _ beginning slash in getChild() threw an NPE -_ XML toString(0) means no indents or newlines -_ but no way to remove indents and still have newlines... -_ toString(-1)? a new method? -_ format(2), format(4)... format() -> default to 2 params - -_ look into json and how it would work wrt XML -_ 1) we bring back getFloatAttribute() et al., -_ and make getFloat() be equivalent to parseFloat(xml.getContent()) -_ 2) we keep getFloat() like it is, and add getFloatContent(), etc. -_ 3) we deprecate our nice short getFloat/getInt/etc and go with -_ getXxxxAttribute() and getXxxxContent() methods. async requests Request r = createRequest("http://p5.org/feed/13134.jpg");