+ * Before the initialization these will be non-null "uninitialized" objects. This is done to distinguish them from
+ * null values which could be held by the observables.
*/
private final Object[] values;
@@ -120,7 +123,7 @@ public DeepNesting(ObservableValue outerObservable, List
* Note that the loop will not stop on null observables and null values. Instead it continues and replaces all
- * stored observables and values with null. This is the desired behavior as the hierarchy is in now an incomplete
- * state and the old observables and values are obsolete and have to be replaced.
+ * stored observables and values with null. This is the desired behavior as the hierarchy is now in an incomplete
+ * state where the old observables and values are obsolete and have to be replaced.
*/
private class NestingUpdater {
@@ -394,6 +408,13 @@ private void updateInnerObservable() {
}
+ /**
+ * Represents an uninitialized entry in the {@link #values} array.
+ */
+ private static class Unitialized {
+ // no body needed
+ }
+
//#end PRIVATE CLASSES
}
diff --git a/src/test/java/org/codefx/libfx/nesting/AbstractDeepNestingTest.java b/src/test/java/org/codefx/libfx/nesting/AbstractDeepNestingTest.java
index dc8f154..a1fecf9 100644
--- a/src/test/java/org/codefx/libfx/nesting/AbstractDeepNestingTest.java
+++ b/src/test/java/org/codefx/libfx/nesting/AbstractDeepNestingTest.java
@@ -1,6 +1,8 @@
package org.codefx.libfx.nesting;
import static org.codefx.libfx.nesting.testhelper.NestingAccess.getNestingObservable;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import javafx.beans.Observable;
@@ -22,6 +24,37 @@ public abstract class AbstractDeepNestingTest
+ * This ensures that a "broken" hierarchy is correctly initialized.
+ */
+ @Test
+ public void testCreatingWhenNestedObservableHasValueNull() {
+ outerObservable = createNewNestingHierarchyWhereNestedObservableHasNullValue();
+ nesting = createNewNestingFromOuterObservable(outerObservable);
+
+ assertNotNull(nesting.innerObservableProperty().getValue());
+ assertFalse(nesting.innerObservableProperty().getValue().isPresent());
+ }
+
// nested value
/**
@@ -90,6 +123,21 @@ public void testWhenSettingOuterValueToNull() {
// #region ABSTRACT METHODS
+ /**
+ * Creates a new outer observable with a null value. The returned instances must be new for each call.
+ *
+ * @return an {@link ObservableValue} containing null
+ */
+ protected abstract OO createNewNestingHierarchyWhereOuterObservableHasNullValue();
+
+ /**
+ * Creates a new nesting hierarchy where one of the nested observables contains null and returns the outer
+ * observable. All returned instances must be new for each call.
+ *
+ * @return an {@link ObservableValue} containing the outer value of a nesting hierarchy
+ */
+ protected abstract OO createNewNestingHierarchyWhereNestedObservableHasNullValue();
+
/**
* Sets a new value of the specified kind on the specified level of the nesting hierarchy contained in the specified
* outer observable.
diff --git a/src/test/java/org/codefx/libfx/nesting/AbstractDeepNestingTestForDefaultNesting.java b/src/test/java/org/codefx/libfx/nesting/AbstractDeepNestingTestForDefaultNesting.java
index 38d02c5..40b30cf 100644
--- a/src/test/java/org/codefx/libfx/nesting/AbstractDeepNestingTestForDefaultNesting.java
+++ b/src/test/java/org/codefx/libfx/nesting/AbstractDeepNestingTestForDefaultNesting.java
@@ -28,6 +28,17 @@ protected Property