blob: 11a2ffc4a8de146e5e287061033f09fdbf8a9721 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}
}
}
}