ConfigAccess.java
001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002  *
003  * Copyright 2000-2013,  Michael Meyling <mime@qedeq.org>.
004  *
005  * "Hilbert II" is free software; you can redistribute
006  * it and/or modify it under the terms of the GNU General Public
007  * License as published by the Free Software Foundation; either
008  * version 2 of the License, or (at your option) any later version.
009  *
010  * This program is distributed in the hope that it will be useful,
011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013  * GNU General Public License for more details.
014  */
015 
016 package org.qedeq.kernel.se.config;
017 
018 import java.io.File;
019 import java.io.FileInputStream;
020 import java.io.FileOutputStream;
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.io.OutputStream;
024 import java.util.ArrayList;
025 import java.util.Collections;
026 import java.util.Enumeration;
027 import java.util.HashMap;
028 import java.util.Iterator;
029 import java.util.List;
030 import java.util.Map;
031 import java.util.Properties;
032 
033 import org.qedeq.base.io.IoUtility;
034 
035 
036 /**
037  * This class reads entries from property files. This class should not
038  * be used outside this package.
039  *
040  @author  Michael Meyling
041  */
042 final class ConfigAccess {
043 
044     /** Config file. */
045     private final File configFile;
046 
047     /** Collector for properties. */
048     private Properties properties = new Properties();
049 
050     /** Config file description. */
051     private final String description;
052 
053     /**
054      * Get access for a config file.
055      *
056      @param   configFile              Config file.
057      @param   description             Config file description
058      @throws  IOException             Config file couldn't be loaded.
059      */
060     public ConfigAccess(final File configFile, final String descriptionthrows IOException {
061         this.configFile = configFile;
062         this.description = description;
063         FileInputStream stream = null;
064         try {
065             stream = new FileInputStream(configFile);
066             load(stream);
067         catch (IOException e) {
068             System.out.println("no config file found, using default values");
069         finally {
070             IoUtility.close(stream);
071         }
072         setString("configFileLocation", configFile.getCanonicalPath());
073     }
074 
075     /**
076      * Get config file.
077      *
078      @return  Config file.
079      */
080     public final File getConfigFile() {
081         return configFile;
082     }
083 
084     /**
085      * Get description for config file.
086      *
087      @return  Config file description.
088      */
089     public final String getConfigDescription() {
090         return description;
091     }
092 
093     /**
094      * Get properties.
095      *
096      @return  properties.
097      */
098     private final Properties getProperties() {
099         return properties;
100     }
101 
102     /**
103      * Load properties from stream. The properties are
104      * added to the previous ones.
105      *
106      @param   inStream    load from this stream
107      @throws  IOException loading failed
108      */
109     private final void load(final InputStream inStreamthrows IOException {
110         getProperties().load(inStream);
111     }
112 
113     /**
114      * Store properties in config file.
115      *
116      @throws  IOException Saving failed.
117      */
118     public final void store() throws IOException {
119         OutputStream out = null;
120         try {
121             final File file = getConfigFile();
122             IoUtility.createNecessaryDirectories(file);
123             out = new FileOutputStream(file);
124             getProperties().store(out, getConfigDescription());
125         finally {
126             if (out != null) {
127                 try {
128                     out.close();
129                 catch (IOException e) {
130                     throw e;
131                 catch (Exception e) {
132                     throw new IOException(e.toString());
133                 }
134             }
135         }
136     }
137 
138     /**
139      * Return String property.
140      *
141      @param   name    Get this property.
142      @return  String for looked property. <code>null</code>, if property is missing.
143      */
144     public final String getString(final String name) {
145         return getProperties().getProperty(name);
146     }
147 
148     /**
149      * Return String property.
150      *
151      @param   name            Look for this String property.
152      @param   defaultValue    Return this value if property doesn't exist.
153      @return  Value of property. Equal to default value if parameter doesn't exist.
154      */
155     public final String getString(final String name, final String defaultValue) {
156         final String value = getProperties().getProperty(name);
157         if (value == null) {
158             setString(name, defaultValue);
159             return defaultValue;
160         else {
161             return value;
162         }
163     }
164 
165     /**
166      * Set String property.
167      *
168      @param name   Set this property.
169      @param value  Set property to this value.
170      */
171     public final void setString(final String name, final String value) {
172         getProperties().setProperty(name, value);
173     }
174 
175     /**
176      * Get list of String properties with certain prefix.
177      * Example:
178      <ul>
179      <li>qeq=green</li>
180      <li>module2=tiger</li>
181      <li>module3=tulip</li>
182      <li>modula=green</li>
183      <li>module1=bluebird</li>
184      </ul>
185      * If namePrefix == "module" we get:
186      <ul>
187      <li>module1=bluebird</li>
188      <li>module2=tiger</li>
189      <li>module3=tulip</li>
190      </ul>
191      * The sequence of resulting properties is sorted by their keys.
192      *
193      @param   namePrefix  Prefix of seek property name.
194      @return  List of key sorted string properties (maybe empty).
195      */
196     public final String[] getStringProperties(final String namePrefix) {
197         final List list = new ArrayList();
198         final Enumeration keys = getProperties().keys();
199         final List keyList = Collections.list(keys);
200         Collections.sort(keyList);
201         for (int i = 0; i < keyList.size(); i++) {
202             final String key = (StringkeyList.get(i);
203             if (key.startsWith(namePrefix)) {
204                 list.add(getProperties().get(key));
205             }
206         }
207         return (String []) list.toArray(new String[list.size()]);
208     }
209 
210     /**
211      * Get map of String properties with certain prefix.
212      *
213      @param   namePrefix  Prefix of seek property name.
214      @return  Map of properties that have String keys that start with <code>namePrefix</code>.
215      *          The prefix is removed of for the resulting map.
216      */
217     public final Map getProperties(final String namePrefix) {
218         final Map result = new HashMap();
219         Iterator i = getProperties().entrySet().iterator();
220         while (i.hasNext()) {
221             Map.Entry entry = (Map.Entryi.next();
222             final String name = String.valueOf(entry.getKey());
223             if (name.startsWith(namePrefix)) {
224                 result.put(name.substring(namePrefix.length()), entry.getValue());
225             }
226         }
227         return result;
228     }
229 
230     /**
231      * Set int property.
232      *
233      @param name   Set this property.
234      @param value  Set property to this value.
235      */
236     public final void setInteger(final String name, final int value) {
237         setString(name, "" + value);
238     }
239 
240 
241     /**
242      * Get int property.
243      *
244      @param   name    look for this property
245      @return  property
246      @throws  IllegalArgumentException    Property is no valid int value
247      @throws  NullPointerException        Property doesn't exist
248      */
249     public final int getInteger(final String name) {
250         final String intPropAsString = getProperties().getProperty(name);
251         if (intPropAsString != null) {
252             try {
253                 return Integer.parseInt(intPropAsString);
254             catch (NumberFormatException ex) {
255                 throw new IllegalArgumentException(
256                     "int property " + intPropAsString + " has invalid format");
257             }
258         else {
259             throw new NullPointerException("property \"" + name + "\" not found");
260         }
261     }
262 
263     /**
264      * Return int property.
265      *
266      @param   name            Look for this integer property.
267      @param   defaultValue    Return this value if property doesn't exist.
268      @return  int value of property. Equal to default value if parameter doesn't exist.
269      @throws  IllegalArgumentException    Property is no valid int value.
270      */
271     public final int getInteger(final String name, final int defaultValue) {
272         final String intPropAsString = getProperties().getProperty(name);
273         if (intPropAsString != null && intPropAsString.length() 0) {
274             try {
275                 return Integer.parseInt(intPropAsString);
276             catch (NumberFormatException ex) {
277                 throw new IllegalArgumentException(
278                     "Integer-Property " + intPropAsString + " has invalid format");
279             }
280         else {
281             setInteger(name, defaultValue);
282             return defaultValue;
283         }
284     }
285 
286     /**
287      * Remove property.
288      *
289      @param   name    Property to delete.
290      */
291     public final void removeProperty(final String name) {
292         getProperties().remove(name);
293     }
294 
295     /**
296      * Remove properties with certain prefix.
297      *
298      * Example:
299      <ul>
300      <li>module1=bluebird</li>
301      <li>module2=tiger</li>
302      <li>module3=tulip</li>
303      </ul>
304      * Calling with value <code>module</code> deletes all.
305      *
306      @param   namePrefix  Prefix of seeked property name.
307      */
308     public final void removeProperties(final String namePrefix) {
309         final Enumeration keys = getProperties().keys();
310         while (keys.hasMoreElements()) {
311             final String key = (Stringkeys.nextElement();
312             if (key.startsWith(namePrefix)) {
313                 getProperties().remove(key);
314             }
315         }
316     }
317 
318 }