You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2014/11/10 16:59:48 UTC

[2/4] incubator-brooklyn git commit: TypeCoercions: recursively unpack for List

TypeCoercions: recursively unpack for List<T>

- e.g. if given “1,2” for type List<Integer>, then first pass will
  coerce to List.of(“1”, “2”), and second pass will coerce to
  List.of(1,2)


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/e3154097
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/e3154097
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/e3154097

Branch: refs/heads/master
Commit: e3154097506624c6c385a64fc6a2e5c466039b8d
Parents: beb87db
Author: Aled Sage <al...@gmail.com>
Authored: Fri Nov 7 19:44:14 2014 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Mon Nov 10 11:34:35 2014 +0000

----------------------------------------------------------------------
 .../java/brooklyn/util/flags/TypeCoercions.java     | 16 ++++++++++++++--
 .../brooklyn/util/internal/TypeCoercionsTest.java   |  6 ++++++
 2 files changed, 20 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e3154097/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/flags/TypeCoercions.java b/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
index f3caeaf..ec08ad0 100644
--- a/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
+++ b/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
@@ -64,6 +64,7 @@ import brooklyn.util.yaml.Yamls;
 
 import com.google.common.base.CaseFormat;
 import com.google.common.base.Function;
+import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.collect.HashBasedTable;
@@ -235,7 +236,18 @@ public class TypeCoercions {
             Map<Class, Function> adapters = registry.row(targetType);
             for (Map.Entry<Class, Function> entry : adapters.entrySet()) {
                 if (entry.getKey().isInstance(value)) {
-                    return (T) entry.getValue().apply(value);
+                    T result = (T) entry.getValue().apply(value);
+                    
+                    // Check if need to unwrap again (e.g. if want List<Integer> and are given a String "1,2,3"
+                    // then we'll have so far converted to List.of("1", "2", "3"). Call recursively.
+                    // First check that value has changed, to avoid stack overflow!
+                    if (!Objects.equal(value, result) && targetTypeToken.getType() instanceof ParameterizedType) {
+                        // Could duplicate check for `result instanceof Collection` etc; but recursive call
+                        // will be fine as if that doesn't match we'll safely reach `targetType.isInstance(value)`
+                        // and just return the result.
+                        return coerce(result, targetTypeToken);
+                    }
+                    return result;
                 }
             }
         }
@@ -459,7 +471,7 @@ public class TypeCoercions {
         return null;
     }
 
-    public synchronized static <A,B> void registerAdapter(Class<A> sourceType, Class<B> targetType, Function<A,B> fn) {
+    public synchronized static <A,B> void registerAdapter(Class<A> sourceType, Class<B> targetType, Function<? super A,B> fn) {
         registry.put(targetType, sourceType, fn);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e3154097/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java b/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
index 8ac1e9c..b4d0470 100644
--- a/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
+++ b/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
@@ -222,6 +222,12 @@ public class TypeCoercionsTest {
     }
 
     @Test
+    @SuppressWarnings("serial")
+    public void testCoerceRecursivelyStringToGenericsCollection() {
+        assertEquals(TypeCoercions.coerce("1,2", new TypeToken<List<Integer>>() {}), ImmutableList.of(1, 2));
+    }
+    
+    @Test
     public void testJsonStringToMapCoercion() {
         Map<?,?> s = TypeCoercions.coerce("{ \"a\" : \"1\", b : 2 }", Map.class);
         Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", 2));