picrate 0.0.2-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +47 -0
  3. data/.mvn/extensions.xml +9 -0
  4. data/.mvn/wrapper/maven-wrapper.properties +1 -0
  5. data/.travis.yml +10 -0
  6. data/CHANGELOG.md +4 -0
  7. data/LICENSE.md +165 -0
  8. data/README.md +51 -0
  9. data/Rakefile +59 -0
  10. data/bin/picrate +8 -0
  11. data/docs/.gitignore +6 -0
  12. data/docs/_config.yml +30 -0
  13. data/docs/_includes/footer.html +38 -0
  14. data/docs/_includes/head.html +16 -0
  15. data/docs/_includes/header.html +27 -0
  16. data/docs/_includes/icon-github.html +1 -0
  17. data/docs/_includes/icon-github.svg +1 -0
  18. data/docs/_includes/icon-twitter.html +1 -0
  19. data/docs/_includes/icon-twitter.svg +1 -0
  20. data/docs/_includes/navigation.html +24 -0
  21. data/docs/_layouts/default.html +20 -0
  22. data/docs/_layouts/page.html +14 -0
  23. data/docs/_layouts/post.html +15 -0
  24. data/docs/_posts/2018-05-06-getting_started.md +8 -0
  25. data/docs/_posts/2018-05-06-install_jruby.md +35 -0
  26. data/docs/_sass/_base.scss +206 -0
  27. data/docs/_sass/_layout.scss +242 -0
  28. data/docs/_sass/_syntax-highlighting.scss +71 -0
  29. data/docs/about.md +10 -0
  30. data/docs/css/main.scss +38 -0
  31. data/docs/favicon.ico +0 -0
  32. data/docs/feed.xml +30 -0
  33. data/docs/index.html +38 -0
  34. data/lib/picrate.rb +10 -0
  35. data/lib/picrate/app.rb +187 -0
  36. data/lib/picrate/creators/sketch_class.rb +57 -0
  37. data/lib/picrate/creators/sketch_factory.rb +12 -0
  38. data/lib/picrate/creators/sketch_writer.rb +21 -0
  39. data/lib/picrate/helper_methods.rb +214 -0
  40. data/lib/picrate/helpers/numeric.rb +9 -0
  41. data/lib/picrate/library.rb +69 -0
  42. data/lib/picrate/library_loader.rb +53 -0
  43. data/lib/picrate/native_folder.rb +35 -0
  44. data/lib/picrate/native_loader.rb +27 -0
  45. data/lib/picrate/runner.rb +81 -0
  46. data/lib/picrate/version.rb +4 -0
  47. data/library/boids/boids.rb +209 -0
  48. data/library/chooser/chooser.rb +19 -0
  49. data/library/control_panel/control_panel.rb +182 -0
  50. data/library/library_proxy/README.md +99 -0
  51. data/library/library_proxy/library_proxy.rb +14 -0
  52. data/library/slider/slider.rb +42 -0
  53. data/library/vector_utils/vector_utils.rb +69 -0
  54. data/library/video_event/video_event.rb +3 -0
  55. data/license.txt +508 -0
  56. data/picrate.gemspec +35 -0
  57. data/pom.rb +122 -0
  58. data/pom.xml +214 -0
  59. data/src/main/java/japplemenubar/JAppleMenuBar.java +88 -0
  60. data/src/main/java/japplemenubar/libjAppleMenuBar.jnilib +0 -0
  61. data/src/main/java/monkstone/ColorUtil.java +115 -0
  62. data/src/main/java/monkstone/MathToolModule.java +236 -0
  63. data/src/main/java/monkstone/PicrateLibrary.java +47 -0
  64. data/src/main/java/monkstone/core/LibraryProxy.java +127 -0
  65. data/src/main/java/monkstone/fastmath/Deglut.java +122 -0
  66. data/src/main/java/monkstone/fastmath/package-info.java +6 -0
  67. data/src/main/java/monkstone/filechooser/Chooser.java +48 -0
  68. data/src/main/java/monkstone/noise/SimplexNoise.java +465 -0
  69. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +168 -0
  70. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +182 -0
  71. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +149 -0
  72. data/src/main/java/monkstone/slider/SimpleSlider.java +196 -0
  73. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +163 -0
  74. data/src/main/java/monkstone/slider/Slider.java +67 -0
  75. data/src/main/java/monkstone/slider/SliderBar.java +277 -0
  76. data/src/main/java/monkstone/slider/SliderGroup.java +78 -0
  77. data/src/main/java/monkstone/slider/WheelHandler.java +35 -0
  78. data/src/main/java/monkstone/vecmath/AppRender.java +87 -0
  79. data/src/main/java/monkstone/vecmath/JRender.java +56 -0
  80. data/src/main/java/monkstone/vecmath/ShapeRender.java +87 -0
  81. data/src/main/java/monkstone/vecmath/package-info.java +20 -0
  82. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +757 -0
  83. data/src/main/java/monkstone/vecmath/vec2/package-info.java +6 -0
  84. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +727 -0
  85. data/src/main/java/monkstone/vecmath/vec3/package-info.java +6 -0
  86. data/src/main/java/monkstone/videoevent/VideoInterface.java +42 -0
  87. data/src/main/java/monkstone/videoevent/package-info.java +20 -0
  88. data/src/main/java/processing/awt/PGraphicsJava2D.java +3098 -0
  89. data/src/main/java/processing/awt/PShapeJava2D.java +401 -0
  90. data/src/main/java/processing/awt/PSurfaceAWT.java +1660 -0
  91. data/src/main/java/processing/core/PApplet.java +17647 -0
  92. data/src/main/java/processing/core/PConstants.java +1033 -0
  93. data/src/main/java/processing/core/PFont.java +1250 -0
  94. data/src/main/java/processing/core/PGraphics.java +9614 -0
  95. data/src/main/java/processing/core/PImage.java +3608 -0
  96. data/src/main/java/processing/core/PMatrix.java +347 -0
  97. data/src/main/java/processing/core/PMatrix2D.java +694 -0
  98. data/src/main/java/processing/core/PMatrix3D.java +1153 -0
  99. data/src/main/java/processing/core/PShape.java +4332 -0
  100. data/src/main/java/processing/core/PShapeOBJ.java +544 -0
  101. data/src/main/java/processing/core/PShapeSVG.java +1987 -0
  102. data/src/main/java/processing/core/PStyle.java +208 -0
  103. data/src/main/java/processing/core/PSurface.java +242 -0
  104. data/src/main/java/processing/core/PSurfaceNone.java +479 -0
  105. data/src/main/java/processing/core/PVector.java +1140 -0
  106. data/src/main/java/processing/data/FloatDict.java +829 -0
  107. data/src/main/java/processing/data/FloatList.java +912 -0
  108. data/src/main/java/processing/data/IntDict.java +796 -0
  109. data/src/main/java/processing/data/IntList.java +913 -0
  110. data/src/main/java/processing/data/JSONArray.java +1260 -0
  111. data/src/main/java/processing/data/JSONObject.java +2282 -0
  112. data/src/main/java/processing/data/JSONTokener.java +435 -0
  113. data/src/main/java/processing/data/Sort.java +46 -0
  114. data/src/main/java/processing/data/StringDict.java +601 -0
  115. data/src/main/java/processing/data/StringList.java +775 -0
  116. data/src/main/java/processing/data/Table.java +4923 -0
  117. data/src/main/java/processing/data/TableRow.java +198 -0
  118. data/src/main/java/processing/data/XML.java +1149 -0
  119. data/src/main/java/processing/event/Event.java +108 -0
  120. data/src/main/java/processing/event/KeyEvent.java +70 -0
  121. data/src/main/java/processing/event/MouseEvent.java +149 -0
  122. data/src/main/java/processing/event/TouchEvent.java +57 -0
  123. data/src/main/java/processing/javafx/PGraphicsFX2D.java +354 -0
  124. data/src/main/java/processing/opengl/FontTexture.java +379 -0
  125. data/src/main/java/processing/opengl/FrameBuffer.java +503 -0
  126. data/src/main/java/processing/opengl/LinePath.java +623 -0
  127. data/src/main/java/processing/opengl/LineStroker.java +685 -0
  128. data/src/main/java/processing/opengl/PGL.java +3366 -0
  129. data/src/main/java/processing/opengl/PGraphics2D.java +615 -0
  130. data/src/main/java/processing/opengl/PGraphics3D.java +281 -0
  131. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +13634 -0
  132. data/src/main/java/processing/opengl/PJOGL.java +1966 -0
  133. data/src/main/java/processing/opengl/PShader.java +1478 -0
  134. data/src/main/java/processing/opengl/PShapeOpenGL.java +5234 -0
  135. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1315 -0
  136. data/src/main/java/processing/opengl/Texture.java +1670 -0
  137. data/src/main/java/processing/opengl/VertexBuffer.java +88 -0
  138. data/src/main/java/processing/opengl/cursors/arrow.png +0 -0
  139. data/src/main/java/processing/opengl/cursors/cross.png +0 -0
  140. data/src/main/java/processing/opengl/cursors/hand.png +0 -0
  141. data/src/main/java/processing/opengl/cursors/license.txt +27 -0
  142. data/src/main/java/processing/opengl/cursors/move.png +0 -0
  143. data/src/main/java/processing/opengl/cursors/text.png +0 -0
  144. data/src/main/java/processing/opengl/cursors/wait.png +0 -0
  145. data/src/main/java/processing/opengl/shaders/ColorFrag.glsl +32 -0
  146. data/src/main/java/processing/opengl/shaders/ColorVert.glsl +34 -0
  147. data/src/main/java/processing/opengl/shaders/LightFrag.glsl +33 -0
  148. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +154 -0
  149. data/src/main/java/processing/opengl/shaders/LightVert.glsl +151 -0
  150. data/src/main/java/processing/opengl/shaders/LineFrag.glsl +32 -0
  151. data/src/main/java/processing/opengl/shaders/LineVert.glsl +100 -0
  152. data/src/main/java/processing/opengl/shaders/MaskFrag.glsl +40 -0
  153. data/src/main/java/processing/opengl/shaders/PointFrag.glsl +32 -0
  154. data/src/main/java/processing/opengl/shaders/PointVert.glsl +56 -0
  155. data/src/main/java/processing/opengl/shaders/TexFrag.glsl +37 -0
  156. data/src/main/java/processing/opengl/shaders/TexLightFrag.glsl +37 -0
  157. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +160 -0
  158. data/src/main/java/processing/opengl/shaders/TexLightVert.glsl +157 -0
  159. data/src/main/java/processing/opengl/shaders/TexVert.glsl +38 -0
  160. data/src/main/resources/icon/icon-1024.png +0 -0
  161. data/src/main/resources/icon/icon-128.png +0 -0
  162. data/src/main/resources/icon/icon-16.png +0 -0
  163. data/src/main/resources/icon/icon-256.png +0 -0
  164. data/src/main/resources/icon/icon-32.png +0 -0
  165. data/src/main/resources/icon/icon-48.png +0 -0
  166. data/src/main/resources/icon/icon-512.png +0 -0
  167. data/src/main/resources/icon/icon-64.png +0 -0
  168. data/src/main/resources/license.txt +508 -0
  169. data/test/create_test.rb +68 -0
  170. data/test/deglut_spec_test.rb +24 -0
  171. data/test/helper_methods_test.rb +58 -0
  172. data/test/math_tool_test.rb +75 -0
  173. data/test/respond_to_test.rb +215 -0
  174. data/test/sketches/key_event.rb +37 -0
  175. data/test/sketches/library/my_library/my_library.rb +32 -0
  176. data/test/test_helper.rb +3 -0
  177. data/test/vecmath_spec_test.rb +522 -0
  178. data/vendors/Rakefile +127 -0
  179. metadata +289 -0
@@ -0,0 +1,198 @@
1
+ package processing.data;
2
+
3
+ import java.io.PrintWriter;
4
+
5
+ /**
6
+ * @webref data:composite
7
+ * @see Table
8
+ * @see Table#addRow()
9
+ * @see Table#removeRow(int)
10
+ * @see Table#clearRows()
11
+ * @see Table#getRow(int)
12
+ * @see Table#rows()
13
+ */
14
+ public interface TableRow {
15
+
16
+ /**
17
+ * @webref tablerow:method
18
+ * @brief Get an String value from the specified column
19
+ * @param column ID number of the column to reference
20
+ * @see TableRow#getInt(int)
21
+ * @see TableRow#getFloat(int)
22
+ */
23
+ public String getString(int column);
24
+
25
+ /**
26
+ * @param columnName title of the column to reference
27
+ */
28
+ public String getString(String columnName);
29
+
30
+ /**
31
+ * @webref tablerow:method
32
+ * @brief Get an integer value from the specified column
33
+ * @param column ID number of the column to reference
34
+ * @see TableRow#getFloat(int)
35
+ * @see TableRow#getString(int)
36
+ */
37
+ public int getInt(int column);
38
+
39
+ /**
40
+ * @param columnName title of the column to reference
41
+ */
42
+ public int getInt(String columnName);
43
+
44
+ /**
45
+ * @brief Get a long value from the specified column
46
+ * @param column ID number of the column to reference
47
+ * @see TableRow#getFloat(int)
48
+ * @see TableRow#getString(int)
49
+ */
50
+
51
+ public long getLong(int column);
52
+
53
+ /**
54
+ * @param columnName title of the column to reference
55
+ */
56
+ public long getLong(String columnName);
57
+
58
+ /**
59
+ * @webref tablerow:method
60
+ * @brief Get a float value from the specified column
61
+ * @param column ID number of the column to reference
62
+ * @see TableRow#getInt(int)
63
+ * @see TableRow#getString(int)
64
+ */
65
+ public float getFloat(int column);
66
+
67
+ /**
68
+ * @param columnName title of the column to reference
69
+ */
70
+ public float getFloat(String columnName);
71
+
72
+ /**
73
+ * @brief Get a double value from the specified column
74
+ * @param column ID number of the column to reference
75
+ * @see TableRow#getInt(int)
76
+ * @see TableRow#getString(int)
77
+ */
78
+ public double getDouble(int column);
79
+
80
+ /**
81
+ * @param columnName title of the column to reference
82
+ */
83
+ public double getDouble(String columnName);
84
+
85
+ /**
86
+ * @webref tablerow:method
87
+ * @brief Store a String value in the specified column
88
+ * @param column ID number of the target column
89
+ * @param value value to assign
90
+ * @see TableRow#setInt(int, int)
91
+ * @see TableRow#setFloat(int, float)
92
+ */
93
+ public void setString(int column, String value);
94
+ /**
95
+ * @param columnName title of the target column
96
+ */
97
+ public void setString(String columnName, String value);
98
+
99
+ /**
100
+ * @webref tablerow:method
101
+ * @brief Store an integer value in the specified column
102
+ * @param column ID number of the target column
103
+ * @param value value to assign
104
+ * @see TableRow#setFloat(int, float)
105
+ * @see TableRow#setString(int, String)
106
+ */
107
+ public void setInt(int column, int value);
108
+
109
+ /**
110
+ * @param columnName title of the target column
111
+ */
112
+ public void setInt(String columnName, int value);
113
+
114
+ /**
115
+ * @brief Store a long value in the specified column
116
+ * @param column ID number of the target column
117
+ * @param value value to assign
118
+ * @see TableRow#setFloat(int, float)
119
+ * @see TableRow#setString(int, String)
120
+ */
121
+ public void setLong(int column, long value);
122
+
123
+ /**
124
+ * @param columnName title of the target column
125
+ */
126
+ public void setLong(String columnName, long value);
127
+
128
+ /**
129
+ * @webref tablerow:method
130
+ * @brief Store a float value in the specified column
131
+ * @param column ID number of the target column
132
+ * @param value value to assign
133
+ * @see TableRow#setInt(int, int)
134
+ * @see TableRow#setString(int, String)
135
+ */
136
+ public void setFloat(int column, float value);
137
+
138
+ /**
139
+ * @param columnName title of the target column
140
+ */
141
+ public void setFloat(String columnName, float value);
142
+
143
+ /**
144
+ * @brief Store a double value in the specified column
145
+ * @param column ID number of the target column
146
+ * @param value value to assign
147
+ * @see TableRow#setFloat(int, float)
148
+ * @see TableRow#setString(int, String)
149
+ */
150
+ public void setDouble(int column, double value);
151
+
152
+ /**
153
+ * @param columnName title of the target column
154
+ */
155
+ public void setDouble(String columnName, double value);
156
+
157
+ /**
158
+ * @webref tablerow:method
159
+ * @brief Get the column count.
160
+ * @return count of all columns
161
+ */
162
+ public int getColumnCount();
163
+
164
+ /**
165
+ * @brief Get the column type.
166
+ * @param columnName title of the target column
167
+ * @return type of the column
168
+ */
169
+ public int getColumnType(String columnName);
170
+
171
+ /**
172
+ * @param column ID number of the target column
173
+ */
174
+ public int getColumnType(int column);
175
+
176
+ /**
177
+ * @brief Get the all column types
178
+ * @return list of all column types
179
+ */
180
+ public int[] getColumnTypes();
181
+
182
+ /**
183
+ * @webref tablerow:method
184
+ * @brief Get the column title.
185
+ * @param column ID number of the target column
186
+ * @return title of the column
187
+ */
188
+ public String getColumnTitle(int column);
189
+
190
+ /**
191
+ * @brief Get the all column titles
192
+ * @return list of all column titles
193
+ */
194
+ public String[] getColumnTitles();
195
+
196
+ public void write(PrintWriter writer);
197
+ public void print();
198
+ }
@@ -0,0 +1,1149 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2012 The Processing Foundation
7
+ Copyright (c) 2009-12 Ben Fry and Casey Reas
8
+
9
+ This library is free software; you can redistribute it and/or
10
+ modify it under the terms of the GNU Lesser General Public
11
+ License as published by the Free Software Foundation, version 2.
12
+
13
+ This library is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty
15
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
+ See the GNU Lesser General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Lesser General
19
+ Public License along with this library; if not, write to the
20
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21
+ Boston, MA 02111-1307 USA
22
+ */
23
+
24
+ package processing.data;
25
+
26
+ import java.io.*;
27
+
28
+ import javax.xml.parsers.*;
29
+
30
+ import org.w3c.dom.*;
31
+ import org.xml.sax.*;
32
+
33
+ import javax.xml.transform.*;
34
+ import javax.xml.transform.dom.*;
35
+ import javax.xml.transform.stream.*;
36
+ import javax.xml.xpath.XPathConstants;
37
+ import javax.xml.xpath.XPathExpression;
38
+ import javax.xml.xpath.XPathFactory;
39
+
40
+ import processing.core.PApplet;
41
+
42
+
43
+ /**
44
+ * This is the base class used for the Processing XML library,
45
+ * representing a single node of an XML tree.
46
+ *
47
+ * @webref data:composite
48
+ * @see PApplet#loadXML(String)
49
+ * @see PApplet#parseXML(String)
50
+ * @see PApplet#saveXML(XML, String)
51
+ */
52
+ public class XML implements Serializable {
53
+
54
+ /** The internal representation, a DOM node. */
55
+ protected Node node;
56
+
57
+ // /** Cached locally because it's used often. */
58
+ // protected String name;
59
+
60
+ /** The parent element. */
61
+ protected XML parent;
62
+
63
+ /** Child elements, once loaded. */
64
+ protected XML[] children;
65
+
66
+ /**
67
+ * @nowebref
68
+ */
69
+ protected XML() { }
70
+
71
+
72
+ // /**
73
+ // * Begin parsing XML data passed in from a PApplet. This code
74
+ // * wraps exception handling, for more advanced exception handling,
75
+ // * use the constructor that takes a Reader or InputStream.
76
+ // *
77
+ // * @throws SAXException
78
+ // * @throws ParserConfigurationException
79
+ // * @throws IOException
80
+ // */
81
+ // public XML(PApplet parent, String filename) throws IOException, ParserConfigurationException, SAXException {
82
+ // this(parent.createReader(filename));
83
+ // }
84
+
85
+
86
+ /**
87
+ * Advanced users only; use loadXML() in PApplet. This is not a supported
88
+ * function and is subject to change. It is available simply for users that
89
+ * would like to handle the exceptions in a particular way.
90
+ *
91
+ * @nowebref
92
+ */
93
+ public XML(File file) throws IOException, ParserConfigurationException, SAXException {
94
+ this(file, null);
95
+ }
96
+
97
+
98
+ /**
99
+ * Advanced users only; use loadXML() in PApplet.
100
+ *
101
+ * @nowebref
102
+ */
103
+ public XML(File file, String options) throws IOException, ParserConfigurationException, SAXException {
104
+ this(PApplet.createReader(file), options);
105
+ }
106
+
107
+ /**
108
+ * @nowebref
109
+ */
110
+ public XML(InputStream input) throws IOException, ParserConfigurationException, SAXException {
111
+ this(input, null);
112
+ }
113
+
114
+
115
+ /**
116
+ * Unlike the loadXML() method in PApplet, this version works with files
117
+ * that are not in UTF-8 format.
118
+ *
119
+ * @nowebref
120
+ */
121
+ public XML(InputStream input, String options) throws IOException, ParserConfigurationException, SAXException {
122
+ //this(PApplet.createReader(input), options); // won't handle non-UTF8
123
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
124
+
125
+ try {
126
+ // Prevent 503 errors from www.w3.org
127
+ factory.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
128
+ } catch (IllegalArgumentException e) {
129
+ // ignore this; Android doesn't like it
130
+ }
131
+
132
+ factory.setExpandEntityReferences(false);
133
+ DocumentBuilder builder = factory.newDocumentBuilder();
134
+ Document document = builder.parse(new InputSource(input));
135
+ node = document.getDocumentElement();
136
+ }
137
+
138
+
139
+ /**
140
+ * Advanced users only; use loadXML() in PApplet.
141
+ *
142
+ * @nowebref
143
+ */
144
+ public XML(Reader reader) throws IOException, ParserConfigurationException, SAXException {
145
+ this(reader, null);
146
+ }
147
+
148
+
149
+ /**
150
+ * Advanced users only; use loadXML() in PApplet.
151
+ *
152
+ * Added extra code to handle \u2028 (Unicode NLF), which is sometimes
153
+ * inserted by web browsers (Safari?) and not distinguishable from a "real"
154
+ * LF (or CRLF) in some text editors (i.e. TextEdit on OS X). Only doing
155
+ * this for XML (and not all Reader objects) because LFs are essential.
156
+ * https://github.com/processing/processing/issues/2100
157
+ *
158
+ * @nowebref
159
+ */
160
+ public XML(final Reader reader, String options) throws IOException, ParserConfigurationException, SAXException {
161
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
162
+
163
+ // Prevent 503 errors from www.w3.org
164
+ try {
165
+ factory.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
166
+ } catch (IllegalArgumentException e) {
167
+ // ignore this; Android doesn't like it
168
+ }
169
+
170
+ // without a validating DTD, this doesn't do anything since it doesn't know what is ignorable
171
+ // factory.setIgnoringElementContentWhitespace(true);
172
+
173
+ factory.setExpandEntityReferences(false);
174
+ // factory.setExpandEntityReferences(true);
175
+
176
+ // factory.setCoalescing(true);
177
+ // builderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
178
+ DocumentBuilder builder = factory.newDocumentBuilder();
179
+ // builder.setEntityResolver()
180
+
181
+ // SAXParserFactory spf = SAXParserFactory.newInstance();
182
+ // spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
183
+ // SAXParser p = spf.newSAXParser();
184
+
185
+ // builder = DocumentBuilderFactory.newDocumentBuilder();
186
+ // builder = new SAXBuilder();
187
+ // builder.setValidation(validating);
188
+
189
+ Document document = builder.parse(new InputSource(new Reader() {
190
+ @Override
191
+ public int read(char[] cbuf, int off, int len) throws IOException {
192
+ int count = reader.read(cbuf, off, len);
193
+ for (int i = 0; i < count; i++) {
194
+ if (cbuf[off+i] == '\u2028') {
195
+ cbuf[off+i] = '\n';
196
+ }
197
+ }
198
+ return count;
199
+ }
200
+
201
+ @Override
202
+ public void close() throws IOException {
203
+ reader.close();
204
+ }
205
+ }));
206
+ node = document.getDocumentElement();
207
+ }
208
+
209
+
210
+ /**
211
+ * @param name creates a node with this name
212
+ *
213
+ */
214
+ public XML(String name) {
215
+ try {
216
+ // TODO is there a more efficient way of doing this? wow.
217
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
218
+ DocumentBuilder builder = factory.newDocumentBuilder();
219
+ Document document = builder.newDocument();
220
+ node = document.createElement(name);
221
+ this.parent = null;
222
+
223
+ } catch (ParserConfigurationException pce) {
224
+ throw new RuntimeException(pce);
225
+ }
226
+ }
227
+
228
+ /**
229
+ * @nowebref
230
+ */
231
+ protected XML(XML parent, Node node) {
232
+ this.node = node;
233
+ this.parent = parent;
234
+
235
+ for (String attr : parent.listAttributes()) {
236
+ if (attr.startsWith("xmlns")) {
237
+ // Copy namespace attributes to the kids, otherwise this XML
238
+ // can no longer be printed (or manipulated in most ways).
239
+ // Only do this when it's an Element, otherwise it's trying to set
240
+ // attributes on text notes (interstitial content).
241
+ if (node instanceof Element) {
242
+ setString(attr, parent.getString(attr));
243
+ }
244
+ }
245
+ }
246
+ }
247
+
248
+
249
+ /**
250
+ * @webref xml:method
251
+ * @brief Converts String content to an XML object
252
+ * @param data the content to be parsed as XML
253
+ * @return an XML object, or null
254
+ * @throws SAXException
255
+ * @throws ParserConfigurationException
256
+ * @throws IOException
257
+ * @nowebref
258
+ */
259
+ static public XML parse(String data) throws IOException, ParserConfigurationException, SAXException {
260
+ return XML.parse(data, null);
261
+ }
262
+
263
+ /**
264
+ * @nowebref
265
+ */
266
+ static public XML parse(String data, String options) throws IOException, ParserConfigurationException, SAXException {
267
+ return new XML(new StringReader(data), null);
268
+ }
269
+
270
+
271
+ // protected boolean save(OutputStream output) {
272
+ // return write(PApplet.createWriter(output));
273
+ // }
274
+
275
+
276
+ public boolean save(File file) {
277
+ return save(file, null);
278
+ }
279
+
280
+
281
+ public boolean save(File file, String options) {
282
+ PrintWriter writer = PApplet.createWriter(file);
283
+ boolean result = write(writer);
284
+ writer.flush();
285
+ writer.close();
286
+ return result;
287
+ }
288
+
289
+
290
+ // Sends this object and its kids to a Writer with an indent of 2 spaces,
291
+ // including the declaration at the top so that the output will be valid XML.
292
+ public boolean write(PrintWriter output) {
293
+ output.print(format(2));
294
+ output.flush();
295
+ return true;
296
+ }
297
+
298
+
299
+ /**
300
+ * Returns the parent element. This method returns null for the root
301
+ * element.
302
+ *
303
+ * @webref xml:method
304
+ * @brief Gets a copy of the element's parent
305
+ */
306
+ public XML getParent() {
307
+ return this.parent;
308
+ }
309
+
310
+ /**
311
+ * Internal function; not included in reference.
312
+ */
313
+ protected Object getNative() {
314
+ return node;
315
+ }
316
+
317
+
318
+ /**
319
+ * Returns the full name (i.e. the name including an eventual namespace
320
+ * prefix) of the element.
321
+ *
322
+ * @webref xml:method
323
+ * @brief Gets the element's full name
324
+ * @return the name, or null if the element only contains #PCDATA.
325
+ */
326
+ public String getName() {
327
+ // return name;
328
+ return node.getNodeName();
329
+ }
330
+
331
+ /**
332
+ * @webref xml:method
333
+ * @brief Sets the element's name
334
+ */
335
+ public void setName(String newName) {
336
+ Document document = node.getOwnerDocument();
337
+ node = document.renameNode(node, null, newName);
338
+ // name = node.getNodeName();
339
+ }
340
+
341
+
342
+ /**
343
+ * Returns the name of the element (without namespace prefix).
344
+ *
345
+ * Internal function; not included in reference.
346
+ */
347
+ public String getLocalName() {
348
+ return node.getLocalName();
349
+ }
350
+
351
+
352
+ /**
353
+ * Honey, can you just check on the kids? Thanks.
354
+ *
355
+ * Internal function; not included in reference.
356
+ */
357
+ protected void checkChildren() {
358
+ if (children == null) {
359
+ NodeList kids = node.getChildNodes();
360
+ int childCount = kids.getLength();
361
+ children = new XML[childCount];
362
+ for (int i = 0; i < childCount; i++) {
363
+ children[i] = new XML(this, kids.item(i));
364
+ }
365
+ }
366
+ }
367
+
368
+
369
+ /**
370
+ * Returns the number of children.
371
+ *
372
+ * @webref xml:method
373
+ * @brief Returns the element's number of children
374
+ * @return the count.
375
+ */
376
+ public int getChildCount() {
377
+ checkChildren();
378
+ return children.length;
379
+ }
380
+
381
+
382
+ /**
383
+ * Returns a boolean of whether or not there are children.
384
+ *
385
+ * @webref xml:method
386
+ * @brief Checks whether or not an element has any children
387
+ */
388
+ public boolean hasChildren() {
389
+ checkChildren();
390
+ return children.length > 0;
391
+ }
392
+
393
+
394
+ /**
395
+ * Put the names of all children into an array. Same as looping through
396
+ * each child and calling getName() on each XMLElement.
397
+ *
398
+ * @webref xml:method
399
+ * @brief Returns the names of all children as an array
400
+ */
401
+ public String[] listChildren() {
402
+ // NodeList children = node.getChildNodes();
403
+ // int childCount = children.getLength();
404
+ // String[] outgoing = new String[childCount];
405
+ // for (int i = 0; i < childCount; i++) {
406
+ // Node kid = children.item(i);
407
+ // if (kid.getNodeType() == Node.ELEMENT_NODE) {
408
+ // outgoing[i] = kid.getNodeName();
409
+ // } // otherwise just leave him null
410
+ // }
411
+ checkChildren();
412
+ String[] outgoing = new String[children.length];
413
+ for (int i = 0; i < children.length; i++) {
414
+ outgoing[i] = children[i].getName();
415
+ }
416
+ return outgoing;
417
+ }
418
+
419
+
420
+ /**
421
+ * Returns an array containing all the child elements.
422
+ *
423
+ * @webref xml:method
424
+ * @brief Returns an array containing all child elements
425
+ */
426
+ public XML[] getChildren() {
427
+ // NodeList children = node.getChildNodes();
428
+ // int childCount = children.getLength();
429
+ // XMLElement[] kids = new XMLElement[childCount];
430
+ // for (int i = 0; i < childCount; i++) {
431
+ // Node kid = children.item(i);
432
+ // kids[i] = new XMLElement(this, kid);
433
+ // }
434
+ // return kids;
435
+ checkChildren();
436
+ return children;
437
+ }
438
+
439
+
440
+ /**
441
+ * Quick accessor for an element at a particular index.
442
+ *
443
+ * @webref xml:method
444
+ * @brief Returns the child element with the specified index value or path
445
+ */
446
+ public XML getChild(int index) {
447
+ checkChildren();
448
+ return children[index];
449
+ }
450
+
451
+
452
+ /**
453
+ * Get a child by its name or path.
454
+ *
455
+ * @param name element name or path/to/element
456
+ * @return the first matching element or null if no match
457
+ */
458
+ public XML getChild(String name) {
459
+ if (name.length() > 0 && name.charAt(0) == '/') {
460
+ throw new IllegalArgumentException("getChild() should not begin with a slash");
461
+ }
462
+ if (name.indexOf('/') != -1) {
463
+ return getChildRecursive(PApplet.split(name, '/'), 0);
464
+ }
465
+ int childCount = getChildCount();
466
+ for (int i = 0; i < childCount; i++) {
467
+ XML kid = getChild(i);
468
+ String kidName = kid.getName();
469
+ if (kidName != null && kidName.equals(name)) {
470
+ return kid;
471
+ }
472
+ }
473
+ return null;
474
+ }
475
+
476
+
477
+ /**
478
+ * Internal helper function for getChild(String).
479
+ *
480
+ * @param items result of splitting the query on slashes
481
+ * @param offset where in the items[] array we're currently looking
482
+ * @return matching element or null if no match
483
+ * @author processing.org
484
+ */
485
+ protected XML getChildRecursive(String[] items, int offset) {
486
+ // if it's a number, do an index instead
487
+ if (Character.isDigit(items[offset].charAt(0))) {
488
+ XML kid = getChild(Integer.parseInt(items[offset]));
489
+ if (offset == items.length-1) {
490
+ return kid;
491
+ } else {
492
+ return kid.getChildRecursive(items, offset+1);
493
+ }
494
+ }
495
+ int childCount = getChildCount();
496
+ for (int i = 0; i < childCount; i++) {
497
+ XML kid = getChild(i);
498
+ String kidName = kid.getName();
499
+ if (kidName != null && kidName.equals(items[offset])) {
500
+ if (offset == items.length-1) {
501
+ return kid;
502
+ } else {
503
+ return kid.getChildRecursive(items, offset+1);
504
+ }
505
+ }
506
+ }
507
+ return null;
508
+ }
509
+
510
+
511
+ /**
512
+ * Get any children that match this name or path. Similar to getChild(),
513
+ * but will grab multiple matches rather than only the first.
514
+ *
515
+ * @param name element name or path/to/element
516
+ * @return array of child elements that match
517
+ * @author processing.org
518
+ */
519
+ public XML[] getChildren(String name) {
520
+ if (name.length() > 0 && name.charAt(0) == '/') {
521
+ throw new IllegalArgumentException("getChildren() should not begin with a slash");
522
+ }
523
+ if (name.indexOf('/') != -1) {
524
+ return getChildrenRecursive(PApplet.split(name, '/'), 0);
525
+ }
526
+ // if it's a number, do an index instead
527
+ // (returns a single element array, since this will be a single match
528
+ if (Character.isDigit(name.charAt(0))) {
529
+ return new XML[] { getChild(Integer.parseInt(name)) };
530
+ }
531
+ int childCount = getChildCount();
532
+ XML[] matches = new XML[childCount];
533
+ int matchCount = 0;
534
+ for (int i = 0; i < childCount; i++) {
535
+ XML kid = getChild(i);
536
+ String kidName = kid.getName();
537
+ if (kidName != null && kidName.equals(name)) {
538
+ matches[matchCount++] = kid;
539
+ }
540
+ }
541
+ return (XML[]) PApplet.subset(matches, 0, matchCount);
542
+ }
543
+
544
+
545
+ protected XML[] getChildrenRecursive(String[] items, int offset) {
546
+ if (offset == items.length-1) {
547
+ return getChildren(items[offset]);
548
+ }
549
+ XML[] matches = getChildren(items[offset]);
550
+ XML[] outgoing = new XML[0];
551
+ for (int i = 0; i < matches.length; i++) {
552
+ XML[] kidMatches = matches[i].getChildrenRecursive(items, offset+1);
553
+ outgoing = (XML[]) PApplet.concat(outgoing, kidMatches);
554
+ }
555
+ return outgoing;
556
+ }
557
+
558
+
559
+ /**
560
+ * @webref xml:method
561
+ * @brief Appends a new child to the element
562
+ */
563
+ public XML addChild(String tag) {
564
+ Document document = node.getOwnerDocument();
565
+ Node newChild = document.createElement(tag);
566
+ return appendChild(newChild);
567
+ }
568
+
569
+
570
+ public XML addChild(XML child) {
571
+ Document document = node.getOwnerDocument();
572
+ Node newChild = document.importNode((Node) child.getNative(), true);
573
+ return appendChild(newChild);
574
+ }
575
+
576
+
577
+ /** Internal handler to add the node structure. */
578
+ protected XML appendChild(Node newNode) {
579
+ node.appendChild(newNode);
580
+ XML newbie = new XML(this, newNode);
581
+ if (children != null) {
582
+ children = (XML[]) PApplet.concat(children, new XML[] { newbie });
583
+ }
584
+ return newbie;
585
+ }
586
+
587
+
588
+ /**
589
+ * @webref xml:method
590
+ * @brief Removes the specified child
591
+ */
592
+ public void removeChild(XML kid) {
593
+ node.removeChild(kid.node);
594
+ children = null; // TODO not efficient
595
+ }
596
+
597
+
598
+ public void trim() {
599
+ try {
600
+ XPathFactory xpathFactory = XPathFactory.newInstance();
601
+ XPathExpression xpathExp =
602
+ xpathFactory.newXPath().compile("//text()[normalize-space(.) = '']");
603
+ NodeList emptyTextNodes = (NodeList)
604
+ xpathExp.evaluate(node, XPathConstants.NODESET);
605
+
606
+ // Remove each empty text node from document.
607
+ for (int i = 0; i < emptyTextNodes.getLength(); i++) {
608
+ Node emptyTextNode = emptyTextNodes.item(i);
609
+ emptyTextNode.getParentNode().removeChild(emptyTextNode);
610
+ }
611
+ } catch (Exception e) {
612
+ throw new RuntimeException(e);
613
+ }
614
+ }
615
+
616
+
617
+ // /** Remove whitespace nodes. */
618
+ // public void trim() {
619
+ ////// public static boolean isWhitespace(XML xml) {
620
+ ////// if (xml.node.getNodeType() != Node.TEXT_NODE)
621
+ ////// return false;
622
+ ////// Matcher m = whitespace.matcher(xml.node.getNodeValue());
623
+ ////// return m.matches();
624
+ ////// }
625
+ //// trim(this);
626
+ //// }
627
+ //
628
+ // checkChildren();
629
+ // int index = 0;
630
+ // for (int i = 0; i < children.length; i++) {
631
+ // if (i != index) {
632
+ // children[index] = children[i];
633
+ // }
634
+ // Node childNode = (Node) children[i].getNative();
635
+ // if (childNode.getNodeType() != Node.TEXT_NODE ||
636
+ // children[i].getContent().trim().length() > 0) {
637
+ // children[i].trim();
638
+ // index++;
639
+ // }
640
+ // }
641
+ // if (index != children.length) {
642
+ // children = (XML[]) PApplet.subset(children, 0, index);
643
+ // }
644
+ //
645
+ // // possibility, but would have to re-parse the object
646
+ //// helpdesk.objects.com.au/java/how-do-i-remove-whitespace-from-an-xml-document
647
+ //// TransformerFactory factory = TransformerFactory.newInstance();
648
+ //// Transformer transformer = factory.newTransformer(new StreamSource("strip-space.xsl"));
649
+ //// DOMSource source = new DOMSource(document);
650
+ //// StreamResult result = new StreamResult(System.out);
651
+ //// transformer.transform(source, result);
652
+ //
653
+ //// <xsl:stylesheet version="1.0"
654
+ //// xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
655
+ //// <xsl:output method="xml" omit-xml-declaration="yes"/>
656
+ //// <xsl:strip-space elements="*"/>
657
+ //// <xsl:template match="@*|node()">
658
+ //// <xsl:copy>
659
+ //// <xsl:apply-templates select="@*|node()"/>
660
+ //// </xsl:copy>
661
+ //// </xsl:template>
662
+ //// </xsl:stylesheet>
663
+ // }
664
+
665
+
666
+ /**
667
+ * Returns the number of attributes.
668
+ *
669
+ * @webref xml:method
670
+ * @brief Counts the specified element's number of attributes
671
+ */
672
+ public int getAttributeCount() {
673
+ return node.getAttributes().getLength();
674
+ }
675
+
676
+
677
+ /**
678
+ * Get a list of the names for all of the attributes for this node.
679
+ *
680
+ * @webref xml:method
681
+ * @brief Returns a list of names of all attributes as an array
682
+ */
683
+ public String[] listAttributes() {
684
+ NamedNodeMap nnm = node.getAttributes();
685
+ String[] outgoing = new String[nnm.getLength()];
686
+ for (int i = 0; i < outgoing.length; i++) {
687
+ outgoing[i] = nnm.item(i).getNodeName();
688
+ }
689
+ return outgoing;
690
+ }
691
+
692
+ /**
693
+ * Returns whether an attribute exists.
694
+ *
695
+ * @webref xml:method
696
+ * @brief Checks whether or not an element has the specified attribute
697
+ */
698
+ public boolean hasAttribute(String name) {
699
+ return (node.getAttributes().getNamedItem(name) != null);
700
+ }
701
+
702
+
703
+ /**
704
+ * Returns the value of an attribute.
705
+ *
706
+ * @param name the non-null name of the attribute.
707
+ * @return the value, or null if the attribute does not exist.
708
+ */
709
+ // public String getAttribute(String name) {
710
+ // return this.getAttribute(name, null);
711
+ // }
712
+
713
+
714
+ /**
715
+ * Returns the value of an attribute.
716
+ *
717
+ * @param name the non-null full name of the attribute.
718
+ * @param defaultValue the default value of the attribute.
719
+ * @return the value, or defaultValue if the attribute does not exist.
720
+ */
721
+ // public String getAttribute(String name, String defaultValue) {
722
+ // Node attr = node.getAttributes().getNamedItem(name);
723
+ // return (attr == null) ? defaultValue : attr.getNodeValue();
724
+ // }
725
+
726
+
727
+ /**
728
+ * @webref xml:method
729
+ * @brief Gets the content of an attribute as a String
730
+ */
731
+ public String getString(String name) {
732
+ return getString(name, null);
733
+ }
734
+
735
+
736
+ public String getString(String name, String defaultValue) {
737
+ NamedNodeMap attrs = node.getAttributes();
738
+ if (attrs != null) {
739
+ Node attr = attrs.getNamedItem(name);
740
+ if (attr != null) {
741
+ return attr.getNodeValue();
742
+ }
743
+ }
744
+ return defaultValue;
745
+ }
746
+
747
+
748
+ /**
749
+ * @webref xml:method
750
+ * @brief Sets the content of an attribute as a String
751
+ */
752
+ public void setString(String name, String value) {
753
+ ((Element) node).setAttribute(name, value);
754
+ }
755
+
756
+
757
+ /**
758
+ * @webref xml:method
759
+ * @brief Gets the content of an attribute as an int
760
+ */
761
+ public int getInt(String name) {
762
+ return getInt(name, 0);
763
+ }
764
+
765
+
766
+ /**
767
+ * @webref xml:method
768
+ * @brief Sets the content of an attribute as an int
769
+ */
770
+ public void setInt(String name, int value) {
771
+ setString(name, String.valueOf(value));
772
+ }
773
+
774
+
775
+ /**
776
+ * Returns the value of an attribute.
777
+ *
778
+ * @param name the non-null full name of the attribute
779
+ * @param defaultValue the default value of the attribute
780
+ * @return the value, or defaultValue if the attribute does not exist
781
+ */
782
+ public int getInt(String name, int defaultValue) {
783
+ String value = getString(name);
784
+ return (value == null) ? defaultValue : Integer.parseInt(value);
785
+ }
786
+
787
+
788
+ /**
789
+ * @webref xml:method
790
+ * @brief Sets the content of an element as an int
791
+ */
792
+ public void setLong(String name, long value) {
793
+ setString(name, String.valueOf(value));
794
+ }
795
+
796
+
797
+ /**
798
+ * Returns the value of an attribute.
799
+ *
800
+ * @param name the non-null full name of the attribute.
801
+ * @param defaultValue the default value of the attribute.
802
+ * @return the value, or defaultValue if the attribute does not exist.
803
+ */
804
+ public long getLong(String name, long defaultValue) {
805
+ String value = getString(name);
806
+ return (value == null) ? defaultValue : Long.parseLong(value);
807
+ }
808
+
809
+
810
+ /**
811
+ * Returns the value of an attribute, or zero if not present.
812
+ *
813
+ * @webref xml:method
814
+ * @brief Gets the content of an attribute as a float
815
+ */
816
+ public float getFloat(String name) {
817
+ return getFloat(name, 0);
818
+ }
819
+
820
+
821
+ /**
822
+ * Returns the value of an attribute.
823
+ *
824
+ * @param name the non-null full name of the attribute.
825
+ * @param defaultValue the default value of the attribute.
826
+ * @return the value, or defaultValue if the attribute does not exist.
827
+ */
828
+ public float getFloat(String name, float defaultValue) {
829
+ String value = getString(name);
830
+ return (value == null) ? defaultValue : Float.parseFloat(value);
831
+ }
832
+
833
+
834
+ /**
835
+ * @webref xml:method
836
+ * @brief Sets the content of an attribute as a float
837
+ */
838
+ public void setFloat(String name, float value) {
839
+ setString(name, String.valueOf(value));
840
+ }
841
+
842
+
843
+ public double getDouble(String name) {
844
+ return getDouble(name, 0);
845
+ }
846
+
847
+
848
+ /**
849
+ * Returns the value of an attribute.
850
+ *
851
+ * @param name the non-null full name of the attribute
852
+ * @param defaultValue the default value of the attribute
853
+ * @return the value, or defaultValue if the attribute does not exist
854
+ */
855
+ public double getDouble(String name, double defaultValue) {
856
+ String value = getString(name);
857
+ return (value == null) ? defaultValue : Double.parseDouble(value);
858
+ }
859
+
860
+
861
+ public void setDouble(String name, double value) {
862
+ setString(name, String.valueOf(value));
863
+ }
864
+
865
+
866
+ /**
867
+ * Return the #PCDATA content of the element. If the element has a
868
+ * combination of #PCDATA content and child elements, the #PCDATA
869
+ * sections can be retrieved as unnamed child objects. In this case,
870
+ * this method returns null.
871
+ *
872
+ * @webref xml:method
873
+ * @brief Gets the content of an element
874
+ * @return the content.
875
+ * @see XML#getIntContent()
876
+ * @see XML#getFloatContent()
877
+ */
878
+ public String getContent() {
879
+ return node.getTextContent();
880
+ }
881
+
882
+
883
+ public String getContent(String defaultValue) {
884
+ String s = node.getTextContent();
885
+ return (s != null) ? s : defaultValue;
886
+ }
887
+
888
+
889
+ /**
890
+ * @webref xml:method
891
+ * @brief Gets the content of an element as an int
892
+ * @return the content.
893
+ * @see XML#getContent()
894
+ * @see XML#getFloatContent()
895
+ */
896
+ public int getIntContent() {
897
+ return getIntContent(0);
898
+ }
899
+
900
+
901
+ /**
902
+ * @param defaultValue the default value of the attribute
903
+ */
904
+ public int getIntContent(int defaultValue) {
905
+ return PApplet.parseInt(node.getTextContent(), defaultValue);
906
+ }
907
+
908
+
909
+ /**
910
+ * @webref xml:method
911
+ * @brief Gets the content of an element as a float
912
+ * @return the content.
913
+ * @see XML#getContent()
914
+ * @see XML#getIntContent()
915
+ */
916
+ public float getFloatContent() {
917
+ return getFloatContent(0);
918
+ }
919
+
920
+
921
+ /**
922
+ * @param defaultValue the default value of the attribute
923
+ */
924
+ public float getFloatContent(float defaultValue) {
925
+ return PApplet.parseFloat(node.getTextContent(), defaultValue);
926
+ }
927
+
928
+
929
+ public long getLongContent() {
930
+ return getLongContent(0);
931
+ }
932
+
933
+
934
+ public long getLongContent(long defaultValue) {
935
+ String c = node.getTextContent();
936
+ if (c != null) {
937
+ try {
938
+ return Long.parseLong(c);
939
+ } catch (NumberFormatException nfe) { }
940
+ }
941
+ return defaultValue;
942
+ }
943
+
944
+
945
+ public double getDoubleContent() {
946
+ return getDoubleContent(0);
947
+ }
948
+
949
+
950
+ public double getDoubleContent(double defaultValue) {
951
+ String c = node.getTextContent();
952
+ if (c != null) {
953
+ try {
954
+ return Double.parseDouble(c);
955
+ } catch (NumberFormatException nfe) { }
956
+ }
957
+ return defaultValue;
958
+ }
959
+
960
+
961
+ /**
962
+ * @webref xml:method
963
+ * @brief Sets the content of an element
964
+ */
965
+ public void setContent(String text) {
966
+ node.setTextContent(text);
967
+ }
968
+
969
+
970
+ public void setIntContent(int value) {
971
+ setContent(String.valueOf(value));
972
+ }
973
+
974
+
975
+ public void setFloatContent(float value) {
976
+ setContent(String.valueOf(value));
977
+ }
978
+
979
+
980
+ public void setLongContent(long value) {
981
+ setContent(String.valueOf(value));
982
+ }
983
+
984
+
985
+ public void setDoubleContent(double value) {
986
+ setContent(String.valueOf(value));
987
+ }
988
+
989
+
990
+ /**
991
+ * Format this XML data as a String.
992
+ *
993
+ * @webref xml:method
994
+ * @brief Formats XML data as a String
995
+ * @param indent -1 for a single line (and no declaration), >= 0 for indents and newlines
996
+ * @return the content
997
+ * @see XML#toString()
998
+ */
999
+ public String format(int indent) {
1000
+ try {
1001
+ // entities = doctype.getEntities()
1002
+ boolean useIndentAmount = false;
1003
+ TransformerFactory factory = TransformerFactory.newInstance();
1004
+ if (indent != -1) {
1005
+ try {
1006
+ factory.setAttribute("indent-number", indent);
1007
+ } catch (IllegalArgumentException e) {
1008
+ useIndentAmount = true;
1009
+ }
1010
+ }
1011
+ Transformer transformer = factory.newTransformer();
1012
+
1013
+ // Add the XML declaration at the top if this node is the root and we're
1014
+ // not writing to a single line (indent = -1 means single line).
1015
+ if (indent == -1 || parent == null) {
1016
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
1017
+ } else {
1018
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
1019
+ }
1020
+
1021
+ // transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "sample.dtd");
1022
+
1023
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");
1024
+
1025
+ // transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "yes"); // huh?
1026
+
1027
+ // transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
1028
+ // "-//W3C//DTD XHTML 1.0 Transitional//EN");
1029
+ // transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
1030
+ // "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
1031
+
1032
+ // For Android, because (at least 2.3.3) doesn't like indent-number
1033
+ if (useIndentAmount) {
1034
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent));
1035
+ }
1036
+
1037
+ // transformer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");
1038
+ // transformer.setOutputProperty(OutputKeys.ENCODING,"UTF8");
1039
+ transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
1040
+ // transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS
1041
+
1042
+ // Always indent, otherwise the XML declaration will just be jammed
1043
+ // onto the first line with the XML code as well.
1044
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
1045
+
1046
+ // Properties p = transformer.getOutputProperties();
1047
+ // for (Object key : p.keySet()) {
1048
+ // System.out.println(key + " -> " + p.get(key));
1049
+ // }
1050
+
1051
+ // If you smell something, that's because this code stinks. No matter
1052
+ // the settings of the Transformer object, if the XML document already
1053
+ // has whitespace elements, it won't bother re-indenting/re-formatting.
1054
+ // So instead, transform the data once into a single line string.
1055
+ // If indent is -1, then we're done. Otherwise re-run and the settings
1056
+ // of the factory will kick in. If you know a better way to do this,
1057
+ // please contribute. I've wasted too much of my Sunday on it. But at
1058
+ // least the Giants are getting blown out by the Falcons.
1059
+
1060
+ final String decl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
1061
+ final String sep = System.getProperty("line.separator");
1062
+
1063
+ StringWriter tempWriter = new StringWriter();
1064
+ StreamResult tempResult = new StreamResult(tempWriter);
1065
+ transformer.transform(new DOMSource(node), tempResult);
1066
+ String[] tempLines = PApplet.split(tempWriter.toString(), sep);
1067
+ // PApplet.println(tempLines);
1068
+ if (tempLines[0].startsWith("<?xml")) {
1069
+ // Remove XML declaration from the top before slamming into one line
1070
+ int declEnd = tempLines[0].indexOf("?>") + 2;
1071
+ //if (tempLines[0].length() == decl.length()) {
1072
+ if (tempLines[0].length() == declEnd) {
1073
+ // If it's all the XML declaration, remove it
1074
+ // PApplet.println("removing first line");
1075
+ tempLines = PApplet.subset(tempLines, 1);
1076
+ } else {
1077
+ // PApplet.println("removing part of first line");
1078
+ // If the first node has been moved to this line, be more careful
1079
+ //tempLines[0] = tempLines[0].substring(decl.length());
1080
+ tempLines[0] = tempLines[0].substring(declEnd);
1081
+ }
1082
+ }
1083
+ String singleLine = PApplet.join(PApplet.trim(tempLines), "");
1084
+ if (indent == -1) {
1085
+ return singleLine;
1086
+ }
1087
+
1088
+ // Might just be whitespace, which won't be valid XML for parsing below.
1089
+ // https://github.com/processing/processing/issues/1796
1090
+ // Since indent is not -1, that means they want valid XML,
1091
+ // so we'll give them the single line plus the decl... Lame? sure.
1092
+ if (singleLine.trim().length() == 0) {
1093
+ // You want whitespace? I've got your whitespace right here.
1094
+ return decl + sep + singleLine;
1095
+ }
1096
+
1097
+ // Since the indent is not -1, bring back the XML declaration
1098
+ //transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
1099
+
1100
+ StringWriter stringWriter = new StringWriter();
1101
+ StreamResult xmlOutput = new StreamResult(stringWriter);
1102
+ // DOMSource source = new DOMSource(node);
1103
+ Source source = new StreamSource(new StringReader(singleLine));
1104
+ transformer.transform(source, xmlOutput);
1105
+ String outgoing = stringWriter.toString();
1106
+
1107
+ // Add the XML declaration to the top if it's not there already
1108
+ if (outgoing.startsWith(decl)) {
1109
+ int declen = decl.length();
1110
+ int seplen = sep.length();
1111
+ if (outgoing.length() > declen + seplen &&
1112
+ !outgoing.substring(declen, declen + seplen).equals(sep)) {
1113
+ // make sure there's a line break between the XML decl and the code
1114
+ return outgoing.substring(0, decl.length()) +
1115
+ sep + outgoing.substring(decl.length());
1116
+ }
1117
+ return outgoing;
1118
+ } else {
1119
+ return decl + sep + outgoing;
1120
+ }
1121
+
1122
+ } catch (Exception e) {
1123
+ e.printStackTrace();
1124
+ }
1125
+ return null;
1126
+ }
1127
+
1128
+
1129
+ public void print() {
1130
+ PApplet.println(format(2));
1131
+ }
1132
+
1133
+
1134
+ /**
1135
+ * Return the XML document formatted with two spaces for indents.
1136
+ * Chosen to do this since it's the most common case (e.g. with println()).
1137
+ * Same as format(2). Use the format() function for more options.
1138
+ *
1139
+ * @webref xml:method
1140
+ * @brief Gets XML data as a String using default formatting
1141
+ * @return the content
1142
+ * @see XML#format(int)
1143
+ */
1144
+ @Override
1145
+ public String toString() {
1146
+ //return format(2);
1147
+ return format(-1);
1148
+ }
1149
+ }