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 }