Skip to content

Commit 05b2ed6

Browse files
committed
fix indents with XML writing, finalize toString() and format() syntax
1 parent 2646049 commit 05b2ed6

File tree

4 files changed

+79
-49
lines changed

4 files changed

+79
-49
lines changed

core/src/processing/data/JSONArray.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -847,21 +847,16 @@ public Object removeIndex(int index) {
847847
// }
848848

849849

850+
850851
/**
851-
* Make a JSON text of this JSONArray as a single line. For compactness,
852-
* no unnecessary whitespace is added. If it is not possible to produce
853-
* a syntactically correct JSON text then null will be returned instead.
854-
* This could occur if the array contains an invalid number.
855-
* <p>
856-
* Warning: This method assumes that the data structure is acyclic.
857-
*
858-
* @return a printable, displayable, transmittable
859-
* representation of the array.
852+
* Return the JSON data formatted with two spaces for indents.
853+
* Chosen to do this since it's the most common case (e.g. with println()).
854+
* Same as format(2). Use the format() function for more options.
860855
*/
861856
@Override
862857
public String toString() {
863858
try {
864-
return toString(-1);
859+
return format(2);
865860
} catch (Exception e) {
866861
return null;
867862
}
@@ -878,7 +873,7 @@ public String toString() {
878873
* with <code>[</code>&nbsp;<small>(left bracket)</small> and ending
879874
* with <code>]</code>&nbsp;<small>(right bracket)</small>.
880875
*/
881-
public String toString(int indentFactor) {
876+
public String format(int indentFactor) {
882877
StringWriter sw = new StringWriter();
883878
synchronized (sw.getBuffer()) {
884879
return this.write(sw, indentFactor, 0).toString();

core/src/processing/data/JSONObject.java

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ public JSONObject getJSONObject(String key) {
690690
* @param key A key string.
691691
* @return true if the key exists in the JSONObject.
692692
*/
693-
public boolean has(String key) {
693+
public boolean hasKey(String key) {
694694
return this.map.containsKey(key);
695695
}
696696

@@ -1419,21 +1419,14 @@ static protected void testValidity(Object o) {
14191419

14201420

14211421
/**
1422-
* Make a JSON text of this JSONObject. For compactness, no whitespace
1423-
* is added. If this would not result in a syntactically correct JSON text,
1424-
* then null will be returned instead.
1425-
* <p>
1426-
* Warning: This method assumes that the data structure is acyclical.
1427-
*
1428-
* @return a printable, displayable, portable, transmittable
1429-
* representation of the object, beginning
1430-
* with <code>{</code>&nbsp;<small>(left brace)</small> and ending
1431-
* with <code>}</code>&nbsp;<small>(right brace)</small>.
1422+
* Return the JSON data formatted with two spaces for indents.
1423+
* Chosen to do this since it's the most common case (e.g. with println()).
1424+
* Same as format(2). Use the format() function for more options.
14321425
*/
14331426
@Override
14341427
public String toString() {
14351428
try {
1436-
return this.toString(-1);
1429+
return format(2);
14371430
} catch (Exception e) {
14381431
return null;
14391432
}
@@ -1452,7 +1445,7 @@ public String toString() {
14521445
* with <code>}</code>&nbsp;<small>(right brace)</small>.
14531446
* @throws JSONException If the object contains an invalid number.
14541447
*/
1455-
public String toString(int indentFactor) {
1448+
public String format(int indentFactor) {
14561449
StringWriter w = new StringWriter();
14571450
synchronized (w.getBuffer()) {
14581451
return this.write(w, indentFactor, 0).toString();
@@ -1578,7 +1571,7 @@ static protected Object wrap(Object object) {
15781571
* @return The writer.
15791572
* @throws JSONException
15801573
*/
1581-
public Writer write(Writer writer) {
1574+
protected Writer write(Writer writer) {
15821575
return this.write(writer, 0, 0);
15831576
}
15841577

core/src/processing/data/XML.java

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public boolean save(File file, String options) {
189189

190190

191191
public boolean save(PrintWriter output) {
192-
output.print(toString(2));
192+
output.print(format(2));
193193
output.flush();
194194
return true;
195195
}
@@ -756,20 +756,30 @@ public void setContent(String text) {
756756
}
757757

758758

759-
public String toString(int indent) {
759+
/**
760+
* Format this XML data as a String.
761+
* @param indent -1 for a single line (and no declaration), >= 0 for indents and newlines
762+
*/
763+
public String format(int indent) {
760764
try {
761-
DOMSource dumSource = new DOMSource(node);
762765
// entities = doctype.getEntities()
763-
TransformerFactory tf = TransformerFactory.newInstance();
764-
Transformer transformer = tf.newTransformer();
765-
// if this is the root, output the decl, if not, hide it
766+
TransformerFactory factory = TransformerFactory.newInstance();
767+
if (indent != -1) {
768+
factory.setAttribute("indent-number", indent);
769+
}
770+
Transformer transformer = factory.newTransformer();
771+
772+
// Add the XML declaration at the top if this node is the root and we're
773+
// not writing to a single line (indent = -1 means single line).
766774
if (indent == -1 || parent != null) {
767775
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
768776
} else {
769777
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
770778
}
771779
// transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "sample.dtd");
780+
772781
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
782+
773783
// transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "yes"); // huh?
774784

775785
// transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
@@ -783,18 +793,45 @@ public String toString(int indent) {
783793
// transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS
784794
// indent by default, but sometimes this needs to be turned off
785795
if (indent != 0) {
786-
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent));
796+
//transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent));
787797
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
798+
} else {
799+
transformer.setOutputProperty(OutputKeys.INDENT, "no");
788800
}
789801
// Properties p = transformer.getOutputProperties();
790802
// for (Object key : p.keySet()) {
791803
// System.out.println(key + " -> " + p.get(key));
792804
// }
793805

794-
StringWriter sw = new StringWriter();
795-
StreamResult sr = new StreamResult(sw);
796-
transformer.transform(dumSource, sr);
797-
return sw.toString();
806+
// If you smell something, that's because this code stinks. No matter
807+
// the settings of the Transformer object, if the XML document already
808+
// has whitespace elements, it won't bother re-indenting/re-formatting.
809+
// So instead, transform the data once into a single line string.
810+
// If indent is -1, then we're done. Otherwise re-run and the settings
811+
// of the factory will kick in. If you know a better way to do this,
812+
// please contribute. I've wasted too much of my Sunday on it. But at
813+
// least the Giants are getting blown out by the Falcons.
814+
815+
StringWriter tempWriter = new StringWriter();
816+
StreamResult tempResult = new StreamResult(tempWriter);
817+
transformer.transform(new DOMSource(node), tempResult);
818+
String[] tempLines = PApplet.split(tempWriter.toString(), '\n');
819+
if (tempLines[0].startsWith("<?xml")) {
820+
// Remove XML declaration from the top before slamming into one line
821+
tempLines = PApplet.subset(tempLines, 1);
822+
}
823+
String singleLine = PApplet.join(PApplet.trim(tempLines), "");
824+
if (indent == -1) {
825+
return singleLine;
826+
}
827+
828+
StringWriter stringWriter = new StringWriter();
829+
StreamResult xmlOutput = new StreamResult(stringWriter);
830+
// DOMSource source = new DOMSource(node);
831+
Source source = new StreamSource(new StringReader(singleLine));
832+
transformer.transform(source, xmlOutput);
833+
return stringWriter.toString();
834+
// return xmlOutput.getWriter().toString();
798835

799836
} catch (Exception e) {
800837
e.printStackTrace();
@@ -803,9 +840,13 @@ public String toString(int indent) {
803840
}
804841

805842

843+
/**
844+
* Return the XML document formatted with two spaces for indents.
845+
* Chosen to do this since it's the most common case (e.g. with println()).
846+
* Same as format(2). Use the format() function for more options.
847+
*/
806848
@Override
807-
/** Return the XML data as a single line, with no DOCTYPE declaration. */
808849
public String toString() {
809-
return toString(-1);
850+
return format(2);
810851
}
811852
}

core/todo.txt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,19 +143,20 @@ X messy, just not great
143143
o isWhitespace() method for nodes? (that's the capitalization used in Character)
144144
X doesn't help much
145145
o get back to PhiLho once finished
146+
X XML toString(0) means no indents or newlines
147+
X but no way to remove indents and still have newlines...
148+
X toString(-1)? a new method?
149+
X format(2), format(4)... toString() -> default to 2 params
150+
X fix this across the other items
151+
X look into json and how it would work wrt XML
152+
o 1) we bring back getFloatAttribute() et al.,
153+
o and make getFloat() be equivalent to parseFloat(xml.getContent())
154+
o 2) we keep getFloat() like it is, and add getFloatContent(), etc.
155+
o 3) we deprecate our nice short getFloat/getInt/etc and go with
156+
o getXxxxAttribute() and getXxxxContent() methods.
157+
X not gonna do getFloatContent() since it's not really any shorter
146158

147159
_ beginning slash in getChild() threw an NPE
148-
_ XML toString(0) means no indents or newlines
149-
_ but no way to remove indents and still have newlines...
150-
_ toString(-1)? a new method?
151-
_ format(2), format(4)... format() -> default to 2 params
152-
153-
_ look into json and how it would work wrt XML
154-
_ 1) we bring back getFloatAttribute() et al.,
155-
_ and make getFloat() be equivalent to parseFloat(xml.getContent())
156-
_ 2) we keep getFloat() like it is, and add getFloatContent(), etc.
157-
_ 3) we deprecate our nice short getFloat/getInt/etc and go with
158-
_ getXxxxAttribute() and getXxxxContent() methods.
159160

160161
async requests
161162
Request r = createRequest("http://p5.org/feed/13134.jpg");

0 commit comments

Comments
 (0)