1
2 package org.apache.commons.configuration2.plist;
3
4 import java.util.Date;
5 import java.util.List;
6 import java.util.ArrayList;
7
8 import org.apache.commons.configuration2.HierarchicalConfiguration;
9 import org.apache.commons.configuration2.tree.ImmutableNode;
10
11 import org.apache.commons.codec.binary.Hex;
12
13
14
15
16 class PropertyListParser implements PropertyListParserConstants {
17
18
19
20
21 protected String removeQuotes(String s) {
22 if (s == null) {
23 return null;
24 }
25 if (s.startsWith("\u005c"") && s.endsWith("\u005c"") && s.length() >= 2) {
26 s = s.substring(1, s.length() - 1);
27 }
28 return s;
29 }
30
31 protected String unescapeQuotes(String s) {
32 return s.replaceAll("\u005c\u005c\u005c\u005c\u005c"", "\u005c"");
33 }
34
35
36
37
38
39 protected byte[] filterData(String s) throws ParseException {
40 if (s == null) {
41 return null;
42 }
43
44 if (s.startsWith("<") && s.endsWith(">") && s.length() >= 2) {
45 s = s.substring(1, s.length() - 1);
46 }
47
48 s = s.replaceAll("\u005c\u005cs", "");
49
50 if (s.length() % 2 != 0) {
51 s = "0" + s;
52 }
53
54 try {
55 return Hex.decodeHex(s.toCharArray());
56 } catch (Exception e) {
57 throw (ParseException) new ParseException("Unable to parse the byte[] : " + e.getMessage());
58 }
59 }
60
61
62
63
64 protected Date parseDate(String s) throws ParseException {
65 return PropertyListConfiguration.parseDate(s);
66 }
67
68 final public PropertyListConfiguration parse() throws ParseException {
69 PropertyListConfiguration configuration = null;
70 configuration = Dictionary();
71 jj_consume_token(0);
72 {if (true) return configuration;}
73 throw new Error("Missing return statement in function");
74 }
75
76 final public PropertyListConfiguration Dictionary() throws ParseException {
77 ImmutableNode.Builder builder = new ImmutableNode.Builder();
78 ImmutableNode child = null;
79 jj_consume_token(DICT_BEGIN);
80 label_1:
81 while (true) {
82 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
83 case STRING:
84 case QUOTED_STRING:
85 ;
86 break;
87 default:
88 jj_la1[0] = jj_gen;
89 break label_1;
90 }
91 child = Property();
92 if (child.getValue() instanceof HierarchicalConfiguration)
93 {
94
95 @SuppressWarnings("unchecked")
96 HierarchicalConfiguration<ImmutableNode> conf =
97 (HierarchicalConfiguration<ImmutableNode>) child.getValue();
98 ImmutableNode root = conf.getNodeModel().getNodeHandler().getRootNode();
99 ImmutableNode.Builder childBuilder = new ImmutableNode.Builder();
100 childBuilder.name(child.getNodeName()).value(root.getValue())
101 .addChildren(root.getChildren());
102 builder.addChild(childBuilder.create());
103 }
104 else
105 {
106 builder.addChild(child);
107 }
108 }
109 jj_consume_token(DICT_END);
110 {if (true) return new PropertyListConfiguration(builder.create());}
111 throw new Error("Missing return statement in function");
112 }
113
114 final public ImmutableNode Property() throws ParseException {
115 String key = null;
116 Object value = null;
117 ImmutableNode.Builder node = new ImmutableNode.Builder();
118 key = String();
119 node.name(key);
120 jj_consume_token(EQUAL);
121 value = Element();
122 node.value(value);
123 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
124 case DICT_SEPARATOR:
125 jj_consume_token(DICT_SEPARATOR);
126 break;
127 default:
128 jj_la1[1] = jj_gen;
129 ;
130 }
131 {if (true) return node.create();}
132 throw new Error("Missing return statement in function");
133 }
134
135 final public Object Element() throws ParseException {
136 Object value = null;
137 if (jj_2_1(2)) {
138 value = Array();
139 {if (true) return value;}
140 } else {
141 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
142 case DICT_BEGIN:
143 value = Dictionary();
144 {if (true) return value;}
145 break;
146 case STRING:
147 case QUOTED_STRING:
148 value = String();
149 {if (true) return value;}
150 break;
151 case DATA:
152 value = Data();
153 {if (true) return value;}
154 break;
155 case DATE:
156 value = Date();
157 {if (true) return value;}
158 break;
159 default:
160 jj_la1[2] = jj_gen;
161 jj_consume_token(-1);
162 throw new ParseException();
163 }
164 }
165 throw new Error("Missing return statement in function");
166 }
167
168 final public List Array() throws ParseException {
169 List<Object> list = new ArrayList<Object>();
170 Object element = null;
171 jj_consume_token(ARRAY_BEGIN);
172 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
173 case ARRAY_BEGIN:
174 case DICT_BEGIN:
175 case DATA:
176 case DATE:
177 case STRING:
178 case QUOTED_STRING:
179 element = Element();
180 list.add(element);
181 label_2:
182 while (true) {
183 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
184 case ARRAY_SEPARATOR:
185 ;
186 break;
187 default:
188 jj_la1[3] = jj_gen;
189 break label_2;
190 }
191 jj_consume_token(ARRAY_SEPARATOR);
192 element = Element();
193 list.add(element);
194 }
195 break;
196 default:
197 jj_la1[4] = jj_gen;
198 ;
199 }
200 jj_consume_token(ARRAY_END);
201 {if (true) return list;}
202 throw new Error("Missing return statement in function");
203 }
204
205 final public String String() throws ParseException {
206 Token token = null;
207 String value = null;
208 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
209 case QUOTED_STRING:
210 token = jj_consume_token(QUOTED_STRING);
211 {if (true) return unescapeQuotes(removeQuotes(token.image));}
212 break;
213 case STRING:
214 token = jj_consume_token(STRING);
215 {if (true) return token.image;}
216 break;
217 default:
218 jj_la1[5] = jj_gen;
219 jj_consume_token(-1);
220 throw new ParseException();
221 }
222 throw new Error("Missing return statement in function");
223 }
224
225 final public byte[] Data() throws ParseException {
226 Token token;
227 token = jj_consume_token(DATA);
228 {if (true) return filterData(token.image);}
229 throw new Error("Missing return statement in function");
230 }
231
232 final public Date Date() throws ParseException {
233 Token token;
234 token = jj_consume_token(DATE);
235 {if (true) return parseDate(token.image);}
236 throw new Error("Missing return statement in function");
237 }
238
239 private boolean jj_2_1(int xla) {
240 jj_la = xla; jj_lastpos = jj_scanpos = token;
241 try { return !jj_3_1(); }
242 catch(LookaheadSuccess ls) { return true; }
243 finally { jj_save(0, xla); }
244 }
245
246 private boolean jj_3R_15() {
247 if (jj_scan_token(STRING)) return true;
248 return false;
249 }
250
251 private boolean jj_3R_3() {
252 if (jj_scan_token(ARRAY_BEGIN)) return true;
253 Token xsp;
254 xsp = jj_scanpos;
255 if (jj_3R_4()) jj_scanpos = xsp;
256 if (jj_scan_token(ARRAY_END)) return true;
257 return false;
258 }
259
260 private boolean jj_3_1() {
261 if (jj_3R_3()) return true;
262 return false;
263 }
264
265 private boolean jj_3R_5() {
266 Token xsp;
267 xsp = jj_scanpos;
268 if (jj_3_1()) {
269 jj_scanpos = xsp;
270 if (jj_3R_6()) {
271 jj_scanpos = xsp;
272 if (jj_3R_7()) {
273 jj_scanpos = xsp;
274 if (jj_3R_8()) {
275 jj_scanpos = xsp;
276 if (jj_3R_9()) return true;
277 }
278 }
279 }
280 }
281 return false;
282 }
283
284 private boolean jj_3R_14() {
285 if (jj_scan_token(QUOTED_STRING)) return true;
286 return false;
287 }
288
289 private boolean jj_3R_11() {
290 Token xsp;
291 xsp = jj_scanpos;
292 if (jj_3R_14()) {
293 jj_scanpos = xsp;
294 if (jj_3R_15()) return true;
295 }
296 return false;
297 }
298
299 private boolean jj_3R_10() {
300 if (jj_scan_token(DICT_BEGIN)) return true;
301 return false;
302 }
303
304 private boolean jj_3R_13() {
305 if (jj_scan_token(DATE)) return true;
306 return false;
307 }
308
309 private boolean jj_3R_9() {
310 if (jj_3R_13()) return true;
311 return false;
312 }
313
314 private boolean jj_3R_8() {
315 if (jj_3R_12()) return true;
316 return false;
317 }
318
319 private boolean jj_3R_12() {
320 if (jj_scan_token(DATA)) return true;
321 return false;
322 }
323
324 private boolean jj_3R_7() {
325 if (jj_3R_11()) return true;
326 return false;
327 }
328
329 private boolean jj_3R_4() {
330 if (jj_3R_5()) return true;
331 return false;
332 }
333
334 private boolean jj_3R_6() {
335 if (jj_3R_10()) return true;
336 return false;
337 }
338
339
340 public PropertyListParserTokenManager token_source;
341 SimpleCharStream jj_input_stream;
342
343 public Token token;
344
345 public Token jj_nt;
346 private int jj_ntk;
347 private Token jj_scanpos, jj_lastpos;
348 private int jj_la;
349 private int jj_gen;
350 final private int[] jj_la1 = new int[6];
351 static private int[] jj_la1_0;
352 static {
353 jj_la1_init_0();
354 }
355 private static void jj_la1_init_0() {
356 jj_la1_0 = new int[] {0x18000000,0x10000,0x1e004000,0x2000,0x1e004800,0x18000000,};
357 }
358 final private JJCalls[] jj_2_rtns = new JJCalls[1];
359 private boolean jj_rescan = false;
360 private int jj_gc = 0;
361
362
363 public PropertyListParser(java.io.InputStream stream) {
364 this(stream, null);
365 }
366
367 public PropertyListParser(java.io.InputStream stream, String encoding) {
368 try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
369 token_source = new PropertyListParserTokenManager(jj_input_stream);
370 token = new Token();
371 jj_ntk = -1;
372 jj_gen = 0;
373 for (int i = 0; i < 6; i++) jj_la1[i] = -1;
374 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
375 }
376
377
378 public void ReInit(java.io.InputStream stream) {
379 ReInit(stream, null);
380 }
381
382 public void ReInit(java.io.InputStream stream, String encoding) {
383 try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
384 token_source.ReInit(jj_input_stream);
385 token = new Token();
386 jj_ntk = -1;
387 jj_gen = 0;
388 for (int i = 0; i < 6; i++) jj_la1[i] = -1;
389 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
390 }
391
392
393 public PropertyListParser(java.io.Reader stream) {
394 jj_input_stream = new SimpleCharStream(stream, 1, 1);
395 token_source = new PropertyListParserTokenManager(jj_input_stream);
396 token = new Token();
397 jj_ntk = -1;
398 jj_gen = 0;
399 for (int i = 0; i < 6; i++) jj_la1[i] = -1;
400 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
401 }
402
403
404 public void ReInit(java.io.Reader stream) {
405 jj_input_stream.ReInit(stream, 1, 1);
406 token_source.ReInit(jj_input_stream);
407 token = new Token();
408 jj_ntk = -1;
409 jj_gen = 0;
410 for (int i = 0; i < 6; i++) jj_la1[i] = -1;
411 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
412 }
413
414
415 public PropertyListParser(PropertyListParserTokenManager tm) {
416 token_source = tm;
417 token = new Token();
418 jj_ntk = -1;
419 jj_gen = 0;
420 for (int i = 0; i < 6; i++) jj_la1[i] = -1;
421 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
422 }
423
424
425 public void ReInit(PropertyListParserTokenManager tm) {
426 token_source = tm;
427 token = new Token();
428 jj_ntk = -1;
429 jj_gen = 0;
430 for (int i = 0; i < 6; i++) jj_la1[i] = -1;
431 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
432 }
433
434 private Token jj_consume_token(int kind) throws ParseException {
435 Token oldToken;
436 if ((oldToken = token).next != null) token = token.next;
437 else token = token.next = token_source.getNextToken();
438 jj_ntk = -1;
439 if (token.kind == kind) {
440 jj_gen++;
441 if (++jj_gc > 100) {
442 jj_gc = 0;
443 for (int i = 0; i < jj_2_rtns.length; i++) {
444 JJCalls c = jj_2_rtns[i];
445 while (c != null) {
446 if (c.gen < jj_gen) c.first = null;
447 c = c.next;
448 }
449 }
450 }
451 return token;
452 }
453 token = oldToken;
454 jj_kind = kind;
455 throw generateParseException();
456 }
457
458 static private final class LookaheadSuccess extends java.lang.Error { }
459 final private LookaheadSuccess jj_ls = new LookaheadSuccess();
460 private boolean jj_scan_token(int kind) {
461 if (jj_scanpos == jj_lastpos) {
462 jj_la--;
463 if (jj_scanpos.next == null) {
464 jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
465 } else {
466 jj_lastpos = jj_scanpos = jj_scanpos.next;
467 }
468 } else {
469 jj_scanpos = jj_scanpos.next;
470 }
471 if (jj_rescan) {
472 int i = 0; Token tok = token;
473 while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
474 if (tok != null) jj_add_error_token(kind, i);
475 }
476 if (jj_scanpos.kind != kind) return true;
477 if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
478 return false;
479 }
480
481
482
483 final public Token getNextToken() {
484 if (token.next != null) token = token.next;
485 else token = token.next = token_source.getNextToken();
486 jj_ntk = -1;
487 jj_gen++;
488 return token;
489 }
490
491
492 final public Token getToken(int index) {
493 Token t = token;
494 for (int i = 0; i < index; i++) {
495 if (t.next != null) t = t.next;
496 else t = t.next = token_source.getNextToken();
497 }
498 return t;
499 }
500
501 private int jj_ntk() {
502 if ((jj_nt=token.next) == null)
503 return (jj_ntk = (token.next=token_source.getNextToken()).kind);
504 else
505 return (jj_ntk = jj_nt.kind);
506 }
507
508 private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
509 private int[] jj_expentry;
510 private int jj_kind = -1;
511 private int[] jj_lasttokens = new int[100];
512 private int jj_endpos;
513
514 private void jj_add_error_token(int kind, int pos) {
515 if (pos >= 100) return;
516 if (pos == jj_endpos + 1) {
517 jj_lasttokens[jj_endpos++] = kind;
518 } else if (jj_endpos != 0) {
519 jj_expentry = new int[jj_endpos];
520 for (int i = 0; i < jj_endpos; i++) {
521 jj_expentry[i] = jj_lasttokens[i];
522 }
523 jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
524 int[] oldentry = (int[])(it.next());
525 if (oldentry.length == jj_expentry.length) {
526 for (int i = 0; i < jj_expentry.length; i++) {
527 if (oldentry[i] != jj_expentry[i]) {
528 continue jj_entries_loop;
529 }
530 }
531 jj_expentries.add(jj_expentry);
532 break jj_entries_loop;
533 }
534 }
535 if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
536 }
537 }
538
539
540 public ParseException generateParseException() {
541 jj_expentries.clear();
542 boolean[] la1tokens = new boolean[30];
543 if (jj_kind >= 0) {
544 la1tokens[jj_kind] = true;
545 jj_kind = -1;
546 }
547 for (int i = 0; i < 6; i++) {
548 if (jj_la1[i] == jj_gen) {
549 for (int j = 0; j < 32; j++) {
550 if ((jj_la1_0[i] & (1<<j)) != 0) {
551 la1tokens[j] = true;
552 }
553 }
554 }
555 }
556 for (int i = 0; i < 30; i++) {
557 if (la1tokens[i]) {
558 jj_expentry = new int[1];
559 jj_expentry[0] = i;
560 jj_expentries.add(jj_expentry);
561 }
562 }
563 jj_endpos = 0;
564 jj_rescan_token();
565 jj_add_error_token(0, 0);
566 int[][] exptokseq = new int[jj_expentries.size()][];
567 for (int i = 0; i < jj_expentries.size(); i++) {
568 exptokseq[i] = jj_expentries.get(i);
569 }
570 return new ParseException(token, exptokseq, tokenImage);
571 }
572
573
574 final public void enable_tracing() {
575 }
576
577
578 final public void disable_tracing() {
579 }
580
581 private void jj_rescan_token() {
582 jj_rescan = true;
583 for (int i = 0; i < 1; i++) {
584 try {
585 JJCalls p = jj_2_rtns[i];
586 do {
587 if (p.gen > jj_gen) {
588 jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
589 switch (i) {
590 case 0: jj_3_1(); break;
591 }
592 }
593 p = p.next;
594 } while (p != null);
595 } catch(LookaheadSuccess ls) { }
596 }
597 jj_rescan = false;
598 }
599
600 private void jj_save(int index, int xla) {
601 JJCalls p = jj_2_rtns[index];
602 while (p.gen > jj_gen) {
603 if (p.next == null) { p = p.next = new JJCalls(); break; }
604 p = p.next;
605 }
606 p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
607 }
608
609 static final class JJCalls {
610 int gen;
611 Token first;
612 int arg;
613 JJCalls next;
614 }
615
616 }