Bug 411147 - ServiceLocator#getService(Class) may register an invalid service object; IEclipseContext#get(Class) does not handle NOT_A_VALUE
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/contexts/IContextFunction.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/contexts/IContextFunction.java
index 4a4f0c8..e10d32d 100644
--- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/contexts/IContextFunction.java
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/contexts/IContextFunction.java
@@ -67,7 +67,8 @@
* @param contextKey
* The context key used to find this function; may be {@code null} such
* as if invoked directly.
- * @return The concrete value.
+ * @return The concrete value. Implementations may return {@link org.eclipse.e4.core.di.IInjector#NOT_A_VALUE}
+ * to cause lookup to continue up the context hierarchy.
*/
public Object compute(IEclipseContext context, String contextKey);
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
index 5552533..6203a16 100644
--- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
@@ -217,8 +217,12 @@
public Object internalGet(EclipseContext originatingContext, String name, boolean local) {
if (this == originatingContext) {
ValueComputation valueComputation = localValueComputations.get(name);
- if (valueComputation != null)
- return valueComputation.get();
+ if (valueComputation != null) {
+ Object result = valueComputation.get();
+ if (result != IInjector.NOT_A_VALUE) {
+ return result;
+ }
+ }
}
Object result = null;
@@ -670,8 +674,12 @@
Map<String, Object> result = new HashMap<String, Object>(localValueComputations.size());
for (String string : localValueComputations.keySet()) {
ValueComputation vc = localValueComputations.get(string);
- if (vc != null)
- result.put(string, vc.get());
+ if (vc != null) {
+ Object r = vc.get();
+ if (r != IInjector.NOT_A_VALUE) {
+ result.put(string, vc.get());
+ }
+ }
}
return result;
}
diff --git a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/EclipseContextTest.java b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/EclipseContextTest.java
index 1423f4c..21e186a 100644
--- a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/EclipseContextTest.java
+++ b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/EclipseContextTest.java
@@ -330,6 +330,10 @@
}
});
+ // must call several times as the underlying ValueComputation wrapper is
+ // created on the first time, but re-used for subsequent calls.
+ assertNull(context.get("x"));
+ assertNull(context.get("x"));
assertNull(context.get("x"));
context.dispose();
}