001/*
002 * ConfigurationPropertiesLoader.java
003 *
004 * Created on 28. April 2002, 14:59
005 */
006
007package org.jconfig;
008
009import java.io.*;
010import java.util.Properties;
011import java.util.HashMap;
012import java.util.Hashtable;
013import java.util.Enumeration;
014import java.util.Iterator;
015import java.util.Vector;
016/**
017 * This class implements the methods for handling a properties file.
018 * It can read a properties file or save one or all categories to
019 * a properties file.
020 *
021 * @author  Andreas Mecky andreas.mecky@xcom.de
022 * @author Terry Dye terry.dye@xcom.de
023 */
024public class ConfigurationPropertiesHandler implements ConfigurationHandler {
025
026    // separator for category and property for HashMap
027    private static final char C_SEP   = 127; 
028    // prefix for category names
029                private static final char C_PFIX  =  64; 
030    private HashMap initValues;
031    private HashMap props;
032    /** Creates a new instance of ConfigurationPropertiesLoader */
033    public ConfigurationPropertiesHandler() {
034        props = new HashMap();
035    }
036    
037    /**
038     * This method save the incoming parameters for
039     * later use.
040     *
041     * @param parameters  a <code>HashMap</code> with all parameters
042     * as key value pairs.
043     */    
044    public void initialize(HashMap parameters) {
045        initValues = parameters;
046    }
047    
048    /**
049     * This is the <code>load</code> method that will be
050     * called by the <code>ConfigurationManager</code>.
051     *
052     * @throws ConfigurationManagerException  if some error will occur
053     */    
054    public void load() throws ConfigurationManagerException {
055        // only call loadPorperties when we have an entry in the initValues
056        if ( initValues.containsKey("File") ) {
057            loadProperties((File)initValues.get("File"));
058        }
059    }
060    /**
061     *  This method will store all categories and properties to a
062     *  Java-properties file. All properties will be in the category "general".
063     *  It will override an existing configuration.
064     *
065     *@param  file                            the file
066     *@throws  ConfigurationManagerException  if the file cannot be processed
067     */
068    public void loadProperties(File file) throws ConfigurationManagerException {        
069        try {
070            FileInputStream input = new FileInputStream(file);
071            Properties myProperties = new Properties();
072            myProperties.load(input);
073            Enumeration propertyNames = myProperties.propertyNames();            
074            while (propertyNames.hasMoreElements()) {
075                String name = (String) propertyNames.nextElement();
076                String value = myProperties.getProperty(name);
077                props.put(C_PFIX+"general"+C_SEP+name, value);                
078            }
079        } catch (Exception e) {
080            throw new ConfigurationManagerException("The file cannot be loaded");
081        }
082    }
083
084    /**
085     * This method returns all properties.
086     *
087     * @return  a <code>HashMap</code> with all properties
088     */    
089    public HashMap getProperties() {        
090        return props;
091    }
092    
093    /**
094     * This method returns all categories. In this particular
095     * case it returns only one category "general".
096     *
097     * @return  a <code>Vector</code> with all categories as <code>String</code>
098     */    
099    public Vector getCategories() {
100        Vector categories = new Vector();
101        // there is only the general category
102        categories.add("general"); 
103        return categories;
104    }
105    
106    /**
107     * This method stores one or all categories as a properties file.
108     * It is called by the <code>ConfigurationManager</code>. The
109     * actual store method it determined by the type that is
110     * passed as parameter. If the type is single then only the
111     * specified category is saved.
112     *
113     * @throws ConfigurationManagerException if the file cannot be saved
114     */    
115    public void store() throws ConfigurationManagerException {
116        String type = (String)initValues.get("Type");
117        if ( type.equals("Single") ) {
118            storeProperties((File)initValues.get("File"),(String)initValues.get("Category"),(Hashtable)initValues.get("Properties"));
119        }
120        else {
121            storeProperties((File)initValues.get("File"),(HashMap)initValues.get("Data"));
122        }
123    }
124    
125    /**
126     * This method will generate a Java-properties file. All categories will be
127     * saved as comments and only the properties are written to the file. The
128     * output is category.property=value
129     *
130     * @param data a <code>HashMap</code> with all categories and properties
131     * @param file the file
132     * @throws ConfigurationManagerException if the file cannot be processed 
133     */
134    public void storeProperties(File file,HashMap data) throws ConfigurationManagerException {
135        // this will store the properties for a certain category
136        Hashtable props = new Hashtable();
137        String currentCategory = new String();
138        Iterator it = data.keySet().iterator();
139        try {
140            // let's open the file
141            FileWriter fw = new FileWriter(file);
142            // and write the header
143            fw.write("#\n");
144            fw.write("# automatically generated properties file\n");
145            fw.write("#\n");
146            // now we walk through all categories
147            while ( it.hasNext() ) {
148                currentCategory = (String)it.next();
149                // write the category as comment
150                fw.write("#\n");
151                fw.write("# category: " + currentCategory + "\n");
152                fw.write("#\n");
153                // now we get all properties for this category
154                props = (Hashtable)data.get(currentCategory);
155                Enumeration lprops = props.keys();
156                // here we walk through the properties
157                while (lprops.hasMoreElements()) {
158                    String currentKey = (String) lprops.nextElement();
159                    // and write it to the file
160                    // form category.property=value
161                    fw.write(currentCategory + "." + currentKey + "=" + (String) props.get(currentKey) + "\n");
162                }
163            }
164            // close the file because we are done
165            fw.close();
166        } catch (Exception e) {
167            throw new ConfigurationManagerException("The file cannot be saved");
168        }
169    }
170
171    /**
172     * This method will write a Java-properties file and fill in the properties
173     * for the particular category. The category will be saved as comment and
174     * only the properties are written to the file. The output is
175     * property=value. The category is not included in the property name.
176     *
177     * @param file      the file 
178     * @param category  the category that will be saved
179     * @param props     a <code>Hashtable</code> with all properties for this category
180     *
181     * @throws ConfigurationManagerException if the file cannot be processed 
182     */
183    public void storeProperties(File file, String category,Hashtable props) throws ConfigurationManagerException {
184        // this will store the properties for a certain category     
185        try {
186            // let's open the file
187            FileWriter fw = new FileWriter(file);
188            // and write the header
189            fw.write("#\n");
190            fw.write("# automatically generated properties file");
191            fw.write("#\n");
192            fw.write("#\n");
193            fw.write("# category: " + category + "\n");
194            fw.write("#\n");
195            // now we get all properties for this category
196            Enumeration myEnum = props.keys();     
197            // here we walk through the properties
198            while ( myEnum.hasMoreElements() ) {
199                String currentKey = (String) myEnum.nextElement();
200                // and write it to the file
201                // form category.property=value
202                fw.write(currentKey + "=" + (String) props.get(currentKey) + "\n");
203            }
204            // close the file because we are done
205            fw.close();
206        } catch (Exception e) {
207            throw new ConfigurationManagerException("The file cannot be saved");
208        }
209    }    
210}