1 | /* This file is part of the project "Hilbert II" - 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 | } |