You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2021/07/28 20:53:49 UTC

[sling-org-apache-sling-scripting-sightly-runtime] branch master updated: SLING-10679 wrap every object in a single item list (#9)

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-runtime.git


The following commit(s) were added to refs/heads/master by this push:
     new 6bcc04f  SLING-10679 wrap every object in a single item list (#9)
6bcc04f is described below

commit 6bcc04f159290aac39f0f6fa725da0a87f59076b
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Wed Jul 28 22:53:42 2021 +0200

    SLING-10679 wrap every object in a single item list (#9)
    
    make all returned collections immutable
---
 pom.xml                                            |  6 ++++
 .../scripting/sightly/render/ObjectModel.java      | 40 +++++++++-------------
 .../scripting/sightly/render/ObjectModelTest.java  |  7 ++--
 3 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/pom.xml b/pom.xml
index d9eec9e..fa76f2f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -167,6 +167,12 @@
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <version>2.2</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/src/main/java/org/apache/sling/scripting/sightly/render/ObjectModel.java b/src/main/java/org/apache/sling/scripting/sightly/render/ObjectModel.java
index 26b6d81..ea13772 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/render/ObjectModel.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/render/ObjectModel.java
@@ -258,7 +258,7 @@ public final class ObjectModel {
     }
 
     /**
-     * Forces the conversion of the passed {@code object} to a collection, according to the following rules:
+     * Forces the conversion of the passed {@code object} to an immutable collection, according to the following rules:
      *
      * <ul>
      *     <li>if the {@code object} is {@code null} an empty collection will be returned</li>
@@ -268,40 +268,41 @@ public final class ObjectModel {
      *     <li>if the {@code object} is an instance of an {@link Enumeration} a list transformation will be returned</li>
      *     <li>if the {@code object} is an instance of an {@link Iterator} or {@link Iterable} the result of {@link #fromIterator(Iterator)}
      *     will be returned</li>
-     *     <li>if the {@code object} is an instance of a {@link String} or {@link Number} a {@link Collection} containing only this
-     *     object will be returned</li>
-     *     <li>any other case not covered by the previous rules will result in an empty {@link Collection}</li>
+     *     <li>otherwise the {@code object} is wrapped in a single item list</li>
      * </ul>
      *
      * @param object the target object
-     * @return the collection representation of the object
+     * @return the immutable collection representation of the object
      */
     public static Collection<Object> toCollection(Object object) {
         if (object == null) {
             return Collections.emptyList();
         }
         if (object instanceof Object[]) {
-            return Arrays.asList((Object[]) object);
+            return Collections.unmodifiableList(Arrays.asList((Object[]) object));
         }
         if (object.getClass().isArray()) {
             int length = Array.getLength(object);
-            Collection<Object> list = new ArrayList<>();
+            List<Object> list = new ArrayList<>();
             for (int i = 0; i < length; i++) {
                 list.add(Array.get(object, i));
             }
-            return list;
+            return Collections.unmodifiableList(list);
         }
         if (object instanceof Optional) {
             return toCollection(((Optional) object).orElse(Collections.emptyList()));
         }
+        if (object instanceof List) {
+            return Collections.unmodifiableList((List<Object>) object);
+        }
         if (object instanceof Collection) {
-            return (Collection<Object>) object;
+            return Collections.unmodifiableCollection((Collection<Object>) object);
         }
         if (object instanceof Map) {
-            return ((Map) object).keySet();
+            return Collections.unmodifiableCollection(((Map) object).keySet());
         }
         if (object instanceof Enumeration) {
-            return Collections.list((Enumeration<Object>) object);
+            return Collections.unmodifiableList(Collections.list((Enumeration<Object>) object));
         }
         if (object instanceof Iterator) {
             return fromIterator((Iterator<Object>) object);
@@ -310,12 +311,7 @@ public final class ObjectModel {
             Iterable<Object> iterable = (Iterable<Object>) object;
             return fromIterator(iterable.iterator());
         }
-        if (object instanceof String || object instanceof Number) {
-            Collection<Object> list = new ArrayList<>();
-            list.add(object);
-            return list;
-        }
-        return Collections.emptyList();
+        return Collections.singletonList(object);
     }
 
     /**
@@ -341,17 +337,15 @@ public final class ObjectModel {
      * Given an {@code iterator}, this method will return a {@link Collection}.
      *
      * @param iterator the iterator to be transformed into a {@code collection}
-     * @return a collection with the iterator's elements
+     * @return an immutable collection with the iterator's elements
      */
     public static Collection<Object> fromIterator(Iterator<Object> iterator) {
         if (iterator == null) {
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
         ArrayList<Object> result = new ArrayList<>();
-        while (iterator.hasNext()) {
-            result.add(iterator.next());
-        }
-        return result;
+        iterator.forEachRemaining(result::add);
+        return Collections.unmodifiableList(result);
     }
 
     /**
diff --git a/src/test/java/org/apache/sling/scripting/sightly/render/ObjectModelTest.java b/src/test/java/org/apache/sling/scripting/sightly/render/ObjectModelTest.java
index 1942492..1ddc7b1 100644
--- a/src/test/java/org/apache/sling/scripting/sightly/render/ObjectModelTest.java
+++ b/src/test/java/org/apache/sling/scripting/sightly/render/ObjectModelTest.java
@@ -34,6 +34,8 @@ import java.util.Vector;
 import org.apache.sling.scripting.sightly.render.testobjects.Person;
 import org.apache.sling.scripting.sightly.render.testobjects.TestEnum;
 import org.apache.sling.scripting.sightly.render.testobjects.internal.AdultFactory;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -141,7 +143,8 @@ public class ObjectModelTest {
     @Test
     public void testToCollection() {
         assertTrue(ObjectModel.toCollection(null).isEmpty());
-        assertTrue(ObjectModel.toCollection(new StringBuilder()).isEmpty());
+        StringBuilder sb = new StringBuilder();
+        assertEquals(Collections.singletonList(sb), ObjectModel.toCollection(sb));
         Integer[] testArray = new Integer[] {1, 2, 3};
         int[] testPrimitiveArray = new int[] {1, 2, 3};
         List<Integer> testList = Arrays.asList(testArray);
@@ -152,7 +155,7 @@ public class ObjectModelTest {
         assertEquals(testList, ObjectModel.toCollection(testArray));
         assertEquals(testList, ObjectModel.toCollection(testPrimitiveArray));
         assertEquals(testList, ObjectModel.toCollection(testList));
-        assertEquals(map.keySet(), ObjectModel.toCollection(map));
+        MatcherAssert.assertThat(ObjectModel.toCollection(map), Matchers.contains(map.keySet().toArray()));
         Vector<Integer> vector = new Vector<>(testList);
         assertEquals(testList, ObjectModel.toCollection(vector.elements()));
         assertEquals(testList, ObjectModel.toCollection(testList.iterator()));