This project has retired. For details please refer to its
Attic page.
JSONParser xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.commons.impl.json.parser;
20
21 import java.io.IOException;
22 import java.io.Reader;
23 import java.io.StringReader;
24 import java.util.LinkedList;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.chemistry.opencmis.commons.impl.json.JSONArray;
29 import org.apache.chemistry.opencmis.commons.impl.json.JSONObject;
30
31
32
33
34
35
36
37
38
39 public class JSONParser {
40 public static final int S_INIT = 0;
41 public static final int S_IN_FINISHED_VALUE = 1;
42 public static final int S_IN_OBJECT = 2;
43 public static final int S_IN_ARRAY = 3;
44 public static final int S_PASSED_PAIR_KEY = 4;
45 public static final int S_IN_PAIR_VALUE = 5;
46 public static final int S_END = 6;
47 public static final int S_IN_ERROR = -1;
48
49 private LinkedList<Integer> handlerStatusStack;
50 private Yylex lexer = new Yylex((Reader) null);
51 private Yytoken token = null;
52 private int status = S_INIT;
53
54 private int peekStatus(LinkedList<Integer> statusStack) {
55 if (statusStack.size() == 0) {
56 return -1;
57 }
58
59 return statusStack.getFirst();
60 }
61
62
63
64
65
66
67 public void reset() {
68 token = null;
69 status = S_INIT;
70 handlerStatusStack = null;
71 }
72
73
74
75
76
77
78
79
80
81 public void reset(Reader in) {
82 lexer.yyreset(in);
83 reset();
84 }
85
86
87
88
89 public int getPosition() {
90 return lexer.getPosition();
91 }
92
93 public Object parse(String s) throws JSONParseException {
94 return parse(s, (ContainerFactory) null);
95 }
96
97 public Object parse(String s, ContainerFactory containerFactory) throws JSONParseException {
98 StringReader in = new StringReader(s);
99 try {
100 return parse(in, containerFactory);
101 } catch (IOException ie) {
102
103
104
105 throw new JSONParseException(-1, JSONParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
106 }
107 }
108
109 public Object parse(Reader in) throws IOException, JSONParseException {
110 return parse(in, (ContainerFactory) null);
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 @SuppressWarnings("unchecked")
128 public Object parse(Reader in, ContainerFactory containerFactory) throws IOException, JSONParseException {
129 reset(in);
130 LinkedList<Integer> statusStack = new LinkedList<Integer>();
131 LinkedList<Object> valueStack = new LinkedList<Object>();
132
133 try {
134 do {
135 nextToken();
136 switch (status) {
137 case S_INIT:
138 switch (token.type) {
139 case Yytoken.TYPE_VALUE:
140 status = S_IN_FINISHED_VALUE;
141 statusStack.addFirst(new Integer(status));
142 valueStack.addFirst(token.value);
143 break;
144 case Yytoken.TYPE_LEFT_BRACE:
145 status = S_IN_OBJECT;
146 statusStack.addFirst(new Integer(status));
147 valueStack.addFirst(createObjectContainer(containerFactory));
148 break;
149 case Yytoken.TYPE_LEFT_SQUARE:
150 status = S_IN_ARRAY;
151 statusStack.addFirst(new Integer(status));
152 valueStack.addFirst(createArrayContainer(containerFactory));
153 break;
154 default:
155 status = S_IN_ERROR;
156 }
157 break;
158
159 case S_IN_FINISHED_VALUE:
160 if (token.type == Yytoken.TYPE_EOF)
161 return valueStack.removeFirst();
162 else
163 throw new JSONParseException(getPosition(), JSONParseException.ERROR_UNEXPECTED_TOKEN, token);
164
165 case S_IN_OBJECT:
166 switch (token.type) {
167 case Yytoken.TYPE_COMMA:
168 break;
169 case Yytoken.TYPE_VALUE:
170 if (token.value instanceof String) {
171 String key = (String) token.value;
172 valueStack.addFirst(key);
173 status = S_PASSED_PAIR_KEY;
174 statusStack.addFirst(new Integer(status));
175 } else {
176 status = S_IN_ERROR;
177 }
178 break;
179 case Yytoken.TYPE_RIGHT_BRACE:
180 if (valueStack.size() > 1) {
181 statusStack.removeFirst();
182 valueStack.removeFirst();
183 status = peekStatus(statusStack);
184 } else {
185 status = S_IN_FINISHED_VALUE;
186 }
187 break;
188 default:
189 status = S_IN_ERROR;
190 break;
191 }
192 break;
193
194 case S_PASSED_PAIR_KEY:
195 switch (token.type) {
196 case Yytoken.TYPE_COLON:
197 break;
198 case Yytoken.TYPE_VALUE:
199 statusStack.removeFirst();
200 String key = (String) valueStack.removeFirst();
201 Map<String, Object> parent = (Map<String, Object>) valueStack.getFirst();
202 parent.put(key, token.value);
203 status = peekStatus(statusStack);
204 break;
205 case Yytoken.TYPE_LEFT_SQUARE:
206 statusStack.removeFirst();
207 key = (String) valueStack.removeFirst();
208 parent = (Map<String, Object>) valueStack.getFirst();
209 List<Object> newArray = createArrayContainer(containerFactory);
210 parent.put(key, newArray);
211 status = S_IN_ARRAY;
212 statusStack.addFirst(new Integer(status));
213 valueStack.addFirst(newArray);
214 break;
215 case Yytoken.TYPE_LEFT_BRACE:
216 statusStack.removeFirst();
217 key = (String) valueStack.removeFirst();
218 parent = (Map<String, Object>) valueStack.getFirst();
219 Map<String, Object> newObject = createObjectContainer(containerFactory);
220 parent.put(key, newObject);
221 status = S_IN_OBJECT;
222 statusStack.addFirst(new Integer(status));
223 valueStack.addFirst(newObject);
224 break;
225 default:
226 status = S_IN_ERROR;
227 }
228 break;
229
230 case S_IN_ARRAY:
231 switch (token.type) {
232 case Yytoken.TYPE_COMMA:
233 break;
234 case Yytoken.TYPE_VALUE:
235 List<Object> val = (List<Object>) valueStack.getFirst();
236 val.add(token.value);
237 break;
238 case Yytoken.TYPE_RIGHT_SQUARE:
239 if (valueStack.size() > 1) {
240 statusStack.removeFirst();
241 valueStack.removeFirst();
242 status = peekStatus(statusStack);
243 } else {
244 status = S_IN_FINISHED_VALUE;
245 }
246 break;
247 case Yytoken.TYPE_LEFT_BRACE:
248 val = (List<Object>) valueStack.getFirst();
249 Map<String, Object> newObject = createObjectContainer(containerFactory);
250 val.add(newObject);
251 status = S_IN_OBJECT;
252 statusStack.addFirst(new Integer(status));
253 valueStack.addFirst(newObject);
254 break;
255 case Yytoken.TYPE_LEFT_SQUARE:
256 val = (List<Object>) valueStack.getFirst();
257 List<Object> newArray = createArrayContainer(containerFactory);
258 val.add(newArray);
259 status = S_IN_ARRAY;
260 statusStack.addFirst(new Integer(status));
261 valueStack.addFirst(newArray);
262 break;
263 default:
264 status = S_IN_ERROR;
265 }
266 break;
267 case S_IN_ERROR:
268 throw new JSONParseException(getPosition(), JSONParseException.ERROR_UNEXPECTED_TOKEN, token);
269 }
270 if (status == S_IN_ERROR) {
271 throw new JSONParseException(getPosition(), JSONParseException.ERROR_UNEXPECTED_TOKEN, token);
272 }
273 } while (token.type != Yytoken.TYPE_EOF);
274 } catch (IOException ie) {
275 throw ie;
276 }
277
278 throw new JSONParseException(getPosition(), JSONParseException.ERROR_UNEXPECTED_TOKEN, token);
279 }
280
281 private void nextToken() throws JSONParseException, IOException {
282 token = lexer.yylex();
283 if (token == null)
284 token = new Yytoken(Yytoken.TYPE_EOF, null);
285 }
286
287 private Map<String, Object> createObjectContainer(ContainerFactory containerFactory) {
288 if (containerFactory == null) {
289 return new JSONObject();
290 }
291
292 Map<String, Object> m = containerFactory.createObjectContainer();
293
294 if (m == null) {
295 return new JSONObject();
296 }
297
298 return m;
299 }
300
301 private List<Object> createArrayContainer(ContainerFactory containerFactory) {
302 if (containerFactory == null) {
303 return new JSONArray();
304 }
305
306 List<Object> l = containerFactory.creatArrayContainer();
307
308 if (l == null) {
309 return new JSONArray();
310 }
311
312 return l;
313 }
314
315 public void parse(String s, ContentHandler contentHandler) throws JSONParseException {
316 parse(s, contentHandler, false);
317 }
318
319 public void parse(String s, ContentHandler contentHandler, boolean isResume) throws JSONParseException {
320 StringReader in = new StringReader(s);
321 try {
322 parse(in, contentHandler, isResume);
323 } catch (IOException ie) {
324
325
326
327 throw new JSONParseException(-1, JSONParseException.ERROR_UNEXPECTED_EXCEPTION, ie);
328 }
329 }
330
331 public void parse(Reader in, ContentHandler contentHandler) throws IOException, JSONParseException {
332 parse(in, contentHandler, false);
333 }
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351 public void parse(Reader in, ContentHandler contentHandler, boolean isResume) throws IOException, JSONParseException {
352 if (!isResume) {
353 reset(in);
354 handlerStatusStack = new LinkedList<Integer>();
355 } else {
356 if (handlerStatusStack == null) {
357 isResume = false;
358 reset(in);
359 handlerStatusStack = new LinkedList<Integer>();
360 }
361 }
362
363 LinkedList<Integer> statusStack = handlerStatusStack;
364
365 try {
366 do {
367 switch (status) {
368 case S_INIT:
369 contentHandler.startJSON();
370 nextToken();
371 switch (token.type) {
372 case Yytoken.TYPE_VALUE:
373 status = S_IN_FINISHED_VALUE;
374 statusStack.addFirst(new Integer(status));
375 if (!contentHandler.primitive(token.value))
376 return;
377 break;
378 case Yytoken.TYPE_LEFT_BRACE:
379 status = S_IN_OBJECT;
380 statusStack.addFirst(new Integer(status));
381 if (!contentHandler.startObject())
382 return;
383 break;
384 case Yytoken.TYPE_LEFT_SQUARE:
385 status = S_IN_ARRAY;
386 statusStack.addFirst(new Integer(status));
387 if (!contentHandler.startArray())
388 return;
389 break;
390 default:
391 status = S_IN_ERROR;
392 }
393 break;
394
395 case S_IN_FINISHED_VALUE:
396 nextToken();
397 if (token.type == Yytoken.TYPE_EOF) {
398 contentHandler.endJSON();
399 status = S_END;
400 return;
401 } else {
402 status = S_IN_ERROR;
403 throw new JSONParseException(getPosition(), JSONParseException.ERROR_UNEXPECTED_TOKEN, token);
404 }
405
406 case S_IN_OBJECT:
407 nextToken();
408 switch (token.type) {
409 case Yytoken.TYPE_COMMA:
410 break;
411 case Yytoken.TYPE_VALUE:
412 if (token.value instanceof String) {
413 String key = (String) token.value;
414 status = S_PASSED_PAIR_KEY;
415 statusStack.addFirst(new Integer(status));
416 if (!contentHandler.startObjectEntry(key))
417 return;
418 } else {
419 status = S_IN_ERROR;
420 }
421 break;
422 case Yytoken.TYPE_RIGHT_BRACE:
423 if (statusStack.size() > 1) {
424 statusStack.removeFirst();
425 status = peekStatus(statusStack);
426 } else {
427 status = S_IN_FINISHED_VALUE;
428 }
429 if (!contentHandler.endObject())
430 return;
431 break;
432 default:
433 status = S_IN_ERROR;
434 break;
435 }
436 break;
437
438 case S_PASSED_PAIR_KEY:
439 nextToken();
440 switch (token.type) {
441 case Yytoken.TYPE_COLON:
442 break;
443 case Yytoken.TYPE_VALUE:
444 statusStack.removeFirst();
445 status = peekStatus(statusStack);
446 if (!contentHandler.primitive(token.value))
447 return;
448 if (!contentHandler.endObjectEntry())
449 return;
450 break;
451 case Yytoken.TYPE_LEFT_SQUARE:
452 statusStack.removeFirst();
453 statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
454 status = S_IN_ARRAY;
455 statusStack.addFirst(new Integer(status));
456 if (!contentHandler.startArray())
457 return;
458 break;
459 case Yytoken.TYPE_LEFT_BRACE:
460 statusStack.removeFirst();
461 statusStack.addFirst(new Integer(S_IN_PAIR_VALUE));
462 status = S_IN_OBJECT;
463 statusStack.addFirst(new Integer(status));
464 if (!contentHandler.startObject())
465 return;
466 break;
467 default:
468 status = S_IN_ERROR;
469 }
470 break;
471
472 case S_IN_PAIR_VALUE:
473
474
475
476
477
478 statusStack.removeFirst();
479 status = peekStatus(statusStack);
480 if (!contentHandler.endObjectEntry())
481 return;
482 break;
483
484 case S_IN_ARRAY:
485 nextToken();
486 switch (token.type) {
487 case Yytoken.TYPE_COMMA:
488 break;
489 case Yytoken.TYPE_VALUE:
490 if (!contentHandler.primitive(token.value))
491 return;
492 break;
493 case Yytoken.TYPE_RIGHT_SQUARE:
494 if (statusStack.size() > 1) {
495 statusStack.removeFirst();
496 status = peekStatus(statusStack);
497 } else {
498 status = S_IN_FINISHED_VALUE;
499 }
500 if (!contentHandler.endArray())
501 return;
502 break;
503 case Yytoken.TYPE_LEFT_BRACE:
504 status = S_IN_OBJECT;
505 statusStack.addFirst(new Integer(status));
506 if (!contentHandler.startObject())
507 return;
508 break;
509 case Yytoken.TYPE_LEFT_SQUARE:
510 status = S_IN_ARRAY;
511 statusStack.addFirst(new Integer(status));
512 if (!contentHandler.startArray())
513 return;
514 break;
515 default:
516 status = S_IN_ERROR;
517 }
518 break;
519
520 case S_END:
521 return;
522
523 case S_IN_ERROR:
524 throw new JSONParseException(getPosition(), JSONParseException.ERROR_UNEXPECTED_TOKEN, token);
525 }
526 if (status == S_IN_ERROR) {
527 throw new JSONParseException(getPosition(), JSONParseException.ERROR_UNEXPECTED_TOKEN, token);
528 }
529 } while (token.type != Yytoken.TYPE_EOF);
530 } catch (IOException ie) {
531 status = S_IN_ERROR;
532 throw ie;
533 } catch (JSONParseException pe) {
534 status = S_IN_ERROR;
535 throw pe;
536 } catch (RuntimeException re) {
537 status = S_IN_ERROR;
538 throw re;
539 } catch (Error e) {
540 status = S_IN_ERROR;
541 throw e;
542 }
543
544 status = S_IN_ERROR;
545 throw new JSONParseException(getPosition(), JSONParseException.ERROR_UNEXPECTED_TOKEN, token);
546 }
547 }