blob: c121a16fa7d648e728dd622b9d4666bdd448f32d [file] [log] [blame]
/*********************************************************************
* Copyright (c) 2005, 2019 SAP SE
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* SAP SE - initial API, implementation and documentation
* mwenz - Bug 352709 - invalid image provider id crashes diagram editor
* fvelasco - Bug 323349 - Enable external invocation of features
* fvelasco - Bug 396247 - ImageDescriptor changes
* pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.graphiti.ui.internal.platform;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.Assert;
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.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.graphiti.dt.IDiagramType;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.internal.util.T;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.ui.editor.IDiagramContainerUI;
import org.eclipse.graphiti.ui.internal.editor.DiagramEditorDummy;
import org.eclipse.graphiti.ui.internal.util.ui.print.IDiagramsExporter;
import org.eclipse.graphiti.ui.platform.IImageProvider;
import org.eclipse.graphiti.ui.platform.PlatformImageProvider;
import org.eclipse.graphiti.ui.services.IExtensionManager;
/**
* @noinstantiate This class is not intended to be instantiated by clients.
* @noextend This class is not intended to be subclassed by clients.
*/
public class ExtensionManager implements IExtensionManager {
private static ExtensionManager singleton;
private static String EP_DIAGRAM_TYPES = "org.eclipse.graphiti.ui.diagramTypes"; //$NON-NLS-1$
private static String EP_IMAGE_PROVIDERS = "org.eclipse.graphiti.ui.imageProviders"; //$NON-NLS-1$
private static String EP_DIAGRAM_TYPE_PROVIDERS = "org.eclipse.graphiti.ui.diagramTypeProviders"; //$NON-NLS-1$
private static String EP_DIAGRAM_EXPORTERS = "org.eclipse.graphiti.ui.diagramExporters"; //$NON-NLS-1$
private static final String EP_CHILD_NODE_DIAGRAM_EXPORTER = "diagramexporter"; //$NON-NLS-1$
private static final String EP_CHILD_NODE_IMAGE_PROVIDER = "imageProvider"; //$NON-NLS-1$
private static final String EP_CHILD_NODE_DIAGRAM_TYPE = "diagramType"; //$NON-NLS-1$
private static final String EP_CHILD_NODE_DIAGRAM_TYPE_PROVIDER = "diagramTypeProvider"; //$NON-NLS-1$
private static final String EP_ATTRIBUTE_CLASS = "class"; //$NON-NLS-1$
private static final String EP_ATTRIBUTE_ID = "id"; //$NON-NLS-1$
private static final String EP_ATTRIBUTE_TYPE = "type"; //$NON-NLS-1$
private static final String EP_ATTRIBUTE_ENABLEUI = "enableScaling"; //$NON-NLS-1$
private static final String EP_ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
private static final String EP_ATTRIBUTE_DESCRIPTION = "description"; //$NON-NLS-1$
private static final String EP_ATTRIBUTE_CONTEXT = "context"; //$NON-NLS-1$
private IDiagramType diagramTypes[] = null;
private IImageProvider imageProviders[] = null;
private IImageProvider platformImageProvider = null;
private Map<String, Set<IImageProvider>> dtp2imageProvider = null;
/**
*
*/
private ExtensionManager() {
super();
dtp2imageProvider = new HashMap<String, Set<IImageProvider>>();
searchForExtensions();
}
public static ExtensionManager getSingleton() {
if (singleton == null) {
singleton = new ExtensionManager();
}
return singleton;
}
public String[] getDiagramTypeProviderIds(String diagramTypeId) {
String ret[] = new String[0];
if (diagramTypeId == null) {
return ret;
}
List<String> retList = new ArrayList<String>();
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_TYPE_PROVIDERS);
IExtension[] extensions = extensionPoint.getExtensions();
for (int i = 0; i < extensions.length; i++) {
IExtension extension = extensions[i];
IConfigurationElement[] configurationElements = extension.getConfigurationElements();
for (int j = 0; j < configurationElements.length; j++) {
IConfigurationElement element = configurationElements[j];
String extensionId = element.getAttribute(EP_ATTRIBUTE_ID);
if (extensionId != null) {
// read references to diagram types
IConfigurationElement[] children = element.getChildren();
for (int k = 0; k < children.length; k++) {
IConfigurationElement childElement = children[k];
String childName = childElement.getName();
String childExtensionId = childElement.getAttribute(EP_ATTRIBUTE_ID);
if (childName != null && childExtensionId != null) {
if (EP_CHILD_NODE_DIAGRAM_TYPE.equals(childName)) {
String typeId = getDiagramTypeIdForDiagramTypeProviderId(childExtensionId);
if (diagramTypeId.equals(typeId)) {
retList.add(extensionId);
break;
}
}
}
}
}
}
}
ret = retList.toArray(ret);
return ret;
}
public Map<String, Boolean> getDiagramExporterTypes() {
Map<String, Boolean> ret = new HashMap<String, Boolean>();
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_EXPORTERS);
IExtension[] extensions = extensionPoint.getExtensions();
for (int i = 0; i < extensions.length; i++) {
IExtension extension = extensions[i];
IConfigurationElement[] configurationElements = extension.getConfigurationElements();
for (int j = 0; j < configurationElements.length; j++) {
IConfigurationElement element = configurationElements[j];
String name = element.getName();
String type = element.getAttribute(EP_ATTRIBUTE_TYPE);
if (name != null && type != null) {
if (EP_CHILD_NODE_DIAGRAM_EXPORTER.equals(name)) {
String enableScaling = element.getAttribute(EP_ATTRIBUTE_ENABLEUI);
ret.put(type, Boolean.valueOf(enableScaling));
break;
}
}
}
}
return ret;
}
public IDiagramsExporter getDiagramExporterForType(String type) {
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_EXPORTERS);
IExtension[] extensions = extensionPoint.getExtensions();
for (int i = 0; i < extensions.length; i++) {
IExtension extension = extensions[i];
IConfigurationElement[] configurationElements = extension.getConfigurationElements();
for (int j = 0; j < configurationElements.length; j++) {
IConfigurationElement element = configurationElements[j];
String name = element.getName();
String currType = element.getAttribute(EP_ATTRIBUTE_TYPE);
if (name != null && type != null) {
if (EP_CHILD_NODE_DIAGRAM_EXPORTER.equals(name) && type.equals(currType)) {
try {
Object executableExtension = element.createExecutableExtension(EP_ATTRIBUTE_CLASS);
if (executableExtension instanceof IDiagramsExporter) {
return (IDiagramsExporter) executableExtension;
}
} catch (CoreException e) {
e.printStackTrace();
}
}
}
}
}
return null;
}
private void searchForExtensions() {
// read and store all diagram types which are registered with the
// extension point
List<IDiagramType> diagramTypeList = createDiagramTypes();
diagramTypes = diagramTypeList.toArray(new IDiagramType[0]);
imageProviders = new IImageProvider[0];
// load image providers from the framework
platformImageProvider = loadImageProvider(PlatformImageProvider.ID);
}
public IDiagramTypeProvider createDiagramTypeProvider(String providerId) {
IDiagramTypeProvider diagramTypeProvider = null;
if (providerId == null) {
return diagramTypeProvider;
}
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_TYPE_PROVIDERS);
IExtension[] extensions = extensionPoint.getExtensions();
for (int i = 0; i < extensions.length; i++) {
IExtension extension = extensions[i];
IConfigurationElement[] configurationElements = extension.getConfigurationElements();
for (int j = 0; j < configurationElements.length; j++) {
IConfigurationElement element = configurationElements[j];
String extensionId = element.getAttribute(EP_ATTRIBUTE_ID);
if (extensionId != null && extensionId.equals(providerId)) {
String name = element.getAttribute(EP_ATTRIBUTE_NAME);
String description = element.getAttribute(EP_ATTRIBUTE_DESCRIPTION);
if (description == null) {
description = ""; //$NON-NLS-1$
}
String context = element.getAttribute(EP_ATTRIBUTE_CONTEXT);
if (context == null) {
context = IDiagramContainerUI.DIAGRAM_CONTEXT_ID;
}
if (name != null) {
// read direct references to image extensions and try to
// instantiate image provider
IConfigurationElement[] children = element.getChildren();
for (int k = 0; k < children.length; k++) {
IConfigurationElement childElement = children[k];
String childName = childElement.getName();
String childExtensionId = childElement.getAttribute(EP_ATTRIBUTE_ID);
if (childName != null && childExtensionId != null) {
if (EP_CHILD_NODE_IMAGE_PROVIDER.equals(childName)) {
IImageProvider imageProvider = loadImageProvider(childExtensionId);
if (imageProvider == null) {
IllegalArgumentException e = new IllegalArgumentException("A Graphiti image provider with id '" //$NON-NLS-1$
+ childExtensionId + "' could not be found"); //$NON-NLS-1$
T.racer().error("Error while creating the children for '" + providerId + "'", e); //$NON-NLS-1$ //$NON-NLS-2$
} else {
registerImageProviderForDiagramTypeProvider(providerId, imageProvider);
}
}
}
}
try {
Object executableExtension = element.createExecutableExtension(EP_ATTRIBUTE_CLASS);
if (executableExtension instanceof IDiagramTypeProvider) {
diagramTypeProvider = (IDiagramTypeProvider) executableExtension;
diagramTypeProvider.setProviderId(extensionId);
diagramTypeProvider.setContextId(context);
// TODO later store also name and description -
// is only necessary if this information
// are shown in the UI
}
} catch (CoreException e) {
// $JL-EXC$
T.racer().error("Unable to create DiagramTypeProvider class", e);
}
}
}
}
}
IExtensionPoint imageProviderExtensionPoint = extensionRegistry.getExtensionPoint(EP_IMAGE_PROVIDERS);
// read image providers that point back to this diagramTypeProvider
for (IExtension extension : imageProviderExtensionPoint.getExtensions()) {
IConfigurationElement[] configurationElements = extension.getConfigurationElements();
for (int j = 0; j < configurationElements.length; j++) {
IConfigurationElement element = configurationElements[j];
String imageProviderId = element.getAttribute(EP_ATTRIBUTE_ID);
IConfigurationElement[] children = element.getChildren(EP_CHILD_NODE_DIAGRAM_TYPE_PROVIDER);
for (IConfigurationElement child : children) {
String referredDiagramTypeProviderId = child.getAttribute(EP_ATTRIBUTE_ID);
if (providerId.equals(referredDiagramTypeProviderId)) {
IImageProvider imageProvider = loadImageProvider(imageProviderId);
registerImageProviderForDiagramTypeProvider(providerId, imageProvider);
break;
}
}
}
}
return diagramTypeProvider;
}
public IImageProvider getPlatformImageProvider() {
return platformImageProvider;
}
public Collection<IImageProvider> getImageProvidersForDiagramTypeProviderId(String providerId) {
Collection<IImageProvider> providers = dtp2imageProvider.get(providerId);
if (providers == null)
return Collections.singleton(platformImageProvider);
else
return providers;
}
public IDiagramType[] getDiagramTypes() {
return diagramTypes;
}
private String getDiagramTypeIdForDiagramTypeProviderId(String providerId) {
if (providerId != null) {
IDiagramType diagramTypes[] = getDiagramTypes();
for (int i = 0; i < diagramTypes.length; i++) {
IDiagramType diagramType = diagramTypes[i];
if (providerId.equals(diagramType.getProviderId())) {
return diagramType.getId();
}
}
}
return null;
}
private IImageProvider loadImageProvider(String imageProviderId) {
// check whether the image provider is already loaded
for (int i = 0; i < imageProviders.length; i++) {
IImageProvider provider = imageProviders[i];
if (imageProviderId.equals(provider.getProviderId())) {
return provider;
}
}
IImageProvider newProvider = createImageProvider(imageProviderId);
if (newProvider != null) {
// extend current list of image providers
IImageProvider imageProvidersDest[] = new IImageProvider[imageProviders.length + 1];
System.arraycopy(imageProviders, 0, imageProvidersDest, 0, imageProviders.length);
imageProvidersDest[imageProviders.length] = newProvider;
imageProviders = imageProvidersDest;
return newProvider;
}
return null;
}
private List<IDiagramType> createDiagramTypes() {
List<IDiagramType> ret = new ArrayList<IDiagramType>();
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_DIAGRAM_TYPES);
IExtension[] extensions = extensionPoint.getExtensions();
for (int i = 0; i < extensions.length; i++) {
IExtension extension = extensions[i];
IConfigurationElement[] configurationElements = extension.getConfigurationElements();
for (int j = 0; j < configurationElements.length; j++) {
IConfigurationElement element = configurationElements[j];
String extensionId = element.getAttribute(EP_ATTRIBUTE_ID);
String typeId = element.getAttribute(EP_ATTRIBUTE_TYPE);
String typeName = element.getAttribute(EP_ATTRIBUTE_NAME);
String typeDescription = element.getAttribute(EP_ATTRIBUTE_DESCRIPTION);
if (typeDescription == null) {
typeDescription = ""; //$NON-NLS-1$
}
if (extensionId != null && typeId != null && typeName != null) {
IDiagramType diagramType = new DiagramTypeImpl(typeId, typeName, typeDescription);
diagramType.setProviderId(extensionId);
ret.add(diagramType);
}
}
}
return ret;
}
private IImageProvider createImageProvider(String providerId) {
if (providerId == null) {
return null;
}
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(EP_IMAGE_PROVIDERS);
IExtension[] extensions = extensionPoint.getExtensions();
for (int i = 0; i < extensions.length; i++) {
IExtension extension = extensions[i];
IConfigurationElement[] configurationElements = extension.getConfigurationElements();
for (int j = 0; j < configurationElements.length; j++) {
IConfigurationElement element = configurationElements[j];
String extensionId = element.getAttribute(EP_ATTRIBUTE_ID);
if (providerId.equals(extensionId)) {
try {
Object executableExtension = element.createExecutableExtension(EP_ATTRIBUTE_CLASS);
if (executableExtension instanceof IImageProvider) {
IContributor contributor = extension.getContributor();
if (contributor != null) {
String pluginId = contributor.getName();
if (pluginId != null) {
IImageProvider imageProvider = (IImageProvider) executableExtension;
imageProvider.setProviderId(extensionId);
imageProvider.setPluginId(pluginId);
return imageProvider;
}
}
}
} catch (CoreException e) {
// $JL-EXC$
e.printStackTrace();
}
}
}
}
return null;
}
private void registerImageProviderForDiagramTypeProvider(String providerId, IImageProvider imageProvider) {
Set<IImageProvider> providers = dtp2imageProvider.get(providerId);
if (providers == null) {
providers = new HashSet<IImageProvider>();
dtp2imageProvider.put(providerId, providers);
providers.add(platformImageProvider);
}
providers.add(imageProvider);
}
public IFeatureProvider createFeatureProvider(Diagram diagram) {
Assert.isNotNull(diagram);
String providerId = getDiagramTypeProviderId(diagram.getDiagramTypeId());
if (providerId != null) {
IDiagramTypeProvider dtp = createDiagramTypeProvider(diagram, providerId);
return dtp.getFeatureProvider();
}
return null;
}
public IDiagramTypeProvider createDiagramTypeProvider(Diagram diagram, String providerId) {
Assert.isNotNull(diagram);
IDiagramTypeProvider dtp = createDiagramTypeProvider(providerId);
if (dtp != null) {
TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(diagram);
DiagramEditorDummy diagramEditor = new DiagramEditorDummy(dtp, editingDomain);
dtp.init(diagram, diagramEditor.getDiagramBehavior());
}
return dtp;
}
public String getDiagramTypeProviderId(String diagramTypeId) {
String diagramTypeProviders[] = getDiagramTypeProviderIds(diagramTypeId);
if (diagramTypeProviders != null && diagramTypeProviders.length > 0) {
return diagramTypeProviders[0];
}
return null;
}
}