1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.log4j.chainsaw.prefs;
18
19 import java.io.BufferedInputStream;
20 import java.io.BufferedOutputStream;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.net.URLEncoder;
28 import java.util.EventListener;
29 import java.util.Properties;
30
31 import javax.swing.event.EventListenerList;
32
33
34 /***
35 * SettingManager allows components to register interest in Saving/Loading
36 * of general application preferences/settings.
37 *
38 * @author Paul Smith <psmith@apache.org>
39 * @author Scott Deboy <sdeboy@apache.org>
40 *
41 */
42 public final class SettingsManager {
43 private static final SettingsManager instance = new SettingsManager();
44 private static final String GLOBAL_SETTINGS_FILE_NAME = "chainsaw.settings.properties";
45 private static final String HEADER = "Chainsaws Settings Files";
46 private EventListenerList listenerList = new EventListenerList();
47 private Properties defaultProperties = new Properties();
48
49 /***
50 * Initialises the SettingsManager by loading the default Properties from
51 * a resource
52 *
53 */
54 private SettingsManager() {
55
56 InputStream is = null;
57
58 try {
59 is = this.getClass().getClassLoader()
60 .getResource("org/apache/log4j/chainsaw/prefs/default.properties")
61 .openStream();
62 defaultProperties.load(is);
63
64
65 is.close();
66 } catch (IOException e) {
67 e.printStackTrace();
68 } finally {
69 if (is != null) {
70 try {
71 is.close();
72 } catch (Exception e) {
73 }
74 }
75 }
76 }
77
78 /***
79 * Returns the singleton instance of the SettingsManager
80 * @return settings manager
81 */
82 public static final SettingsManager getInstance() {
83 return instance;
84 }
85
86 /***
87 * Registers the listener with the manager
88 * @param listener
89 */
90 public void addSettingsListener(SettingsListener listener) {
91 listenerList.add(SettingsListener.class, listener);
92 }
93
94 /***
95 * Requests that the settings be loaded, all listeners will be notified of
96 * this call, and configure themselves according to the values found in the
97 * loaded settings
98 *
99 */
100 public void loadSettings() {
101
102
103
104
105 File settingsDir = getSettingsDirectory();
106
107 if (!settingsDir.exists()) {
108 settingsDir.mkdir();
109 }
110
111 loadGlobalSettings();
112 loadProfileableSettings();
113 }
114
115 /***
116 *
117 */
118 private void loadProfileableSettings() {
119 EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
120
121 for (int i = 0; i < listeners.length; i++) {
122 SettingsListener settingsListener = (SettingsListener) listeners[i];
123
124 if (settingsListener instanceof Profileable) {
125 Profileable p = (Profileable) settingsListener;
126 loadProfileble(p);
127 }
128 }
129 }
130
131 private void loadProfileble(Profileable p) {
132 LoadSettingsEvent event = createProfilebleEvent(p);
133 p.loadSettings(event);
134 }
135
136 private LoadSettingsEvent createProfilebleEvent(Profileable p) {
137 Properties loadedProperties = new Properties();
138 loadedProperties.putAll(getDefaultSettings());
139 loadedProperties.putAll(loadProperties(p));
140
141
142 LoadSettingsEvent event = new LoadSettingsEvent(this, loadedProperties);
143
144 return event;
145 }
146
147 /***
148 * @param p
149 * @return
150 */
151 private Properties loadProperties(Profileable p) {
152 Properties properties = new Properties(defaultProperties);
153 InputStream is = null;
154
155 File f = new File(getSettingsDirectory(),
156 URLEncoder.encode(p.getNamespace() + ".properties"));
157
158 if (!f.exists()) {
159 f = new File(getSettingsDirectory(),
160 p.getNamespace() + ".properties");
161 }
162
163 if (f.exists()) {
164 try {
165 is = new BufferedInputStream(new FileInputStream(f));
166
167 Properties toLoad = new Properties();
168 toLoad.load(is);
169 properties.putAll(toLoad);
170 } catch (IOException ioe) {
171 ioe.printStackTrace();
172 } finally {
173 if (is != null) {
174 try {
175 is.close();
176 } catch (IOException e1) {
177 e1.printStackTrace();
178 }
179 }
180 }
181 }
182
183 return properties;
184 }
185
186 private void loadGlobalSettings() {
187 EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
188 LoadSettingsEvent event = null;
189
190 for (int i = 0; i < listeners.length; i++) {
191 SettingsListener settingsListener = (SettingsListener) listeners[i];
192
193 if (event == null) {
194 Properties loadedProperties = loadGlobalProperties();
195
196
197 event = new LoadSettingsEvent(this, loadedProperties);
198 }
199
200 settingsListener.loadSettings(event);
201 }
202 }
203
204 /***
205 * Creates a SaveSettingsEvent and calls all the SettingsListeners
206 * to populate the properties with configuration information
207 *
208 */
209 public void saveSettings() {
210
211
212
213
214 File settingsDir = getSettingsDirectory();
215
216 if (!settingsDir.exists()) {
217 settingsDir.mkdir();
218 }
219
220 saveGlobalSettings(settingsDir);
221 saveProfileableSetting(settingsDir);
222 }
223
224 /***
225 * Looks up all the Profileable's that have been registered
226 * and creates a new event for each of them, and ensures that they
227 * are saved within a separate external store
228 * @param settingsDir
229 */
230 private void saveProfileableSetting(File settingsDir) {
231 EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
232 SaveSettingsEvent event = null;
233
234 for (int i = 0; i < listeners.length; i++) {
235 SettingsListener settingsListener = (SettingsListener) listeners[i];
236
237 if (settingsListener instanceof Profileable) {
238 Profileable profileable = (Profileable) settingsListener;
239 event = new SaveSettingsEvent(this, getSettingsDirectory());
240
241 profileable.saveSettings(event);
242
243 OutputStream os = null;
244
245 try {
246 os = new BufferedOutputStream(new FileOutputStream(
247 new File(settingsDir,
248 URLEncoder.encode(profileable.getNamespace()) + ".properties")));
249 event.getProperties().store(os, HEADER);
250 } catch (Exception e) {
251 e.printStackTrace();
252 } finally {
253 if (os != null) {
254 try {
255 os.close();
256 } catch (IOException e1) {
257 e1.printStackTrace();
258 }
259 }
260 }
261 }
262 }
263 }
264
265 private void saveGlobalSettings(File settingsDir) {
266 EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
267 SaveSettingsEvent event = null;
268
269 for (int i = 0; i < listeners.length; i++) {
270 SettingsListener settingsListener = (SettingsListener) listeners[i];
271
272 if (!(settingsListener instanceof Profileable)) {
273 if (event == null) {
274 event = new SaveSettingsEvent(this, getSettingsDirectory());
275 }
276
277 settingsListener.saveSettings(event);
278 }
279 }
280
281 OutputStream os = null;
282
283 try {
284 os = new BufferedOutputStream(new FileOutputStream(
285 new File(settingsDir, GLOBAL_SETTINGS_FILE_NAME)));
286 event.getProperties().store(os, HEADER);
287 } catch (Exception e) {
288 e.printStackTrace();
289 } finally {
290 if (os != null) {
291 try {
292 os.close();
293 } catch (IOException e1) {
294 e1.printStackTrace();
295 }
296 }
297 }
298 }
299
300 public File getSettingsDirectory() {
301 return new File(System.getProperty("user.home"), ".chainsaw");
302 }
303
304 public void configure(SettingsListener listener) {
305 if (listener instanceof Profileable) {
306 loadProfileble((Profileable) listener);
307 } else {
308 Properties loadedProperties = loadGlobalProperties();
309 LoadSettingsEvent event = new LoadSettingsEvent(this,
310 loadedProperties);
311 listener.loadSettings(event);
312 }
313 }
314
315 /***
316 * Returns the current Properties settings for this user
317 * by merging the default Properties with the ones we find in their directory.
318 *
319 * @return
320 */
321 private Properties loadGlobalProperties() {
322 Properties properties = new Properties(defaultProperties);
323 InputStream is = null;
324
325 File f = new File(getSettingsDirectory(), GLOBAL_SETTINGS_FILE_NAME);
326
327 if (f.exists()) {
328 try {
329 is = new BufferedInputStream(new FileInputStream(f));
330
331 Properties toLoad = new Properties();
332 toLoad.load(is);
333 properties.putAll(toLoad);
334 } catch (IOException ioe) {
335 ioe.printStackTrace();
336 } finally {
337 if (is != null) {
338 try {
339 is.close();
340 } catch (IOException e1) {
341 e1.printStackTrace();
342 }
343 }
344 }
345 }
346
347 return properties;
348 }
349
350 /***
351 * Returns the loaded default settings, which can be used by
352 * other classes within this package.
353 * @return Properties defaults
354 */
355 public Properties getDefaultSettings() {
356 return defaultProperties;
357 }
358 }