1 /* 2 * Copyright (C) 2016 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.internal.codegen.extension; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 import static com.google.common.collect.Lists.asList; 21 22 import java.util.Comparator; 23 import java.util.Optional; 24 import java.util.function.Function; 25 26 /** Utilities for {@link Optional}s. */ 27 public final class Optionals { 28 /** 29 * A {@link Comparator} that puts empty {@link Optional}s before present ones, and compares 30 * present {@link Optional}s by their values. 31 */ optionalComparator()32 public static <C extends Comparable<C>> Comparator<Optional<C>> optionalComparator() { 33 return Comparator.comparing((Optional<C> optional) -> optional.isPresent()) 34 .thenComparing(Optional::get); 35 } 36 emptiesLast(Comparator<? super T> valueComparator)37 public static <T> Comparator<Optional<T>> emptiesLast(Comparator<? super T> valueComparator) { 38 checkNotNull(valueComparator); 39 return Comparator.comparing(o -> o.orElse(null), Comparator.nullsLast(valueComparator)); 40 } 41 42 /** Returns the first argument that is present, or empty if none are. */ 43 @SafeVarargs firstPresent( Optional<T> first, Optional<T> second, Optional<T>... rest)44 public static <T> Optional<T> firstPresent( 45 Optional<T> first, Optional<T> second, Optional<T>... rest) { 46 return asList(first, second, rest).stream() 47 .filter(Optional::isPresent) 48 .findFirst() 49 .orElse(Optional.empty()); 50 } 51 52 /** 53 * Walks a chain of present optionals as defined by successive calls to {@code nextFunction}, 54 * returning the value of the final optional that is present. The first optional in the chain is 55 * the result of {@code nextFunction(start)}. 56 */ rootmostValue(T start, Function<T, Optional<T>> nextFunction)57 public static <T> T rootmostValue(T start, Function<T, Optional<T>> nextFunction) { 58 T current = start; 59 for (Optional<T> next = nextFunction.apply(start); 60 next.isPresent(); 61 next = nextFunction.apply(current)) { 62 current = next.get(); 63 } 64 return current; 65 } 66 Optionals()67 private Optionals() {} 68 } 69