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