1 19 20 package org.netbeans.modules.registry.mergedctx; 21 22 import org.netbeans.api.registry.*; 23 import org.netbeans.spi.registry.BasicContext; 24 import org.netbeans.spi.registry.ResettableContext; 25 import org.netbeans.spi.registry.SpiUtils; 26 import org.openide.util.NbBundle; 27 28 import javax.swing.event.EventListenerList ; 29 import java.util.ArrayList ; 30 import java.util.Collection ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 34 35 class BasicContextImpl implements ResettableContext { 36 private MergedDelegates contextDelegates; 37 38 final private EventListenerList listeners = new EventListenerList (); 39 final private EventDispatcher dispatcher = new EventDispatcher(); 40 41 protected BasicContextImpl() {} 42 43 private BasicContextImpl(final MergedDelegates ctxDelegates) { 44 contextDelegates = ctxDelegates; 45 } 46 47 48 public final boolean hasDefault(final String bindingName) { 49 final BasicContext[] notMaskedDelegates = getAllDelegates(); 50 return (notMaskedDelegates == null) ? true : getContextDelegates().hasDefault(bindingName, notMaskedDelegates); 51 } 52 53 public final boolean isModified(final String bindingName) { 54 boolean isOnActive = false; 55 final boolean hasDefault = hasDefault(bindingName); 56 57 if (hasDefault) { 58 try { 59 if (getContextDelegates().getActiveDelegate(false) != null) { 60 isOnActive = (bindingName == null) ? true : getContextDelegates().getActiveDelegate(false).lookupObject(bindingName) != null; 61 MaskUtils.deleteMaskForBinding(getContextDelegates().getActiveDelegate(false), bindingName); 62 } 63 } catch (ContextException e) { 64 isOnActive = false; 65 } 66 } 67 68 return ((hasDefault && isOnActive) || !hasDefault); 69 } 70 71 public final void revert(final String bindingName) throws ContextException { 72 if (isModified(bindingName)) { 73 final boolean hasDefault = hasDefault(bindingName); 74 75 76 final BasicContext activeOrMerged = (!hasDefault) ? this : getContextDelegates().getActiveDelegate(false); 77 78 if (bindingName != null && activeOrMerged != null) { 79 activeOrMerged.bindObject(bindingName, null); 80 if (hasDefault) MaskUtils.deleteMaskForBinding(activeOrMerged, bindingName); 81 } 82 83 if (bindingName == null && activeOrMerged != null) { 84 destroyContent(activeOrMerged); 85 } 86 } 87 } 88 89 public final String getContextName() { 90 return getAbsolutePath().getName(); 91 } 92 93 public final BasicContext getSubcontext(final String subcontextName) { 94 BasicContextImpl retVal; 95 final Cache cache = getRootContextImpl().getCache(); 96 97 synchronized (cache.getContextSync()) { 98 final Resource absolutePath1 = getAbsolutePath().getChild(subcontextName); 99 retVal = cache.getContext(absolutePath1); 100 101 if (retVal == null) { 102 final MergedDelegates delegs = getContextDelegates().createChild(subcontextName); 103 if (delegs != null) delegs.init(); 104 retVal = (delegs != null) ? new BasicContextImpl(delegs) : null; 105 if (retVal != null) cache.cacheContext(retVal); 106 } 107 } 108 return retVal; 109 } 110 111 public final BasicContext getParentContext() { 112 BasicContextImpl retVal = null; 113 final Cache cache = getRootContextImpl().getCache(); 114 115 if (!getAbsolutePath().isRoot()) { 116 final Resource parent = getAbsolutePath().getParent(); 117 if (parent == null || !parent.isRoot()) { 118 synchronized (cache.getContextSync()) { 119 final Resource absolutePath1 = getAbsolutePath().getParent(); 120 retVal = cache.getContext(absolutePath1); 121 122 if (retVal == null) { 123 final MergedDelegates delegs = getContextDelegates().createParent(); 124 if (delegs != null) delegs.init(); 125 retVal = (delegs != null) ? new BasicContextImpl(delegs) : null; 126 if (retVal != null) cache.cacheContext(retVal); 127 } 128 } 129 } else { 130 retVal = getRootContextImpl(); 131 } 132 } 133 134 return retVal; 135 } 136 137 public final BasicContext createSubcontext(final String subcontextName) throws ContextException { 138 validityTest(); 139 BasicContext retVal = getSubcontext(subcontextName); 140 141 if (retVal != null) { 142 143 String msg = NbBundle.getMessage(BasicContextImpl.class, 144 "Subcontext_Exists_Exception", subcontextName, getAbsolutePath().getPath()); throw SpiUtils.createContextException(this, msg); 146 } 147 148 getContextDelegates().createSubcontext(subcontextName); 149 retVal = getSubcontext(subcontextName); 150 151 if (retVal == null) { 152 153 String msg = NbBundle.getMessage(BasicContextImpl.class, 154 "Subcontext_Not_Created_Exception", subcontextName, getAbsolutePath().getPath()); throw SpiUtils.createContextException(this, msg); 156 } 157 158 return retVal; 159 } 160 161 public final void destroySubcontext(final String subcontextName) throws ContextException { 162 validityTest(); 163 final BasicContextImpl deletedSubctx = (BasicContextImpl) getSubcontext(subcontextName); 164 165 if (deletedSubctx == null) { 166 167 String msg = NbBundle.getMessage(BasicContextImpl.class, 168 "Subcontext_Not_Exist_Exception", subcontextName, getAbsolutePath().getPath()); throw SpiUtils.createContextException(this, msg); 170 } 171 172 final Collection subOrdered = getRootContextImpl().getCache().existingSubcontexts(deletedSubctx); 173 for (Iterator iterator = subOrdered.iterator(); iterator.hasNext();) { 174 final BasicContextImpl subCtx = (BasicContextImpl) iterator.next(); 175 final BasicContext activeDelegate = subCtx.getContextDelegates().getActiveDelegate(true); 176 177 MergedDelegates.destroyActiveDelegate(activeDelegate); 178 } 179 } 180 181 public final Collection getSubcontextNames() { 182 return getContextDelegates().getSubcontextNames(); 183 } 184 185 public final Collection getBindingNames() { 186 return getContextDelegates().getBindingNames(); 187 } 188 189 public final Collection getAttributeNames(final String bindingName) { 190 return getContextDelegates().getAttributeNames(bindingName); 191 } 192 193 public final Object lookupObject(final String bindingName) throws ContextException { 194 final Object retVal = getContextDelegates().lookupObject(bindingName); 195 getRootContextImpl().getCache().cacheObjectRef(getRootContextImpl(), this, bindingName, retVal); 196 197 return retVal; 198 } 199 200 public final void bindObject(final String bindingName, final Object object) throws ContextException { 201 getContextDelegates().bindObject(bindingName, object); 202 if (object == null) { 203 getRootContextImpl().getCache().removeObjectRef(object); 204 } else { 205 getRootContextImpl().getCache().cacheObjectRef(getRootContextImpl(), this, bindingName, object); 206 } 207 } 208 209 public final String getAttribute(final String bindingName, final String attributeName) throws ContextException { 210 return getContextDelegates().getAttribute(bindingName, attributeName); 211 } 212 213 public final void setAttribute(final String bindingName, final String attributeName, final String value) throws ContextException { 214 final Object binding = (bindingName != null) ? lookupObject(bindingName) : null; 215 if (binding == null && bindingName != null) { 216 String msg = NbBundle.getMessage(BasicContextImpl.class, 217 "Binding_Not_Exist_Exception", attributeName, bindingName, getAbsolutePath().getPath()); throw SpiUtils.createContextException(this, msg); 219 } 220 221 final String originalValue = getAttribute(bindingName, attributeName); 222 if (originalValue == value) return; 223 224 getContextDelegates().setAttribute(bindingName, binding, attributeName, value); 225 } 226 227 public final void addContextListener(final ContextListener listener) { 228 synchronized (listeners) { 229 listeners.add(ContextListener.class, listener); 230 } 231 getCopyOfCtxListeners(); 232 233 } 234 235 public final void removeContextListener(final ContextListener listener) { 236 synchronized (listeners) { 237 listeners.remove(ContextListener.class, listener); 238 } 239 } 240 241 private List getCopyOfCtxListeners() { 242 final ArrayList ctxListeners = new ArrayList (); 243 synchronized (listeners) { 244 if (listeners.getListenerCount() > 0) { 245 final Object [] l = listeners.getListenerList(); 246 for (int i = l.length - 2; i >= 0; i -= 2) { 247 ctxListeners.add(l[i + 1]); 248 } 249 } 250 } 251 return ctxListeners; 252 } 253 254 final Resource getAbsolutePath() { 255 return getContextDelegates().getAbsolutePath(); 256 } 257 258 259 protected final MergedDelegates getContextDelegates() { 260 return contextDelegates; 261 } 262 263 void setContextDelegates(final MergedDelegates contextDelegates) { 264 if (contextDelegates != null && this.contextDelegates != contextDelegates) { 265 if (this.contextDelegates != null) { 266 this.contextDelegates.setDelegates(getDispatcher(), contextDelegates); 267 } else { 268 this.contextDelegates = contextDelegates; 269 } 270 } 271 } 272 273 final boolean isInvalid() { 274 return (getRootContextImpl().getCache().getContext(getAbsolutePath()) == null); 275 } 276 277 public BasicContext getRootContext() { 278 return getRootContextImpl(); 279 } 280 281 private RootContextImpl getRootContextImpl() { 282 return getContextDelegates().getRootContext(); 283 } 284 285 private void validityTest() throws ContextException { 286 if (isInvalid()) { 287 String msg = NbBundle.getMessage(BasicContextImpl.class, 288 "Invalid_Context_Exception", getAbsolutePath().getPath()); throw SpiUtils.createContextException(this, msg); 290 } 291 } 292 293 static private void destroyContent(final BasicContext activeOrMerged) throws ContextException { 294 295 final Collection sNames = activeOrMerged.getSubcontextNames(); 296 for (Iterator iterator1 = sNames.iterator(); iterator1.hasNext();) { 297 final String sName = (String ) iterator1.next(); 298 activeOrMerged.destroySubcontext(sName); 299 } 300 301 302 final Collection bNames = activeOrMerged.getBindingNames(); 303 for (Iterator iterator = bNames.iterator(); iterator.hasNext();) { 304 final String bName = (String ) iterator.next(); 305 final Collection aNames = activeOrMerged.getAttributeNames(bName); 306 307 308 for (Iterator iterator2 = aNames.iterator(); iterator2.hasNext();) { 309 final String aName = (String ) iterator2.next(); 310 activeOrMerged.setAttribute(bName, aName, null); 311 } 312 activeOrMerged.bindObject(bName, null); 313 } 314 } 315 316 320 private BasicContext[] getAllDelegates() { 321 final BasicContext[] notMaskedDelegates; 322 final BasicContextImpl parentContext = ((BasicContextImpl) getParentContext()); 323 324 if (parentContext != null) { 325 notMaskedDelegates = parentContext.getContextDelegates().getSubcontexts(getContextName(), false); 326 } else 327 notMaskedDelegates = getRootContextImpl().getContextDelegates().getDelegates(); 328 return notMaskedDelegates; 329 } 330 331 final EventDispatcher getDispatcher() { 332 return dispatcher; 333 } 334 335 final class EventDispatcher { 336 public final String toString() { 338 return (Integer.toString(System.identityHashCode(this)) + " | " + Integer.toString(System.identityHashCode(BasicContextImpl.this))); 339 } 340 341 final void fireSubcontextEvent(final String name, final int eventType) { 342 Resource res = getAbsolutePath(); 343 SubcontextEvent se = SpiUtils.createSubcontextEvent(BasicContextImpl.this, name, eventType); 344 se = (se.getSource() == this) ? se : 345 SpiUtils.createSubcontextEvent(BasicContextImpl.this, se.getSubcontextName(), se.getType()); 346 347 final List thisListeners = getCopyOfCtxListeners(); 348 for (int i = 0; i < thisListeners.size(); i++) { 349 final ContextListener ctxListener = (ContextListener) thisListeners.get(i); 350 ctxListener.subcontextChanged(se); 351 } 352 353 while (!res.isRoot()) { 355 res = res.getParent(); 356 final BasicContextImpl parent = getRootContextImpl().getCache().getContext(res); 357 358 if (parent != null) { 359 final List parentListeners = parent.getCopyOfCtxListeners(); 360 for (int i = 0; i < parentListeners.size(); i++) { 361 final ContextListener ctxListener = (ContextListener) parentListeners.get(i); 362 ctxListener.subcontextChanged(se); 363 } 364 } 365 } 366 } 367 368 final void fireAttributeEvent(final String bindingName, final String name, final int eventType) { 369 AttributeEvent ae = SpiUtils.createAttributeEvent(BasicContextImpl.this, bindingName, name, eventType); 370 371 Resource res = getAbsolutePath(); 372 ae = (ae.getSource() == this) ? ae : 373 SpiUtils.createAttributeEvent(BasicContextImpl.this, ae.getBindingName(), ae.getAttributeName(), ae.getType()); 374 375 final List thisListeners = getCopyOfCtxListeners(); 376 for (int i = 0; i < thisListeners.size(); i++) { 377 final ContextListener ctxListener = (ContextListener) thisListeners.get(i); 378 ctxListener.attributeChanged(ae); 379 } 380 381 while (!res.isRoot()) { 383 res = res.getParent(); 384 final BasicContextImpl parent = getRootContextImpl().getCache().getContext(res); 385 386 if (parent != null) { 387 final List parentListeners = parent.getCopyOfCtxListeners(); 388 for (int i = 0; i < parentListeners.size(); i++) { 389 final ContextListener ctxListener = (ContextListener) parentListeners.get(i); 390 ctxListener.attributeChanged(ae); 391 } 392 } 393 } 394 } 395 396 397 final void fireBindingEvent(final String name, final int eventType) { 398 Resource res = getAbsolutePath(); 399 BindingEvent be = SpiUtils.createBindingEvent(BasicContextImpl.this, name, eventType); 400 be = (be.getSource() == this) ? be : 401 SpiUtils.createBindingEvent(BasicContextImpl.this, be.getBindingName(), be.getType()); 402 403 final List thisListeners = getCopyOfCtxListeners(); 404 for (int i = 0; i < thisListeners.size(); i++) { 405 final ContextListener ctxListener = (ContextListener) thisListeners.get(i); 406 ctxListener.bindingChanged(be); 407 } 408 409 while (!res.isRoot()) { 411 res = res.getParent(); 412 final BasicContextImpl parent = getRootContextImpl().getCache().getContext(res); 413 414 if (parent != null) { 415 final List parentListeners = parent.getCopyOfCtxListeners(); 416 for (int i = 0; i < parentListeners.size(); i++) { 417 final ContextListener ctxListener = (ContextListener) parentListeners.get(i); 418 ctxListener.bindingChanged(be); 419 } 420 } 421 } 422 } 423 424 } 425 } 426 | Popular Tags |