View Javadoc

1   /* This file is part of the project "Hilbert II" - http://www.qedeq.org" target="alexandria_uri">http://www.qedeq.org
2    *
3    * Copyright 2000-2014,  Michael Meyling <mime@qedeq.org>.
4    *
5    * "Hilbert II" is free software; you can redistribute
6    * it and/or modify it under the terms of the GNU General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU General Public License for more details.
14   */
15  
16  package org.qedeq.kernel.se.config;
17  
18  import java.io.File;
19  import java.io.FileInputStream;
20  import java.io.FileOutputStream;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.util.ArrayList;
25  import java.util.Collections;
26  import java.util.Enumeration;
27  import java.util.HashMap;
28  import java.util.Iterator;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Properties;
32  
33  import org.qedeq.base.io.IoUtility;
34  
35  
36  /**
37   * This class reads entries from property files. This class should not
38   * be used outside this package.
39   *
40   * @author  Michael Meyling
41   */
42  final class ConfigAccess {
43  
44      /** Config file. */
45      private final File configFile;
46  
47      /** Collector for properties. */
48      private Properties properties = new Properties();
49  
50      /** Config file description. */
51      private final String description;
52  
53      /**
54       * Get access for a config file.
55       *
56       * @param   configFile              Config file.
57       * @param   description             Config file description
58       * @throws  IOException             Config file couldn't be loaded.
59       */
60      public ConfigAccess(final File configFile, final String description) throws IOException {
61          this.configFile = configFile;
62          this.description = description;
63          FileInputStream stream = null;
64          try {
65              stream = new FileInputStream(configFile);
66              load(stream);
67          } catch (IOException e) {
68              System.out.println("no config file found, using default values");
69          } finally {
70              IoUtility.close(stream);
71          }
72          setString("configFileLocation", configFile.getCanonicalPath());
73      }
74  
75      /**
76       * Get config file.
77       *
78       * @return  Config file.
79       */
80      public final synchronized File getConfigFile() {
81          return configFile;
82      }
83  
84      /**
85       * Get description for config file.
86       *
87       * @return  Config file description.
88       */
89      public final synchronized String getConfigDescription() {
90          return description;
91      }
92  
93      /**
94       * Get properties.
95       *
96       * @return  properties.
97       */
98      private final Properties getProperties() {
99          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 inStream) throws IOException {
110         getProperties().load(inStream);
111     }
112 
113     /**
114      * Store properties in config file.
115      *
116      * @throws  IOException Saving failed.
117      */
118     public final synchronized 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 synchronized 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 synchronized 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         }
161         return value;
162     }
163 
164     /**
165      * Set String property.
166      *
167      * @param name   Set this property.
168      * @param value  Set property to this value.
169      */
170     public final synchronized void setString(final String name, final String value) {
171         getProperties().setProperty(name, value);
172     }
173 
174     /**
175      * Get list of String properties with certain prefix.
176      * Example:
177      * <ul>
178      * <li>qeq=green</li>
179      * <li>module2=tiger</li>
180      * <li>module3=tulip</li>
181      * <li>modula=green</li>
182      * <li>module1=bluebird</li>
183      * </ul>
184      * If namePrefix == "module" we get:
185      * <ul>
186      * <li>module1=bluebird</li>
187      * <li>module2=tiger</li>
188      * <li>module3=tulip</li>
189      * </ul>
190      * The sequence of resulting properties is sorted by their keys.
191      *
192      * @param   namePrefix  Prefix of seek property name.
193      * @return  List of key sorted string properties (maybe empty).
194      */
195     public final synchronized String[] getStringProperties(final String namePrefix) {
196         final List list = new ArrayList();
197         final Enumeration keys = getProperties().keys();
198         final List keyList = Collections.list(keys);
199         Collections.sort(keyList);
200         for (int i = 0; i < keyList.size(); i++) {
201             final String key = (String) keyList.get(i);
202             if (key.startsWith(namePrefix)) {
203                 list.add(getProperties().get(key));
204             }
205         }
206         return (String []) list.toArray(new String[list.size()]);
207     }
208 
209     /**
210      * Get map of String properties with certain prefix.
211      *
212      * @param   namePrefix  Prefix of seek property name.
213      * @return  Map of properties that have String keys that start with <code>namePrefix</code>.
214      *          The prefix is removed of for the resulting map.
215      */
216     public final synchronized Map getProperties(final String namePrefix) {
217         final Map result = new HashMap();
218         Iterator i = getProperties().entrySet().iterator();
219         while (i.hasNext()) {
220             Map.Entry entry = (Map.Entry) i.next();
221             final String name = String.valueOf(entry.getKey());
222             if (name.startsWith(namePrefix)) {
223                 result.put(name.substring(namePrefix.length()), entry.getValue());
224             }
225         }
226         return result;
227     }
228 
229     /**
230      * Set int property.
231      *
232      * @param name   Set this property.
233      * @param value  Set property to this value.
234      */
235     public final synchronized void setInteger(final String name, final int value) {
236         setString(name, "" + value);
237     }
238 
239 
240     /**
241      * Get int property.
242      *
243      * @param   name    look for this property
244      * @return  property
245      * @throws  IllegalArgumentException    Property is no valid int value
246      * @throws  NullPointerException        Property doesn't exist
247      */
248     public final synchronized int getInteger(final String name) {
249         final String intPropAsString = getProperties().getProperty(name);
250         if (intPropAsString == null) {
251             throw new NullPointerException("property \"" + name + "\" not found");
252         }
253         try {
254             return Integer.parseInt(intPropAsString);
255         } catch (NumberFormatException ex) {
256             throw new IllegalArgumentException(
257                 "int property " + intPropAsString + " has invalid format");
258         }
259     }
260 
261     /**
262      * Return int property.
263      *
264      * @param   name            Look for this integer property.
265      * @param   defaultValue    Return this value if property doesn't exist.
266      * @return  int value of property. Equal to default value if parameter doesn't exist.
267      * @throws  IllegalArgumentException    Property is no valid int value.
268      */
269     public final synchronized int getInteger(final String name, final int defaultValue) {
270         final String intPropAsString = getProperties().getProperty(name);
271         if (intPropAsString == null || intPropAsString.length() == 0) {
272             setInteger(name, defaultValue);
273             return defaultValue;
274         }
275         try {
276             return Integer.parseInt(intPropAsString);
277         } catch (NumberFormatException ex) {
278             throw new IllegalArgumentException(
279                 "Integer-Property " + intPropAsString + " has invalid format");
280         }
281     }
282 
283     /**
284      * Remove property.
285      *
286      * @param   name    Property to delete.
287      */
288     public final synchronized void removeProperty(final String name) {
289         getProperties().remove(name);
290     }
291 
292     /**
293      * Remove properties with certain prefix.
294      *
295      * Example:
296      * <ul>
297      * <li>module1=bluebird</li>
298      * <li>module2=tiger</li>
299      * <li>module3=tulip</li>
300      * </ul>
301      * Calling with value <code>module</code> deletes all.
302      *
303      * @param   namePrefix  Prefix of seeked property name.
304      */
305     public final synchronized void removeProperties(final String namePrefix) {
306         final Enumeration keys = getProperties().keys();
307         while (keys.hasMoreElements()) {
308             final String key = (String) keys.nextElement();
309             if (key.startsWith(namePrefix)) {
310                 getProperties().remove(key);
311             }
312         }
313     }
314 
315 }