[sword-devel] SWConfig.java

Mike Dougherty sword-devel@crosswire.org
09 Dec 2001 23:42:42 -0800


--=-DWEJfXfdzh+l65bDOSme
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Here's my version of SWConfig. It provides access to multiple
configuration properties (files), which may themselves contain multiple
values. This version does not use anything that is not in the Java 2
core library (It also does not have any naked variables, which is a pet
peeve of mine ;-).

I haven't had a chance to run it through a complete unit test so it may
have some bugs in it. But I wanted to put it out there for comment as
soon as possible.

I have included the Javadoc (thanks to Bobby's build script) so you can
get and idea what the usage will be. Trying running the main(String[])
with your own files to see how it does.

/mike



-- 
******************************************
 Mike Dougherty -- Java Software Engineer
******************************************
 The hearing ear is always found close to the speaking tongue, a custom
 whereof the memory of man runneth not howsomever to the contrary,
nohow.

--=-DWEJfXfdzh+l65bDOSme
Content-Disposition: attachment; filename=SWConfig.html
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org=
/TR/REC-html40/frameset.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by javadoc on Sun Dec 09 23:36:25 PST 2001 -->
<TITLE>
: Class  SWConfig
</TITLE>
<LINK REL =3D"stylesheet" TYPE=3D"text/css" HREF=3D"../../../../stylesheet.=
css" TITLE=3D"Style">
</HEAD>
<BODY BGCOLOR=3D"white">

<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D START OF NAVBAR =3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D -->
<A NAME=3D"navbar_top"><!-- --></A>
<TABLE BORDER=3D"0" WIDTH=3D"100%" CELLPADDING=3D"1" CELLSPACING=3D"0">
<TR>
<TD COLSPAN=3D2 BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">
<A NAME=3D"navbar_top_firstrow"><!-- --></A>
<TABLE BORDER=3D"0" CELLPADDING=3D"0" CELLSPACING=3D"3">
  <TR ALIGN=3D"center" VALIGN=3D"top">
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"../../../../=
overview-summary.html"><FONT CLASS=3D"NavBarFont1"><B>Overview</B></FONT></=
A>&nbsp;</TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"package-summ=
ary.html"><FONT CLASS=3D"NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
  <TD BGCOLOR=3D"#FFFFFF" CLASS=3D"NavBarCell1Rev"> &nbsp;<FONT CLASS=3D"Na=
vBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"package-tree=
.html"><FONT CLASS=3D"NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"../../../../=
deprecated-list.html"><FONT CLASS=3D"NavBarFont1"><B>Deprecated</B></FONT><=
/A>&nbsp;</TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"../../../../=
index-all.html"><FONT CLASS=3D"NavBarFont1"><B>Index</B></FONT></A>&nbsp;</=
TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"../../../../=
help-doc.html"><FONT CLASS=3D"NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD=
>
  </TR>
</TABLE>
</TD>
<TD ALIGN=3D"right" VALIGN=3D"top" ROWSPAN=3D3><EM>
</EM>
</TD>
</TR>

<TR>
<TD BGCOLOR=3D"white" CLASS=3D"NavBarCell2"><FONT SIZE=3D"-2">
&nbsp;<A HREF=3D"../../../../org/crosswire/sword/mgr/LocaleMgr.html"><B>PRE=
V CLASS</B></A>&nbsp;
&nbsp;<A HREF=3D"../../../../org/crosswire/sword/mgr/SWLocale.html"><B>NEXT=
 CLASS</B></A></FONT></TD>
<TD BGCOLOR=3D"white" CLASS=3D"NavBarCell2"><FONT SIZE=3D"-2">
  <A HREF=3D"../../../../index.html" TARGET=3D"_top"><B>FRAMES</B></A>  &nb=
sp;
&nbsp;<A HREF=3D"SWConfig.html" TARGET=3D"_top"><B>NO FRAMES</B></A></FONT>=
</TD>
</TR>
<TR>
<TD VALIGN=3D"top" CLASS=3D"NavBarCell3"><FONT SIZE=3D"-2">
  SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF=3D"#constructo=
r_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF=3D"#method_summary">METHOD</A></F=
ONT></TD>
<TD VALIGN=3D"top" CLASS=3D"NavBarCell3"><FONT SIZE=3D"-2">
DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF=3D"#constructor_detail">CONSTR</A>&=
nbsp;|&nbsp;<A HREF=3D"#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D END OF NAVBAR =3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D -->

<HR>
<!-- =3D=3D=3D=3D=3D=3D=3D=3D START OF CLASS DATA =3D=3D=3D=3D=3D=3D=3D=3D =
-->
<H2>
<FONT SIZE=3D"-1">
org.crosswire.sword.mgr</FONT>
<BR>
Class  SWConfig</H2>
<PRE>
java.lang.Object
  |
  +--<B>org.crosswire.sword.mgr.SWConfig</B>
</PRE>
<HR>
<DL>
<DT>public class <B>SWConfig</B><DT>extends java.lang.Object</DL>

<P>
<HR>

<P>
<!-- =3D=3D=3D=3D=3D=3D=3D=3D INNER CLASS SUMMARY =3D=3D=3D=3D=3D=3D=3D=3D =
-->


<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D FIELD SUMMARY =3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D -->


<!-- =3D=3D=3D=3D=3D=3D=3D=3D CONSTRUCTOR SUMMARY =3D=3D=3D=3D=3D=3D=3D=3D =
-->

<A NAME=3D"constructor_summary"><!-- --></A>
<TABLE BORDER=3D"1" CELLPADDING=3D"3" CELLSPACING=3D"0" WIDTH=3D"100%">
<TR BGCOLOR=3D"#CCCCFF" CLASS=3D"TableHeadingColor">
<TD COLSPAN=3D2><FONT SIZE=3D"+2">
<B>Constructor Summary</B></FONT></TD>
</TR>
<TR BGCOLOR=3D"white" CLASS=3D"TableRowColor">
<TD><CODE><B><A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html#S=
WConfig(java.lang.String)">SWConfig</A></B>(java.lang.String&nbsp;filename)=
</CODE>

<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
</TABLE>
&nbsp;
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D METHOD SUMMARY =3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D -->

<A NAME=3D"method_summary"><!-- --></A>
<TABLE BORDER=3D"1" CELLPADDING=3D"3" CELLSPACING=3D"0" WIDTH=3D"100%">
<TR BGCOLOR=3D"#CCCCFF" CLASS=3D"TableHeadingColor">
<TD COLSPAN=3D2><FONT SIZE=3D"+2">
<B>Method Summary</B></FONT></TD>
</TR>
<TR BGCOLOR=3D"white" CLASS=3D"TableRowColor">
<TD ALIGN=3D"right" VALIGN=3D"top" WIDTH=3D"1%"><FONT SIZE=3D"-1">
<CODE>&nbsp;<A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html">S=
WConfig</A></CODE></FONT></TD>
<TD><CODE><B><A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html#a=
ugment(org.crosswire.sword.mgr.SWConfig)">augment</A></B>(<A HREF=3D"../../=
../../org/crosswire/sword/mgr/SWConfig.html">SWConfig</A>&nbsp;addFrom)</CO=
DE>

<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copies the prop=
erties of the <code>addFrom</code> SWConfig
 object into the current property set.</TD>
</TR>
<TR BGCOLOR=3D"white" CLASS=3D"TableRowColor">
<TD ALIGN=3D"right" VALIGN=3D"top" WIDTH=3D"1%"><FONT SIZE=3D"-1">
<CODE>&nbsp;java.util.Iterator</CODE></FONT></TD>
<TD><CODE><B><A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html#g=
etProperties(java.lang.String, java.lang.String)">getProperties</A></B>(jav=
a.lang.String&nbsp;section,
              java.lang.String&nbsp;key)</CODE>

<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves an It=
erator of values for the named property.</TD>
</TR>
<TR BGCOLOR=3D"white" CLASS=3D"TableRowColor">
<TD ALIGN=3D"right" VALIGN=3D"top" WIDTH=3D"1%"><FONT SIZE=3D"-1">
<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
<TD><CODE><B><A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html#g=
etProperty(java.lang.String, java.lang.String)">getProperty</A></B>(java.la=
ng.String&nbsp;section,
            java.lang.String&nbsp;key)</CODE>

<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieves the v=
alue of the named property.</TD>
</TR>
<TR BGCOLOR=3D"white" CLASS=3D"TableRowColor">
<TD ALIGN=3D"right" VALIGN=3D"top" WIDTH=3D"1%"><FONT SIZE=3D"-1">
<CODE>&nbsp;void</CODE></FONT></TD>
<TD><CODE><B><A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html#l=
oad(java.lang.String)">load</A></B>(java.lang.String&nbsp;file)</CODE>

<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loads the prope=
rties from the file into the object
 making them ready to retrieve.</TD>
</TR>
<TR BGCOLOR=3D"white" CLASS=3D"TableRowColor">
<TD ALIGN=3D"right" VALIGN=3D"top" WIDTH=3D"1%"><FONT SIZE=3D"-1">
<CODE>static&nbsp;void</CODE></FONT></TD>
<TD><CODE><B><A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html#m=
ain(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;args)</CODE>

<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Usage: java org=
.crosswire.sword.mgr.SWConfig <file> [<file> <file> ...]
=20
 Prints the contents of each configuration file to STDOUT.</TD>
</TR>
<TR BGCOLOR=3D"white" CLASS=3D"TableRowColor">
<TD ALIGN=3D"right" VALIGN=3D"top" WIDTH=3D"1%"><FONT SIZE=3D"-1">
<CODE>&nbsp;java.util.Iterator</CODE></FONT></TD>
<TD><CODE><B><A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html#p=
ropertyNames(java.lang.String)">propertyNames</A></B>(java.lang.String&nbsp=
;section)</CODE>

<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Retrieve a list=
 of property names for the given section.</TD>
</TR>
<TR BGCOLOR=3D"white" CLASS=3D"TableRowColor">
<TD ALIGN=3D"right" VALIGN=3D"top" WIDTH=3D"1%"><FONT SIZE=3D"-1">
<CODE>&nbsp;java.util.Iterator</CODE></FONT></TD>
<TD><CODE><B><A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html#s=
ectionNames()">sectionNames</A></B>()</CODE>

<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
</TR>
</TABLE>
&nbsp;<A NAME=3D"methods_inherited_from_class_java.lang.Object"><!-- --></A=
>
<TABLE BORDER=3D"1" CELLPADDING=3D"3" CELLSPACING=3D"0" WIDTH=3D"100%">
<TR BGCOLOR=3D"#EEEEFF" CLASS=3D"TableSubHeadingColor">
<TD><B>Methods inherited from class java.lang.Object</B></TD>
</TR>
<TR BGCOLOR=3D"white" CLASS=3D"TableRowColor">
<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, t=
oString, wait, wait, wait</CODE></TD>
</TR>
</TABLE>
&nbsp;
<P>

<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D FIELD DETAIL =3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D -->


<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D CONSTRUCTOR DETAIL =3D=3D=3D=3D=3D=3D=3D=
=3D -->

<A NAME=3D"constructor_detail"><!-- --></A>
<TABLE BORDER=3D"1" CELLPADDING=3D"3" CELLSPACING=3D"0" WIDTH=3D"100%">
<TR BGCOLOR=3D"#CCCCFF" CLASS=3D"TableHeadingColor">
<TD COLSPAN=3D1><FONT SIZE=3D"+2">
<B>Constructor Detail</B></FONT></TD>
</TR>
</TABLE>

<A NAME=3D"SWConfig(java.lang.String)"><!-- --></A><H3>
SWConfig</H3>
<PRE>
public <B>SWConfig</B>(java.lang.String&nbsp;filename)
         throws java.io.IOException</PRE>
<DL>
</DL>

<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D METHOD DETAIL =3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D -->

<A NAME=3D"method_detail"><!-- --></A>
<TABLE BORDER=3D"1" CELLPADDING=3D"3" CELLSPACING=3D"0" WIDTH=3D"100%">
<TR BGCOLOR=3D"#CCCCFF" CLASS=3D"TableHeadingColor">
<TD COLSPAN=3D1><FONT SIZE=3D"+2">
<B>Method Detail</B></FONT></TD>
</TR>
</TABLE>

<A NAME=3D"load(java.lang.String)"><!-- --></A><H3>
load</H3>
<PRE>
public void <B>load</B>(java.lang.String&nbsp;file)
          throws java.io.IOException</PRE>
<DL>
<DD>Loads the properties from the file into the object
 making them ready to retrieve.</DL>
<HR>

<A NAME=3D"getProperty(java.lang.String, java.lang.String)"><!-- --></A><H3=
>
getProperty</H3>
<PRE>
public java.lang.String <B>getProperty</B>(java.lang.String&nbsp;section,
                                    java.lang.String&nbsp;key)</PRE>
<DL>
<DD>Retrieves the value of the named property.</DL>
<HR>

<A NAME=3D"getProperties(java.lang.String, java.lang.String)"><!-- --></A><=
H3>
getProperties</H3>
<PRE>
public java.util.Iterator <B>getProperties</B>(java.lang.String&nbsp;sectio=
n,
                                        java.lang.String&nbsp;key)</PRE>
<DL>
<DD>Retrieves an Iterator of values for the named property.
 If the property only has a single value a one item
 iterator will be returned rather than forcing the
 caller to check for null and recall the getProperty()
 method.</DL>
<HR>

<A NAME=3D"propertyNames(java.lang.String)"><!-- --></A><H3>
propertyNames</H3>
<PRE>
public java.util.Iterator <B>propertyNames</B>(java.lang.String&nbsp;sectio=
n)</PRE>
<DL>
<DD>Retrieve a list of property names for the given section.</DL>
<HR>

<A NAME=3D"sectionNames()"><!-- --></A><H3>
sectionNames</H3>
<PRE>
public java.util.Iterator <B>sectionNames</B>()</PRE>
<DL>
</DL>
<HR>

<A NAME=3D"augment(org.crosswire.sword.mgr.SWConfig)"><!-- --></A><H3>
augment</H3>
<PRE>
public <A HREF=3D"../../../../org/crosswire/sword/mgr/SWConfig.html">SWConf=
ig</A> <B>augment</B>(<A HREF=3D"../../../../org/crosswire/sword/mgr/SWConf=
ig.html">SWConfig</A>&nbsp;addFrom)</PRE>
<DL>
<DD>Copies the properties of the <code>addFrom</code> SWConfig
 object into the current property set.</DL>
<HR>

<A NAME=3D"main(java.lang.String[])"><!-- --></A><H3>
main</H3>
<PRE>
public static void <B>main</B>(java.lang.String[]&nbsp;args)</PRE>
<DL>
<DD>Usage: java org.crosswire.sword.mgr.SWConfig <file> [<file> <file> ...]
=20
 Prints the contents of each configuration file to STDOUT.</DL>
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D END OF CLASS DATA =3D=3D=3D=3D=3D=3D=3D=3D=
=3D -->
<HR>

<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D START OF NAVBAR =3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D -->
<A NAME=3D"navbar_bottom"><!-- --></A>
<TABLE BORDER=3D"0" WIDTH=3D"100%" CELLPADDING=3D"1" CELLSPACING=3D"0">
<TR>
<TD COLSPAN=3D2 BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">
<A NAME=3D"navbar_bottom_firstrow"><!-- --></A>
<TABLE BORDER=3D"0" CELLPADDING=3D"0" CELLSPACING=3D"3">
  <TR ALIGN=3D"center" VALIGN=3D"top">
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"../../../../=
overview-summary.html"><FONT CLASS=3D"NavBarFont1"><B>Overview</B></FONT></=
A>&nbsp;</TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"package-summ=
ary.html"><FONT CLASS=3D"NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
  <TD BGCOLOR=3D"#FFFFFF" CLASS=3D"NavBarCell1Rev"> &nbsp;<FONT CLASS=3D"Na=
vBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"package-tree=
.html"><FONT CLASS=3D"NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"../../../../=
deprecated-list.html"><FONT CLASS=3D"NavBarFont1"><B>Deprecated</B></FONT><=
/A>&nbsp;</TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"../../../../=
index-all.html"><FONT CLASS=3D"NavBarFont1"><B>Index</B></FONT></A>&nbsp;</=
TD>
  <TD BGCOLOR=3D"#EEEEFF" CLASS=3D"NavBarCell1">    <A HREF=3D"../../../../=
help-doc.html"><FONT CLASS=3D"NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD=
>
  </TR>
</TABLE>
</TD>
<TD ALIGN=3D"right" VALIGN=3D"top" ROWSPAN=3D3><EM>
</EM>
</TD>
</TR>

<TR>
<TD BGCOLOR=3D"white" CLASS=3D"NavBarCell2"><FONT SIZE=3D"-2">
&nbsp;<A HREF=3D"../../../../org/crosswire/sword/mgr/LocaleMgr.html"><B>PRE=
V CLASS</B></A>&nbsp;
&nbsp;<A HREF=3D"../../../../org/crosswire/sword/mgr/SWLocale.html"><B>NEXT=
 CLASS</B></A></FONT></TD>
<TD BGCOLOR=3D"white" CLASS=3D"NavBarCell2"><FONT SIZE=3D"-2">
  <A HREF=3D"../../../../index.html" TARGET=3D"_top"><B>FRAMES</B></A>  &nb=
sp;
&nbsp;<A HREF=3D"SWConfig.html" TARGET=3D"_top"><B>NO FRAMES</B></A></FONT>=
</TD>
</TR>
<TR>
<TD VALIGN=3D"top" CLASS=3D"NavBarCell3"><FONT SIZE=3D"-2">
  SUMMARY: &nbsp;INNER&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF=3D"#constructo=
r_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF=3D"#method_summary">METHOD</A></F=
ONT></TD>
<TD VALIGN=3D"top" CLASS=3D"NavBarCell3"><FONT SIZE=3D"-2">
DETAIL: &nbsp;FIELD&nbsp;|&nbsp;<A HREF=3D"#constructor_detail">CONSTR</A>&=
nbsp;|&nbsp;<A HREF=3D"#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<!-- =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D END OF NAVBAR =3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D -->

<HR>

</BODY>
</HTML>

--=-DWEJfXfdzh+l65bDOSme
Content-Disposition: attachment; filename=SWConfig.java
Content-Transfer-Encoding: quoted-printable
Content-Type: text/x-c; charset=ISO-8859-1

/**************************************************************************=
****
 *  SWConfig.java   - implementation of Class SWConfig used for saving and
 *			retrieval of configuration information
 *
 * $Id: SWConfig.java,v 1.1.1.1 1999/11/23 13:37:41 scribe Exp $
 *
 * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
 *	CrossWire Bible Society
 *	P. O. Box 2528
 *	Tempe, AZ  85280-2528
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation version 2.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 */
package org.crosswire.sword.mgr;

import java.util.LinkedList;
import java.util.HashMap;
import java.util.List;
import java.util.LinkedList;
import java.util.Enumeration;
import java.util.Iterator;
import java.io.FileInputStream;
import java.io.IOException;


public class SWConfig {

	private String filename;
    private HashMap propMap =3D null;

	public SWConfig(String filename)=20
        throws IOException
    {
		this.filename =3D filename;
        propMap =3D new HashMap();
		load(filename);
	}

    /**
     * Loads the properties from the file into the object
     * making them ready to retrieve.
     */
    public void load(String file)
        throws IOException
    {
        try {
            Properties props =3D new Properties();
            FileInputStream cfile =3D new FileInputStream(file);
            props.load( cfile );
            propMap.put( props.getSectionName(), props );
        }
        catch (Exception e) {
            throw new IOException( e.getMessage() );
        }
    }

    /**
     * Retrieves the value of the named property.
     */
    public String getProperty(String section, String key) {
        Properties props =3D (Properties)propMap.get( section );
        return props !=3D null ? props.getProperty( key ) : null;
    }

    /**
     * Retrieves an Iterator of values for the named property.
     * If the property only has a single value a one item
     * iterator will be returned rather than forcing the
     * caller to check for null and recall the getProperty()
     * method.
     */
    public Iterator getProperties(String section, String key) {
        Properties props =3D (Properties)propMap.get( section );
        return props !=3D null ? props.getProperties( key ) : null;
    }

    /**
     * Retrieve a list of property names for the given section.
     */
    public Iterator propertyNames(String section) {
        Properties props =3D (Properties)propMap.get( section );
        return props !=3D null ? enumToIterator( props.propertyNames() ) : =
null;
    }

    private Iterator enumToIterator(Enumeration enum) {
        List list =3D new LinkedList();
        while( enum.hasMoreElements() )
            list.add( enum.nextElement() );
        return list.iterator();
    }

    public Iterator sectionNames() {
        return propMap.keySet().iterator();
    }

    /**
     * Copies the properties of the <code>addFrom</code> SWConfig
     * object into the current property set.
     */
    public SWConfig augment(SWConfig addFrom)
    {
        Iterator sit =3D addFrom.sectionNames();
        while( sit.hasNext() ) {
            String sname =3D (String)sit.next();
            Object props =3D addFrom.propMap.get( sname );
            this.propMap.put( sname, props );
        }
        return this;
    }

    /**
     * Usage: java org.crosswire.sword.mgr.SWConfig <file> [<file> <file> .=
..]
     *=20
     * Prints the contents of each configuration file to STDOUT.
     */
    public static void main(String[] args) {
        if( args.length < 1 ) {
            System.out.println("Usage: java SWConfig <file> [<file> <file> =
...]");
            System.exit( 0 );
        }

        try {
            System.out.println("Showing Properties in file: " + args[0] );
            SWConfig config =3D new SWConfig( args[0] );
            // If there were multiple files given, load them
            // all.
            if( args.length > 1 ) {
                for( int i =3D 1; i < args.length; i++ ) {
                    config.load( args[i] );
                }
            }
            Iterator sit =3D config.sectionNames();
            while( sit.hasNext() ) {
                String sectionName =3D (String)sit.next();
                System.out.println("Section: " + sectionName);
                Iterator spit =3D config.propertyNames( sectionName );
                while( spit.hasNext() ) {
                    String key =3D (String)spit.next();
                    Iterator vit =3D config.getProperties( sectionName, key=
 );
                    while( vit.hasNext() ) {
                        System.out.println("\t" + key + ": " + vit.next() )=
;
                    }
                }
            }
        }catch(Exception ex) {
            System.err.println("Error: " + ex.getMessage() );
            ex.printStackTrace();
        }

    }

    private class Properties extends java.util.Properties {

        private String name =3D null;
        public String getSectionName() { return name; }

        /**
         * Overrides the super classes (HashMap) put(Object,Object) method
         * taking into account that some properties may have multiple
         * values.
         */
        public Object put(Object key, Object value) {
            // if the key isn't a String it's not one of the properties
            // we are looking for, so return without setting it.
            if( !(key instanceof String) ) { return null; }

            // check to see if this is the SectionName
            if( ((String)key).startsWith("[") ) {
                String skey =3D (String)key;
                this.name =3D skey.substring(1, (skey.length() - 1));
                // Shouldn't be any values associated with this
                // key so just return so it isn't set in the
                // HashMap
                return null;
            }
            // get the existing value.
            Object svalue =3D get( key );
            // see if it exists
            if( svalue !=3D null ) {
                if( svalue instanceof List ) {
                    // if it's a List, then add to it
                    // and put it back.
                    ((List)svalue).add( value );
                    return super.put( key, svalue );
                }else{
                    // if it's not a list, assume it's
                    // a String. Create a List collection
                    // add the current value and the pased
                    // in value to the list and then put
                    // the List in the Map associated with
                    // the key.
                    List list =3D new LinkedList();
                    list.add( svalue );
                    list.add( value );
                    return super.put( key, list );
                }
            }
            // key doesn't already exist so just add
            // it as normal.
            return super.put( key, value );
        }

        /**
         * Overrides the super classes getProperty(String,String) method
         * taking into account that some properties may have multiple
         * values.
         */
        public String getProperty(String key, String defaultValue) {
            String value =3D getProperty( key );
            if( value !=3D null )
                // if the value existed, return it.
                return value;
            // otherwise return the default value.
            return defaultValue;
        }

        /**
         * Overrides the super classes getProperty(String) method
         * taking into account that some properties may have multiple
         * values.
         */
        public String getProperty(String key) {
            Object value =3D get(key);
            // if the value associated with the key is a List
            // then return the first element in it as the value
            if( value !=3D null && value instanceof List ) {
                return (String)((List)value).get(0);
            }
            // otherwise just return the value as a Stirng
            return (String)value;
        }

        /**
         * Provides a method to retrieve multiple values of a property
         * if they exist. This method can safely be called with keys
         * that only have a single value (an Iterator with one element
         * in it will be returned).
         */
        protected Iterator getProperties(String key) {
            Object value =3D get( key );
            if( value !=3D null && value instanceof List )
                // If the value is already a List then just
                // return and Iterator for it.
                return ((List)value).iterator();

            // Otherwise create a List, set a single value
            // and return an Iterator for it.
            List list =3D new LinkedList();
            list.add( value !=3D null ? value : "" );
            return list.iterator();
        }
    }
}

--=-DWEJfXfdzh+l65bDOSme--