blob: c59976f9ad27d7473188e2b0db1e420dc07bac5d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2010 Mia-Software.
* 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:
* Nicolas Bros (Mia-Software) - initial API and implementation
*
*******************************************************************************/
package org.eclipse.gmt.modisco.infra.browser.uicore.internal.extensions;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.gmt.modisco.infra.browser.uicore.extensions.icons.FilteredIconProvider;
import org.eclipse.gmt.modisco.infra.browser.uicore.extensions.icons.IconProvider;
import org.eclipse.gmt.modisco.infra.browser.uicore.internal.Activator;
import org.eclipse.gmt.modisco.infra.browser.uicore.internal.Messages;
import org.eclipse.gmt.modisco.infra.common.core.internal.extensions.AbstractRegistry;
import org.eclipse.gmt.modisco.infra.common.core.internal.utils.ModelUtils;
import org.eclipse.gmt.modisco.infra.common.core.logging.MoDiscoLogger;
import org.eclipse.swt.graphics.Image;
/**
* The singleton registry of name providers, which initializes the registry by
* reading extensions when first accessed. It can provide names for model
* elements, using {@link IconProvider}s provided through the naming extension
* point.
* @deprecated Will be replaced by EMF Facet,
* cf https://bugs.eclipse.org/bugs/show_bug.cgi?id=470715
*/
@Deprecated
public class IconProvidersRegistry extends AbstractRegistry {
private static final String METACLASS_ELEMENT = "metaclass"; //$NON-NLS-1$
private static final String EXTENSION_POINT_NAMESPACE = "org.eclipse.gmt.modisco.infra.browser.uicore"; //$NON-NLS-1$
private static final String EXTENSION_POINT_NAME = "icons"; //$NON-NLS-1$
private static final String METAMODEL_ID_ATTRIBUTE = "id"; //$NON-NLS-1$
private static final String METAMODEL_ELEMENT = "metamodel"; //$NON-NLS-1$
private static final String ICON_PROVIDER_ELEMENT = "iconProvider"; //$NON-NLS-1$
private static final String ICON_PROVIDER_CLASS = "class"; //$NON-NLS-1$
private static final String FILTER_ELEMENT = "filter"; //$NON-NLS-1$
private static final String METACLASS_NAME_ATTRIBUTE = "name"; //$NON-NLS-1$
private static IconProvidersRegistry instance = null;
/**
* A map of metamodels to lists of FilteredIconProvider that provide icons
* for the metamodel's instances
*/
private final Map<String, List<FilteredIconProvider>> iconProviders = new HashMap<String, List<FilteredIconProvider>>();
public static IconProvidersRegistry getInstance() {
if (IconProvidersRegistry.instance == null) {
IconProvidersRegistry.instance = new IconProvidersRegistry();
}
return IconProvidersRegistry.instance;
}
public IconProvidersRegistry() {
initialize();
}
@Override
protected String getExtensionPointName() {
return IconProvidersRegistry.EXTENSION_POINT_NAME;
}
@Override
protected String getExtensionPointNamespace() {
return IconProvidersRegistry.EXTENSION_POINT_NAMESPACE;
}
/**
* Query the icon providers registry for an icon for the given
* {@link EObject}.
*
* @param eObject
* the model instance whose icon is queried
*
* @return the icon or <code>null</code> if no icon was provided
*/
public Image getIcon(final EObject eObject) {
final EClass eClass = eObject.eClass();
if (eClass == null) {
return null;
}
final String metaclassQualifiedName = ModelUtils.getMetaclassQualifiedName(eClass);
// find the nsURI of the package containing the metamodel definition
final EPackage ePackage = eClass.getEPackage();
if (ePackage == null) {
return null;
}
final String nsURI = ePackage.getNsURI();
List<FilteredIconProvider> filteredIconProviders = this.iconProviders.get(nsURI);
if (filteredIconProviders == null) {
// try to retrieve a generic icon provider
filteredIconProviders = this.iconProviders.get("*"); //$NON-NLS-1$
if (filteredIconProviders == null) {
return null;
}
}
for (final FilteredIconProvider filteredIconProvider : filteredIconProviders) {
if (filteredIconProvider.filter(metaclassQualifiedName)) {
final Image icon = filteredIconProvider.getIcon(eObject);
if (icon != null) {
return icon;
}
}
}
return null;
}
@Override
protected void handleRootElement(final IConfigurationElement configurationElement) {
final String name = configurationElement.getName();
if (name.equalsIgnoreCase(IconProvidersRegistry.METAMODEL_ELEMENT)) {
readMetamodelElement(configurationElement);
} else {
logUnknownElement(configurationElement);
}
}
/** Read a 'metamodel' element */
private void readMetamodelElement(final IConfigurationElement configurationElement) {
final String metamodelId = configurationElement
.getAttribute(IconProvidersRegistry.METAMODEL_ID_ATTRIBUTE);
if (metamodelId == null) {
logMissingAttribute(configurationElement, IconProvidersRegistry.METAMODEL_ID_ATTRIBUTE);
return;
}
final IConfigurationElement[] children = configurationElement.getChildren();
for (final IConfigurationElement child : children) {
final String name = child.getName();
if (name.equalsIgnoreCase(IconProvidersRegistry.ICON_PROVIDER_ELEMENT)) {
readIconProviderElement(child, metamodelId);
} else {
logUnknownElement(configurationElement);
}
}
}
/**
* Read an 'iconProvider' element, and adds the icon providers to the
* registry.
*
* @param configurationElement
* the 'iconProvider' element
* @param metamodelId
* the nsURI of the package containing the metamodel's
* metaclasses
*/
private void readIconProviderElement(final IConfigurationElement configurationElement,
final String metamodelId) {
// if not null, filters on the metaclass name
HashSet<String> filteredMetaclasses = null;
final IConfigurationElement[] filterElements = configurationElement
.getChildren(IconProvidersRegistry.FILTER_ELEMENT);
if (filterElements.length > 0) {
// optional element : 0 or 1
final IConfigurationElement[] metaclassElements = filterElements[0]
.getChildren(IconProvidersRegistry.METACLASS_ELEMENT);
for (final IConfigurationElement metaclassElement : metaclassElements) {
final String metaclassName = metaclassElement
.getAttribute(IconProvidersRegistry.METACLASS_NAME_ATTRIBUTE);
if (metaclassName != null) {
if (filteredMetaclasses == null) {
filteredMetaclasses = new HashSet<String>();
}
filteredMetaclasses.add(metaclassName);
}
}
}
final HashSet<String> fFilteredMetaclasses = filteredMetaclasses;
Object iconProviderObject;
try {
iconProviderObject = configurationElement
.createExecutableExtension(IconProvidersRegistry.ICON_PROVIDER_CLASS);
} catch (final CoreException e) {
MoDiscoLogger.logError(e, Activator.getDefault());
return;
}
if (iconProviderObject == null) {
logMissingAttribute(configurationElement, IconProvidersRegistry.ICON_PROVIDER_CLASS);
return;
}
List<FilteredIconProvider> filteredIconProviders = this.iconProviders.get(metamodelId);
if (filteredIconProviders == null) {
filteredIconProviders = new ArrayList<FilteredIconProvider>();
}
/*
* The user can either provide a FilteredIconProvider or an
* IconProvider. In either case, if a filter is set in the extension
* definition, then it will get applied before the user code is called.
*/
if (iconProviderObject instanceof FilteredIconProvider) {
final FilteredIconProvider filteredIconProvider = (FilteredIconProvider) iconProviderObject;
filteredIconProviders.add(new FilteredIconProvider() {
public Image getIcon(final EObject object) {
return filteredIconProvider.getIcon(object);
}
public boolean filter(final String metaclass) {
if (fFilteredMetaclasses != null && !fFilteredMetaclasses.contains(metaclass)) {
return false;
}
return filteredIconProvider.filter(metaclass);
}
});
} else if (iconProviderObject instanceof IconProvider) {
final IconProvider iconProvider = (IconProvider) iconProviderObject;
final FilteredIconProvider filteredNameProvider = new FilteredIconProvider() {
public Image getIcon(final EObject object) {
return iconProvider.getIcon(object);
}
public boolean filter(final String metaclass) {
if (fFilteredMetaclasses == null) {
return true;
}
return fFilteredMetaclasses.contains(metaclass);
}
};
filteredIconProviders.add(filteredNameProvider);
} else {
logError(configurationElement, Messages.IconProvidersRegistry_notAnIconProvider);
}
this.iconProviders.put(metamodelId, filteredIconProviders);
}
}