From 3c4ff7cd0d6f2301fd327a0d14c01b7f5b149b8d Mon Sep 17 00:00:00 2001
From: Simon Barner <barner@fortiss.org>
Date: Tue, 26 Aug 2014 14:57:20 +0000
Subject: [PATCH] Finalize annotation framework overhaul

- IAnnotationValueProvider
  - allowsMultipleValues() -> allowsMultipleAnnotationInstances()
  - createEditingSupport()
     - Remove unused parameter
     - Method is unconditionally used to construct the editing support. Defaults
       are set in base classes implementing IAnnotationValueProvider.
  - remove getFixedValues(): SingleEnumAttributeValueProviderBase() creates the required ComboBoxEditingSupport

- IAnnotationValueProvider base classes:
  - ValueProviderBase: Empty implementation of interface
  - SingleAttributeValueProviderBase: IAnnotationValueProvider manages a single attribute of a given specification class. Probably nearly all static annotations will be based on this.
  - SingleEDataTypeAttributeValueProvider: primitive data types (e.g., int, double), and potentially many other data types managed by EMF
  - SingleEnumAttributeValueProvider: Provides ComboBoxEditingSupport based on enum declaration in Ecore meta-model.

- Further fixes:
  - Make combo box in ComboBoxEditionSupport non-editable
  - Prevent NPE in TextEditingSupport.getValue()

- Use new base classes in test annotation classes
refs 1841
---
 .../base/ui/annotation/AnnotationEntry.java   |  23 +--
 .../ComboBoxEditingSupport.java               |  14 +-
 .../editingsupport/TextEditingSupport.java    |  12 +-
 .../IAnnotationValueProvider.java             |  26 ++-
 .../SingleAttributeValueProviderBase.java     | 116 ++++++++++++
 ...leEDataTypeAttributeValueProviderBase.java | 118 ++++++++++++
 .../SingleEnumAttributeValueProviderBase.java |  88 +++++++++
 ...lePrimitiveAttributeValueProviderBase.java | 173 ------------------
 .../valueprovider/ValueProviderBase.java      |  17 +-
 .../view/AnnotationLabelProvider.java         |   7 +-
 .../view/GenericAnnotationView.java           |  38 +---
 11 files changed, 377 insertions(+), 255 deletions(-)
 create mode 100644 org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleAttributeValueProviderBase.java
 create mode 100644 org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEDataTypeAttributeValueProviderBase.java
 create mode 100644 org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java
 delete mode 100644 org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SinglePrimitiveAttributeValueProviderBase.java

diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java
index 8ab3644ed..e6053d0a4 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/AnnotationEntry.java
@@ -18,7 +18,6 @@ $Id$
 package org.fortiss.tooling.base.ui.annotation;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 
@@ -27,6 +26,7 @@ import org.eclipse.jface.viewers.EditingSupport;
 import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
 import org.fortiss.tooling.base.model.element.IModelElement;
 import org.fortiss.tooling.base.ui.annotation.valueprovider.IAnnotationValueProvider;
+import org.fortiss.tooling.base.ui.annotation.view.GenericAnnotationView;
 
 /**
  * The class {@link AnnotationEntry} is responsible for providing those annotations (or annotation
@@ -76,7 +76,7 @@ public final class AnnotationEntry {
 	public boolean allowsMultipleValues(Class<? extends IAnnotatedSpecification> clazz) {
 		for(IAnnotatedSpecification s : specificationsList) {
 			if(clazz.isInstance(s)) {
-				return providerSpecMapping.get(clazz).allowsMultipleValues();
+				return providerSpecMapping.get(clazz).allowsMultipleAnnotationInstances();
 			}
 		}
 
@@ -150,24 +150,15 @@ public final class AnnotationEntry {
 		throw new Exception("Could not find a AnnotationValueProvider for " + clazz.toString());
 	}
 
-	/** Returns the possible values of the the given specification clazz */
-	public List<String> getFixedSpecificationValues(Class<? extends IAnnotatedSpecification> clazz) {
-		for(IAnnotatedSpecification s : specificationsList) {
-			if(clazz.isInstance(s)) {
-				return providerSpecMapping.get(clazz).getFixedValues();
-			}
-		}
-		return Collections.emptyList();
-	}
-
 	/**
-	 * Returns a custom EditingSupport element for the annotation view
+	 * Creates the {@link EditingSupport} element for the {@link IAnnotatedSpecification} of type
+	 * {@code clazz} (for use in the {@link GenericAnnotationView} .
 	 */
-	public EditingSupport getSpecificationEditElement(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> clazz, Object parent) {
+	public EditingSupport createSpecificationEditElement(ColumnViewer viewer,
+			Class<? extends IAnnotatedSpecification> clazz) {
 		for(IAnnotatedSpecification s : specificationsList) {
 			if(clazz.isInstance(s)) {
-				return providerSpecMapping.get(clazz).getEditingSupport(viewer, clazz, parent);
+				return providerSpecMapping.get(clazz).createEditingSupport(viewer, clazz);
 			}
 		}
 
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/ComboBoxEditingSupport.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/ComboBoxEditingSupport.java
index e2e8e37fa..379d6bcb5 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/ComboBoxEditingSupport.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/ComboBoxEditingSupport.java
@@ -53,19 +53,21 @@ public class ComboBoxEditingSupport extends EditingSupport {
 	 * Constructor.
 	 * 
 	 * @param viewer
-	 *            the column viewer
+	 *            Column viewer
+	 * @param clazz
+	 *            Annotation class handled by this editing support
 	 * @param values
-	 *            the values for the combo box
-	 * @param class1
+	 *            Values for the combo box
 	 */
-	public ComboBoxEditingSupport(ColumnViewer viewer, List<String> values,
-			Class<? extends IAnnotatedSpecification> class1) {
+	public ComboBoxEditingSupport(ColumnViewer viewer,
+			Class<? extends IAnnotatedSpecification> clazz, List<String> values) {
 		super(viewer);
 		cellEditor = new ComboBoxViewerCellEditor((Composite)getViewer().getControl());
 		cellEditor.setLabelProvider(new LabelProvider());
 		cellEditor.setContentProvider(new ArrayContentProvider());
 		cellEditor.setInput(values);
-		specClass = class1;
+		cellEditor.getViewer().getCCombo().setEditable(false);
+		specClass = clazz;
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/TextEditingSupport.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/TextEditingSupport.java
index c1ef9e8f5..ba152d6a6 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/TextEditingSupport.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/editingsupport/TextEditingSupport.java
@@ -48,8 +48,7 @@ public class TextEditingSupport extends EditingSupport {
 	protected Class<? extends IAnnotatedSpecification> specClass;
 
 	/** Constructor. */
-	public TextEditingSupport(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> class1) {
+	public TextEditingSupport(ColumnViewer viewer, Class<? extends IAnnotatedSpecification> class1) {
 		super(viewer);
 
 		cellEditor = new TextCellEditor((Composite)getViewer().getControl(), SWT.NONE);
@@ -77,10 +76,13 @@ public class TextEditingSupport extends EditingSupport {
 	@Override
 	protected Object getValue(Object element) {
 		if(element instanceof AnnotationEntry) {
-			AnnotationEntry data = (AnnotationEntry)element;
-			return data.getSpecificationValue(specClass).toString();
+			AnnotationEntry annotationEntry = (AnnotationEntry)element;
+			Object value = annotationEntry.getSpecificationValue(specClass);
+			if(value != null) {
+				return value.toString();
+			}
 		}
-		return null;
+		return "-";
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java
index c5ab4f930..99394f9db 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/IAnnotationValueProvider.java
@@ -67,11 +67,12 @@ public interface IAnnotationValueProvider<T extends IAnnotatedSpecification> ext
 		IEObjectAware<IModelElement> {
 
 	/**
-	 * Returns a boolean whether the implemented specification supports storing multiple values.
-	 * This method is used to handle these classes in the view part in a simpler manner.
+	 * Predicate whether multiple instances of the {@link IAnnotatedSpecification} managed
+	 * by this {@link IAnnotationValueProvider} can exist. For instance, the
+	 * {@link GenericAnnotationView} will in this case create UI controls to enable the creation of
+	 * these instances.
 	 */
-	// TODO: Review
-	public boolean allowsMultipleValues();
+	public boolean allowsMultipleAnnotationInstances();
 
 	/**
 	 * Returns the name of the annotation (e.g., used as column label in the table-based
@@ -111,18 +112,13 @@ public interface IAnnotationValueProvider<T extends IAnnotatedSpecification> ext
 	public void setAnnotationValue(String value, T specification) throws Exception;
 
 	/**
-	 * If this method does not return null, a combo box is provided with the specific return values
+	 * Creates and returns the {@link EditingSupport} support element for the table-based
+	 * {@link GenericAnnotationView}. {@link IAnnotationValueProvider}s for specialized
+	 * {@link IAnnotatedSpecification} may choose to provide a dedicated, custom
+	 * {@link EditingSupport}.
 	 */
-	// TODO: Review / Remove from interface, implement {@link EditingSupport} for Enums instead
-	public List<String> getFixedValues();
-
-	/**
-	 * Returns a custom {@link EditingSupport} support element for the table-based
-	 * {@link GenericAnnotationView}. In case {@code null} is returned, the annotation framework
-	 * tries to fall back to one of the stand {@link EditingSupport}s instead.
-	 */
-	public EditingSupport getEditingSupport(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> class1, Object parent);
+	public EditingSupport createEditingSupport(ColumnViewer viewer,
+			Class<? extends IAnnotatedSpecification> clazz);
 
 	/**
 	 * Factory method that creates a new {@link IAnnotatedSpecification} specialization of type T to
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleAttributeValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleAttributeValueProviderBase.java
new file mode 100644
index 000000000..fe2649995
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleAttributeValueProviderBase.java
@@ -0,0 +1,116 @@
+/*--------------------------------------------------------------------------+
+$Id$
+|                                                                          |
+| Copyright 2014 ForTISS GmbH                     |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.annotation.valueprovider;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EFactory;
+import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
+import org.fortiss.tooling.base.model.element.IModelElement;
+import org.fortiss.tooling.base.model.element.IModelElementSpecification;
+
+/**
+ * Base class for {@link IAnnotationValueProvider}s that manages a single {@link EAttribute}
+ * contained by a {@link IAnnotatedSpecification}.
+ * 
+ * @author barner
+ * @author $Author$
+ * @version $Rev$
+ * @ConQAT.Rating RED Hash:
+ */
+public abstract class SingleAttributeValueProviderBase<T extends IAnnotatedSpecification> extends
+		ValueProviderBase<T> {
+
+	/**
+	 * {@link EClass} of {@link IAnnotatedSpecification} that contains the respective attribute and
+	 * that is managed by this {@link IAnnotationValueProvider}.
+	 */
+	final protected EClass annotatedSpecificationEClass;
+
+	/**
+	 * {@link EFactory} of ECore model that contains {@link IAnnotatedSpecification} identified by
+	 * {@code annotatedSpecificationEClass} (used to create new instances of the annotation).
+	 */
+	final protected EFactory annotationFactory;
+
+	/**
+	 * The attribute of the {@link IAnnotatedSpecification} that is managed by this
+	 * {@link IAnnotationValueProvider}.
+	 */
+	final protected EAttribute attribute;
+
+	/**
+	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
+	 * whose storage is implemented by a single attribute.
+	 */
+	public SingleAttributeValueProviderBase(EClass annotatedSpecificationEClass, EFactory eFactory,
+			EAttribute attribute) {
+		this.annotatedSpecificationEClass = annotatedSpecificationEClass;
+		this.annotationFactory = eFactory;
+		this.attribute = attribute;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public <U> void setAnnotationValue(U value, T specification) throws Exception {
+		specification.eSet(attribute, value);
+	}
+
+	/** {@inheritDoc} */
+	@SuppressWarnings("unchecked")
+	@Override
+	public <U> U getAnnotationValue(T specification) {
+		return (U)specification.eGet(attribute);
+	}
+
+	/**
+	 * Creates a new instance of the attribute (use to populate newly created annotation instances
+	 * created in {@link #getAnnotatedSpecificationForModelElement(IModelElement)}.
+	 */
+	protected abstract Object createAttributeValue() throws Exception;
+
+	/** {@inheritDoc} */
+	@SuppressWarnings("unchecked")
+	@Override
+	public T getAnnotatedSpecificationForModelElement(IModelElement element) throws Exception {
+		// Return existing annotation
+		for(IModelElementSpecification specification : element.getSpecifications()) {
+			if(annotatedSpecificationEClass.equals(specification.eClass())) {
+				return (T)specification;
+			}
+		}
+
+		// Create annotation
+		T specification = (T)annotationFactory.create(annotatedSpecificationEClass);
+
+		// Create an set annotation attribute
+		specification.eSet(attribute, createAttributeValue());
+
+		// Hook specification to model element
+		element.addSpecification(specification);
+
+		return specification;
+	}
+
+	/** {@inheritDoc} */
+	@SuppressWarnings("unchecked")
+	@Override
+	public Class<T> getAnnotationClazz() {
+		return (Class<T>)annotatedSpecificationEClass.getClass();
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEDataTypeAttributeValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEDataTypeAttributeValueProviderBase.java
new file mode 100644
index 000000000..35590a870
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEDataTypeAttributeValueProviderBase.java
@@ -0,0 +1,118 @@
+/*--------------------------------------------------------------------------+
+$Id$
+|                                                                          |
+| Copyright 2014 ForTISS GmbH                     |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.annotation.valueprovider;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EFactory;
+import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
+
+/**
+ * Base class for {@link IAnnotationValueProvider}s that manages a single {@link EDataType}
+ * attribute contained in a {@link IAnnotatedSpecification} (e.g., including primitive data types
+ * such as {@code int, double, ...}).
+ * 
+ * @author barner
+ * @author $Author$
+ * @version $Rev$
+ * @ConQAT.Rating RED Hash:
+ */
+public abstract class SingleEDataTypeAttributeValueProviderBase<T extends IAnnotatedSpecification>
+		extends SingleAttributeValueProviderBase<T> {
+
+	/**
+	 * {@link EDataType} of the primitive attribute used to implemented the storage
+	 * of the underlying {@link IAnnotatedSpecification}.
+	 */
+	final protected EDataType attributeEDataType;
+
+	/**
+	 * String representation of default value used to initialize the primitive attribute of the
+	 * underlying {@link IAnnotatedSpecification}. If it is {@code null}, {@link EDataType}'s
+	 * default value will be used.
+	 */
+	final protected String attributeDefaultValue;
+
+	/**
+	 * {@link EFactory} of used to create new attribute instances.
+	 */
+	final protected EFactory attributeFactory;
+
+	/**
+	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
+	 * that manages a single {@link EDataType} attribute contained in a
+	 * {@link IAnnotatedSpecification}. New instances of the attribute will be initialized to the
+	 * respective default value.
+	 */
+	public SingleEDataTypeAttributeValueProviderBase(EClass annotatedSpecificationEClass,
+			EFactory annotationFactory, EAttribute attribute, EDataType attributeEDataType,
+			EFactory attributeFactory) {
+		this(annotatedSpecificationEClass, annotationFactory, attribute, attributeEDataType,
+				attributeFactory, null);
+	}
+
+	/**
+	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
+	 * that that manages a single {@link EDataType} attribute contained in a
+	 * {@link IAnnotatedSpecification}. The constructor assumes that an instance of the attribute
+	 * type can initialized from a {@link String}.
+	 */
+	public SingleEDataTypeAttributeValueProviderBase(EClass annotatedSpecificationEClass,
+			EFactory annotationFactory, EAttribute attribute, EDataType attributeEDataType,
+			EFactory attributeFactory, final String attributeDefaultValue) {
+		super(annotatedSpecificationEClass, annotationFactory, attribute);
+		this.attributeEDataType = attributeEDataType;
+		this.attributeDefaultValue = attributeDefaultValue;
+		this.attributeFactory = attributeFactory;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void setAnnotationValue(String value, T specification) throws Exception {
+		setAnnotationValue(attributeFactory.createFromString(attributeEDataType, value),
+				specification);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected Object createAttributeValue() throws Exception {
+		if(attributeDefaultValue != null) {
+			// Use default value if it has been specified
+			return attributeFactory.createFromString(attributeEDataType, attributeDefaultValue);
+		}
+
+		// Return data types default value, it it is non-null.
+		Object rval = attributeEDataType.getDefaultValue();
+
+		if(rval != null) {
+			return rval;
+		}
+
+		try {
+			// Try to construct attribute from empty string
+			rval = attributeFactory.createFromString(attributeEDataType, "");
+		} catch(NumberFormatException e) {
+			// Last try: initialize numbers with 0 (throws NumberFormatException if not
+			// successful).
+			rval = attributeFactory.createFromString(attributeEDataType, "0");
+		}
+
+		return rval;
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java
new file mode 100644
index 000000000..cc0a39c73
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SingleEnumAttributeValueProviderBase.java
@@ -0,0 +1,88 @@
+/*--------------------------------------------------------------------------+
+$Id$
+|                                                                          |
+| Copyright 2014 ForTISS GmbH                     |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.base.ui.annotation.valueprovider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EEnumLiteral;
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
+import org.fortiss.tooling.base.ui.annotation.editingsupport.ComboBoxEditingSupport;
+
+/**
+ * Base class for {@link IAnnotationValueProvider}s that manages a single enumeration contained in a
+ * {@link IAnnotatedSpecification}. The provider will provide a {@link ComboBoxEditingSupport} that
+ * is initialized to the enumeration value names specified in the respective ECore model
+ * containing the enumeration type.
+ * 
+ * @author barner
+ * @author $Author$
+ * @version $Rev$
+ * @ConQAT.Rating RED Hash:
+ */
+public abstract class SingleEnumAttributeValueProviderBase<T extends IAnnotatedSpecification>
+		extends SingleEDataTypeAttributeValueProviderBase<T> {
+
+	/** Data type of the enumeration managed by this {@link IAnnotationValueProvider} */
+	private EEnum eEnum;
+
+	/**
+	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
+	 * that that manages a single enumeration attribute contained in a
+	 * {@link IAnnotatedSpecification}. The enumeration attribute is initialized to its default
+	 * value.
+	 */
+	public SingleEnumAttributeValueProviderBase(EClass annotatedSpecificationEClass,
+			EFactory annotationFactory, EAttribute attribute, EEnum eEnum, EFactory attributeFactory) {
+		this(annotatedSpecificationEClass, annotationFactory, attribute, eEnum, attributeFactory,
+				null);
+	}
+
+	/**
+	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
+	 * that that manages a single enumeration attribute contained in a
+	 * {@link IAnnotatedSpecification}. The constructor assumes that the
+	 * {@code attributeDefaultValue} matches of the enumeration names.
+	 */
+	public SingleEnumAttributeValueProviderBase(EClass annotatedSpecificationEClass,
+			EFactory annotationFactory, EAttribute attribute, EEnum eEnum,
+			EFactory attributeFactory, final String attributeDefaultValue) {
+		super(annotatedSpecificationEClass, annotationFactory, attribute, eEnum, attributeFactory,
+				attributeDefaultValue);
+		this.eEnum = eEnum;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public EditingSupport createEditingSupport(ColumnViewer viewer,
+			Class<? extends IAnnotatedSpecification> clazz) {
+
+		List<String> enumValues = new ArrayList<String>();
+		for(EEnumLiteral e : eEnum.getELiterals()) {
+			enumValues.add(e.getName());
+		}
+
+		return new ComboBoxEditingSupport(viewer, clazz, enumValues);
+	}
+}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SinglePrimitiveAttributeValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SinglePrimitiveAttributeValueProviderBase.java
deleted file mode 100644
index b8ad8fb72..000000000
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/SinglePrimitiveAttributeValueProviderBase.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*--------------------------------------------------------------------------+
-$Id$
-|                                                                          |
-| Copyright 2014 ForTISS GmbH                     |
-|                                                                          |
-| Licensed under the Apache License, Version 2.0 (the "License");          |
-| you may not use this file except in compliance with the License.         |
-| You may obtain a copy of the License at                                  |
-|                                                                          |
-|    http://www.apache.org/licenses/LICENSE-2.0                            |
-|                                                                          |
-| Unless required by applicable law or agreed to in writing, software      |
-| distributed under the License is distributed on an "AS IS" BASIS,        |
-| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-| See the License for the specific language governing permissions and      |
-| limitations under the License.                                           |
-+--------------------------------------------------------------------------*/
-package org.fortiss.tooling.base.ui.annotation.valueprovider;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EFactory;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
-import org.fortiss.tooling.base.model.element.IModelElement;
-import org.fortiss.tooling.base.model.element.IModelElementSpecification;
-
-/**
- * Base class for {@link IAnnotationValueProvider}s for {@link IAnnotatedSpecification}s that
- * contain only a single (primitive type) attribute.
- * 
- * @author barner
- * @author $Author$
- * @version $Rev$
- * @ConQAT.Rating RED Hash:
- */
-public abstract class SinglePrimitiveAttributeValueProviderBase<T extends IAnnotatedSpecification>
-		extends ValueProviderBase<T> {
-
-	/**
-	 * {@link EClass} of {@link IAnnotatedSpecification} managed by this
-	 * {@link IAnnotationValueProvider}.
-	 */
-	final private EClass annotatedSpecificationEClass;
-
-	/**
-	 * {@link EFactory} of ECore model that contains {@link IAnnotatedSpecification} identified by
-	 * {@code annotatedSpecificationEClass} (used to create new instances of the annotation).
-	 */
-	final private EFactory eFactory;
-
-	/**
-	 * {@link Class} of the primitive attribute used to implemented the storage of the underlying
-	 * {@link IAnnotatedSpecification}.
-	 */
-	final private Class<?> attributeClazz;
-
-	/**
-	 * String representation of default value used to initialize the primitive attribute of the
-	 * underlying {@link IAnnotatedSpecification}. If it is {@code null}, the default constructor
-	 * of the data type identified by {@code attributeClazz} is used to create the attribute
-	 * instance.
-	 */
-	final String attributeDefaultValue;
-
-	/**
-	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
-	 * whose storage is implemented by a single, primitive attribute. Unless the type of the
-	 * attribute (contained in {@code attributeClazz} is {@link Double} or {@link Integer}, this
-	 * constructor assumes that the attribute is default constructible. Otherwise, the new instances
-	 * of the attribute are initialized to {@code 0}.
-	 */
-	public SinglePrimitiveAttributeValueProviderBase(EClass annotatedSpecificationEClass,
-			EFactory eFactory, Class<?> attributeClazz) {
-		this(annotatedSpecificationEClass, eFactory, attributeClazz,
-				getDefaultValueInitializer(attributeClazz));
-	}
-
-	/**
-	 * Constructs a {@link IAnnotationValueProvider} for a {@link IAnnotatedSpecification} that
-	 * whose storage is implemented by a single, primitive attribute. The constructor assumes that
-	 * the attribute type has a constructor that can initialize the new instance from a
-	 * {@link String}.
-	 */
-	public SinglePrimitiveAttributeValueProviderBase(EClass annotatedSpecificationEClass,
-			EFactory eFactory, Class<?> attributeClazz, final String attributeDefaultValue) {
-		this.annotatedSpecificationEClass = annotatedSpecificationEClass;
-		this.eFactory = eFactory;
-		this.attributeClazz = attributeClazz;
-		this.attributeDefaultValue = attributeDefaultValue;
-	}
-
-	/**
-	 * Returns the initializer {@link String} in case this {@link IAnnotationValueProvider} is
-	 * constructed without specifying a default value, i.e. using
-	 * {@link #SinglePrimitiveAttributeValueProviderBase(EClass, EFactory, Class)}, or {@code null}
-	 * that indicates that the attribute type's default constructor should be used to initialize new
-	 * instances of the {@link IAnnotatedSpecification}'s attribute.
-	 */
-	private static String getDefaultValueInitializer(Class<?> attributeClazz) {
-		if(attributeClazz.equals(Double.class) || attributeClazz.equals(Integer.class)) {
-			return "0";
-		}
-
-		return null;
-	}
-
-	/**
-	 * Returns the structural {@link EStructuralFeature} of the attribute used to implement the
-	 * storage of the underlying {@link IAnnotatedSpecification}. This implementation returns the
-	 * first attribute of the annotation identified by {@code annotatedSpecificationEClass}.
-	 */
-	private EStructuralFeature getStructuralFeature() {
-		return annotatedSpecificationEClass.getEStructuralFeatures().get(0);
-	}
-
-	/** {@inheritDoc} */
-	@Override
-	public void setAnnotationValue(String value, T specification) throws Exception {
-		specification.eSet(getStructuralFeature(),
-				attributeClazz.getDeclaredConstructor(String.class).newInstance(value));
-	}
-
-	/** {@inheritDoc} */
-	@Override
-	public <U> void setAnnotationValue(U value, T specification) throws Exception {
-		specification.eSet(getStructuralFeature(), value);
-	}
-
-	/** {@inheritDoc} */
-	@SuppressWarnings("unchecked")
-	@Override
-	public <U> U getAnnotationValue(T specification) {
-		return (U)specification.eGet(getStructuralFeature());
-	}
-
-	/** {@inheritDoc} */
-	@SuppressWarnings("unchecked")
-	@Override
-	public T getAnnotatedSpecificationForModelElement(IModelElement element) throws Exception {
-		// Return existing annotation
-		for(IModelElementSpecification specification : element.getSpecifications()) {
-			if(annotatedSpecificationEClass.equals(specification.eClass())) {
-				return (T)specification;
-			}
-		}
-
-		// Create annotation
-		T specification = (T)eFactory.create(annotatedSpecificationEClass);
-		Object attributeValue;
-
-		// Create annotation attribute
-		if(attributeDefaultValue != null) {
-			attributeValue =
-					attributeClazz.getDeclaredConstructor(String.class).newInstance(
-							attributeDefaultValue);
-		} else {
-			attributeValue = attributeClazz.newInstance();
-		}
-		specification.eSet(getStructuralFeature(), attributeValue);
-
-		// Hook specification to model element
-		element.addSpecification(specification);
-
-		return specification;
-	}
-
-	/** {@inheritDoc} */
-	@SuppressWarnings("unchecked")
-	@Override
-	public Class<T> getAnnotationClazz() {
-		return (Class<T>)annotatedSpecificationEClass.getClass();
-	}
-}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java
index abe8ef1c4..0422a2bd5 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/ValueProviderBase.java
@@ -23,11 +23,12 @@ import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jface.viewers.ColumnViewer;
 import org.eclipse.jface.viewers.EditingSupport;
 import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
+import org.fortiss.tooling.base.ui.annotation.editingsupport.TextEditingSupport;
 
 /**
  * Base class for {@link IAnnotationValueProvider}s.
  * 
- * @author diewald
+ * @author diewald, barner
  * @author $Author$
  * @version $Rev$
  * @ConQAT.Rating RED Hash:
@@ -60,21 +61,17 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 
 	/** {@inheritDoc} */
 	@Override
-	public boolean allowsMultipleValues() {
+	public boolean allowsMultipleAnnotationInstances() {
 		return false;
 	}
 
 	/** {@inheritDoc} */
 	@Override
-	public List<String> getFixedValues() {
-		return null;
-	}
+	public EditingSupport createEditingSupport(ColumnViewer viewer,
+			Class<? extends IAnnotatedSpecification> clazz) {
 
-	/** {@inheritDoc} */
-	@Override
-	public EditingSupport getEditingSupport(ColumnViewer viewer,
-			Class<? extends IAnnotatedSpecification> class1, Object parent) {
-		return null;
+		// Default to text editing cell.
+		return new TextEditingSupport(viewer, clazz);
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/AnnotationLabelProvider.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/AnnotationLabelProvider.java
index 5d0c68364..7922a2956 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/AnnotationLabelProvider.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/AnnotationLabelProvider.java
@@ -56,8 +56,11 @@ public class AnnotationLabelProvider extends ColumnLabelProvider {
 	@Override
 	public String getText(Object element) {
 		if(element instanceof AnnotationEntry) {
-			AnnotationEntry data = (AnnotationEntry)element;
-			return data.getSpecificationValue(specClass).toString();
+			AnnotationEntry annotationEntry = (AnnotationEntry)element;
+			Object value = annotationEntry.getSpecificationValue(specClass);
+			if(value != null) {
+				return value.toString();
+			}
 		}
 		return "-";
 	}
diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
index f6fc12f51..d2a5a49ca 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/view/GenericAnnotationView.java
@@ -34,8 +34,6 @@ import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.wb.swt.SWTResourceManager;
 import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
 import org.fortiss.tooling.base.ui.annotation.AnnotationEntry;
-import org.fortiss.tooling.base.ui.annotation.editingsupport.ComboBoxEditingSupport;
-import org.fortiss.tooling.base.ui.annotation.editingsupport.TextEditingSupport;
 import org.fortiss.tooling.kernel.model.INamedCommentedElement;
 
 /**
@@ -143,38 +141,22 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
 	protected void createAnnotationColumn(AnnotationEntry entry, IAnnotatedSpecification spec) {
 		/* add the new column and name it */
 		TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE);
-		String specName = (String)entry.getSpecificationAnnotationName(spec.getClass());
+		String specName = entry.getSpecificationAnnotationName(spec.getClass());
 		if(specName == null)
 			specName = "Empty Annotation";
 		column.getColumn().setText(specName);
 		column.getColumn().setWidth(125);
 		annotationSpecColumns.put(spec.getClass(), column);
 
-		/*
-		 * Whenever an editing element is defined use this instead of the
-		 * generic
-		 * fixed
-		 * Combo List or the simple text edit field
-		 */
-		if(entry.getSpecificationEditElement(tableViewer, spec.getClass(), this) != null) {
-			column.setLabelProvider(new AnnotationLabelProvider(spec.getClass(), this));
-			EditingSupport editingSupport =
-					entry.getSpecificationEditElement(tableViewer, spec.getClass(), this);
-			column.setEditingSupport(editingSupport);
-		} else {
-			if(entry.getFixedSpecificationValues(spec.getClass()) == null) {
-				column.setLabelProvider(new AnnotationLabelProvider(spec.getClass(), this));
-				EditingSupport editingSupport =
-						new TextEditingSupport(column.getViewer(), spec.getClass());
-				column.setEditingSupport(editingSupport);
-			} else {
-				column.setLabelProvider(new AnnotationLabelProvider(spec.getClass(), this));
-				EditingSupport editingSupport =
-						new ComboBoxEditingSupport(column.getViewer(),
-								entry.getFixedSpecificationValues(spec.getClass()), spec.getClass());
-				column.setEditingSupport(editingSupport);
-			}
-		}
+		// Have the matching EditingSupport created for the current annotated specification
+		// (work is delegated to respective IAnnotationValueProvider implementation)
+		EditingSupport editingSupport =
+				entry.createSpecificationEditElement(tableViewer, spec.getClass());
+
+		// Add column label provider, and set EditingSupport
+		column.setLabelProvider(new AnnotationLabelProvider(spec.getClass(), this));
+		column.setEditingSupport(editingSupport);
+
 	}
 
 	/** Checks if column for given specification already exists */
-- 
GitLab