Merge branch 'feature/SLING-8066'
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockNode.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockNode.java
index db7bdc0..27806c8 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockNode.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockNode.java
@@ -195,8 +195,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItemOrRemoveIfValueNull(itemData, value);
return property;
}
@@ -205,8 +204,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(values);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItemOrRemoveIfValueNull(itemData, values);
return property;
}
@@ -215,8 +213,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(values);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItemOrRemoveIfValueNull(itemData, values);
return property;
}
@@ -225,8 +222,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItemOrRemoveIfValueNull(itemData, value);
return property;
}
@@ -236,8 +232,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItemOrRemoveIfValueNull(itemData, value);
return property;
}
@@ -246,8 +241,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItem(itemData);
return property;
}
@@ -256,8 +250,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItem(itemData);
return property;
}
@@ -266,8 +259,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItem(itemData);
return property;
}
@@ -276,8 +268,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItemOrRemoveIfValueNull(itemData, value);
return property;
}
@@ -286,8 +277,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItemOrRemoveIfValueNull(itemData, value);
return property;
}
@@ -296,8 +286,7 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
- getMockedSession().addItem(itemData);
- this.itemData.setIsChanged(true);
+ addItemOrRemoveIfValueNull(itemData, value);
return property;
}
@@ -306,9 +295,34 @@
ItemData itemData = ItemData.newProperty(getPath() + "/" + name);
Property property = new MockProperty(itemData, getSession());
property.setValue(value);
+ addItemOrRemoveIfValueNull(itemData, value);
+ return property;
+ }
+
+ /**
+ * Adds or overwrites an item and marks the item value as changed.
+ * @param itemData Item data
+ * @throws RepositoryException
+ */
+ private void addItem(ItemData itemData) throws RepositoryException {
getMockedSession().addItem(itemData);
this.itemData.setIsChanged(true);
- return property;
+ }
+
+ /**
+ * Adds or overwrites an item and marks the item value as changed.
+ * If the given value is null, the item is removed instead.
+ * @param itemData Item data
+ * @throws RepositoryException
+ */
+ private void addItemOrRemoveIfValueNull(ItemData itemData, Object value) throws RepositoryException {
+ if (value == null) {
+ getMockedSession().removeItem(itemData.getPath());
+ }
+ else {
+ getMockedSession().addItem(itemData);
+ }
+ this.itemData.setIsChanged(true);
}
@Override
diff --git a/src/main/java/org/apache/sling/testing/mock/jcr/MockProperty.java b/src/main/java/org/apache/sling/testing/mock/jcr/MockProperty.java
index 291a165..bb15aef 100644
--- a/src/main/java/org/apache/sling/testing/mock/jcr/MockProperty.java
+++ b/src/main/java/org/apache/sling/testing/mock/jcr/MockProperty.java
@@ -80,12 +80,18 @@
@Override
public void setValue(final Value newValue) throws RepositoryException {
+ if (removePropertyIfValueNull(newValue)) {
+ return;
+ }
this.itemData.setValues(new Value[] { newValue });
this.itemData.setMultiple(false);
}
@Override
public void setValue(final Value[] newValues) throws RepositoryException {
+ if (removePropertyIfValueNull(newValues)) {
+ return;
+ }
Value[] values = new Value[newValues.length];
for (int i = 0; i < newValues.length; i++) {
values[i] = newValues[i];
@@ -96,12 +102,18 @@
@Override
public void setValue(final String newValue) throws RepositoryException {
+ if (removePropertyIfValueNull(newValue)) {
+ return;
+ }
this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
this.itemData.setMultiple(false);
}
@Override
public void setValue(final String[] newValues) throws RepositoryException {
+ if (removePropertyIfValueNull(newValues)) {
+ return;
+ }
Value[] values = new Value[newValues.length];
for (int i = 0; i < newValues.length; i++) {
values[i] = getSession().getValueFactory().createValue(newValues[i]);
@@ -112,6 +124,9 @@
@Override
public void setValue(final InputStream newValue) throws RepositoryException {
+ if (removePropertyIfValueNull(newValue)) {
+ return;
+ }
this.itemData.setValues(new Value[] { new BinaryValue(newValue) });
this.itemData.setMultiple(false);
}
@@ -130,6 +145,9 @@
@Override
public void setValue(final Calendar newValue) throws RepositoryException {
+ if (removePropertyIfValueNull(newValue)) {
+ return;
+ }
this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
this.itemData.setMultiple(false);
}
@@ -142,21 +160,44 @@
@Override
public void setValue(final Node newValue) throws RepositoryException {
+ if (removePropertyIfValueNull(newValue)) {
+ return;
+ }
this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
this.itemData.setMultiple(false);
}
@Override
public void setValue(final Binary newValue) throws RepositoryException {
+ if (removePropertyIfValueNull(newValue)) {
+ return;
+ }
this.itemData.setValues(new Value[] { new BinaryValue(newValue) });
this.itemData.setMultiple(false);
}
@Override
public void setValue(final BigDecimal newValue) throws RepositoryException {
+ if (removePropertyIfValueNull(newValue)) {
+ return;
+ }
this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
this.itemData.setMultiple(false);
}
+
+ /**
+ * Removes the current property (itself) if the given value is null.
+ * @param value Value to check
+ * @return true if property was removed
+ * @throws RepositoryException
+ */
+ private boolean removePropertyIfValueNull(Object value) throws RepositoryException {
+ if (value == null) {
+ remove();
+ return true;
+ }
+ return false;
+ }
@Override
public boolean getBoolean() throws RepositoryException {
@@ -206,7 +247,7 @@
}
else {
return PropertyType.UNDEFINED;
- }
+ }
}
@Override
@@ -253,7 +294,7 @@
}
return false;
}
-
+
// --- unsupported operations ---
@Override
public Node getNode() throws RepositoryException {
@@ -286,7 +327,7 @@
public boolean isProtected() {
return false;
}
-
+
@Override
public boolean isFullTextSearchable() {
return false;
@@ -296,7 +337,7 @@
public boolean isQueryOrderable() {
return false;
}
-
+
// --- unsupported operations ---
@Override
public Value[] getDefaultValues() {
diff --git a/src/test/java/org/apache/sling/testing/mock/jcr/MockPropertyTest.java b/src/test/java/org/apache/sling/testing/mock/jcr/MockPropertyTest.java
index 949dbb3..640ff8c 100644
--- a/src/test/java/org/apache/sling/testing/mock/jcr/MockPropertyTest.java
+++ b/src/test/java/org/apache/sling/testing/mock/jcr/MockPropertyTest.java
@@ -25,6 +25,7 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Calendar;
@@ -87,6 +88,22 @@
}
@Test
+ public void testStringSetNullViaNode() throws RepositoryException {
+ this.node1.setProperty("prop1", "value1");
+
+ this.node1.setProperty("prop1", (String)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
+ public void testStringSetNullViaProp() throws RepositoryException {
+ this.node1.setProperty("prop1", "value1");
+
+ this.node1.getProperty("prop1").setValue((String)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
public void testStringArray() throws RepositoryException {
String[] value1 = new String[] { "aaa", "bbb" };
this.node1.setProperty("prop1", value1);
@@ -110,6 +127,24 @@
}
@Test
+ public void testStringArraySetNullViaNode() throws RepositoryException {
+ String[] value1 = new String[] { "aaa", "bbb" };
+ this.node1.setProperty("prop1", value1);
+
+ this.node1.setProperty("prop1", (String[])null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
+ public void testStringArraySetNullViaProp() throws RepositoryException {
+ String[] value1 = new String[] { "aaa", "bbb" };
+ this.node1.setProperty("prop1", value1);
+
+ this.node1.getProperty("prop1").setValue((String[])null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
public void testBoolean() throws RepositoryException {
this.node1.setProperty("prop1", true);
Property prop1 = this.node1.getProperty("prop1");
@@ -158,6 +193,22 @@
}
@Test
+ public void testBigDecimalSetNullViaNode() throws RepositoryException {
+ this.node1.setProperty("prop1", new BigDecimal("1.5"));
+
+ this.node1.setProperty("prop1", (BigDecimal)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
+ public void testBigDecimalSetNullViaProp() throws RepositoryException {
+ this.node1.setProperty("prop1", new BigDecimal("1.5"));
+
+ this.node1.getProperty("prop1").setValue((BigDecimal)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
public void testCalendar() throws RepositoryException {
Calendar value1 = Calendar.getInstance();
@@ -175,6 +226,24 @@
}
@Test
+ public void testCalendarSetNullViaNode() throws RepositoryException {
+ Calendar value1 = Calendar.getInstance();
+ this.node1.setProperty("prop1", value1);
+
+ this.node1.setProperty("prop1", (Calendar)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
+ public void testCalendarSetNullViaProp() throws RepositoryException {
+ Calendar value1 = Calendar.getInstance();
+ this.node1.setProperty("prop1", value1);
+
+ this.node1.getProperty("prop1").setValue((Calendar)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
public void testBinary() throws RepositoryException, IOException {
byte[] value1 = new byte[] { 0x01, 0x01, 0x03 };
@@ -190,6 +259,24 @@
assertArrayEquals(value2, IOUtils.toByteArray(prop1.getValue().getBinary().getStream()));
}
+ @Test
+ public void testBinarySetNullViaNode() throws RepositoryException {
+ byte[] value1 = new byte[] { 0x01, 0x01, 0x03 };
+ this.node1.setProperty("prop1", new BinaryValue(value1).getBinary());
+
+ this.node1.setProperty("prop1", (BinaryValue)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
+ public void testBinarySetNullViaProp() throws RepositoryException {
+ byte[] value1 = new byte[] { 0x01, 0x01, 0x03 };
+ this.node1.setProperty("prop1", new BinaryValue(value1).getBinary());
+
+ this.node1.getProperty("prop1").setValue((BinaryValue)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
@SuppressWarnings("deprecation")
@Test
public void testInputStream() throws RepositoryException, IOException {
@@ -205,6 +292,26 @@
assertArrayEquals(value2, IOUtils.toByteArray(prop1.getValue().getStream()));
}
+ @SuppressWarnings("deprecation")
+ @Test
+ public void testInputStreamSetNullViaNode() throws RepositoryException {
+ byte[] value1 = new byte[] { 0x01, 0x01, 0x03 };
+ this.node1.setProperty("prop1", new ByteArrayInputStream(value1));
+
+ this.node1.setProperty("prop1", (InputStream)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void testInputStreamSetNullViaProp() throws RepositoryException {
+ byte[] value1 = new byte[] { 0x01, 0x01, 0x03 };
+ this.node1.setProperty("prop1", new ByteArrayInputStream(value1));
+
+ this.node1.getProperty("prop1").setValue((InputStream)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
@Test
public void testValue() throws RepositoryException {
this.node1.setProperty("prop1", this.session.getValueFactory().createValue("value1"));
@@ -222,6 +329,22 @@
}
@Test
+ public void testValueSetNullViaNode() throws RepositoryException {
+ this.node1.setProperty("prop1", this.session.getValueFactory().createValue("value1"));
+
+ this.node1.setProperty("prop1", (Value)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
+ public void testValueSetNullViaProp() throws RepositoryException {
+ this.node1.setProperty("prop1", this.session.getValueFactory().createValue("value1"));
+
+ this.node1.getProperty("prop1").setValue((Value)null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
public void testValueArray() throws RepositoryException {
Value[] value1 = new Value[] { this.session.getValueFactory().createValue("aaa"),
this.session.getValueFactory().createValue("bbb") };
@@ -246,6 +369,26 @@
}
@Test
+ public void testValueArraySetNullViaNode() throws RepositoryException {
+ Value[] value1 = new Value[] { this.session.getValueFactory().createValue("aaa"),
+ this.session.getValueFactory().createValue("bbb") };
+ this.node1.setProperty("prop1", value1);
+
+ this.node1.setProperty("prop1", (Value[])null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
+ public void testValueArraySetNullViaProp() throws RepositoryException {
+ Value[] value1 = new Value[] { this.session.getValueFactory().createValue("aaa"),
+ this.session.getValueFactory().createValue("bbb") };
+ this.node1.setProperty("prop1", value1);
+
+ this.node1.getProperty("prop1").setValue((Value[])null);
+ assertFalse(this.node1.hasProperty("prop1"));
+ }
+
+ @Test
public void testEmptyArrayGetType() throws RepositoryException {
this.node1.setProperty("prop1", new Value[] {});
Property prop1 = this.node1.getProperty("prop1");