Source code: com/flexstor/common/util/PropertyReader.java
1 /*
2 * PropertyReader.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:31 $ FLEXSTOR.net Inc.
5 *
6 * This work is licensed for use and distribution under license terms found at
7 * http://www.flexstor.org/license.html
8 *
9 */
10
11 package com.flexstor.common.util;
12
13 import java.io.BufferedReader;
14 import java.io.IOException;
15 import java.io.InputStreamReader;
16 import java.net.URL;
17 import java.util.Hashtable;
18 import java.util.Vector;
19
20 import com.flexstor.common.io.xfile.FlexXFile;
21
22 /**
23 * PropertyReader provides functionality to read sections, properties and
24 * values from an input file. Data is accessed on demand with no caching.
25 *
26 * @author Jose Hernandez
27 * @version 3.0
28 */
29 public class PropertyReader
30 {
31 /** Reference to XFile object for input file. */
32 private FlexXFile xInputFile = null;
33
34 /** Reference to URL object for input file. */
35 private URL fileURL = null;
36
37 public PropertyReader()
38 {
39 }
40
41 /**
42 * Sets the input file to get data from. Test file for reading.
43 * If sFileName start with "http://" or "file://" we read the data
44 * from an URL otherwise via FlexXFile.
45 * This condition may be removed once XFile supports URLs itself.
46 *
47 * @param sFileName the input data source to get the data from.
48 * @exception IOException if there is any problem accessing the file.
49 */
50 public void setInputFile( String sFileName )
51 throws IOException
52 {
53 if ( sFileName.startsWith( "http://" ) )
54 {
55 setInputFile( new URL( StringUtil.encodeURLString( sFileName ) ) );
56 }
57 else if ( sFileName.startsWith( "file://" ) )
58 {
59 setInputFile( new URL( sFileName ) );
60 }
61 else
62 {
63 setInputFile( new FlexXFile( sFileName ) );
64 }
65 }
66
67 /**
68 * Sets the input file to get data from. Test file for reading.
69 *
70 * @param sFileName the input file name to get the data from.
71 * @param bUseXFile If true then use the FlexXFile classes to access this file,
72 * else use the standard java classes.
73 * @exception IOException if there is any problem accessing the file.
74 */
75 public void setInputFile( String sFileName, boolean bUseXFile )
76 throws IOException
77 {
78 if ( bUseXFile )
79 setInputFile( new FlexXFile( sFileName ) );
80 else
81 setInputFile( new URL ( sFileName ) );
82 }
83
84 /**
85 * Sets the input file to get data from. Test file for reading.
86 *
87 * @param xInputFile an FlexXFile object for the input file to get the data from.
88 * @exception IOException if there is any problem accessing the file.
89 */
90 public void setInputFile( FlexXFile xInputFile )
91 throws IOException
92 {
93 this.xInputFile = xInputFile;
94 this.fileURL = null;
95
96 // test file access
97 //BufferedReader inputReader = new BufferedReader( new XFileReader( xInputFile ), 512 );
98 BufferedReader inputReader = xInputFile.getBufferedReader(512);
99 inputReader.readLine();
100 inputReader.close();
101 }
102
103 /**
104 * Sets the input file to get data from. Test file for reading.
105 * This method uses the File class not the FlexXFile Class, due to problems with FlexXFile.
106 *
107 * @param fileURL an URL to get the data from.
108 * @exception IOException if there is any problem accessing the URL.
109 */
110 public void setInputFile( URL fileURL )
111 throws IOException
112 {
113 this.fileURL = fileURL;
114 this.xInputFile = null;
115
116 // test file access
117 BufferedReader inputReader = new BufferedReader( new InputStreamReader( fileURL.openStream() ), 512 );
118 inputReader.readLine();
119 inputReader.close();
120 }
121
122 /**
123 * Opens input file.
124 *
125 * @return a BufferedReader object for the input file.
126 * @exception IOException if a problem is found trying to open the file.
127 */
128 private BufferedReader openInputFile()
129 throws IOException
130 {
131 if ( xInputFile != null )
132 //return new BufferedReader( new XFileReader( xInputFile ), 512 );
133 return xInputFile.getBufferedReader(512);
134 else if ( fileURL != null )
135 return new BufferedReader( new InputStreamReader( fileURL.openStream() ), 512 );
136
137 return null;
138 }
139
140 /**
141 * Closes input file.
142 *
143 * @param inputReader a buffered reader object for the input file.
144 * @exception IOException if a problem is found trying to close the file.
145 */
146 private void closeInputFile( BufferedReader inputReader )
147 throws IOException
148 {
149 inputReader.close();
150 }
151
152 /**
153 * Retrieves the sections defined in the input file.
154 *
155 * @return An array of strings including the sections defined with brackets in the input file,
156 * returns null if a problem if found reading the file.
157 */
158 public String[] readSections()
159 {
160 Vector vSections = new Vector();
161
162 try
163 {
164 BufferedReader inputReader = openInputFile();
165 if ( inputReader == null )
166 return null;
167
168 // read first line
169 String sLine = inputReader.readLine();
170 while( sLine != null ) // not EOF
171 {
172 // line is not a "blank" or "comment"
173 if ( sLine.equals( "" ) == false && sLine.trim().startsWith( "#" ) == false )
174 {
175 sLine = sLine.trim();
176
177 // line is a "section header"
178 if ( sLine.startsWith( "[" ) && ( sLine.indexOf( "]" ) != -1 ) )
179 {
180 // add new section to list
181 vSections.addElement( sLine.substring( 1, sLine.indexOf( "]" ) ).trim() );
182 }
183 }
184
185 // read next line
186 sLine = inputReader.readLine();
187 }
188
189 closeInputFile( inputReader );
190 }
191 catch ( IOException e )
192 {
193 return null;
194 }
195
196 String[] saSections = new String[ vSections.size() ];
197 vSections.copyInto( saSections );
198
199 return saSections;
200 }
201
202 /**
203 * Retrieves the property/value pairs for a specified section.
204 *
205 * @param sSection the name of the section to retrieve properties/values from.
206 * @return A Hashtable that holds property/value pairs for the specified section,
207 * returns null if a problem if found reading the file.
208 */
209 public Hashtable readSection( String sSection )
210 throws PropertyReaderException
211 {
212 if ( sSection == null )
213 return null;
214
215 Hashtable htProperties = new Hashtable();
216 boolean bSectionFound = false;
217
218 try
219 {
220 BufferedReader inputReader = openInputFile();
221 if ( inputReader == null )
222 return null;;
223
224 // read first line
225 String sLine = inputReader.readLine();
226 while( sLine != null ) // not EOF
227 {
228 // line is not a "blank" or "comment"
229 if ( sLine.equals( "" ) == false && sLine.trim().startsWith( "#" ) == false )
230 {
231 sLine = sLine.trim();
232
233 // line is a "section header"
234 if ( sLine.startsWith( "[" ) && ( sLine.indexOf( "]" ) != -1 ) )
235 {
236 if ( bSectionFound )
237 break;
238
239 if ( sSection.equals( sLine.substring( 1, sLine.indexOf( "]" ) ).trim() ) )
240 bSectionFound = true;
241 }
242 // line is a "property = value" and one section has been defined
243 else if ( sLine.indexOf( "=" ) != -1 && bSectionFound )
244 {
245 htProperties.put( sLine.substring( 0, sLine.indexOf( "=" ) ).trim(),
246 sLine.substring( sLine.indexOf( "=" ) + 1 ).trim() );
247 }
248 }
249
250 // read next line
251 sLine = inputReader.readLine();
252 }
253
254 closeInputFile( inputReader );
255 }
256 catch ( IOException e )
257 {
258 return null;
259 }
260
261 if ( bSectionFound == false )
262 throw new PropertyReaderException( "Section <" + sSection + "> not found." );
263
264 return htProperties;
265 }
266
267 /**
268 * Retrieves all the properties in the file.
269 *
270 * @return A hashtable containing all the property/value pairs in the file.
271 * Returns null if a problem if found reading the file.
272 */
273 public Hashtable readProperties()
274 {
275 Hashtable htProperties = new Hashtable();
276
277 try
278 {
279 BufferedReader inputReader = openInputFile();
280 if ( inputReader == null )
281 return null;;
282
283 // read first line
284 String sLine = inputReader.readLine();
285 while( sLine != null ) // not EOF
286 {
287 // line is not a "blank" or "comment"
288 if ( sLine.equals( "" ) == false && sLine.trim().startsWith( "#" ) == false )
289 {
290 sLine = sLine.trim();
291
292 // line is a "section header"
293 if ( sLine.startsWith( "[" ) && ( sLine.indexOf( "]" ) != -1 ) )
294 {
295 // ignore it
296 }
297 // line is a "property = value" and one section has been defined
298 else if ( sLine.indexOf( "=" ) != -1 )
299 {
300 htProperties.put( sLine.substring( 0, sLine.indexOf( "=" ) ).trim(),
301 sLine.substring( sLine.indexOf( "=" ) + 1 ).trim() );
302 }
303 }
304
305 // read next line
306 sLine = inputReader.readLine();
307 }
308
309 closeInputFile( inputReader );
310 }
311 catch ( IOException e )
312 {
313 return null;
314 }
315
316 return htProperties;
317 }
318
319 /**
320 * Retrieves the properties for a specific section.
321 *
322 * @param sSection the name of the section to retrieve properties for.
323 * @return An array of strings including the properties for the specified section,
324 * returns null if a problem if found reading the file.
325 */
326 public String[] readProperties( String sSection )
327 throws PropertyReaderException
328 {
329 if ( sSection == null )
330 return null;
331
332 Vector vProperties = new Vector();
333 boolean bSectionFound = false;
334
335 try
336 {
337 BufferedReader inputReader = openInputFile();
338 if ( inputReader == null )
339 return null;;
340
341 // read first line
342 String sLine = inputReader.readLine();
343 while( sLine != null ) // not EOF
344 {
345 // line is not a "blank" or "comment"
346 if ( sLine.equals( "" ) == false && sLine.trim().startsWith( "#" ) == false )
347 {
348 sLine = sLine.trim();
349
350 // line is a "section header"
351 if ( sLine.startsWith( "[" ) && ( sLine.indexOf( "]" ) != -1 ) )
352 {
353 if ( bSectionFound )
354 break;
355
356 if ( sSection.equals( sLine.substring( 1, sLine.indexOf( "]" ) ).trim() ) )
357 bSectionFound = true;
358 }
359 // line is a "property = value" and one section has been defined
360 else if ( sLine.indexOf( "=" ) != -1 && bSectionFound )
361 {
362 vProperties.addElement( sLine.substring( 0, sLine.indexOf( "=" ) ).trim() );
363 }
364 }
365
366 // read next line
367 sLine = inputReader.readLine();
368 }
369
370 closeInputFile( inputReader );
371 }
372 catch ( IOException e )
373 {
374 return null;
375 }
376
377 if ( bSectionFound == false )
378 throw new PropertyReaderException( "Section <" + sSection + "> not found." );
379
380 String[] saProperties = new String[ vProperties.size() ];
381 vProperties.copyInto( saProperties );
382
383 return saProperties;
384 }
385
386 /**
387 * Retrieves the value for a specific property within a section.
388 *
389 * @param sSection the name of the section the property belongs to.
390 * @param sProperty the name of the property to retrieve a value for.
391 * @return A string with the property value in the specified section,
392 * returns null if a problem if found reading the file.
393 */
394 public String readValue( String sSection, String sProperty )
395 throws PropertyReaderException
396 {
397 if ( sSection == null || sProperty == null )
398 return null;
399
400 String sValue = null;
401 boolean bSectionFound = false;
402
403 try
404 {
405 BufferedReader inputReader = openInputFile();
406 if ( inputReader == null )
407 return null;;
408
409 // read first line
410 String sLine = inputReader.readLine();
411 while( sLine != null ) // not EOF
412 {
413 // line is not a "blank" or "comment"
414 if ( sLine.equals( "" ) == false && sLine.trim().startsWith( "#" ) == false )
415 {
416 sLine = sLine.trim();
417
418 // line is a "section header"
419 if ( sLine.startsWith( "[" ) && ( sLine.indexOf( "]" ) != -1 ) )
420 {
421 if ( bSectionFound )
422 break;
423
424 if ( sSection.equals( sLine.substring( 1, sLine.indexOf( "]" ) ).trim() ) )
425 bSectionFound = true;
426 }
427 // line is a "property = value" and one section has been defined
428 else if ( sLine.indexOf( "=" ) != -1 && bSectionFound )
429 {
430 if ( sProperty.equals( sLine.substring( 0, sLine.indexOf( "=" ) ).trim() ) )
431 {
432 sValue = sLine.substring( sLine.indexOf( "=" ) + 1 ).trim();
433 break;
434 }
435 }
436 }
437
438 // read next line
439 sLine = inputReader.readLine();
440 }
441
442 closeInputFile( inputReader );
443 }
444 catch ( IOException e )
445 {
446 return null;
447 }
448
449 if ( bSectionFound == false )
450 throw new PropertyReaderException( "Section <" + sSection + "> not found." );
451
452 if ( sValue == null )
453 throw new PropertyReaderException( "Property <" + sProperty + "> not found." );
454
455 return sValue;
456 }
457
458 /**
459 * Retrieves the value for a specific property.
460 *
461 * @param sProperty the name of the property to retrieve a value for.
462 * @return A string with the property value.
463 * Returns null if a problem if found reading the file.
464 */
465 public String readValue( String sProperty )
466 throws PropertyReaderException
467 {
468 if ( sProperty == null )
469 return null;
470
471 String sValue = null;
472
473 try
474 {
475 BufferedReader inputReader = openInputFile();
476 if ( inputReader == null )
477 return null;;
478
479 // read first line
480 String sLine = inputReader.readLine();
481 while( sLine != null ) // not EOF
482 {
483 // line is not a "blank" or "comment"
484 if ( sLine.equals( "" ) == false && sLine.trim().startsWith( "#" ) == false )
485 {
486 sLine = sLine.trim();
487
488 // line is a "section header"
489 if ( sLine.startsWith( "[" ) && ( sLine.indexOf( "]" ) != -1 ) )
490 {
491 // ignore it
492 }
493 // line is a "property = value" and one section has been defined
494 else if ( sLine.indexOf( "=" ) != -1 )
495 {
496 if ( sProperty.equals( sLine.substring( 0, sLine.indexOf( "=" ) ).trim() ) )
497 {
498 sValue = sLine.substring( sLine.indexOf( "=" ) + 1 ).trim();
499 break;
500 }
501 }
502 }
503
504 // read next line
505 sLine = inputReader.readLine();
506 }
507
508 closeInputFile( inputReader );
509 }
510 catch ( IOException e )
511 {
512 return null;
513 }
514
515 if ( sValue == null )
516 throw new PropertyReaderException( "Property <" + sProperty + "> not found." );
517
518 return sValue;
519 }
520
521 } // end of class
522