1 11 package org.eclipse.core.runtime.dynamichelpers; 12 13 import java.util.HashMap ; 14 import java.util.Map ; 15 import org.eclipse.core.internal.registry.RegistryMessages; 16 import org.eclipse.core.internal.runtime.ReferenceHashSet; 17 import org.eclipse.core.internal.runtime.RuntimeLog; 18 import org.eclipse.core.runtime.IExtension; 19 import org.eclipse.core.runtime.IExtensionDelta; 20 import org.eclipse.core.runtime.IExtensionPoint; 21 import org.eclipse.core.runtime.IExtensionRegistry; 22 import org.eclipse.core.runtime.IRegistryChangeEvent; 23 import org.eclipse.core.runtime.IRegistryChangeListener; 24 import org.eclipse.core.runtime.IStatus; 25 import org.eclipse.core.runtime.ListenerList; 26 import org.eclipse.core.runtime.RegistryFactory; 27 import org.eclipse.core.runtime.Status; 28 29 37 public class ExtensionTracker implements IExtensionTracker, IRegistryChangeListener { 38 private Map extensionToObjects = new HashMap (); 40 private ListenerList handlers = new ListenerList(); 41 private final Object lock = new Object (); 42 private boolean closed = false; 43 private IExtensionRegistry registry; 45 private static final Object [] EMPTY_ARRAY = new Object [0]; 46 47 50 public ExtensionTracker() { 51 this(RegistryFactory.getRegistry()); 52 } 53 54 61 public ExtensionTracker(IExtensionRegistry theRegistry) { 62 registry = theRegistry; 63 if (registry != null) 64 registry.addRegistryChangeListener(this); 65 else 66 RuntimeLog.log(new Status(IStatus.ERROR, RegistryMessages.OWNER_NAME, 0, RegistryMessages.registry_no_default, null)); 67 } 68 69 72 public void registerHandler(IExtensionChangeHandler handler, IFilter filter) { 73 synchronized (lock) { 74 if (closed) 75 return; 76 handlers.add(new HandlerWrapper(handler, filter)); 78 } 79 } 80 81 84 public void unregisterHandler(IExtensionChangeHandler handler) { 85 synchronized (lock) { 86 if (closed) 87 return; 88 handlers.remove(new HandlerWrapper(handler, null)); 89 } 90 } 91 92 95 public void registerObject(IExtension element, Object object, int referenceType) { 96 if (element == null || object == null) 97 return; 98 99 synchronized (lock) { 100 if (closed) 101 return; 102 103 ReferenceHashSet associatedObjects = (ReferenceHashSet) extensionToObjects.get(element); 104 if (associatedObjects == null) { 105 associatedObjects = new ReferenceHashSet(); 106 extensionToObjects.put(element, associatedObjects); 107 } 108 associatedObjects.add(object, referenceType); 109 } 110 } 111 112 118 public void registryChanged(IRegistryChangeEvent event) { 119 IExtensionDelta delta[] = event.getExtensionDeltas(); 120 int len = delta.length; 121 for (int i = 0; i < len; i++) 122 switch (delta[i].getKind()) { 123 case IExtensionDelta.ADDED : 124 doAdd(delta[i]); 125 break; 126 case IExtensionDelta.REMOVED : 127 doRemove(delta[i]); 128 break; 129 default : 130 break; 131 } 132 } 133 134 143 private void notify(IExtensionDelta delta, Object [] objects) { 144 Object [] handlersCopy = null; 146 synchronized (lock) { 147 if (closed) 148 return; 149 150 if (handlers == null || handlers.isEmpty()) 151 return; 152 handlersCopy = handlers.getListeners(); 153 } 154 155 for (int i = 0; i < handlersCopy.length; i++) { 156 HandlerWrapper wrapper = (HandlerWrapper) handlersCopy[i]; 157 if (wrapper.filter == null || wrapper.filter.matches(delta.getExtensionPoint())) { 158 if (objects == null) 159 applyAdd(wrapper.handler, delta.getExtension()); 160 else 161 applyRemove(wrapper.handler, delta.getExtension(), objects); 162 } 163 } 164 } 165 166 protected void applyAdd(IExtensionChangeHandler handler, IExtension extension) { 167 handler.addExtension(this, extension); 168 } 169 170 private void doAdd(IExtensionDelta delta) { 171 notify(delta, null); 172 } 173 174 private void doRemove(IExtensionDelta delta) { 175 Object [] removedObjects = null; 176 synchronized (lock) { 177 if (closed) 178 return; 179 180 ReferenceHashSet associatedObjects = (ReferenceHashSet) extensionToObjects.remove(delta.getExtension()); 181 if (associatedObjects == null) 182 return; 183 removedObjects = associatedObjects.toArray(); 185 } 186 notify(delta, removedObjects); 187 } 188 189 protected void applyRemove(IExtensionChangeHandler handler, IExtension removedExtension, Object [] removedObjects) { 190 handler.removeExtension(removedExtension, removedObjects); 191 } 192 193 196 public Object [] getObjects(IExtension element) { 197 synchronized (lock) { 198 if (closed) 199 return EMPTY_ARRAY; 200 ReferenceHashSet objectSet = (ReferenceHashSet) extensionToObjects.get(element); 201 if (objectSet == null) 202 return EMPTY_ARRAY; 203 204 return objectSet.toArray(); 205 } 206 } 207 208 211 public void close() { 212 synchronized (lock) { 213 if (closed) 214 return; 215 if (registry != null) 216 registry.removeRegistryChangeListener(this); 217 extensionToObjects = null; 218 handlers = null; 219 220 closed = true; 221 } 222 } 223 224 227 public void unregisterObject(IExtension extension, Object object) { 228 synchronized (lock) { 229 if (closed) 230 return; 231 ReferenceHashSet associatedObjects = (ReferenceHashSet) extensionToObjects.get(extension); 232 if (associatedObjects != null) 233 associatedObjects.remove(object); 234 } 235 } 236 237 240 public Object [] unregisterObject(IExtension extension) { 241 synchronized (lock) { 242 if (closed) 243 return EMPTY_ARRAY; 244 ReferenceHashSet associatedObjects = (ReferenceHashSet) extensionToObjects.remove(extension); 245 if (associatedObjects == null) 246 return EMPTY_ARRAY; 247 return associatedObjects.toArray(); 248 } 249 } 250 251 257 public static IFilter createExtensionPointFilter(final IExtensionPoint xpt) { 258 return new IFilter() { 259 public boolean matches(IExtensionPoint target) { 260 return xpt.equals(target); 261 } 262 }; 263 } 264 265 271 public static IFilter createExtensionPointFilter(final IExtensionPoint[] xpts) { 272 return new IFilter() { 273 public boolean matches(IExtensionPoint target) { 274 for (int i = 0; i < xpts.length; i++) 275 if (xpts[i].equals(target)) 276 return true; 277 return false; 278 } 279 }; 280 } 281 282 288 public static IFilter createNamespaceFilter(final String id) { 289 return new IFilter() { 290 public boolean matches(IExtensionPoint target) { 291 return id.equals(target.getNamespaceIdentifier()); 292 } 293 }; 294 } 295 296 private class HandlerWrapper { 297 IExtensionChangeHandler handler; 298 IFilter filter; 299 300 public HandlerWrapper(IExtensionChangeHandler handler, IFilter filter) { 301 this.handler = handler; 302 this.filter = filter; 303 } 304 305 public boolean equals(Object target) { 306 return handler.equals(((HandlerWrapper) target).handler); 307 } 308 309 public int hashCode() { 310 return handler.hashCode(); 311 } 312 } 313 314 } 315 | Popular Tags |