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