1 package atg.taglib.json.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 /**
28 * This provides static methods to convert comma delimited text into a
29 * JSONArray, and to covert a JSONArray into comma delimited text. Comma
30 * delimited text is a very popular format for data interchange. It is
31 * understood by most database, spreadsheet, and organizer programs.
32 * <p>
33 * Each row of text represents a row in a table or a data record. Each row
34 * ends with a NEWLINE character. Each row contains one or more values.
35 * Values are separated by commas. A value can contain any character except
36 * for comma, unless is is wrapped in single quotes or double quotes.
37 * <p>
38 * The first row usually contains the names of the columns.
39 * <p>
40 * A comma delimited list can be converted into a JSONArray of JSONObjects.
41 * The names for the elements in the JSONObjects can be taken from the names
42 * in the first row.
43 * @author JSON.org
44 * @version 2
45 */
46 public class CDL {
47
48 /**
49 * Get the next value. The value can be wrapped in quotes. The value can
50 * be empty.
51 * @param x A JSONTokener of the source text.
52 * @return The value string, or null if empty.
53 * @throws JSONException if the quoted string is badly formed.
54 */
55 private static String getValue(JSONTokener x) throws JSONException {
56 char c;
57 do {
58 c = x.next();
59 } while (c <= ' ' && c != 0);
60 switch (c) {
61 case 0:
62 return null;
63 case '"':
64 case '\'':
65 return x.nextString(c);
66 case ',':
67 x.back();
68 return "";
69 default:
70 x.back();
71 return x.nextTo(',');
72 }
73 }
74
75 /**
76 * Produce a JSONArray of strings from a row of comma delimited values.
77 * @param x A JSONTokener of the source text.
78 * @return A JSONArray of strings.
79 * @throws JSONException
80 */
81 public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
82 JSONArray ja = new JSONArray();
83 for (;;) {
84 String value = getValue(x);
85 if (value == null) {
86 return null;
87 }
88 ja.put(value);
89 for (;;) {
90 char c = x.next();
91 if (c == ',') {
92 break;
93 }
94 if (c != ' ') {
95 if (c == '\n' || c == '\r' || c == 0) {
96 return ja;
97 }
98 throw x.syntaxError("Bad character '" + c + "' (" +
99 (int)c + ").");
100 }
101 }
102 }
103 }
104
105 /**
106 * Produce a JSONObject from a row of comma delimited text, using a
107 * parallel JSONArray of strings to provides the names of the elements.
108 * @param names A JSONArray of names. This is commonly obtained from the
109 * first row of a comma delimited text file using the rowToJSONArray
110 * method.
111 * @param x A JSONTokener of the source text.
112 * @return A JSONObject combining the names and values.
113 * @throws JSONException
114 */
115 public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
116 throws JSONException {
117 JSONArray ja = rowToJSONArray(x);
118 return ja != null ? ja.toJSONObject(names) : null;
119 }
120
121 /**
122 * Produce a JSONArray of JSONObjects from a comma delimited text string,
123 * using the first row as a source of names.
124 * @param string The comma delimited text.
125 * @return A JSONArray of JSONObjects.
126 * @throws JSONException
127 */
128 public static JSONArray toJSONArray(String string) throws JSONException {
129 return toJSONArray(new JSONTokener(string));
130 }
131
132 /**
133 * Produce a JSONArray of JSONObjects from a comma delimited text string,
134 * using the first row as a source of names.
135 * @param x The JSONTokener containing the comma delimited text.
136 * @return A JSONArray of JSONObjects.
137 * @throws JSONException
138 */
139 public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
140 return toJSONArray(rowToJSONArray(x), x);
141 }
142
143 /**
144 * Produce a JSONArray of JSONObjects from a comma delimited text string
145 * using a supplied JSONArray as the source of element names.
146 * @param names A JSONArray of strings.
147 * @param string The comma delimited text.
148 * @return A JSONArray of JSONObjects.
149 * @throws JSONException
150 */
151 public static JSONArray toJSONArray(JSONArray names, String string)
152 throws JSONException {
153 return toJSONArray(names, new JSONTokener(string));
154 }
155
156 /**
157 * Produce a JSONArray of JSONObjects from a comma delimited text string
158 * using a supplied JSONArray as the source of element names.
159 * @param names A JSONArray of strings.
160 * @param x A JSONTokener of the source text.
161 * @return A JSONArray of JSONObjects.
162 * @throws JSONException
163 */
164 public static JSONArray toJSONArray(JSONArray names, JSONTokener x)
165 throws JSONException {
166 if (names == null || names.length() == 0) {
167 return null;
168 }
169 JSONArray ja = new JSONArray();
170 for (;;) {
171 JSONObject jo = rowToJSONObject(names, x);
172 if (jo == null) {
173 break;
174 }
175 ja.put(jo);
176 }
177 if (ja.length() == 0) {
178 return null;
179 }
180 return ja;
181 }
182
183
184 /**
185 * Produce a comma delimited text row from a JSONArray. Values containing
186 * the comma character will be quoted.
187 * @param ja A JSONArray of strings.
188 * @return A string ending in NEWLINE.
189 */
190 public static String rowToString(JSONArray ja) {
191 StringBuffer sb = new StringBuffer();
192 for (int i = 0; i < ja.length(); i += 1) {
193 if (i > 0) {
194 sb.append(',');
195 }
196 Object o = ja.opt(i);
197 if (o != null) {
198 String s = o.toString();
199 if (s.indexOf(',') >= 0) {
200 if (s.indexOf('"') >= 0) {
201 sb.append('\'');
202 sb.append(s);
203 sb.append('\'');
204 } else {
205 sb.append('"');
206 sb.append(s);
207 sb.append('"');
208 }
209 } else {
210 sb.append(s);
211 }
212 }
213 }
214 sb.append('\n');
215 return sb.toString();
216
217 }
218
219 /**
220 * Produce a comma delimited text from a JSONArray of JSONObjects. The
221 * first row will be a list of names obtained by inspecting the first
222 * JSONObject.
223 * @param ja A JSONArray of JSONObjects.
224 * @return A comma delimited text.
225 * @throws JSONException
226 */
227 public static String toString(JSONArray ja) throws JSONException {
228 JSONObject jo = ja.optJSONObject(0);
229 if (jo != null) {
230 JSONArray names = jo.names();
231 if (names != null) {
232 return rowToString(names) + toString(names, ja);
233 }
234 }
235 return null;
236 }
237
238 /**
239 * Produce a comma delimited text from a JSONArray of JSONObjects using
240 * a provided list of names. The list of names is not included in the
241 * output.
242 * @param names A JSONArray of strings.
243 * @param ja A JSONArray of JSONObjects.
244 * @return A comma delimited text.
245 * @throws JSONException
246 */
247 public static String toString(JSONArray names, JSONArray ja)
248 throws JSONException {
249 if (names == null || names.length() == 0) {
250 return null;
251 }
252 StringBuffer sb = new StringBuffer();
253 for (int i = 0; i < ja.length(); i += 1) {
254 JSONObject jo = ja.optJSONObject(i);
255 if (jo != null) {
256 sb.append(rowToString(jo.toJSONArray(names)));
257 }
258 }
259 return sb.toString();
260 }
261 }