/******************************************************************************* * Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cognos Incorporated - initial API and implementation * IBM Corporation - bug fixes and enhancements *******************************************************************************/ package org.eclipse.equinox.http.registry.internal; import java.util.*; import org.eclipse.core.runtime.*; public class ExtensionPointTracker { public interface Listener { public void added(IExtension extension); public void removed(IExtension extension); } private static final Listener NULL_LISTENER = new Listener() { public void added(IExtension extension) { } public void removed(IExtension extension) { } }; private final IExtensionRegistry registry; private final String extensionPointId; final String namespace; final String simpleIdentifier; private final Set extensionCache = new HashSet(); protected final Listener listener; private final RegistryChangeListener registryChangeListener = new RegistryChangeListener(); private boolean closed = true; public ExtensionPointTracker(IExtensionRegistry registry, String extensionPointId, Listener listener) { this.registry = registry; this.extensionPointId = extensionPointId; this.listener = (listener != null) ? listener : NULL_LISTENER; if (extensionPointId == null || -1 == extensionPointId.indexOf('.')) throw new IllegalArgumentException("Unexpected Extension Point Identifier: " + extensionPointId); //$NON-NLS-1$ int lastDotIndex = extensionPointId.lastIndexOf('.'); namespace = extensionPointId.substring(0, lastDotIndex); simpleIdentifier = extensionPointId.substring(lastDotIndex + 1); } public void open() { IExtension[] extensions = null; synchronized (this) { if (!closed) { return; } registry.addRegistryChangeListener(registryChangeListener, namespace); try { IExtensionPoint point = registry.getExtensionPoint(extensionPointId); if (point != null) { extensions = point.getExtensions(); extensionCache.addAll(Arrays.asList(extensions)); } closed = false; } catch (InvalidRegistryObjectException e) { registry.removeRegistryChangeListener(registryChangeListener); throw e; } } if (extensions != null) { for (int i = 0; i < extensions.length; ++i) { listener.added(extensions[i]); } } } public void close() { IExtension[] extensions = null; synchronized (this) { if (closed) { return; } closed = true; registry.removeRegistryChangeListener(registryChangeListener); extensions = this.getExtensions(); extensionCache.clear(); } for (int i = 0; i < extensions.length; ++i) { listener.removed(extensions[i]); } } synchronized boolean removeExtension(IExtension extension) { if (closed) { return false; } return extensionCache.remove(extension); } synchronized boolean addExtension(IExtension extension) { if (closed) { return false; } return extensionCache.add(extension); } public synchronized IExtension[] getExtensions() { return (IExtension[]) extensionCache.toArray(new IExtension[extensionCache.size()]); } class RegistryChangeListener implements IRegistryChangeListener { public void registryChanged(IRegistryChangeEvent event) { IExtensionDelta[] deltas = event.getExtensionDeltas(namespace, simpleIdentifier); for (int i = 0; i < deltas.length; ++i) { IExtensionDelta delta = deltas[i]; IExtension extension = delta.getExtension(); switch (delta.getKind()) { case IExtensionDelta.ADDED : if (addExtension(extension)) { listener.added(extension); } break; case IExtensionDelta.REMOVED : if (removeExtension(extension)) { listener.removed(extension); } default : break; } } } } }