KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > boot > PropertyPreferences


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
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  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.boot;
21
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Properties JavaDoc;
29 import java.util.Timer JavaDoc;
30 import java.util.TimerTask JavaDoc;
31 import java.util.prefs.AbstractPreferences JavaDoc;
32 import java.util.prefs.BackingStoreException JavaDoc;
33 import java.util.prefs.Preferences JavaDoc;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37
38
39 /**
40  * A simple implementation for the preferences API. That stores preferences
41  * in propery files. We do not have to worry about sharing the preferencese
42  * with other JVM instance so there is no need for any kind of synchronising
43  * or locking.
44  *
45  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
46  */

47 public class PropertyPreferences extends AbstractPreferences JavaDoc {
48     
49     /**
50      * System root
51      */

52     public final static Preferences JavaDoc SYSTEM_ROOT = new PropertyPreferences(new File JavaDoc(new File JavaDoc(ContextHolder.getContext().getConfDirectory(), "prefs"), "system"));
53     
54     /**
55      * User root
56      */

57     public final static Preferences JavaDoc USER_ROOT = new PropertyPreferences(new File JavaDoc(new File JavaDoc(ContextHolder.getContext().getConfDirectory(), "prefs"), "system"));
58     
59     private static final String JavaDoc[] EMPTY_STRING_ARRAY = new String JavaDoc[0];
60     private static final int FLUSH_INTERVAL = 30; // seconds
61

62     final static Log log = LogFactory.getLog(PropertyPreferences.class);
63
64
65     private static Timer JavaDoc flushTimer = new Timer JavaDoc(true); // Daemon Thread
66

67     static {
68         // Add periodic timer task to periodically sync cached prefs
69
flushTimer.schedule(new TimerTask JavaDoc() {
70             public void run() {
71                 flushAll();
72             }
73         }, FLUSH_INTERVAL*1000, FLUSH_INTERVAL*1000);
74
75         Runtime.getRuntime().addShutdownHook(new Thread JavaDoc() {
76             public void run() {
77                 flushTimer.cancel();
78                 flushAll();
79             }
80         });
81     }
82     
83     // Private instance variables
84

85     private File JavaDoc dir;
86     private File JavaDoc prefFile;
87     private Properties JavaDoc prefs;
88
89     /**
90      * Constructor for root node.
91      *
92      * @param dir directory
93      */

94     public PropertyPreferences(File JavaDoc dir) {
95         this(dir, null, "");
96     }
97
98     /**
99      * Constructor.
100      *
101      * @param dir directory containing preferences and children
102      * @param parent
103      * @param name
104      */

105     public PropertyPreferences(File JavaDoc dir, AbstractPreferences JavaDoc parent, String JavaDoc name) {
106         super(parent, name);
107         this.dir = dir;
108     }
109
110     /* (non-Javadoc)
111      * @see java.util.prefs.AbstractPreferences#childSpi(java.lang.String)
112      */

113     protected AbstractPreferences JavaDoc childSpi(String JavaDoc name) {
114         return new PropertyPreferences(new File JavaDoc(dir, encodeDirName(name)), this, name);
115     }
116
117     /* (non-Javadoc)
118      * @see java.util.prefs.AbstractPreferences#childrenNamesSpi()
119      */

120     protected String JavaDoc[] childrenNamesSpi() throws BackingStoreException JavaDoc {
121         List JavaDoc result = new ArrayList JavaDoc();
122         File JavaDoc[] dirContents = dir.listFiles();
123         if (dirContents != null) {
124             for (int i = 0; i < dirContents.length; i++)
125                 if (dirContents[i].isDirectory())
126                     result.add(decodeDirName(dirContents[i].getName()));
127         }
128         return (String JavaDoc[])result.toArray(EMPTY_STRING_ARRAY);
129     }
130
131     /* (non-Javadoc)
132      * @see java.util.prefs.AbstractPreferences#flushSpi()
133      */

134     protected void flushSpi() throws BackingStoreException JavaDoc {
135         if(prefs == null) {
136             return;
137         }
138         if(prefFile == null) {
139             prefFile = new File JavaDoc(dir, "prefs.properties");
140         }
141         if(!dir.exists() && !dir.mkdirs()) {
142             throw new BackingStoreException JavaDoc("Failed to create node directory " + dir.getPath() + ".");
143         }
144         FileOutputStream JavaDoc fos = null;
145         try {
146             fos = new FileOutputStream JavaDoc(prefFile);
147             prefs.store(fos, name());
148         }
149         catch(IOException JavaDoc ioe) {
150             throw new BackingStoreException JavaDoc(ioe);
151         }
152         finally {
153             Util.closeStream(fos);
154         }
155     }
156
157     /* (non-Javadoc)
158      * @see java.util.prefs.AbstractPreferences#getSpi(java.lang.String)
159      */

160     protected String JavaDoc getSpi(String JavaDoc key) {
161         checkLoaded();
162         return prefs == null ? null : prefs.getProperty(key);
163     }
164
165     /* (non-Javadoc)
166      * @see java.util.prefs.AbstractPreferences#keysSpi()
167      */

168     protected String JavaDoc[] keysSpi() throws BackingStoreException JavaDoc {
169         checkLoaded();
170         return prefs == null ? EMPTY_STRING_ARRAY : (String JavaDoc[])
171             prefs.keySet().toArray(new String JavaDoc[prefs.size()]);
172     }
173
174     /* (non-Javadoc)
175      * @see java.util.prefs.AbstractPreferences#putSpi(java.lang.String, java.lang.String)
176      */

177     protected void putSpi(String JavaDoc key, String JavaDoc value) {
178         checkLoaded();
179         if(prefs == null) {
180             prefs = new Properties JavaDoc();
181         }
182         prefs.setProperty(key, value);
183     }
184
185     /* (non-Javadoc)
186      * @see java.util.prefs.AbstractPreferences#removeNodeSpi()
187      */

188     protected void removeNodeSpi() throws BackingStoreException JavaDoc {
189         if(!Util.delTree(dir)) {
190             throw new BackingStoreException JavaDoc("Failed to remove preferencese node " + dir.getPath() + ".");
191         }
192     }
193
194     /* (non-Javadoc)
195      * @see java.util.prefs.AbstractPreferences#removeSpi(java.lang.String)
196      */

197     protected void removeSpi(String JavaDoc key) {
198         checkLoaded();
199         if(prefs != null) {
200             prefs.remove(key);
201         }
202
203     }
204
205     /* (non-Javadoc)
206      * @see java.util.prefs.AbstractPreferences#syncSpi()
207      */

208     protected void syncSpi() throws BackingStoreException JavaDoc {
209         flushSpi();
210
211     }
212     
213     String JavaDoc encodeDirName(String JavaDoc dirName) {
214         for (int i=0, n=dirName.length(); i < n; i++) {
215             if (!isValidChar(dirName.charAt(i))) {
216                 return "_" + Base64.encode(dirName.getBytes());
217             }
218         }
219         return dirName;
220     }
221     
222     String JavaDoc decodeDirName(String JavaDoc dirName) {
223         if(dirName.startsWith("_")) {
224             return new String JavaDoc(Base64.decode(dirName.substring(1)));
225         }
226         return dirName;
227     }
228     
229     boolean isValidChar(char ch) {
230         return ch > 0x1f && ch < 0x7f && ch != '/' && ch != '.' && ch != '_' && ch != '\\';
231     }
232     
233     synchronized void checkLoaded() {
234         if(prefFile == null) {
235             prefFile = new File JavaDoc(dir, "prefs.properties");
236         }
237         if(prefFile.exists()) {
238             if(prefs == null) {
239                 prefs = new Properties JavaDoc();
240                 FileInputStream JavaDoc fin = null;
241                 try {
242                     fin = new FileInputStream JavaDoc(prefFile);
243                     prefs.load(fin);
244                 }
245                 catch(IOException JavaDoc ioe) {
246                     log.error("Failed to open preferences file " + prefFile.getPath() + ".", ioe);
247                 }
248                 finally {
249                     Util.closeStream(fin);
250                 }
251                 
252             }
253         }
254     }
255     
256     static void flushAll() {
257         try {
258             if (SYSTEM_ROOT != null)
259                 SYSTEM_ROOT.flush();
260         } catch(BackingStoreException JavaDoc e) {
261             log.warn("Couldn't flush system prefs.", e);
262         }
263         try {
264             if (USER_ROOT != null)
265                 USER_ROOT.flush();
266         } catch(BackingStoreException JavaDoc e) {
267             log.warn("Couldn't flush user prefs.", e);
268         }
269     }
270
271 }
272
Popular Tags