View Javadoc
1   /* Generated By:JavaCC: Do not edit this line. PropertyListParser.java */
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   * JavaCC based parser for the PropertyList format.
15   *
16   * @author Emmanuel Bourg
17   */
18  class PropertyListParser implements PropertyListParserConstants {
19  
20      /**
21       * Remove the quotes at the beginning and at the end of the specified String.
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       * Remove the white spaces and the data delimiters from the specified
45       * string and parse it as a byte array.
46       */
47      protected byte[] filterData(String s) throws ParseException
48      {
49          if (s == null)
50          {
51              return null;
52          }
53  
54          // remove the delimiters
55          if (s.startsWith("<") && s.endsWith(">") && s.length() >= 2)
56          {
57              s = s.substring(1, s.length() - 1);
58          }
59  
60          // remove the white spaces
61          s = s.replaceAll("\u005c\u005cs", "");
62  
63          // add a leading 0 to ensure well formed bytes
64          if (s.length() % 2 != 0)
65          {
66              s = "0" + s;
67          }
68  
69          // parse and return the bytes
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       * Parse a date formatted as <*D2002-03-22 11:30:00 +0100>
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                 // prune & graft the nested configuration to the parent configuration
115                 @SuppressWarnings("unchecked") // we created this configuration
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   /** Generated Token Manager. */
360   public PropertyListParserTokenManager token_source;
361   SimpleCharStream jj_input_stream;
362   /** Current token. */
363   public Token token;
364   /** Next token. */
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   /** Constructor with InputStream. */
383   public PropertyListParser(java.io.InputStream stream) {
384      this(stream, null);
385   }
386   /** Constructor with InputStream and supplied encoding */
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   /** Reinitialise. */
398   public void ReInit(java.io.InputStream stream) {
399      ReInit(stream, null);
400   }
401   /** Reinitialise. */
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   /** Constructor. */
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   /** Reinitialise. */
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   /** Constructor with generated Token Manager. */
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   /** Reinitialise. */
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 /** Get the next Token. */
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 /** Get the specific Token. */
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   /** Generate ParseException. */
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   /** Enable tracing. */
594   final public void enable_tracing() {
595   }
596 
597   /** Disable tracing. */
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 }