add WhenFunctions which allows `Functionals.when(false).value("F")` approach to 
building up functions


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

Branch: refs/heads/master
Commit: 45e3035de648e32487535bf7a8050d5b3926b057
Parents: 238fab7
Author: Alex Heneveld <[email protected]>
Authored: Wed Aug 6 15:38:40 2014 -0400
Committer: Alex Heneveld <[email protected]>
Committed: Mon Aug 25 09:32:26 2014 +0100

----------------------------------------------------------------------
 .../java/brooklyn/util/guava/Functionals.java   |  25 +++
 .../java/brooklyn/util/guava/WhenFunctions.java | 190 +++++++++++++++++++
 .../brooklyn/util/guava/FunctionalsTest.java    |  58 ++++++
 .../guava/KeyTransformingLoadingCacheTest.java  |   1 -
 .../brooklyn/util/guava/WhenFunctionsTest.java  |  91 +++++++++
 5 files changed, 364 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45e3035d/utils/common/src/main/java/brooklyn/util/guava/Functionals.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/guava/Functionals.java 
b/utils/common/src/main/java/brooklyn/util/guava/Functionals.java
index 6eb65e5..caebc7b 100644
--- a/utils/common/src/main/java/brooklyn/util/guava/Functionals.java
+++ b/utils/common/src/main/java/brooklyn/util/guava/Functionals.java
@@ -18,8 +18,13 @@
  */
 package brooklyn.util.guava;
 
+import brooklyn.util.guava.WhenFunctions.WhenFunctionBuilder;
+import brooklyn.util.guava.WhenFunctions.WhenFunctionBuilderWhenFirst;
+
 import com.google.common.base.Function;
 import com.google.common.base.Functions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
 
 public class Functionals {
 
@@ -38,4 +43,24 @@ public class Functionals {
         return chain(f1, chain(f2, chain(f3, f4)));
     }
 
+    /** @see WhenFunctions */
+    public static <I> WhenFunctionBuilderWhenFirst<I> when(I test) {
+        return WhenFunctions.when(test);
+    }
+    
+    /** @see WhenFunctions */
+    public static <I> WhenFunctionBuilderWhenFirst<I> when(Predicate<I> test) {
+        return WhenFunctions.when(test);
+    }
+
+    /** @see WhenFunctions */
+    public static <I,O> WhenFunctionBuilder<I,O> when(Predicate<I> test, 
Supplier<O> supplier) {
+        return WhenFunctions.when(test, supplier);
+    }
+    
+    /** @see WhenFunctions */
+    public static <I,O> WhenFunctionBuilder<I,O> when(Predicate<I> test, O 
value) {
+        return WhenFunctions.when(test, value);
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45e3035d/utils/common/src/main/java/brooklyn/util/guava/WhenFunctions.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/guava/WhenFunctions.java 
b/utils/common/src/main/java/brooklyn/util/guava/WhenFunctions.java
new file mode 100644
index 0000000..50a1e35
--- /dev/null
+++ b/utils/common/src/main/java/brooklyn/util/guava/WhenFunctions.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.util.guava;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+
+/** Utilities for building {@link Function} instances which return specific 
values
+ * (or {@link Supplier} instances) when certain predicates are satisfied,
+ * tested in order and returning the first matching,
+ * with support for an "else" default value if none are satisfied (null by 
default). */
+public class WhenFunctions {
+
+    public static <I,O> WhenFunctionBuilder<I,O> newInstance(Class<I> 
testType, Class<O> returnType) {
+        return new WhenFunctionBuilder<I,O>();
+    }
+    
+    public static <I,O> WhenFunctionBuilderWhenFirst<I> when(Predicate<I> 
test) {
+        return new WhenFunctionBuilderWhenFirst<I>(test);
+    }
+    public static <I,O> WhenFunctionBuilderWhenFirst<I> when(I test) {
+        return new WhenFunctionBuilderWhenFirst<I>(test);
+    }
+    public static <I,O> WhenFunctionBuilder<I,O> when(Predicate<I> test, 
Supplier<O> supplier) {
+        return new WhenFunctionBuilder<I,O>().when(test, supplier);
+    }
+    public static <I,O> WhenFunctionBuilder<I,O> when(Predicate<I> test, O 
value) {
+        return new WhenFunctionBuilder<I,O>().when(test, value);
+    }
+    
+    public static class WhenFunction<I,O> implements Function<I,O> {
+        protected final Map<Predicate<I>,Supplier<O>> tests = new 
LinkedHashMap<Predicate<I>,Supplier<O>>();
+        protected Supplier<O> defaultValue = null;
+        
+        protected WhenFunction(WhenFunction<I,O> input) {
+            this.tests.putAll(input.tests);
+            this.defaultValue = input.defaultValue;
+        }
+
+        protected WhenFunction() {
+        }
+        
+        @Override
+        public O apply(I input) {
+            for (Map.Entry<Predicate<I>,Supplier<O>> test: tests.entrySet()) {
+                if (test.getKey().apply(input)) 
+                    return test.getValue().get();
+            }
+            return defaultValue==null ? null : defaultValue.get();
+        }
+        
+        @Override
+        public String toString() {
+            return "if["+tests+"]"+(defaultValue!=null ? 
"-else["+defaultValue+"]" : "");
+        }
+    }
+    
+    public static class WhenFunctionBuilder<I,O> extends WhenFunction<I,O> {
+        protected WhenFunctionBuilder() { super(); }
+        protected WhenFunctionBuilder(WhenFunction<I,O> input) { super(input); 
}
+        
+        public WhenFunction<I,O> build() {
+            return new WhenFunction<I,O>(this);
+        }
+        
+        public WhenFunctionBuilder<I,O> when(Predicate<I> test, Supplier<O> 
supplier) {
+            return when(test).value(supplier);
+        }
+
+        public WhenFunctionBuilder<I,O> when(Predicate<I> test, O value) {
+            return when(test).value(value);
+        }
+
+        public WhenFunctionBuilderWhen<I,O> when(Predicate<I> test) {
+            return whenUnchecked(test);
+        }
+        public WhenFunctionBuilderWhen<I,O> when(I test) {
+            return whenUnchecked(test);
+        }
+        @SuppressWarnings("unchecked")
+        protected WhenFunctionBuilderWhen<I,O> whenUnchecked(Object test) {
+            if (!(test instanceof Predicate)) {
+                test = Predicates.equalTo(test);
+            }
+            return new WhenFunctionBuilderWhen<I,O>(this, (Predicate<I>)test);
+        }
+
+        public WhenFunctionBuilder<I,O> defaultValue(O defaultValue) {
+            return defaultValueUnchecked(defaultValue);
+        }
+        public WhenFunctionBuilder<I,O> defaultValue(Supplier<O> defaultValue) 
{
+            return defaultValueUnchecked(defaultValue);
+        }
+        @SuppressWarnings("unchecked")
+        protected WhenFunctionBuilder<I,O> defaultValueUnchecked(Object 
defaultValue) {
+            if (!(defaultValue instanceof Supplier)) {
+                defaultValue = Suppliers.ofInstance(defaultValue);
+            }
+            WhenFunctionBuilder<I, O> result = new 
WhenFunctionBuilder<I,O>(this);
+            result.defaultValue = (Supplier<O>)defaultValue;
+            return result;
+        }
+    }
+
+    public static class WhenFunctionBuilderWhen<I,O> {
+        private WhenFunction<I, O> input;
+        private Predicate<I> test;
+        
+        private WhenFunctionBuilderWhen(WhenFunction<I,O> input, Predicate<I> 
test) {
+            this.input = input;
+            this.test = test;
+        }
+        
+        public WhenFunctionBuilder<I,O> value(O value) {
+            return valueUnchecked(value);
+        }
+        public WhenFunctionBuilder<I,O> value(Supplier<O> value) {
+            return valueUnchecked(value);
+        }
+        @SuppressWarnings("unchecked")
+        protected WhenFunctionBuilder<I,O> valueUnchecked(Object value) {
+            if (!(value instanceof Supplier)) {
+                value = Suppliers.ofInstance(value);
+            }
+            WhenFunctionBuilder<I, O> result = new 
WhenFunctionBuilder<I,O>(input);
+            result.tests.put(test, (Supplier<O>) value);
+            return result;
+        }
+    }
+
+    public static class WhenFunctionBuilderWhenFirst<I> {
+        private Predicate<I> test;
+        
+        private WhenFunctionBuilderWhenFirst(Predicate<I> test) {
+            whenUnchecked(test);
+        }
+        
+        public WhenFunctionBuilderWhenFirst(I test) {
+            whenUnchecked(test);
+        }
+
+        @SuppressWarnings("unchecked")
+        protected void whenUnchecked(Object test) {
+            if (!(test instanceof Predicate)) {
+                this.test = Predicates.equalTo((I)test);
+            } else {
+                this.test = (Predicate<I>) test;
+            }
+        }
+        
+        public <O> WhenFunctionBuilder<I,O> value(O value) {
+            return valueUnchecked(value);
+        }
+        public <O> WhenFunctionBuilder<I,O> value(Supplier<O> value) {
+            return valueUnchecked(value);
+        }
+        @SuppressWarnings("unchecked")
+        protected <O> WhenFunctionBuilder<I,O> valueUnchecked(Object value) {
+            if (!(value instanceof Supplier)) {
+                value = Suppliers.ofInstance(value);
+            }
+            WhenFunctionBuilder<I, O> result = new WhenFunctionBuilder<I,O>();
+            result.tests.put(test, (Supplier<O>) value);
+            return result;
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45e3035d/utils/common/src/test/java/brooklyn/util/guava/FunctionalsTest.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/test/java/brooklyn/util/guava/FunctionalsTest.java 
b/utils/common/src/test/java/brooklyn/util/guava/FunctionalsTest.java
new file mode 100644
index 0000000..7e2ab35
--- /dev/null
+++ b/utils/common/src/test/java/brooklyn/util/guava/FunctionalsTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.util.guava;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.util.math.MathFunctions;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Suppliers;
+
+public class FunctionalsTest {
+
+    @Test
+    public void testChain() {
+        Assert.assertEquals(Functionals.chain(MathFunctions.plus(1), 
MathFunctions.times(2)).apply(3), (Integer)8);
+        Assert.assertEquals(Functionals.chain(MathFunctions.times(2), 
MathFunctions.plus(1)).apply(3), (Integer)7);
+    }
+
+    @Test
+    public void testWhen() {
+        
WhenFunctionsTest.checkTF(Functionals.when(false).value("F").when(true).value("T").defaultValue("?").build(),
 "?");
+    }
+
+    @Test
+    public void testWhenNoBuilder() {
+        
WhenFunctionsTest.checkTF(Functionals.when(false).value("F").when(true).value("T").defaultValue("?"),
 "?");
+    }
+    
+    @Test
+    public void testWhenPredicateAndSupplier() {
+        
WhenFunctionsTest.checkTF(Functionals.when(Predicates.equalTo(false)).value(Suppliers.ofInstance("F"))
+            
.when(true).value("T").defaultValue(Suppliers.ofInstance("?")).build(), "?");
+    }
+
+    @Test
+    public void testWhenTwoArgs() {
+        WhenFunctionsTest.checkTF(Functionals.when(Predicates.equalTo(false), 
"F").when(Predicates.equalTo(true), "T").defaultValue("?").build(), "?");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45e3035d/utils/common/src/test/java/brooklyn/util/guava/KeyTransformingLoadingCacheTest.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/test/java/brooklyn/util/guava/KeyTransformingLoadingCacheTest.java
 
b/utils/common/src/test/java/brooklyn/util/guava/KeyTransformingLoadingCacheTest.java
index 1f85b23..ed3c3ad 100644
--- 
a/utils/common/src/test/java/brooklyn/util/guava/KeyTransformingLoadingCacheTest.java
+++ 
b/utils/common/src/test/java/brooklyn/util/guava/KeyTransformingLoadingCacheTest.java
@@ -34,7 +34,6 @@ import com.google.common.cache.LoadingCache;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
 
 public class KeyTransformingLoadingCacheTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/45e3035d/utils/common/src/test/java/brooklyn/util/guava/WhenFunctionsTest.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/test/java/brooklyn/util/guava/WhenFunctionsTest.java 
b/utils/common/src/test/java/brooklyn/util/guava/WhenFunctionsTest.java
new file mode 100644
index 0000000..2b01b14
--- /dev/null
+++ b/utils/common/src/test/java/brooklyn/util/guava/WhenFunctionsTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.util.guava;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.util.guava.WhenFunctions.WhenFunctionBuilder;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.base.Suppliers;
+
+public class WhenFunctionsTest {
+
+    @Test
+    public void testWhen() {
+        
checkTF(WhenFunctions.when(false).value("F").when(true).value("T").defaultValue("?").build(),
 "?");
+    }
+
+    @Test
+    public void testWhenNoBuilder() {
+        
checkTF(WhenFunctions.when(false).value("F").when(true).value("T").defaultValue("?"),
 "?");
+    }
+    
+    @Test
+    public void testWhenPredicateAndSupplier() {
+        
checkTF(WhenFunctions.when(Predicates.equalTo(false)).value(Suppliers.ofInstance("F"))
+            
.when(true).value("T").defaultValue(Suppliers.ofInstance("?")).build(), "?");
+    }
+
+    @Test
+    public void testWhenTwoArgs() {
+        checkTF(WhenFunctions.when(Predicates.equalTo(false), 
"F").when(Predicates.equalTo(true), "T").defaultValue("?").build(), "?");
+    }
+    
+    @Test
+    public void testWhenNoDefault() {
+        
checkTF(WhenFunctions.when(false).value("F").when(true).value("T").build(), 
null);
+    }
+
+    @Test
+    public void testWhenWithCast() {
+        Function<Boolean, String> f = 
WhenFunctions.<Boolean,String>when(false).value("F").when(true).value("T").defaultValue("?").build();
+        checkTF(f, "?");
+    }
+
+    @Test
+    public void testWhenWithoutCast() {
+        Function<Boolean, String> f = WhenFunctions.newInstance(Boolean.class, 
String.class).when(false).value("F").when(true).value("T").defaultValue("?").build();
+        checkTF(f, "?");
+    }
+
+    @Test
+    public void testWhenSupportsReplace() {
+        
checkTF(WhenFunctions.when(false).value("false").when(false).value("F").when(true).value("T").defaultValue("?").build(),
 "?");
+    }
+
+    @Test
+    public void testWhenIsImmutableAndSupportsReplace() {
+        WhenFunctionBuilder<Boolean, String> f = 
WhenFunctions.when(false).value("F").when(true).value("T").defaultValue("?");
+        WhenFunctionBuilder<Boolean, String> f2 = 
f.when(false).value("false").defaultValue("X");
+        WhenFunctionBuilder<Boolean, String> f3 = f2.when(false).value("F");
+        checkTF(f, "?");
+        checkTF(f3, "X");
+        Assert.assertEquals(f2.apply(false), "false");
+    }
+
+    static void checkTF(Function<Boolean, String> f, Object defaultValue) {
+        Assert.assertEquals(f.apply(true), "T");
+        Assert.assertEquals(f.apply(false), "F");
+        Assert.assertEquals(f.apply(null), defaultValue);
+    }
+    
+}

Reply via email to