1 19 20 package org.netbeans.core.startup.preferences; 21 22 import java.io.IOException ; 23 import java.util.Properties ; 24 import java.util.prefs.AbstractPreferences ; 25 import java.util.prefs.BackingStoreException ; 26 import java.util.prefs.Preferences ; 27 import org.openide.ErrorManager; 28 import org.openide.util.RequestProcessor; 29 30 34 public abstract class NbPreferences extends AbstractPreferences { 35 private static Preferences USER_ROOT; 36 private static Preferences SYSTEM_ROOT; 37 38 Properties properties; 39 FileStorage fileStorage; 40 41 private static final RequestProcessor RP = new RequestProcessor(); 42 final RequestProcessor.Task flushTask = RP.create(new Runnable () { 43 public void run() { 44 synchronized(lock) { 45 try { 46 flushSpi(); 47 } catch (BackingStoreException ex) { 48 ErrorManager.getDefault().notify(ex); 49 } 50 } 51 } 52 },true); 53 54 55 static Preferences userRootImpl() { 56 if (USER_ROOT == null) { 57 USER_ROOT = new NbPreferences.UserPreferences(); 58 } 59 assert USER_ROOT != null; 60 return USER_ROOT; 61 } 62 63 static Preferences systemRootImpl() { 64 if (SYSTEM_ROOT == null) { 65 SYSTEM_ROOT = new NbPreferences.SystemPreferences(); 66 } 67 assert SYSTEM_ROOT != null; 68 return SYSTEM_ROOT; 69 } 70 71 private NbPreferences(boolean user) { 72 super(null, ""); 73 fileStorage = getFileStorage(absolutePath()); 74 } 75 76 77 private NbPreferences(NbPreferences parent, String name) { 78 super(parent, name); 79 fileStorage = getFileStorage(absolutePath()); 80 newNode = !fileStorage.existsNode(); 81 } 82 83 protected final String getSpi(String key) { 84 return (String )properties().getProperty(key); 85 } 86 87 protected final String [] childrenNamesSpi() throws BackingStoreException { 88 return fileStorage.childrenNames(); 90 } 91 92 protected final String [] keysSpi() throws BackingStoreException { 93 return (String [])properties().keySet().toArray(new String [0]); 94 } 95 96 protected final void putSpi(String key, String value) { 97 properties().put(key,value); 98 fileStorage.markModified(); 99 asyncInvocationOfFlushSpi(); 100 } 101 102 @Override 103 public void put(String key, String value) { 104 String oldValue = getSpi(key); 105 if (value.equals(oldValue)) {return;} 106 try { 107 super.put(key, value); 108 } catch (IllegalArgumentException iae) { 109 if (iae.getMessage().contains("too long")) { 110 putSpi(key, value); 112 } else { 113 throw iae; 114 } 115 } 116 } 117 118 protected final void removeSpi(String key) { 119 properties().remove(key); 120 fileStorage.markModified(); 121 asyncInvocationOfFlushSpi(); 122 } 123 124 protected final void removeNodeSpi() throws BackingStoreException { 125 try { 126 fileStorage.removeNode(); 127 } catch (IOException ex) { 128 throw new BackingStoreException (ex); 129 } 130 } 131 132 void asyncInvocationOfFlushSpi() { 133 if (!fileStorage.isReadOnly()) { 134 flushTask.schedule(200); 135 } 136 } 137 138 protected void flushSpi() throws BackingStoreException { 139 try { 140 fileStorage.save(properties()); 141 } catch (IOException ex) { 142 throw new BackingStoreException (ex); 143 } 144 } 145 146 protected void syncSpi() throws BackingStoreException { 147 if (properties != null) { 148 try { 149 properties.clear(); 150 properties().putAll(fileStorage.load()); 151 152 } catch (IOException ex) { 153 throw new BackingStoreException (ex); 154 } 155 } 156 } 157 158 Properties properties() { 159 if (properties == null) { 160 properties = new Properties (); 161 try { 162 properties().putAll(fileStorage.load()); 163 } catch (IOException ex) { 164 ErrorManager.getDefault().notify(ex); 165 } 166 } 167 return properties; 168 } 169 170 public final void removeNode() throws BackingStoreException { 171 if (fileStorage.isReadOnly()) { 172 throw new BackingStoreException ("Unsupported operation: read-only storage"); } else { 174 properties().clear(); 175 super.removeNode(); 176 } 177 } 178 179 public final void flush() throws BackingStoreException { 180 if (fileStorage.isReadOnly()) { 181 throw new BackingStoreException ("Unsupported operation: read-only storage"); } else { 183 super.flush(); 184 } 185 } 186 187 public final void sync() throws BackingStoreException { 188 if (fileStorage.isReadOnly()) { 189 throw new BackingStoreException ("Unsupported operation: read-only storage"); } else { 191 flushTask.waitFinished(); 192 super.sync(); 193 } 194 } 195 196 protected abstract FileStorage getFileStorage(String absolutePath); 197 198 public static class UserPreferences extends NbPreferences { 199 public UserPreferences() { 200 super(true); 201 } 202 203 204 private UserPreferences(NbPreferences parent, String name) { 205 super(parent, name); 206 } 207 208 protected AbstractPreferences childSpi(String name) { 209 return new UserPreferences(this, name); 210 } 211 212 protected NbPreferences.FileStorage getFileStorage(String absolutePath) { 213 return PropertiesStorage.instance(absolutePath()); 214 } 215 } 216 217 private static final class SystemPreferences extends NbPreferences { 218 private SystemPreferences() { 219 super(false); 220 } 221 222 private SystemPreferences(NbPreferences parent, String name) { 223 super(parent, name); 224 } 225 226 protected AbstractPreferences childSpi(String name) { 227 return new SystemPreferences(this, name); 228 } 229 230 protected NbPreferences.FileStorage getFileStorage(String absolutePath) { 231 return PropertiesStorage.instanceReadOnly(absolutePath()); 232 } 233 } 234 235 interface FileStorage { 236 boolean isReadOnly(); 237 String [] childrenNames(); 238 boolean existsNode(); 239 void removeNode() throws IOException ; 240 void markModified(); 241 Properties load() throws IOException ; 242 void save(final Properties properties) throws IOException ; 243 } 244 } 245 | Popular Tags |