package com.sap.emf.bundlelistener;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.ContributorFactoryOSGi;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IContributor;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
public class EMFBundleListener extends Plugin implements BundleListener {
private static final String PLUGIN_ID = "com.sap.emf.bundlelistener";
private static final String EXTENSION_POINT_ID = "emf_bundle_listener";
private static final String EXTENSION_CLASS_PROPERTY_NAME = "classname";
private static EMFBundleListener instance;
private static BundleContext context;
private Collection<EcorePackageLoadListener> listeners;
static BundleContext getContext() {
return context;
}
/*
* (non-Javadoc)
*
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
@Override
public void start(BundleContext bundleContext) throws Exception {
EMFBundleListener.context = bundleContext;
instance = this;
bundleContext.addBundleListener(this);
}
/*
* (non-Javadoc)
*
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
@Override
public void stop(BundleContext bundleContext) throws Exception {
EMFBundleListener.context = null;
}
/**
* Returns a started instance of this bundle's activator or <code>null</code> in case
* we're not running in an OSGi environment.
*
* @return May return <code>null</code>, e.g., in case this class runs outside of an OSGi environment
*/
public static EMFBundleListener getDefault() {
return instance;
}
@Override
public void bundleChanged(BundleEvent event) {
if (event.getType() == BundleEvent.STARTED) {
Collection<String> contributedPackageURIs = getContributedEcorePackageURIs(event.getBundle());
if (listeners == null && !contributedPackageURIs.isEmpty()) {
listeners = loadListeners(context);
}
for (String nsURI : contributedPackageURIs) {
for (EcorePackageLoadListener listener : listeners) {
listener.packageLoaded(nsURI);
}
}
}
}
/**
* @return a non-<code>null</code> collection
*/
private Collection<String> getContributedEcorePackageURIs(Bundle bundle) {
Set<String> packageURIs = new HashSet<String>();
addGeneratedPackageNames(bundle, packageURIs);
return packageURIs;
}
private void addGeneratedPackageNames(Bundle bundle, Set<String> packageURIs) {
IExtensionRegistry registry = Platform.getExtensionRegistry();
IContributor contributor = ContributorFactoryOSGi.createContributor(bundle);
IExtension[] extensions = registry.getExtensions(contributor);
if (extensions != null) {
for (IExtension extension : extensions) {
if ("org.eclipse.emf.ecore.generated_package".equals(extension.getExtensionPointUniqueIdentifier())) {
IConfigurationElement[] configurationElements = extension.getConfigurationElements();
for (IConfigurationElement configurationElement : configurationElements) {
packageURIs.add(configurationElement.getAttribute("uri"));
}
}
}
}
}
/**
* Retrieve all listeners (and as a side-effect, force their bundles to load)
*/
private static Collection<EcorePackageLoadListener> loadListeners(BundleContext bundleContext) {
Collection<EcorePackageLoadListener> listeners = new HashSet<EcorePackageLoadListener>();
IExtensionRegistry registry = Platform.getExtensionRegistry();
for (IConfigurationElement listenerConfig : registry.getConfigurationElementsFor(bundleContext.getBundle()
.getSymbolicName() + "." + EXTENSION_POINT_ID)) {
try {
EcorePackageLoadListener listener = (EcorePackageLoadListener) listenerConfig
.createExecutableExtension(EXTENSION_CLASS_PROPERTY_NAME);
listeners.add(listener);
} catch (CoreException e) {
getDefault().getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK,
"Failed to load EcorePackageLoadListeners", e));
}
}
return listeners;
}
}