/* * 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 org.apache.brooklyn.util.guava; import java.util.LinkedHashMap; import java.util.Map; import com.google.common.annotations.Beta; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.base.Supplier; /** Utilities for building {@link Function} instances which return specific values * (or {@link Supplier} or {@link Function} 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 IfFunctions { public static <I,O> IfFunctionBuilder<I,O> newInstance(Class<I> testType, Class<O> returnType) { return new IfFunctionBuilder<I,O>(); } public static <I> IfFunctionBuilderApplyingFirst<I> ifPredicate(Predicate<? super I> test) { return new IfFunctionBuilderApplyingFirst<I>(test); } public static <I> IfFunctionBuilderApplyingFirst<I> ifEquals(I test) { return ifPredicate(Predicates.equalTo(test)); } public static <I> IfFunctionBuilderApplyingFirst<I> ifNotEquals(I test) { return ifPredicate(Predicates.not(Predicates.equalTo(test))); } @Beta public static class IfFunction<I,O> implements Function<I,O> { protected final Map<Predicate<? super I>,Function<? super I,? extends O>> tests = new LinkedHashMap<Predicate<? super I>,Function<? super I,? extends O>>(); protected Function<? super I,? extends O> defaultFunction = null; protected IfFunction(IfFunction<I,O> input) { this.tests.putAll(input.tests); this.defaultFunction = input.defaultFunction; } protected IfFunction() { } @Override public O apply(I input) { for (Map.Entry<Predicate<? super I>,Function<? super I,? extends O>> test: tests.entrySet()) { if (test.getKey().apply(input)) return test.getValue().apply(input); } return defaultFunction==null ? null : defaultFunction.apply(input); } @Override public String toString() { return "if["+tests+"]"+(defaultFunction!=null ? "-else["+defaultFunction+"]" : ""); } } @Beta public static class IfFunctionBuilder<I,O> extends IfFunction<I,O> { protected IfFunctionBuilder() { super(); } protected IfFunctionBuilder(IfFunction<I,O> input) { super(input); } public IfFunction<I,O> build() { return new IfFunction<I,O>(this); } public IfFunctionBuilderApplying<I,O> ifPredicate(Predicate<I> test) { return new IfFunctionBuilderApplying<I,O>(this, (Predicate<I>)test); } public IfFunctionBuilderApplying<I,O> ifEquals(I test) { return ifPredicate(Predicates.equalTo(test)); } public IfFunctionBuilderApplying<I,O> ifNotEquals(I test) { return ifPredicate(Predicates.not(Predicates.equalTo(test))); } public IfFunctionBuilder<I,O> defaultValue(O defaultValue) { return defaultApply(new Functionals.ConstantFunction<I,O>(defaultValue, defaultValue)); } @SuppressWarnings("unchecked") public IfFunctionBuilder<I,O> defaultGet(Supplier<? extends O> defaultSupplier) { return defaultApply((Function<I,O>)Functions.forSupplier(defaultSupplier)); } public IfFunctionBuilder<I,O> defaultApply(Function<? super I,? extends O> defaultFunction) { IfFunctionBuilder<I, O> result = new IfFunctionBuilder<I,O>(this); result.defaultFunction = defaultFunction; return result; } } @Beta public static class IfFunctionBuilderApplying<I,O> { private IfFunction<I, O> input; private Predicate<? super I> test; private IfFunctionBuilderApplying(IfFunction<I,O> input, Predicate<? super I> test) { this.input = input; this.test = test; } public IfFunctionBuilder<I,O> value(O value) { return apply(new Functionals.ConstantFunction<I,O>(value, value)); } @SuppressWarnings("unchecked") public IfFunctionBuilder<I,O> get(Supplier<? extends O> supplier) { return apply((Function<I,O>)Functions.forSupplier(supplier)); } public IfFunctionBuilder<I,O> apply(Function<? super I,? extends O> function) { IfFunctionBuilder<I, O> result = new IfFunctionBuilder<I,O>(input); result.tests.put(test, function); return result; } } @Beta public static class IfFunctionBuilderApplyingFirst<I> { private Predicate<? super I> test; private IfFunctionBuilderApplyingFirst(Predicate<? super I> test) { this.test = test; } public <O> IfFunctionBuilder<I,O> value(O value) { return apply(new Functionals.ConstantFunction<I,O>(value, value)); } @SuppressWarnings("unchecked") public <O> IfFunctionBuilder<I,O> get(Supplier<? extends O> supplier) { return apply((Function<I,O>)Functions.forSupplier(supplier)); } public <O> IfFunctionBuilder<I,O> apply(Function<? super I,? extends O> function) { IfFunctionBuilder<I, O> result = new IfFunctionBuilder<I,O>(); result.tests.put(test, function); return result; } } }