1 19 20 package com.sslexplorer.boot; 21 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileOutputStream ; 25 import java.io.IOException ; 26 import java.util.ArrayList ; 27 import java.util.List ; 28 import java.util.Properties ; 29 import java.util.Timer ; 30 import java.util.TimerTask ; 31 import java.util.prefs.AbstractPreferences ; 32 import java.util.prefs.BackingStoreException ; 33 import java.util.prefs.Preferences ; 34 35 import org.apache.commons.logging.Log; 36 import org.apache.commons.logging.LogFactory; 37 38 39 47 public class PropertyPreferences extends AbstractPreferences { 48 49 52 public final static Preferences SYSTEM_ROOT = new PropertyPreferences(new File (new File (ContextHolder.getContext().getConfDirectory(), "prefs"), "system")); 53 54 57 public final static Preferences USER_ROOT = new PropertyPreferences(new File (new File (ContextHolder.getContext().getConfDirectory(), "prefs"), "system")); 58 59 private static final String [] EMPTY_STRING_ARRAY = new String [0]; 60 private static final int FLUSH_INTERVAL = 30; 62 final static Log log = LogFactory.getLog(PropertyPreferences.class); 63 64 65 private static Timer flushTimer = new Timer (true); 67 static { 68 flushTimer.schedule(new TimerTask () { 70 public void run() { 71 flushAll(); 72 } 73 }, FLUSH_INTERVAL*1000, FLUSH_INTERVAL*1000); 74 75 Runtime.getRuntime().addShutdownHook(new Thread () { 76 public void run() { 77 flushTimer.cancel(); 78 flushAll(); 79 } 80 }); 81 } 82 83 85 private File dir; 86 private File prefFile; 87 private Properties prefs; 88 89 94 public PropertyPreferences(File dir) { 95 this(dir, null, ""); 96 } 97 98 105 public PropertyPreferences(File dir, AbstractPreferences parent, String name) { 106 super(parent, name); 107 this.dir = dir; 108 } 109 110 113 protected AbstractPreferences childSpi(String name) { 114 return new PropertyPreferences(new File (dir, encodeDirName(name)), this, name); 115 } 116 117 120 protected String [] childrenNamesSpi() throws BackingStoreException { 121 List result = new ArrayList (); 122 File [] 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 [])result.toArray(EMPTY_STRING_ARRAY); 129 } 130 131 134 protected void flushSpi() throws BackingStoreException { 135 if(prefs == null) { 136 return; 137 } 138 if(prefFile == null) { 139 prefFile = new File (dir, "prefs.properties"); 140 } 141 if(!dir.exists() && !dir.mkdirs()) { 142 throw new BackingStoreException ("Failed to create node directory " + dir.getPath() + "."); 143 } 144 FileOutputStream fos = null; 145 try { 146 fos = new FileOutputStream (prefFile); 147 prefs.store(fos, name()); 148 } 149 catch(IOException ioe) { 150 throw new BackingStoreException (ioe); 151 } 152 finally { 153 Util.closeStream(fos); 154 } 155 } 156 157 160 protected String getSpi(String key) { 161 checkLoaded(); 162 return prefs == null ? null : prefs.getProperty(key); 163 } 164 165 168 protected String [] keysSpi() throws BackingStoreException { 169 checkLoaded(); 170 return prefs == null ? EMPTY_STRING_ARRAY : (String []) 171 prefs.keySet().toArray(new String [prefs.size()]); 172 } 173 174 177 protected void putSpi(String key, String value) { 178 checkLoaded(); 179 if(prefs == null) { 180 prefs = new Properties (); 181 } 182 prefs.setProperty(key, value); 183 } 184 185 188 protected void removeNodeSpi() throws BackingStoreException { 189 if(!Util.delTree(dir)) { 190 throw new BackingStoreException ("Failed to remove preferencese node " + dir.getPath() + "."); 191 } 192 } 193 194 197 protected void removeSpi(String key) { 198 checkLoaded(); 199 if(prefs != null) { 200 prefs.remove(key); 201 } 202 203 } 204 205 208 protected void syncSpi() throws BackingStoreException { 209 flushSpi(); 210 211 } 212 213 String encodeDirName(String 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 decodeDirName(String dirName) { 223 if(dirName.startsWith("_")) { 224 return new String (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 (dir, "prefs.properties"); 236 } 237 if(prefFile.exists()) { 238 if(prefs == null) { 239 prefs = new Properties (); 240 FileInputStream fin = null; 241 try { 242 fin = new FileInputStream (prefFile); 243 prefs.load(fin); 244 } 245 catch(IOException 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 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 e) { 267 log.warn("Couldn't flush user prefs.", e); 268 } 269 } 270 271 } 272 | Popular Tags |