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);
+ }
+
+}