1 19 20 package org.netbeans.core.registry; 21 22 import org.netbeans.api.registry.BindingEvent; 23 import org.netbeans.api.registry.Context; 24 import org.netbeans.api.registry.ContextException; 25 import org.netbeans.spi.registry.BasicContext; 26 import org.netbeans.spi.registry.SpiUtils; 27 import org.openide.ErrorManager; 28 import org.openide.filesystems.FileObject; 29 import org.openide.filesystems.FileSystem; 30 31 import java.io.IOException ; 32 import java.util.*; 33 34 38 class ContextBindings { 39 40 private FileObject folder; 42 43 private BasicContext ctx; 45 46 private FileObject defFO; 49 private FileObject custFO; 50 private FileSystem defFS; 51 private FileSystem custFS; 52 53 static FileSystem.AtomicAction referenceAction = new RegistryAtomicAction () { 55 public void run() throws IOException { 56 } 57 }; 58 59 public static final String PRIMITIVE_BINDING_PREFIX = "BINDING:"; 60 61 private Map bindings = new HashMap(); 63 64 private ContextBindings(FileObject folder, BasicContext ctx, FileSystem defFS, FileSystem custFS) { 65 this.folder = folder; 66 this.ctx = ctx; 67 this.defFS = defFS; 68 this.custFS= custFS; 69 70 FileObject[] children = this.folder.getChildren(); 71 for (int i=0; i<children.length; i++) { 72 ObjectBinding ob = ObjectBinding.get(this.ctx, children[i]); 73 if (ob != null) { 74 bindings.put(ob.getBindingName(),ob); 75 } 76 } 77 } 78 79 public static ContextBindings createContextBindings(FileObject folder, BasicContext ctx) { 80 return new ContextBindings(folder, ctx, null, null); 81 } 82 83 public static ContextBindings createResettableContextBindings(FileObject folder, BasicContext ctx, FileSystem defaults, FileSystem customizations) { 84 return new ContextBindings(folder, ctx, defaults, customizations); 85 } 86 87 private synchronized FileObject getDefFolder() { 88 if (defFO != null && defFO.isValid()) { 89 return defFO; 90 } 91 defFO = (defFS != null) ? defFS.findResource(folder.getPath()) : null; 92 return defFO; 93 } 94 95 private synchronized FileObject getCustFolder() { 96 if (custFO != null && custFO.isValid()) { 97 return custFO; 98 } 99 custFO = custFS.findResource(folder.getPath()); 100 return custFO; 101 } 102 103 void modulesChanged(Collection added, Collection removed) { 105 assert added != null; 106 assert removed != null; 107 Iterator it = added.iterator(); 108 while (it.hasNext()) { 109 processBindingChange(BindingEvent.BINDING_ADDED, it.next()); 110 } 111 it = removed.iterator(); 112 while (it.hasNext()) { 113 processBindingChange(BindingEvent.BINDING_REMOVED, it.next()); 114 } 115 } 116 117 private void processBindingChange(int eventType, Object moduleDescriptor) { 118 Iterator it = bindings.values().iterator(); 119 while (it.hasNext()) { 120 ObjectBinding ob = (ObjectBinding)it.next(); 121 if (ob.getModuleDescriptor().equals(moduleDescriptor)) { 122 fireBindingEvent(ob.getBindingName(), eventType); 123 } 124 } 125 } 126 127 128 private void fireBindingEvent(String bindingName, int eventType) { 129 BindingEvent be = SpiUtils.createBindingEvent(ctx, bindingName, eventType); 130 FileSystemListener.fireContextEvent(((ContextImpl)ctx).getRootContextImpl(), folder, be); 132 } 133 134 135 142 boolean isRelevantChange(FileObject fo, boolean removed) { 143 if (!removed) { 144 ObjectBinding ob = findObjectBinding(fo.getName()); 145 if (ob != null) { 146 return true; 147 } else { 148 ob = ObjectBinding.get(ctx, fo); 149 if (ob != null) { 150 bindings.put(ob.getBindingName(), ob); 151 return true; 152 } else { 153 return false; 154 } 155 } 156 } else { 157 ObjectBinding ob = findObjectBinding(fo.getName()); 158 if (ob != null) { 159 bindings.remove(fo.getName()); 160 return true; 161 } else { 162 return false; 163 } 164 } 165 } 166 167 168 170 171 180 public void bindObject(final String bindingName, final Object object) throws ContextException { 181 try { 182 folder.getFileSystem().runAtomicAction(new RegistryAtomicAction () { 183 public void run() throws IOException { 184 doBindObject(bindingName, object); 185 } 186 }); 187 } catch (IOException ex) { 188 ContextException ce = SpiUtils.createContextException(ctx, "Error on underlaying filesystem occured."); 189 ErrorManager.getDefault().annotate(ce, ex); 190 throw ce; 191 } 192 } 193 194 private void doBindObject(String bindingName, Object object) throws IOException { 195 if (object == null) { 196 ObjectBinding[] ob = new ObjectBinding[] {findObjectBinding(bindingName), PrimitiveBinding.get(folder, bindingName)}; 197 for (int i = 0; i < ob.length; i++) { 198 ObjectBinding objectBinding = ob[i]; 199 if (objectBinding != null ) { 200 objectBinding.delete(); 201 } 202 } 203 bindings.remove(bindingName); 204 } else { 205 boolean isPrimitive = PrimitiveBinding.isPrimitive(object); 206 ObjectBinding toDelete = isPrimitive ? findObjectBinding(bindingName) : PrimitiveBinding.get(folder, bindingName); 207 if (toDelete != null) toDelete.delete(); 208 bindings.remove(bindingName); 209 210 ObjectBinding toCreate = PrimitiveBinding.create(folder, bindingName, object); 211 if (toCreate == null) { 212 toCreate = ObjectBinding.write (ctx, folder, bindingName, object); 213 bindings.put(bindingName, toCreate); 214 } 215 } 216 } 217 218 public Object lookupObject(String bindingName) throws ContextException { 219 Object o = getBindingFromCache(bindingName); 220 if (o != null) return o; 221 222 try { 223 ObjectBinding[] ob = new ObjectBinding[] {findObjectBinding(bindingName), PrimitiveBinding.get(folder, bindingName)}; 224 for (int i = 0; i < ob.length; i++) { 225 ObjectBinding objectBinding = ob[i]; 226 if (objectBinding != null && objectBinding.isEnabled() ) { 227 o = objectBinding.getObject(); 228 } 229 } 230 231 return o; 232 } catch (IOException e) { 233 ContextException ce = SpiUtils.createContextException(ctx, e.getLocalizedMessage()); 234 ObjectBinding.getErrorManager().annotate(ce,e); 235 throw ce; 236 } 237 } 238 239 private Object getBindingFromCache(String bindingName) throws ContextException { 240 Object o = null; 241 ObjectBinding ob1 = (ObjectBinding)bindings.get(bindingName); 242 if (ob1 != null && ob1.isEnabled()) { 243 try { 244 o = ob1.getObject(); 245 } catch (IOException e) { 246 ContextException ce = SpiUtils.createContextException(ctx,e.getLocalizedMessage()); 247 ObjectBinding.getErrorManager().annotate(ce, e); 248 throw ce; 249 } 250 } 251 return o; 252 } 253 254 private ObjectBinding findObjectBinding(String bindingName) { 255 Iterator it = bindings.values().iterator(); 256 while (it.hasNext()) { 257 ObjectBinding ob = (ObjectBinding)it.next(); 258 if (ob.getBindingName().equals(bindingName)) { 259 return ob; 260 } 261 } 262 return null; 263 } 264 265 public Collection getNames() { 266 Set retVal = new HashSet(); 267 268 Set obMerged = new HashSet (); 269 obMerged.addAll(bindings.values()); 270 obMerged.addAll (PrimitiveBinding.getAll(folder)); 271 272 for (Iterator iterator = obMerged.iterator(); iterator.hasNext();) { 273 ObjectBinding ob = (ObjectBinding) iterator.next(); 274 if (ob != null && ob.isEnabled()) retVal.add(ob.getBindingName()); 275 } 276 277 return retVal; 278 } 279 280 public boolean hasDefault(String bindingName) { 281 assert bindingName != null; 282 boolean retVal = false; 283 284 FileObject defF = getDefFolder(); 285 if (defF != null) { 286 retVal = (findBindingFile(defF, bindingName) != null || PrimitiveBinding.get(defF, bindingName) != null); 287 } 288 289 return retVal; 290 } 291 292 private static FileObject findBindingFile(FileObject folder, String bindingName) { 293 FileObject fo = null; 294 Collection exts = ObjectBinding.getFileExtensions(); 295 for (Iterator iterator = exts.iterator(); iterator.hasNext();) { 296 String ext = (String ) iterator.next(); 297 fo = folder.getFileObject(bindingName, ext); 298 if (fo != null) break; 299 } 300 return fo; 301 } 302 303 304 public boolean isModified(String bindingName) { 305 assert bindingName != null; 306 if (custFS == null) { 307 return false; 308 } 309 FileObject custF = getCustFolder(); 310 if (custF == null) { 311 return PrimitiveBinding.isCustomizedAndAttachedToRoot(custFS, folder, bindingName) ? true : false; 315 } 316 317 return (findBindingFile(custF, bindingName) != null || PrimitiveBinding.get(custF, bindingName) != null); 318 } 319 320 public void revert(final String bindingName) throws ContextException { 321 try { 323 folder.getFileSystem().runAtomicAction(new RegistryAtomicAction () { 324 public void run() throws IOException { 325 doRevert(bindingName); 326 } 327 }); 328 } catch (IOException ex) { 329 ContextException ce = SpiUtils.createContextException(ctx, "Error on underlaying filesystem occured."); 330 ErrorManager.getDefault().annotate(ce, ex); 331 throw ce; 332 } 333 } 334 335 private void doRevert(String bindingName) throws IOException { 336 assert bindingName != null; 337 if (isModified(bindingName)) { 338 FileObject custF = getCustFolder(); 339 if (custF != null) { 340 ObjectBinding ob = PrimitiveBinding.get(custF, bindingName); 341 if (ob == null) ob = ObjectBinding.get(ctx, findBindingFile(custF, bindingName)); 342 if (ob != null) ob.delete(); 343 bindings.remove(bindingName); 344 removeMaskFile(custF, bindingName); 345 346 ob = ObjectBinding.get(ctx, findBindingFile(folder, bindingName)); 349 if (ob != null) bindings.put(ob.getBindingName(), ob); 350 } else { 351 PrimitiveBinding.deleteIfCustomizedAndAttachedToRoot(custFS, folder, bindingName); 356 } 357 } 358 } 359 360 private static void removeMaskFile(FileObject folder, String name) throws IOException { 361 Enumeration en = folder.getChildren(false); 362 while (en.hasMoreElements()) { 363 FileObject fo = (FileObject)en.nextElement(); 364 if (fo.getName().equals(name) && fo.getExt().endsWith("_hidden")) { 365 fo.delete(); 366 break; 367 } 368 } 369 } 370 371 public boolean existBinding(String bindingName) { 372 return (findObjectBinding(bindingName) != null || PrimitiveBinding.get(folder, bindingName) != null); 373 } 374 375 376 public FileObject getBindingFile(String bindingName) { 377 ObjectBinding ob = findObjectBinding(bindingName); 378 if (ob == null) { 379 return null; 380 } 381 if (!ob.isEnabled()) { 382 return null; 383 } 384 return ob.getFile(); 385 } 386 387 public boolean isBindingFile(FileObject fo) { 388 Iterator it = bindings.values().iterator(); 389 while (it.hasNext()) { 390 ObjectBinding ob = (ObjectBinding)it.next(); 391 if (fo.equals(ob.getFile())) { 392 return true; 393 } 394 } 395 return false; 396 } 397 private static abstract class RegistryAtomicAction implements FileSystem.AtomicAction { 398 public boolean equals(Object obj) { 399 return (obj instanceof RegistryAtomicAction); 400 } 401 402 public int hashCode() { 403 return RegistryAtomicAction.class.hashCode(); 404 } 405 } 406 } 407 | Popular Tags |