1 19 20 package org.netbeans.modules.settings; 21 22 import java.beans.*; 23 import java.io.IOException ; 24 import java.util.logging.Level ; 25 import java.util.logging.Logger ; 26 27 import org.openide.cookies.SaveCookie; 28 import org.openide.filesystems.FileSystem; 29 import org.openide.filesystems.FileObject; 30 31 import org.netbeans.spi.settings.Convertor; 32 import org.netbeans.spi.settings.Saver; 33 import org.openide.util.Exceptions; 34 35 39 final class SaveSupport { 40 41 public final static String PROP_SAVE = "savecookie"; 43 public final static String PROP_FILE_CHANGED = "fileChanged"; 48 static final String EA_NAME = "name"; 50 51 private PropertyChangeSupport changeSupport; 52 53 54 private Convertor convertor; 55 56 private final SaveCookieImpl instToSave = new SaveCookieImpl(); 57 58 private boolean isChanged = false; 59 60 private final FileObject file; 61 62 private final java.lang.ref.SoftReference <Object > instance; 63 private final InstanceProvider ip; 64 65 private Boolean knownToBeTemplate = null; 66 67 71 public SaveSupport(InstanceProvider ip, Object inst) { 72 this.ip = ip; 73 this.instance = new java.lang.ref.SoftReference <Object >(inst); 74 this.file = ip.getFile(); 75 } 76 77 78 private Convertor getConvertor() { 79 return convertor; 80 } 81 82 83 private Convertor initConvertor() { 84 Object inst = instance.get(); 85 if (inst == null) { 86 throw new IllegalStateException ("setting object cannot be null: " + ip); } 88 89 try { 90 FileObject newProviderFO = Env.findProvider(inst.getClass()); 91 if (newProviderFO != null) { 92 if (getPublicID(newProviderFO).equals(getPublicID(ip.getProvider()))) { 93 convertor = ip.getConvertor(); 95 return convertor; 96 } 97 Object attrb = newProviderFO.getAttribute(Env.EA_CONVERTOR); 98 if (attrb == null || !(attrb instanceof Convertor)) { 99 throw new IOException ("cannot create convertor: " + attrb + ", provider: " + newProviderFO); } else { 101 convertor = (Convertor) attrb; 102 return convertor; 103 } 104 } 105 convertor = ip.getConvertor(); 106 } catch (IOException ex) { 107 Logger.getLogger(SaveSupport.class.getName()).log(Level.WARNING, null, ex); 108 } 109 return convertor; 110 } 111 112 113 private String getPublicID(FileObject fo) throws IOException { 114 FileObject foEntity = Env.findEntityRegistration(fo); 115 if (foEntity == null) foEntity = fo; 116 Object publicId = foEntity.getAttribute(Env.EA_PUBLICID); 117 if (publicId == null || !(publicId instanceof String )) { 118 throw new IOException ("missing or invalid attribute: " + Env.EA_PUBLICID + ", provider: " + foEntity); } 121 return (String ) publicId; 122 } 123 124 125 public final SaveCookie getSaveCookie () { 126 return instToSave; 127 } 128 129 130 public final boolean isChanged() { 131 return isChanged; 132 } 133 134 138 public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { 139 if (changeSupport == null) { 140 changeSupport = new PropertyChangeSupport(this); 141 Object inst = instance.get(); 142 if (inst == null) return; 143 Convertor conv = initConvertor(); 144 if (conv != null) { 145 conv.registerSaver(inst, instToSave); 146 } 147 } 148 changeSupport.addPropertyChangeListener(listener); 149 } 150 151 154 public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { 155 if (changeSupport != null) { 156 changeSupport.removePropertyChangeListener(listener); 157 Object inst = instance.get(); 158 if (inst == null) return; 159 Convertor conv = getConvertor(); 160 if (conv != null) { 161 conv.unregisterSaver(inst, instToSave); 162 } 163 } 164 } 165 166 171 private void firePropertyChange(String name) { 172 if (changeSupport != null) 173 changeSupport.firePropertyChange(name, null, null); 174 } 175 176 177 public void writeDown() throws IOException { 178 instToSave.writeDown(); 179 } 180 181 184 private class SaveCookieImpl implements FileSystem.AtomicAction, SaveCookie, Saver { 185 186 private java.io.ByteArrayOutputStream buf; 187 188 private SaveCookieImpl() { 189 } 190 191 192 public void run () throws IOException { 193 if (!ip.getDataObject().isValid()) { 194 Logger.getAnonymousLogger().fine("invalid data object cannot be used for storing " + ip.getDataObject()); return; 197 } 198 org.openide.filesystems.FileLock lock = null; 199 java.io.OutputStream los; 200 synchronized (ip.READWRITE_LOCK) { 201 lock = ip.getScheduledRequest().getFileLock(); 205 if (lock == null) return; 206 los = file.getOutputStream(lock); 207 208 java.io.OutputStream os = new java.io.BufferedOutputStream (los, 1024); 209 try { 210 buf.writeTo(os); 211 } finally { 215 os.close(); 216 } 217 } 218 } 219 220 221 public void save() throws IOException { 222 if (!isChanged) return; 223 ip.getScheduledRequest().runAndWait(); 224 } 225 226 private void writeDown() throws IOException { 227 Object inst = instance.get(); 228 if (inst == null) return ; 229 Convertor conv = getConvertor(); 230 if (conv == null) return ; 231 java.io.ByteArrayOutputStream b = new java.io.ByteArrayOutputStream (1024); 232 java.io.Writer w = ContextProvider.createWriterContextProvider( 233 new java.io.OutputStreamWriter (b, "UTF-8"), SaveSupport.this.file 235 ); 236 isChanged = false; 237 try { 238 conv.write(w, inst); 239 } finally { 240 w.close(); 241 } 242 243 buf = b; 244 file.getFileSystem().runAtomicAction(this); 245 buf = null; 246 synchronizeName(inst); 247 if (!isChanged) firePropertyChange(PROP_SAVE); 248 } 249 250 public void markDirty() { 251 if (isChanged || !ip.getDataObject().isValid()) return; 252 if (knownToBeTemplate == null) knownToBeTemplate = ip.getDataObject().isTemplate() ? Boolean.TRUE : Boolean.FALSE; 253 if (knownToBeTemplate.booleanValue()) return; 254 isChanged = true; 255 firePropertyChange(PROP_SAVE); 256 } 257 258 public void requestSave() throws java.io.IOException { 259 if (isChanged || !ip.getDataObject().isValid()) return; 260 if (knownToBeTemplate == null) knownToBeTemplate = ip.getDataObject().isTemplate() ? Boolean.TRUE : Boolean.FALSE; 261 if (knownToBeTemplate.booleanValue()) return; 262 isChanged = true; 263 firePropertyChange(PROP_SAVE); 264 ip.getScheduledRequest().schedule(instance.get()); 265 } 266 267 268 private void synchronizeName(Object inst) { 269 java.lang.reflect.Method getter; 270 try { 271 try { 272 getter = inst.getClass().getMethod("getDisplayName"); } catch (NoSuchMethodException me) { 274 getter = inst.getClass().getMethod("getName"); } 276 } catch (Exception ex) { return; 278 } 279 if (!getter.isAccessible()) return; 280 281 try { 282 String name = (String ) getter.invoke(inst); 283 String oldName = ip.getDataObject().getName(); 284 if (!name.equals(oldName)) { 285 file.setAttribute(EA_NAME, name); 286 } else if (file.getAttribute(EA_NAME) == null) { 287 file.setAttribute(EA_NAME, name); 288 } 289 } catch (Exception ex) { 290 Exceptions.attachLocalizedMessage(ex, file.toString()); 291 Logger.getLogger(SaveSupport.class.getName()).log(Level.WARNING, null, ex); 292 } 293 } 294 295 } 296 297 } 298 | Popular Tags |