1 19 package org.netbeans.modules.registry.mergedctx; 20 21 import org.netbeans.api.registry.*; 22 import org.netbeans.spi.registry.BasicContext; 23 import org.netbeans.spi.registry.MergedContextProvider; 24 import org.netbeans.spi.registry.SpiUtils; 25 import org.openide.util.Mutex; 26 import org.openide.util.WeakListeners; 27 28 import java.beans.PropertyChangeEvent ; 29 import java.beans.PropertyChangeListener ; 30 import java.util.ArrayList ; 31 import java.util.Arrays ; 32 import java.util.Iterator ; 33 import java.util.List ; 34 35 public final class RootContextImpl extends BasicContextImpl { 36 private final Mutex.Privileged privilegedMutex = new Mutex.Privileged(); 37 private final Mutex mutex = new Mutex(privilegedMutex); 38 39 private final MergedContextProvider provider; 40 private final Cache cache = new Cache(); 41 42 private final MergeCtxProviderListener mergeCtxProviderListener = new MergeCtxProviderListener();; 43 private ContextListenerImpl[] listeners; 44 45 46 public static final BasicContext create(final MergedContextProvider provider) { 47 return new RootContextImpl(provider); 48 } 49 50 private RootContextImpl(final MergedContextProvider provider) { 51 super(); 52 this.provider = provider; 53 setContextDelegates(provider); 54 getCache().cacheContext(this); 55 this.provider.addPropertyChangeListener( 56 (PropertyChangeListener ) WeakListeners.create(PropertyChangeListener .class, mergeCtxProviderListener, this.provider)); 57 } 58 59 private void setContextDelegates(final MergedContextProvider provider) { 60 final MergedDelegates rootCtxDelegates = MergedDelegates.createRoot(provider.getDelegates(), RootContextImpl.this); 61 if (rootCtxDelegates != null) rootCtxDelegates.init(); 62 if (getContextDelegates() == null && rootCtxDelegates == null) return; 63 removeListeners(); 64 super.setContextDelegates(rootCtxDelegates); 65 addListeners(); 66 67 for (Iterator iterator = getCache().existingSubcontexts(this).iterator(); iterator.hasNext();) { 68 final BasicContextImpl context = (BasicContextImpl) iterator.next(); 69 if (context == this) continue; 70 final MergedDelegates newDelegate = MergedDelegates.createChild(rootCtxDelegates, context.getAbsolutePath()); 71 if (newDelegate != null) { 72 context.setContextDelegates(newDelegate); 73 } else { 74 getCache().removeContext(context.getAbsolutePath()); 75 } 76 } 77 } 78 79 void setContextDelegates(final MergedDelegates contextDelegates) { 80 } 81 82 private synchronized void removeListeners() { 83 if (getContextDelegates() != null) { 84 final BasicContext[] oldDelegates = getContextDelegates().getDelegates(); 85 if (listeners != null && listeners.length == oldDelegates.length) { 86 for (int i = 0; i < oldDelegates.length; i++) { 87 final BasicContext basicContext = oldDelegates[i]; 88 if (basicContext != null && listeners[i] != null) { 89 basicContext.removeContextListener(listeners[i]); 90 } 91 } 92 } 93 } 94 listeners = null; 95 } 96 97 private synchronized void addListeners() { 98 final BasicContext[] newDelegates = getContextDelegates().getDelegates(); 99 if (listeners == null) { 100 final List list = new ArrayList (); 101 for (int layoutIndex = 0; layoutIndex < newDelegates.length; layoutIndex++) { 102 if (newDelegates[layoutIndex] != null) { 103 final String absoluteName = SpiUtils.createContext(newDelegates[layoutIndex]).getAbsoluteContextName(); 104 final ContextListenerImpl l = new ContextListenerImpl(absoluteName); 105 newDelegates[layoutIndex].addContextListener( 106 (ContextListener) WeakListeners.create(ContextListener.class, l, newDelegates[layoutIndex])); 107 list.add(l); 108 } 109 } 110 111 listeners = (ContextListenerImpl[]) list.toArray(new ContextListenerImpl[list.size()]); 112 } 113 } 114 115 public ObjectRef findObject(final Object object) { 116 return cache.getObjectRef(object); 117 } 118 119 public void flush() { 120 } 121 122 public Mutex.Privileged getMutex() { 123 return privilegedMutex; 124 } 125 126 final protected Cache getCache() { 127 return cache; 128 } 129 130 private final class MergeCtxProviderListener implements PropertyChangeListener { 131 public final void propertyChange(final PropertyChangeEvent evt) { 132 setContextDelegates(provider); 133 } 134 } 135 136 137 private final class ContextListenerImpl implements ContextListener { 138 private final String absoluteName; 139 140 private ContextListenerImpl(final String absoluteName) { 141 this.absoluteName = absoluteName; 142 } 143 144 145 public final void subcontextChanged(final SubcontextEvent evt) { 146 147 if (MaskUtils.isMaskForCtxName(evt.getSubcontextName())) { 148 return; 149 } 150 151 final Resource contextPath; 152 contextPath = new Resource(evt.getContext().getAbsoluteContextName().substring(absoluteName.length())); 153 final BasicContextImpl mergedSource = getCache().getContext(contextPath); 154 final BasicContextImpl mergedSubcontext = getCache().getContext(contextPath.getChild(evt.getSubcontextName())); 155 156 if (mergedSubcontext != null) { 157 updateContext(mergedSource, mergedSubcontext, evt); 158 } 159 160 if (mergedSource != null) { 161 if (!mergedSource.isInvalid()) { 162 if (mergedSubcontext != null && !mergedSubcontext.isInvalid()) { 163 final int layout = Arrays.asList(listeners).indexOf(this); 164 mergedSubcontext.getContextDelegates().refreshBindingNames(mergedSubcontext.getDispatcher(), null, layout); 165 mergedSubcontext.getContextDelegates().refreshAttributeNames(mergedSubcontext.getDispatcher(), null, layout); 166 } 167 mergedSource.getContextDelegates().refreshSubcontextNames(mergedSource.getDispatcher()); 168 } 169 } 170 } 171 172 private void updateContext(final BasicContextImpl mergedSource, final BasicContextImpl mergedSubcontext, final SubcontextEvent evt) { 173 BasicContextImpl parent = mergedSource; 174 parent = (parent == null) ? (BasicContextImpl) mergedSubcontext.getParentContext() : parent; 175 if (parent != null) { 176 final MergedDelegates updatedContext = parent.getContextDelegates().createChild(evt.getSubcontextName()); 177 if (updatedContext != null) { 178 mergedSubcontext.setContextDelegates(updatedContext); 179 } else { 180 getCache().removeContext(mergedSubcontext.getAbsolutePath()); 181 } 182 } 183 } 184 185 public final void bindingChanged(final BindingEvent evt) { 186 if (MaskUtils.isMaskForBindingName(evt.getBindingName())) { 187 return; 188 } 189 190 final Resource contextPath; 191 contextPath = new Resource(evt.getContext().getAbsoluteContextName().substring(absoluteName.length())); 192 final BasicContextImpl mergedSource = getCache().getContext(contextPath); 193 194 if (mergedSource != null) { 195 if (!mergedSource.isInvalid()) { 196 final int layout = Arrays.asList(listeners).indexOf(this); 197 mergedSource.getContextDelegates().refreshBindingNames(mergedSource.getDispatcher(), evt, layout); } 199 } 200 } 201 202 public final void attributeChanged(final AttributeEvent evt) { 203 if (MaskUtils.isMaskForAttributeName(evt.getAttributeName())) return; 204 205 final Resource contextPath; 206 contextPath = new Resource(evt.getContext().getAbsoluteContextName().substring(absoluteName.length())); 207 final BasicContextImpl mergedSource = getCache().getContext(contextPath); 208 209 210 if (mergedSource != null) { 211 if (!mergedSource.isInvalid()) { 212 mergedSource.getContextDelegates().refreshAttributeNames(mergedSource.getDispatcher(), evt, Arrays.asList(listeners).indexOf(this)); 213 } 214 } 215 } 216 } 217 218 219 } | Popular Tags |