Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/edelbyte/util/UnixCfgParser.java


1   /* ######################################################################### */
2   /* ##                                                                     ## */
3   /* ##  U T I L / U N I X C F G P A R S E R . J A V A                      ## */
4   /* ##                                                                     ## */
5   /* ## ------------------------------------------------------------------- ## */
6   /* ##                                                                     ## */
7   /* ##  Job .......: Parse a Unix Configuration file from an instance      ## */
8   /* ##               of java.io.BufferedReader (or its subclasses)         ## */
9   /* ##                                                                     ## */
10  /* ## ------------------------------------------------------------------- ## */
11  /* ##                                                                     ## */
12  /* ##  Copyright (C) 2002  Daniel Scheibli                                ## */
13  /* ##                                                                     ## */
14  /* ##  This library is free software; you can redistribute it and/or      ## */
15  /* ##  modify it under the terms of the GNU Lesser General Public         ## */
16  /* ##  License as published by the Free Software Foundation; either       ## */
17  /* ##  version 2.1 of the License, or (at your option) any later version. ## */
18  /* ##                                                                     ## */
19  /* ##  This library is distributed in the hope that it will be useful,    ## */
20  /* ##  but WITHOUT ANY WARRANTY; without even the implied warranty of     ## */
21  /* ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  ## */
22  /* ##  Lesser General Public License for more details.                    ## */
23  /* ##                                                                     ## */
24  /* ##  You should have received a copy of the GNU Lesser General Public   ## */
25  /* ##  License along with this library; if not, write to the Free         ## */
26  /* ##  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,     ## */
27  /* ##  MA 02111-1307 USA                                                  ## */
28  /* ##                                                                     ## */
29  /* ## ------------------------------------------------------------------- ## */
30  /* ##                                                                     ## */
31  /* ##  Remark ....: <none>                                                ## */
32  /* ##                                                                     ## */
33  /* ## ------------------------------------------------------------------- ## */
34  /* ##                                                                     ## */
35  /* ##  Author ....: Daniel Scheibli <daniel.scheibli@edelbyte.org>        ## */
36  /* ##  Date ......: 2002-11-10                                            ## */
37  /* ##  Changes ...: ----- UnixCfgParser.java V00.99/R020 ---------------- ## */
38  /* ##               <none>                                                ## */
39  /* ##               ----- UnixCfgParser.java V00.99/R011 ---------------- ## */
40  /* ##               <none>                                                ## */
41  /* ##                                                                     ## */
42  /* ######################################################################### */
43  
44  
45  
46  /* ##### Presettings */
47  /* ------------------------------------------------------------------------- */
48  package org.edelbyte.util;
49  /* ------------------------------------------------------------------------- */
50  
51  
52  
53  
54  
55  /* ##### Class definition */
56  /** ************************************************************************
57   * A basic Unix configuration file parser. The parser reads from
58   * a <code>java.io.BufferedReader</code> (or one of its subclasses)
59   * and returns a <code>java.util.Properties</code> object with
60   * the found key and value pairs. It is an alternative to the
61   * <code>java.lang.Properties.load()</code> method (which
62   * has some strange behavior).<br />
63   * <br />
64   * More information can be found in the detailed description
65   * of the {@link #parse} method.
66   *
67   * @author Daniel Scheibli &lt;daniel.scheibli at edelbyte.org&gt;
68   * ************************************************************************* */
69  public class UnixCfgParser
70  {
71   /* ##### Presettings (class fields) */
72   /* ------------------------------------------------------------------------ */
73   /** ***********************************************************************
74    * Constant holding the token used for the comment detection
75    * within the stream.
76    * ************************************************************************ */
77   protected static final java.lang.String COMMENT_TOKEN      = "#";
78   /** ***********************************************************************
79    * Constant holding the token used for the key and value pair
80    * separation within the stream.
81    * ************************************************************************ */
82   protected static final java.lang.String EQUALS_TOKEN       = "=";
83   /** ***********************************************************************
84    * Constant holding the token used for the line continuation detection
85    * within the stream.
86    * ************************************************************************ */
87   protected static final java.lang.String CONTINUATION_TOKEN = " \\"; 
88   /* ------------------------------------------------------------------------ */
89  
90  
91  
92  
93  
94   /* ##### Presettings (instance fields) */
95   /* ------------------------------------------------------------------------ */
96   /** ***********************************************************************
97    * Field holding the token, which indicates the beginning of the
98    * key and value pairs part of the stream. It is used for the
99    * Between Check mechanism.
100   * ************************************************************************ */
101  protected java.lang.String oBetweenBeginToken   = "#BEGIN";
102  /** ***********************************************************************
103   * Field holding the token, which indicates the end of the
104   * key and value pairs part of the stream. It is used for the
105   * Between Check mechanism.
106   * ************************************************************************ */
107  protected java.lang.String oBetweenEndToken     = "#END";
108  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- */
109  /** ***********************************************************************
110   * Field holding the activation status of the Between Check
111   * mechanism (default is <code>false</code>).
112   * ************************************************************************ */
113  protected boolean          bBetweenCheckEnabled = false;
114  /* ------------------------------------------------------------------------ */ 
115 
116 
117 
118 
119 
120  /* ######################################################################## */
121  /* ##                                                                    ## */
122  /* ##   U N I X C F G P A R S E R ()                                     ## */
123  /* ##                                                                    ## */ 
124  /* ######################################################################## */
125  /** ***********************************************************************
126   * Creates a new instance of this class.
127   * ************************************************************************ */
128  public UnixCfgParser( )
129  { }
130 
131 
132 
133 
134 
135  /* ######################################################################## */
136  /* ##                                                                    ## */
137  /* ##   G E T B E T W E E N B E G I N T O K E N ()                       ## */
138  /* ##                                                                    ## */ 
139  /* ######################################################################## */
140  /** ***********************************************************************
141   * Returns the token, which indicates the beginning of the
142   * key and value pairs part
143   * (from the {@link #oBetweenBeginToken} field).
144   *
145   * @return A new String, containing the indicator token
146   * ************************************************************************ */ 
147  public java.lang.String getBetweenBeginToken( )
148  { return( this.oBetweenBeginToken ); }
149 
150 
151 
152 
153 
154  /* ######################################################################## */
155  /* ##                                                                    ## */
156  /* ##   G E T B E T W E E N E N D T O K E N ()                           ## */
157  /* ##                                                                    ## */ 
158  /* ######################################################################## */
159  /** ***********************************************************************
160   * Returns the token, which indicates the end of the
161   * key and value pairs part
162   * (from the {@link #oBetweenEndToken} field).
163   *
164   * @return A new String, containing the indicator token
165   * ************************************************************************ */ 
166  public java.lang.String getBetweenEndToken( )
167  { return( this.oBetweenEndToken ); }
168 
169 
170 
171 
172 
173  /* ######################################################################## */
174  /* ##                                                                    ## */
175  /* ##   I S B E T W E E N C H E C K E N A B L E D ()                     ## */
176  /* ##                                                                    ## */ 
177  /* ######################################################################## */
178  /** ***********************************************************************
179   * Returns <code>true</code> for the case, that the Between Check
180   * mechanism is active.<br />
181   * <br />
182   * The Between Check mechanism ensures, that there are key and value
183   * pairs between the so called BetweenBegin and BetweenEnd tokens
184   * (see {@link #getBetweenBeginToken} and {@link #getBetweenEndToken})
185   * only.
186   *
187   * @return <code>true</code> if the Between Check mechanism
188   * is active.
189   * ************************************************************************ */ 
190  public boolean isBetweenCheckEnabled( )
191  { return( this.bBetweenCheckEnabled ); }
192 
193 
194 
195 
196 
197  /* ######################################################################## */
198  /* ##                                                                    ## */
199  /* ##   P A R S E ()                                                     ## */
200  /* ##                                                                    ## */ 
201  /* ######################################################################## */
202  /** ***********************************************************************
203   * Reads key and value pairs from a <code>java.io.BufferedReader</code>
204   * (or one of its subclasses).<br />
205   * <br />
206   * The parser reads the stream line wise using the <code>readLine()</code>
207   * method of the object given by the <code>oReader</code> parameter.
208   * A line can hold up to one key and value pair. Everything after the
209   * first occurrence of &quot;<code>#</code>&quot; is interpreted as
210   * comment and therefore skipped. Lines containing tabs and blanks only
211   * are skipped as well. The first occurrence of &quot;<code>=</code>&quot;
212   * is interpreted as a delimiter separating key and value. After the
213   * separation of key and value, the key is converted to upper case.
214   * Lines ending with &quot;<code> \</code>&quot; (please notice the
215   * blank leading the backslash!) indicates a line continuation.<br />
216   * <br />
217   * An sample configuration file is listed below:<br />
218   * <br />
219   * <tt>##### Database configuration file for SAMPLE database<br />
220   *     <br />
221   *     #BEGIN<br />
222   *     Backup.Enabled = YES&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;##### Backup allowed [YES|NO]<br />
223   *     Backup.Rule.1&#160;&#160;= (A &gt; B) &amp;&amp;&#160;&#160;\&#160;&#160;&#160;##### Backup rule number one<br />
224   *     &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;(C != D)<br />
225   *     #END<br /></tt>
226   * <br />
227   * For the given example, the returning <code>java.util.Properties</code>
228   * object contains the following key and value pairs:<br />
229   * <ul>
230   *  <li>The key is &quot;<code>BACKUP.ENABLED</code>&quot; and the associated
231   *      value is &quot;<code>YES</code>&quot;.</li>
232   *  <li>The key is &quot;<code>BACKUP.RULE.1</code>&quot; and the associated
233   *      value is &quot;<code>(A &gt; B) && (C != D)</code>&quot;.</li>
234   * </ul>
235   *
236   * @param oReader
237   *        The name of the DB2 Instance to be addressed.
238   * @return The <code>java.util.Properties</code> object containing
239   *         the key and value pairs found while parsing.
240   * @exception java.io.IOException
241   *            For the case, that there was an error while reading
242   *            the stream.
243   * @exception java.text.ParseException
244   *            For the case, that there was an error while parsing
245   *            the stream.
246   * ************************************************************************ */ 
247  public java.util.Properties parse( java.io.BufferedReader oReader ) throws java.io.IOException,
248                                                                             java.text.ParseException
249  {
250   /* ##### Presettings */
251   /* ----------------------------------------------------------------------- */
252   java.util.Properties   oPairTable          = new java.util.Properties();  
253   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
254   boolean                bIsBetweenFlag;
255   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */  
256   java.lang.String       oCurrentRow;
257   java.lang.String       oCurrentRowKey      = null;
258   java.lang.String       oCurrentRowValue;
259   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
260   int                    iRowNumber          = -1;
261   int                    iRowNumberValueNext = -1;
262   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
263   int                    iDummy;
264   /* ----------------------------------------------------------------------- */
265   
266 
267 
268   /* ##### Initialize the Between Check related stuff */
269   /* ----------------------------------------------------------------------- */
270   if( bBetweenCheckEnabled == true )
271   { bIsBetweenFlag = false; }
272   else
273   { bIsBetweenFlag = true; }
274   /* ----------------------------------------------------------------------- */
275   
276 
277 
278   /* ##### Loop over the stream */
279   /* ----------------------------------------------------------------------- */
280   while( (oCurrentRow = oReader.readLine()) != null )
281   {
282    /* ##### Presettings */
283    iRowNumber++;   
284 
285    /* ##### BetweenCheck: Detect the indicators */
286    /* ##### (given the fact, that the check is enabled) */
287    if( bBetweenCheckEnabled == true )
288    {
289     if( oCurrentRow.trim().equals( oBetweenBeginToken ) == true )
290     { bIsBetweenFlag = true;  continue; }
291     if( oCurrentRow.trim().equals( oBetweenEndToken )   == true )
292     { bIsBetweenFlag = false; continue; }   
293    }
294 
295    /* ##### Remove the comment part from the current row */
296    iDummy = oCurrentRow.indexOf( COMMENT_TOKEN );
297    if( iDummy > -1 )
298    { oCurrentRow = oCurrentRow.substring( 0, iDummy ); }
299 
300    /* ##### Skip empty rows */ 
301    if( oCurrentRow.trim().length() == 0 )
302    { continue; }
303    
304    /* ##### BetweenCheck: If there is content,... */
305    /* ##### (given the fact, that the check is enabled) */
306    if( (bBetweenCheckEnabled == true) && (bIsBetweenFlag == false) )
307    { throw new java.text.ParseException( "The Between Check feature found content outside the allowed boundaries (RowNo = " + iRowNumber + ").", iRowNumber ); }
308 
309    /* ##### Check integrity (based on line continuation only) */
310    if( (iRowNumberValueNext >= 0) && (iRowNumberValueNext != iRowNumber) )
311    { throw new java.text.ParseException( "A line continuation was indicated, but seems to be interrupted (RowNo = " + iRowNumber + ").", iRowNumber ); }
312 
313    /* ##### Seperate the current row into (Key and) Value part */
314    if( iRowNumberValueNext < 0 )
315    {
316     /* ##### Detect the first equals character (our delimiter) */
317     iDummy = oCurrentRow.indexOf( EQUALS_TOKEN );
318     if( iDummy > -1 )
319     {
320      oCurrentRowValue = ("A" + oCurrentRow.substring( iDummy + 1 )).trim();
321      oCurrentRowKey   =        oCurrentRow.substring( 0, iDummy ).trim().toUpperCase();
322      /* ##### On error,... */
323      if( oCurrentRowKey.length() == 0 )
324      { throw new java.text.ParseException( "Invalid Key part within the current Key/Value pair found (RowNo = " + iRowNumber + ").", iRowNumber ); }
325     }
326     /* ##### On error,... */
327     else
328     { throw new java.text.ParseException( "A Key/Value pair was expected, but there was no equals/delimiter found (RowNo = " + iRowNumber + ").", iRowNumber ); }
329    }
330    else
331    { oCurrentRowValue = ("A" + oCurrentRow).trim(); }
332 
333    /* ##### Process tailing Continuation Token (indicates line continuation) */
334    if( oCurrentRowValue.endsWith( CONTINUATION_TOKEN ) == true )
335    {
336     oCurrentRowValue    = oCurrentRowValue.substring( 0, oCurrentRowValue.length() - CONTINUATION_TOKEN.length() );
337     iRowNumberValueNext = iRowNumber + 1;
338    }
339    else
340    { iRowNumberValueNext = -1; }
341 
342    /* ##### Remove the magic "A" and temporary append the magic "Z" */
343    /* ##### to remove the leading [tabs|blanks] */
344    oCurrentRowValue = (oCurrentRowValue.substring( 1 ) + "Z").trim();
345    oCurrentRowValue = oCurrentRowValue.substring( 0, oCurrentRowValue.length() - 1 );
346    
347    /* ##### Add the Key/Value pairs to the Hashtable */
348    if( oPairTable.get( oCurrentRowKey ) != null )
349    { oPairTable.put( oCurrentRowKey, oPairTable.get(oCurrentRowKey).toString() + oCurrentRowValue ); }
350    else
351    { oPairTable.put( oCurrentRowKey, oCurrentRowValue ); }
352   }
353   /* ----------------------------------------------------------------------- */
354 
355 
356 
357   /* ##### Check integrity (based on "open" line continuation) */
358   /* ----------------------------------------------------------------------- */
359   if( iRowNumberValueNext >= 0 )
360    { throw new java.text.ParseException( "A line continuation was indicated, but there was no line continuation found (RowNo = " + iRowNumber + ").", iRowNumber ); }
361   /* ----------------------------------------------------------------------- */
362 
363 
364 
365   /* ##### Return the Key/Value pairs */
366   /* ----------------------------------------------------------------------- */  
367   return( oPairTable );
368   /* ----------------------------------------------------------------------- */
369  }
370 
371 
372 
373 
374 
375  /* ######################################################################## */
376  /* ##                                                                    ## */
377  /* ##   S E T B E T W E E N B E G I N T O K E N ()                       ## */
378  /* ##                                                                    ## */ 
379  /* ######################################################################## */
380  /** ***********************************************************************
381   * Set a alternative value for the BetweenBegin token, which is
382   * used by the Between Check mechanism.
383   *
384   * @param oBetweeenBeginToken
385   *        The String containing the new value
386   *        (for the {@link #oBetweenBeginToken} field).
387   * ************************************************************************ */ 
388  public void setBetweenBeginToken( java.lang.String oBetweenBeginToken )
389  { this.oBetweenBeginToken = oBetweenBeginToken; }
390 
391 
392 
393 
394 
395  /* ######################################################################## */
396  /* ##                                                                    ## */
397  /* ##   S E T B E T W E E N C H E C K E N A B L E D ()                   ## */
398  /* ##                                                                    ## */ 
399  /* ######################################################################## */
400  /** ***********************************************************************
401   * Enables or disables the Between Check mechanism while parsing the
402   * stream.<br />
403   * <br />
404   * The Between Check mechanism ensures, that there are key and value
405   * pairs between the so called BetweenBegin and BetweenEnd tokens
406   * (see {@link #getBetweenBeginToken} and {@link #getBetweenEndToken})
407   * only.
408   *
409   * @param bStatus
410   *        The status for the Between Check mechanism to be set.
411   * ************************************************************************ */ 
412  public void setBetweenCheckEnabled( boolean bStatus )
413  { this.bBetweenCheckEnabled = bStatus; }
414 
415 
416 
417 
418 
419  /* ######################################################################## */
420  /* ##                                                                    ## */
421  /* ##   S E T B E T W E E N E N D T O K E N ()                           ## */
422  /* ##                                                                    ## */ 
423  /* ######################################################################## */
424  /** ***********************************************************************
425   * Set a alternative value for the BetweenEnd token, which is
426   * used by the Between Check mechanism.
427   *
428   * @param oBetweeenEndToken
429   *        The String containing the new value
430   *        (for the {@link #oBetweenEndToken} field).
431   * ************************************************************************ */ 
432  public void setBetweenEndToken( java.lang.String oBetweenEndToken )
433  { this.oBetweenEndToken = oBetweenEndToken; }
434 }
435 /* ------------------------------------------------------------------------- */
436 
437 
438 
439