1 12 13 package org.eclipse.equinox.http.registry.internal; 14 15 import java.util.*; 16 import org.eclipse.core.runtime.*; 17 18 public class ExtensionPointTracker { 19 public interface Listener { 20 public void added(IExtension extension); 21 22 public void removed(IExtension extension); 23 } 24 25 private static final Listener NULL_LISTENER = new Listener() { 26 public void added(IExtension extension) { 27 } 28 29 public void removed(IExtension extension) { 30 } 31 }; 32 33 private final IExtensionRegistry registry; 34 private final String extensionPointId; 35 final String namespace; 36 final String simpleIdentifier; 37 private final Set extensionCache = new HashSet(); 38 protected final Listener listener; 39 private final RegistryChangeListener registryChangeListener = new RegistryChangeListener(); 40 private boolean closed = true; 41 42 public ExtensionPointTracker(IExtensionRegistry registry, String extensionPointId, Listener listener) { 43 this.registry = registry; 44 this.extensionPointId = extensionPointId; 45 this.listener = (listener != null) ? listener : NULL_LISTENER; 46 47 if (extensionPointId == null || -1 == extensionPointId.indexOf('.')) 48 throw new IllegalArgumentException ("Unexpected Extension Point Identifier: " + extensionPointId); int lastDotIndex = extensionPointId.lastIndexOf('.'); 50 namespace = extensionPointId.substring(0, lastDotIndex); 51 simpleIdentifier = extensionPointId.substring(lastDotIndex + 1); 52 } 53 54 public void open() { 55 IExtension[] extensions = null; 56 synchronized (this) { 57 if (!closed) { 58 return; 59 } 60 registry.addRegistryChangeListener(registryChangeListener, namespace); 61 try { 62 IExtensionPoint point = registry.getExtensionPoint(extensionPointId); 63 if (point != null) { 64 extensions = point.getExtensions(); 65 extensionCache.addAll(Arrays.asList(extensions)); 66 } 67 closed = false; 68 } catch (InvalidRegistryObjectException e) { 69 registry.removeRegistryChangeListener(registryChangeListener); 70 throw e; 71 } 72 } 73 if (extensions != null) { 74 for (int i = 0; i < extensions.length; ++i) { 75 listener.added(extensions[i]); 76 } 77 } 78 } 79 80 public void close() { 81 IExtension[] extensions = null; 82 synchronized (this) { 83 if (closed) { 84 return; 85 } 86 closed = true; 87 registry.removeRegistryChangeListener(registryChangeListener); 88 extensions = this.getExtensions(); 89 extensionCache.clear(); 90 } 91 for (int i = 0; i < extensions.length; ++i) { 92 listener.removed(extensions[i]); 93 } 94 } 95 96 synchronized boolean removeExtension(IExtension extension) { 97 if (closed) { 98 return false; 99 } 100 return extensionCache.remove(extension); 101 } 102 103 synchronized boolean addExtension(IExtension extension) { 104 if (closed) { 105 return false; 106 } 107 return extensionCache.add(extension); 108 } 109 110 public synchronized IExtension[] getExtensions() { 111 return (IExtension[]) extensionCache.toArray(new IExtension[extensionCache.size()]); 112 } 113 114 class RegistryChangeListener implements IRegistryChangeListener { 115 public void registryChanged(IRegistryChangeEvent event) { 116 IExtensionDelta[] deltas = event.getExtensionDeltas(namespace, simpleIdentifier); 117 for (int i = 0; i < deltas.length; ++i) { 118 IExtensionDelta delta = deltas[i]; 119 IExtension extension = delta.getExtension(); 120 switch (delta.getKind()) { 121 case IExtensionDelta.ADDED : 122 if (addExtension(extension)) { 123 listener.added(extension); 124 } 125 break; 126 case IExtensionDelta.REMOVED : 127 if (removeExtension(extension)) { 128 listener.removed(extension); 129 } 130 default : 131 break; 132 } 133 } 134 } 135 } 136 } 137 | Popular Tags |