From 2b59d35887879fb9ac5d25474d1556b7e910fa2f Mon Sep 17 00:00:00 2001
From: Simon Barner <barner@fortiss.org>
Date: Fri, 5 Sep 2014 08:06:56 +0000
Subject: [PATCH] - EStructuralFeatureValueProviderBase: Gracefully handle the
 case that instance keys returned by getInstanceKeys() are not backed by a
 EStructuralFeatureValue - Concrete value providers may use this to implement
 an overlay of e.g. derived/computed annotations onto a concrete
 IAnnotationSpecification that consists of one or more EAttributes refs 1841

---
 .../EStructuralFeatureValueProviderBase.java  | 38 ++++++++++++++-----
 .../valueprovider/ValueProviderBase.java      | 10 ++++-
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java
index 23ac948b4..ba7cfb967 100644
--- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java
+++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/annotation/valueprovider/EStructuralFeatureValueProviderBase.java
@@ -107,14 +107,32 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 		handlesMultipleEstructuralFeatures = true;
 	}
 
+	/**
+	 * Returns the {@link EStructuralFeatureDescriptor} for a given {@code instanceKey}, or throws
+	 * an exception, if the key is unknown.
+	 * 
+	 */
+	protected EStructuralFeatureDescriptor getEStructuralFeatureDescriptor(String instanceKey)
+			throws Exception {
+		EStructuralFeatureDescriptor fd = structuralFeatureDescriptorMap.get(instanceKey);
+		if(fd == null) {
+			throw new Exception("Instance key " + instanceKey +
+					" is unknown for annotation provider " +
+					annotatedSpecificationEClass.getInstanceClassName() + ".");
+		}
+
+		return fd;
+	}
+
 	/**
 	 * Sets a value for a {@link IAnnotatedSpecification} from a {@link String} representation of
 	 * the input.
 	 */
 	private <V> void
-			setAnnotationValueFromString(String value, T specification, String instanceKey) {
+			setAnnotationValueFromString(String value, T specification, String instanceKey)
+					throws Exception {
 
-		EStructuralFeatureDescriptor fd = structuralFeatureDescriptorMap.get(instanceKey);
+		EStructuralFeatureDescriptor fd = getEStructuralFeatureDescriptor(instanceKey);
 
 		specification.eSet(
 				fd.getStructuralFeature(),
@@ -142,8 +160,8 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 
 			setAnnotationValueFromString((String)value, specification, instanceKey);
 		} else {
-			specification.eSet(structuralFeatureDescriptorMap.get(instanceKey)
-					.getStructuralFeature(), value);
+			specification.eSet(getEStructuralFeatureDescriptor(instanceKey).getStructuralFeature(),
+					value);
 		}
 	}
 
@@ -166,7 +184,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 		}
 
 		EStructuralFeature structuralFeature =
-				structuralFeatureDescriptorMap.get(instanceKey).getStructuralFeature();
+				getEStructuralFeatureDescriptor(instanceKey).getStructuralFeature();
 
 		if(structuralFeature instanceof EAttribute) {
 			setAnnotationValueFromString(value, specification, instanceKey);
@@ -189,7 +207,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 	@SuppressWarnings("unchecked")
 	@Override
 	public <U> U getAnnotationValue(T specification, String instanceKey) throws Exception {
-		return (U)specification.eGet(structuralFeatureDescriptorMap.get(instanceKey)
+		return (U)specification.eGet(getEStructuralFeatureDescriptor(instanceKey)
 				.getStructuralFeature());
 	}
 
@@ -205,7 +223,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 	 * {@link #getAnnotatedSpecificationForModelElement(IModelElement)}.
 	 */
 	protected Object createStructuralFeatureInstance(String instanceKey) throws Exception {
-		EStructuralFeatureDescriptor fd = structuralFeatureDescriptorMap.get(instanceKey);
+		EStructuralFeatureDescriptor fd = getEStructuralFeatureDescriptor(instanceKey);
 
 		if(fd.getStructuralFeature() instanceof EAttribute) {
 
@@ -246,7 +264,7 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 		} else {
 			throw new Exception(
 					"createStructuralFeatureInstance() is not supported / has not been implemented the annotation type " +
-							fd.getStructuralFeature().getEType().getName() + ".");
+							fd.getStructuralFeature().getName() + ".");
 		}
 	}
 
@@ -258,8 +276,8 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
 		// Create and set structural feature implementing the annotation
 		Object structuralFeatureVal = createStructuralFeatureInstance(instanceKey);
 		if(structuralFeatureVal != null) {
-			specification.eSet(structuralFeatureDescriptorMap.get(instanceKey)
-					.getStructuralFeature(), structuralFeatureVal);
+			specification.eSet(getEStructuralFeatureDescriptor(instanceKey).getStructuralFeature(),
+					structuralFeatureVal);
 		}
 	}
 
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 a8081095c..6244062db 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
@@ -215,7 +215,15 @@ public abstract class ValueProviderBase<T extends IAnnotatedSpecification> imple
 			decorateAnnotationSpecification(specification);
 		} else {
 			for(String key : getInstanceKeys(specification)) {
-				decorateAnnotationSpecification(specification, key);
+				try {
+					decorateAnnotationSpecification(specification, key);
+				} catch(Exception e) {
+					// Some of the keys might not be backed by an implementation that needs to
+					// "decorate" the underlying specification object (e.g., a custom key that
+					// represents a calculated, volatile value. Hence, just ignore invalid keys
+					// during this setup phase. The other methods (get/set/...) will throw an
+					// Exception on invalid keys.
+				}
 			}
 		}
 
-- 
GitLab