blob: 9b012740e68d4a1b33dd551a7c0072d712d5c355 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2013 Formal Mind GmbH and University of Dusseldorf.
* 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:
* Michael Jastram - initial API and implementation
******************************************************************************/
package org.eclipse.rmf.reqif10.pror.editor.presentation.service;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.agilemore.agilegrid.AgileGrid;
import org.agilemore.agilegrid.CellEditor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
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.common.notify.AdapterFactory;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.rmf.reqif10.AttributeValue;
import org.eclipse.rmf.reqif10.DatatypeDefinition;
import org.eclipse.rmf.reqif10.DatatypeDefinitionBoolean;
import org.eclipse.rmf.reqif10.DatatypeDefinitionDate;
import org.eclipse.rmf.reqif10.DatatypeDefinitionEnumeration;
import org.eclipse.rmf.reqif10.DatatypeDefinitionInteger;
import org.eclipse.rmf.reqif10.DatatypeDefinitionReal;
import org.eclipse.rmf.reqif10.DatatypeDefinitionString;
import org.eclipse.rmf.reqif10.DatatypeDefinitionXHTML;
import org.eclipse.rmf.reqif10.ReqIF;
import org.eclipse.rmf.reqif10.SpecElementWithAttributes;
import org.eclipse.rmf.reqif10.common.util.ReqIF10Util;
import org.eclipse.rmf.reqif10.pror.configuration.ProrPresentationConfiguration;
import org.eclipse.rmf.reqif10.pror.configuration.ProrPresentationConfigurations;
import org.eclipse.rmf.reqif10.pror.configuration.provider.ProrPresentationConfigurationItemProvider;
import org.eclipse.rmf.reqif10.pror.configuration.provider.ProrPresentationConfigurationsItemProvider;
import org.eclipse.rmf.reqif10.pror.edit.presentation.service.PresentationInterface;
import org.eclipse.rmf.reqif10.pror.edit.presentation.service.PresentationManager;
import org.eclipse.rmf.reqif10.pror.editor.preferences.PreferenceConstants;
import org.eclipse.rmf.reqif10.pror.editor.presentation.Reqif10EditorPlugin;
import org.eclipse.rmf.reqif10.pror.util.ConfigurationUtil;
import org.eclipse.rmf.reqif10.pror.util.ProrUtil;
/**
* This class manages installed Presentations (and is therefore independent of
* open ReqIF Files). It is not meant to be instantiated and consists
* exclusively of static methods.
* <p>
*
*
*/
public class PresentationServiceManager {
public static final String PRESENTATION_EXTENSION_POINT_NAME = "org.eclipse.rmf.reqif10.pror.editor.presentation";
private static Map<Class<? extends ProrPresentationConfiguration>, PresentationInterface> presentationServiceRegistry;
/*
* Private default constructor, to ensure that this class is never
* instantiated.
*/
private PresentationServiceManager() {
throw new InstantiationError(
"This class is not designed to be instantiated.");
}
// // There is one entry per Plugin
// private static Set<PresentationData> presentationTypeRegistry;
/**
* Returns the cached {@link PresentationInterface} representing all installed
* Presentation Extensions.
*
* We use this method to initialize the presentation service map in the item
* provider plugin.
*
* @return A an unmodifyable map of {@link ProrPresentationConfiguration}
* classes and {@link PresentationInterface}s.
*/
public static Map<Class<? extends ProrPresentationConfiguration>, PresentationInterface> getPresentationInterfaceMap() {
if (presentationServiceRegistry == null) {
HashMap<Class<? extends ProrPresentationConfiguration>, PresentationInterface> tmpRegistry = new HashMap<Class<? extends ProrPresentationConfiguration>, PresentationInterface>();
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = registry
.getExtensionPoint(PRESENTATION_EXTENSION_POINT_NAME);
IExtension[] extensions = extensionPoint.getExtensions();
for (IExtension extension : extensions) {
IConfigurationElement[] configElements = extension
.getConfigurationElements();
for (IConfigurationElement configElement : configElements) {
try {
PresentationInterface service = (PresentationInterface) configElement
.createExecutableExtension("service");
tmpRegistry.put(service.getConfigurationInterface(),
service);
PresentationManager.addService(
service.getConfigurationInterface(), service);
} catch (CoreException e) {
MessageDialog
.openError(
null,
"Plugin Configuration Error",
"When initializing the installed plugins, something went wrong. "
+ "You can continue working, but Presentations may not be activated:"
+ e.getMessage());
e.printStackTrace();
}
}
}
presentationServiceRegistry = Collections
.unmodifiableMap(tmpRegistry);
}
return presentationServiceRegistry;
}
/**
* Returns the {@link PresentationInterface} for the given
* {@link ProrPresentationConfiguration} instance, or null if none found.
*/
public static PresentationInterface getPresentationService(
ProrPresentationConfiguration configuration) {
for (Class<? extends ProrPresentationConfiguration> clazz : getPresentationInterfaceMap()
.keySet()) {
if (clazz.isInstance(configuration)) {
return getPresentationInterfaceMap().get(clazz);
}
}
return null;
}
/**
* Upon opening a ReqIF File, this method notifies each
* {@link ProrPresentationConfigurationItemProvider#registerPresentationConfiguration(ReqIF, EditingDomain)}
*/
public static void notifiyOpenReqif(ReqIF reqif,
AdapterFactory adapterFactory, EditingDomain editingDomain) {
ProrPresentationConfigurations configs = ConfigurationUtil
.getPresentationConfigurations(reqif);
if (configs == null)
return;
((ProrPresentationConfigurationsItemProvider) ProrUtil.getItemProvider(
adapterFactory, configs)).setEditingDomain(editingDomain);
for (ProrPresentationConfiguration config : configs
.getPresentationConfigurations()) {
System.out.println("Registering: " + config);
ProrUtil.getConfigItemProvider(config, adapterFactory)
.registerPresentationConfiguration(config, editingDomain);
}
}
/**
* Upon closing a ReqIF File, this method notifies each
* {@link ProrPresentationConfigurationItemProvider#unregisterReqIF(ReqIF, EditingDomain)}
*/
public static void notifiyCloseReqif(ReqIF reqif,
AdapterFactory adapterFactory, EditingDomain editingDomain) {
ProrPresentationConfigurations configs = ConfigurationUtil
.getPresentationConfigurations(reqif);
if (configs == null)
return;
for (ProrPresentationConfiguration config : configs
.getPresentationConfigurations()) {
System.out.println("Unregistering: " + config);
ProrUtil.getConfigItemProvider(config, adapterFactory)
.unregisterPresentationConfiguration(config);
}
}
public static PresentationInterface getPresentationService(
AttributeValue value, EditingDomain editingDomain) {
PresentationInterface service = null;
ProrPresentationConfiguration config = ConfigurationUtil
.getPresentationConfig(value);
if (config != null) {
service = PresentationServiceManager.getPresentationService(config);
}
return service;
}
/**
* This map caches the Default-Renderers. If a Datattype does not have a
* default, there is still an entry in the map to null. This way we know
* whether we already looked up a default. This map may be flushed, which is
* done when the user changes preference settings.
*/
private final static Map<DatatypeDefinition, PresentationEditorInterface> defaultRenderers = new HashMap<DatatypeDefinition, PresentationEditorInterface>();
/**
* Clears the cache of default renderers. The cache will be rebuild on
* demand.
*/
public static void clearDefaultRenderers() {
defaultRenderers.clear();
}
/**
* Returns a default renderer for the AttributeValue's Datatype, if there is
* one, otherwise null.
*
* @param adapterFactory
*/
public static IProrCellRenderer getDefaultCellRenderer(
AttributeValue attrValue, AdapterFactory adapterFactory) {
DatatypeDefinition dd = ReqIF10Util.getDatatypeDefinition(attrValue);
if (dd == null)
return null;
// We do this to prevent repeated lookups if a dd has no default
// renderer.
ensureDefaultEntry(dd, adapterFactory);
PresentationEditorInterface presentationEditor = defaultRenderers
.get(dd);
return presentationEditor == null ? null : presentationEditor
.getCellRenderer(attrValue);
}
public static CellEditor getDefaultCellEditor(AgileGrid agileGrid,
EditingDomain editingDomain, AdapterFactory adapterFactory,
AttributeValue attrValue, SpecElementWithAttributes specElement,
Object affectedObject) {
DatatypeDefinition dd = ReqIF10Util.getDatatypeDefinition(attrValue);
if (dd == null)
return null;
// We do this to prevent repeated lookups if a dd has no default
// renderer.
ensureDefaultEntry(dd, adapterFactory);
PresentationEditorInterface presentationEditor = defaultRenderers
.get(dd);
return presentationEditor == null ? null : presentationEditor
.getCellEditor(agileGrid, editingDomain, attrValue,
specElement, affectedObject);
}
/**
* Ensures that there is an entry for the given {@link DatatypeDefinition}
* in the cache of default Handlers.
*/
private static void ensureDefaultEntry(DatatypeDefinition dd,
AdapterFactory adapterFactory) {
if (defaultRenderers.containsKey(dd)) {
return;
}
String className = getPresentationClassName(dd);
Map<Class<? extends ProrPresentationConfiguration>, PresentationInterface> presentationMap = PresentationServiceManager
.getPresentationInterfaceMap();
for (@SuppressWarnings("rawtypes")
Class key : presentationMap.keySet()) {
if (className.equals(key.getCanonicalName())) {
PresentationInterface p = presentationMap.get(key);
ProrPresentationConfiguration config = p
.getConfigurationInstance();
config.setDatatype(dd);
ItemProviderAdapter provider = ProrUtil.getItemProvider(
adapterFactory, config);
if (provider instanceof PresentationEditorInterface) {
defaultRenderers.put(dd,
(PresentationEditorInterface) provider);
} else {
defaultRenderers.put(dd, null);
}
}
}
}
private static String getPresentationClassName(
org.eclipse.rmf.reqif10.DatatypeDefinition dd) {
IPreferenceStore store = Reqif10EditorPlugin.getPlugin()
.getPreferenceStore();
if (dd instanceof DatatypeDefinitionString)
return store
.getString(PreferenceConstants.P_DEFAULT_PRESENTATION_STRING);
else if (dd instanceof DatatypeDefinitionXHTML)
return store
.getString(PreferenceConstants.P_DEFAULT_PRESENTATION_XHTML);
else if (dd instanceof DatatypeDefinitionBoolean)
return store
.getString(PreferenceConstants.P_DEFAULT_PRESENTATION_BOOLEAN);
else if (dd instanceof DatatypeDefinitionDate)
return store
.getString(PreferenceConstants.P_DEFAULT_PRESENTATION_DATE);
else if (dd instanceof DatatypeDefinitionEnumeration)
return store
.getString(PreferenceConstants.P_DEFAULT_PRESENTATION_ENUMERATION);
else if (dd instanceof DatatypeDefinitionInteger)
return store
.getString(PreferenceConstants.P_DEFAULT_PRESENTATION_INTEGER);
else if (dd instanceof DatatypeDefinitionReal)
return store
.getString(PreferenceConstants.P_DEFAULT_PRESENTATION_REAL);
else
throw new IllegalArgumentException("Not yet covered: " + dd);
}
}