Skip to content

Content of file ExtensionParser.java

/********************************************************************************
 * Copyright (c) 2011 Eike Stepper (Berlin, Germany) and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * Eike Stepper - initial API and implementation
 ********************************************************************************/
package org.eclipse.emf.ecp.internal.core.util;

import java.io.File;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionDelta;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.IRegistryChangeListener;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecp.spi.core.util.ECPDisposable;
import org.eclipse.emf.ecp.spi.core.util.InternalRegistryElement;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
import org.osgi.framework.Bundle;

/**
 * @author Eike Stepper
 * @param <ELEMENT>
 */
public abstract class ExtensionParser<ELEMENT extends InternalRegistryElement> extends Lifecycle implements
	IRegistryChangeListener {
	private final ElementRegistry<ELEMENT, ?> elementRegistry;

	private final String namespace;

	private final String name;

	public ExtensionParser(ElementRegistry<ELEMENT, ?> elementRegistry, String namespace, String name) {
		this.elementRegistry = elementRegistry;
		this.namespace = namespace;
		this.name = name;
	}

	public final ElementRegistry<ELEMENT, ?> getElementRegistry() {
		return elementRegistry;
	}

	public final String getNamespace() {
		return namespace;
	}

	public final String getName() {
		return name;
	}

	/** {@inheritDoc} */
	@Override
	public void registryChanged(IRegistryChangeEvent event) {
		final Set<String> remove = new HashSet<String>();
		final Set<ELEMENT> add = new HashSet<ELEMENT>();
		for (final IExtensionDelta delta : event.getExtensionDeltas(namespace, name)) {
			final IExtension extension = delta.getExtension();
			final int kind = delta.getKind();
			switch (kind) {
			case IExtensionDelta.ADDED:
				addExtension(extension, add);
				break;

			case IExtensionDelta.REMOVED:
				removeExtension(extension, remove);
				break;
			default:
				break;
			}
		}

		final Set<ELEMENT> removedElements = elementRegistry.doChangeElements(remove, add);
		if (removedElements != null) {
			for (final ELEMENT removedElement : removedElements) {
				if (removedElement instanceof ECPDisposable) {
final ECPDisposable disposable = removedElement; disposable.dispose(); } } } } @Override protected void doActivate() throws Exception { super.doActivate(); final String extensionPointID = namespace + "." + name; //$NON-NLS-1$ final Set<ELEMENT> add = new HashSet<ELEMENT>(); final IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(extensionPointID); for (final IExtension extension : extensionPoint.getExtensions()) { addExtension(extension, add); } elementRegistry.doChangeElements(null, add); Platform.getExtensionRegistry().addRegistryChangeListener(this, namespace); } @Override protected void doDeactivate() throws Exception { Platform.getExtensionRegistry().removeRegistryChangeListener(this); super.doDeactivate(); } protected void addExtension(IExtension extension, Set<ELEMENT> result) { final String name = extension.getUniqueIdentifier(); final IConfigurationElement configurationElement = extension.getConfigurationElements()[0]; final ELEMENT element = createElement(name, configurationElement); element.setLabel(extension.getLabel()); element.setDescription(configurationElement.getAttribute("description")); //$NON-NLS-1$ result.add(element); } protected void removeExtension(IExtension extension, Set<String> result) { final String name = extension.getUniqueIdentifier(); result.add(name); } protected abstract ELEMENT createElement(String name, IConfigurationElement configurationElement); /** * @author Eike Stepper * @param <ELEMENT> The type of this descriptor which must extend {@link InternalRegistryElement} */ public static class ExtensionDescriptor<ELEMENT extends InternalRegistryElement> extends ElementDescriptor<ELEMENT> { private final String type; private final IConfigurationElement configurationElement; public ExtensionDescriptor(ElementRegistry<ELEMENT, ?> registry, String name, String type, IConfigurationElement configurationElement) { super(registry, name); this.type = type; this.configurationElement = configurationElement; try { final String bundleName = configurationElement.getContributor().getName(); final Bundle bundle = Platform.getBundle(bundleName); String location = bundle.getLocation(); if (location.startsWith("initial@")) { //$NON-NLS-1$ location = location.substring("initial@".length()); //$NON-NLS-1$ } final String prefix = "reference:file:"; //$NON-NLS-1$ if (location.startsWith(prefix)) { location = location.substring(prefix.length()); // TODO Trace properly System.out.println(getClass().getSimpleName() + ": " + bundleName + " [" + bundle.getBundleId() //$NON-NLS-1$ //$NON-NLS-2$ + "] --> file:" + new File(location).getCanonicalPath()); //$NON-NLS-1$ } } catch (final Exception ex) { ex.printStackTrace(); } } /** {@inheritDoc} */ @Override public String getType() { return type; } public final IConfigurationElement getConfigurationElement() { return configurationElement; } @Override @SuppressWarnings("unchecked") protected ELEMENT resolve() throws Exception { return (ELEMENT) configurationElement.createExecutableExtension(getClassAttributeName()); } protected String getClassAttributeName() { return "class"; //$NON-NLS-1$ } } }