001    /*
002     * Copyright (C) 2007 The Guava Authors
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package com.google.common.base;
018    
019    import static com.google.common.base.Preconditions.checkArgument;
020    import static com.google.common.base.Preconditions.checkNotNull;
021    
022    import com.google.common.annotations.Beta;
023    import com.google.common.annotations.GwtCompatible;
024    
025    import java.io.Serializable;
026    import java.util.Map;
027    
028    import javax.annotation.Nullable;
029    
030    /**
031     * Static utility methods pertaining to {@code Function} instances.
032     *
033     * <p>All methods returns serializable functions as long as they're given serializable parameters.
034     *
035     * @author Mike Bostock
036     * @author Jared Levy
037     * @since 2.0 (imported from Google Collections Library)
038     */
039    @GwtCompatible
040    public final class Functions {
041      private Functions() {}
042    
043      /**
044       * Returns a function that calls {@code toString()} on its argument. The function does not accept
045       * nulls; it will throw a {@link NullPointerException} when applied to {@code null}.
046       *
047       * <p><b>Warning:</b> The returned function may not be <i>consistent with equals</i> (as
048       * documented at {@link Function#apply}). For example, this function yields different results for
049       * the two equal instances {@code ImmutableSet.of(1, 2)} and {@code ImmutableSet.of(2, 1)}.
050       */
051      public static Function<Object, String> toStringFunction() {
052        return ToStringFunction.INSTANCE;
053      }
054    
055      // enum singleton pattern
056      private enum ToStringFunction implements Function<Object, String> {
057        INSTANCE;
058    
059        @Override
060        public String apply(Object o) {
061          checkNotNull(o);  // eager for GWT.
062          return o.toString();
063        }
064    
065        @Override public String toString() {
066          return "toString";
067        }
068      }
069    
070      /**
071       * Returns the identity function.
072       */
073      @SuppressWarnings("unchecked")
074      public static <E> Function<E, E> identity() {
075        return (Function<E, E>) IdentityFunction.INSTANCE;
076      }
077    
078      // enum singleton pattern
079      private enum IdentityFunction implements Function<Object, Object> {
080        INSTANCE;
081    
082        @Override
083        public Object apply(Object o) {
084          return o;
085        }
086    
087        @Override public String toString() {
088          return "identity";
089        }
090      }
091    
092      /**
093       * Returns a function which performs a map lookup. The returned function throws an {@link
094       * IllegalArgumentException} if given a key that does not exist in the map.
095       */
096      public static <K, V> Function<K, V> forMap(Map<K, V> map) {
097        return new FunctionForMapNoDefault<K, V>(map);
098      }
099    
100      private static class FunctionForMapNoDefault<K, V> implements Function<K, V>, Serializable {
101        final Map<K, V> map;
102    
103        FunctionForMapNoDefault(Map<K, V> map) {
104          this.map = checkNotNull(map);
105        }
106    
107        @Override
108        public V apply(K key) {
109          V result = map.get(key);
110          checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
111          return result;
112        }
113    
114        @Override public boolean equals(@Nullable Object o) {
115          if (o instanceof FunctionForMapNoDefault) {
116            FunctionForMapNoDefault<?, ?> that = (FunctionForMapNoDefault<?, ?>) o;
117            return map.equals(that.map);
118          }
119          return false;
120        }
121    
122        @Override public int hashCode() {
123          return map.hashCode();
124        }
125    
126        @Override public String toString() {
127          return "forMap(" + map + ")";
128        }
129    
130        private static final long serialVersionUID = 0;
131      }
132    
133      /**
134       * Returns a function which performs a map lookup with a default value. The function created by
135       * this method returns {@code defaultValue} for all inputs that do not belong to the map's key
136       * set.
137       *
138       * @param map source map that determines the function behavior
139       * @param defaultValue the value to return for inputs that aren't map keys
140       * @return function that returns {@code map.get(a)} when {@code a} is a key, or {@code
141       *         defaultValue} otherwise
142       */
143      public static <K, V> Function<K, V> forMap(Map<K, ? extends V> map, @Nullable V defaultValue) {
144        return new ForMapWithDefault<K, V>(map, defaultValue);
145      }
146    
147      private static class ForMapWithDefault<K, V> implements Function<K, V>, Serializable {
148        final Map<K, ? extends V> map;
149        final V defaultValue;
150    
151        ForMapWithDefault(Map<K, ? extends V> map, @Nullable V defaultValue) {
152          this.map = checkNotNull(map);
153          this.defaultValue = defaultValue;
154        }
155    
156        @Override
157        public V apply(K key) {
158          V result = map.get(key);
159          return (result != null || map.containsKey(key)) ? result : defaultValue;
160        }
161    
162        @Override public boolean equals(@Nullable Object o) {
163          if (o instanceof ForMapWithDefault) {
164            ForMapWithDefault<?, ?> that = (ForMapWithDefault<?, ?>) o;
165            return map.equals(that.map) && Objects.equal(defaultValue, that.defaultValue);
166          }
167          return false;
168        }
169    
170        @Override public int hashCode() {
171          return Objects.hashCode(map, defaultValue);
172        }
173    
174        @Override public String toString() {
175          return "forMap(" + map + ", defaultValue=" + defaultValue + ")";
176        }
177    
178        private static final long serialVersionUID = 0;
179      }
180    
181      /**
182       * Returns the composition of two functions. For {@code f: A->B} and {@code g: B->C}, composition
183       * is defined as the function h such that {@code h(a) == g(f(a))} for each {@code a}.
184       *
185       * @param g the second function to apply
186       * @param f the first function to apply
187       * @return the composition of {@code f} and {@code g}
188       * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
189       */
190      public static <A, B, C> Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) {
191        return new FunctionComposition<A, B, C>(g, f);
192      }
193    
194      private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable {
195        private final Function<B, C> g;
196        private final Function<A, ? extends B> f;
197    
198        public FunctionComposition(Function<B, C> g, Function<A, ? extends B> f) {
199          this.g = checkNotNull(g);
200          this.f = checkNotNull(f);
201        }
202    
203        @Override
204        public C apply(A a) {
205          return g.apply(f.apply(a));
206        }
207    
208        @Override public boolean equals(@Nullable Object obj) {
209          if (obj instanceof FunctionComposition) {
210            FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
211            return f.equals(that.f) && g.equals(that.g);
212          }
213          return false;
214        }
215    
216        @Override public int hashCode() {
217          return f.hashCode() ^ g.hashCode();
218        }
219    
220        @Override public String toString() {
221          return g.toString() + "(" + f.toString() + ")";
222        }
223    
224        private static final long serialVersionUID = 0;
225      }
226    
227      /**
228       * Creates a function that returns the same boolean output as the given predicate for all inputs.
229       *
230       * <p>The returned function is <i>consistent with equals</i> (as documented at {@link
231       * Function#apply}) if and only if {@code predicate} is itself consistent with equals.
232       */
233      public static <T> Function<T, Boolean> forPredicate(Predicate<T> predicate) {
234        return new PredicateFunction<T>(predicate);
235      }
236    
237      /** @see Functions#forPredicate */
238      private static class PredicateFunction<T> implements Function<T, Boolean>, Serializable {
239        private final Predicate<T> predicate;
240    
241        private PredicateFunction(Predicate<T> predicate) {
242          this.predicate = checkNotNull(predicate);
243        }
244    
245        @Override
246        public Boolean apply(T t) {
247          return predicate.apply(t);
248        }
249    
250        @Override public boolean equals(@Nullable Object obj) {
251          if (obj instanceof PredicateFunction) {
252            PredicateFunction<?> that = (PredicateFunction<?>) obj;
253            return predicate.equals(that.predicate);
254          }
255          return false;
256        }
257    
258        @Override public int hashCode() {
259          return predicate.hashCode();
260        }
261    
262        @Override public String toString() {
263          return "forPredicate(" + predicate + ")";
264        }
265    
266        private static final long serialVersionUID = 0;
267      }
268    
269      /**
270       * Creates a function that returns {@code value} for any input.
271       *
272       * @param value the constant value for the function to return
273       * @return a function that always returns {@code value}
274       */
275      public static <E> Function<Object, E> constant(@Nullable E value) {
276        return new ConstantFunction<E>(value);
277      }
278    
279      private static class ConstantFunction<E> implements Function<Object, E>, Serializable {
280        private final E value;
281    
282        public ConstantFunction(@Nullable E value) {
283          this.value = value;
284        }
285    
286        @Override
287        public E apply(@Nullable Object from) {
288          return value;
289        }
290    
291        @Override public boolean equals(@Nullable Object obj) {
292          if (obj instanceof ConstantFunction) {
293            ConstantFunction<?> that = (ConstantFunction<?>) obj;
294            return Objects.equal(value, that.value);
295          }
296          return false;
297        }
298    
299        @Override public int hashCode() {
300          return (value == null) ? 0 : value.hashCode();
301        }
302    
303        @Override public String toString() {
304          return "constant(" + value + ")";
305        }
306    
307        private static final long serialVersionUID = 0;
308      }
309    
310      /**
311       * Returns a function that always returns the result of invoking {@link Supplier#get} on {@code
312       * supplier}, regardless of its input.
313       * 
314       * @since 10.0
315       */
316      @Beta
317      public static <T> Function<Object, T> forSupplier(Supplier<T> supplier) {
318        return new SupplierFunction<T>(supplier);
319      }
320    
321      /** @see Functions#forSupplier*/
322      private static class SupplierFunction<T> implements Function<Object, T>, Serializable {
323        
324        private final Supplier<T> supplier;
325    
326        private SupplierFunction(Supplier<T> supplier) {
327          this.supplier = checkNotNull(supplier);
328        }
329    
330        @Override public T apply(@Nullable Object input) {
331          return supplier.get();
332        }
333        
334        @Override public boolean equals(@Nullable Object obj) {
335          if (obj instanceof SupplierFunction) {
336            SupplierFunction<?> that = (SupplierFunction<?>) obj;
337            return this.supplier.equals(that.supplier);
338          }
339          return false;
340        }
341        
342        @Override public int hashCode() {
343          return supplier.hashCode();
344        }
345        
346        @Override public String toString() {
347          return "forSupplier(" + supplier + ")";
348        }
349        
350        private static final long serialVersionUID = 0;
351      }
352    }