View Javadoc
1   package io.atlassian.fugue;
2   
3   /**
4    * Helpers to work with functions that may throw exceptions. Used with
5    * {@link Try}.
6    *
7    * @since 4.4.0
8    */
9   @SuppressWarnings({ "WeakerAccess", "unused" }) public class Checked {
10    // do not ctor
11    private Checked() {}
12  
13    /**
14     * Represents a {@link Function} that may throw an exception.
15     *
16     * @param <A> the type of the input to the function
17     * @param <B> the type of the result of the function
18     * @param <E> The type of exception potentially thrown
19     */
20    @SuppressWarnings("unused") @FunctionalInterface public interface Function<A, B, E extends Exception> {
21      B apply(A t) throws E;
22  
23      default java.util.function.Function<A, Try<B>> lift() {
24        return Checked.lift(this);
25      }
26    }
27  
28    /**
29     * Represents a {@link Supplier} that may throw an exception.
30     *
31     * @param <A> the type of the result of the supplier
32     * @param <E> The type of exception potentially thrown
33     */
34    @SuppressWarnings("unused") @FunctionalInterface public interface Supplier<A, E extends Exception> {
35      A get() throws E;
36  
37      default Try<A> attempt() {
38        return now(this);
39      }
40    }
41  
42    /**
43     * Lifts a function that potentially throws into a function that either
44     * returns a Success of the value or a failure containing the thrown
45     * exception.
46     *
47     * @param f a function that can throw
48     * @param <A> the function argument type
49     * @param <B> the function return type
50     * @param <E> The type of exception potentially thrown
51     * @return the argument function lifted into returning a Try
52     *
53     */
54    public static <A, B, E extends Exception> java.util.function.Function<A, Try<B>> lift(Checked.Function<A, B, E> f) {
55      return a -> Checked.now(() -> f.apply(a));
56    }
57  
58    /**
59     * Lifts a function that potentially throws into a function that either
60     * returns a delayed Try, which, when evaluated, returns a Success of the
61     * result or a failure containing the thrown exception.
62     *
63     * @param f a function that can throw
64     * @param <A> the function argument type
65     * @param <B> the function return type
66     * @param <E> The type of exception potentially thrown
67     * @return the argument function lifted into returning a delayed Try
68     *
69     */
70    public static <A, B, E extends Exception> java.util.function.Function<A, Try<B>> delayedLift(Checked.Function<A, B, E> f) {
71      return a -> Checked.delay(() -> f.apply(a));
72    }
73  
74    /**
75     * Create a new Try representing the result of a potentially exception
76     * throwing operation. If the provided supplier throws an exception this will
77     * return a failure wrapping the exception, otherwise a success of the
78     * supplied value will be returned.
79     *
80     * @param s a supplier that may throw an exception
81     * @param <A> the type of value s supplies
82     * @param <E> The type of exception potentially thrown
83     * @return If s throws an exception this will return a failure wrapping the
84     * exception, otherwise a success of the supplied value.
85     * @deprecated since 4.6 This is being replaced with {@link #now(Supplier)} to
86     * make it clear that the supplier is evaluated immediately. If the evaluation
87     * needs to be delayed, use {@link #delay(Supplier)}.
88     */
89    @Deprecated public static <A, E extends Exception> Try<A> of(Checked.Supplier<A, E> s) {
90      return now(s);
91    }
92  
93    /**
94     * Create a new Try representing the result of a potentially exception
95     * throwing operation. The provided supplier is evaluated immediately. If the
96     * provided supplier throws an exception this will return a failure wrapping
97     * the exception, otherwise a success of the supplied value will be returned.
98     *
99     * @param s a supplier that may throw an exception
100    * @param <A> the type of value s supplies
101    * @param <E> The type of exception potentially thrown
102    * @return If s throws an exception this will return a failure wrapping the
103    * exception, otherwise a success of the supplied value.
104    */
105   public static <A, E extends Exception> Try<A> now(Checked.Supplier<A, E> s) {
106     try {
107       return Try.successful(s.get());
108     } catch (final Exception e) {
109       return Try.failure(e);
110     }
111   }
112 
113   /**
114    * Create a new delayed Try representing a delayed evaluation of a potentially
115    * exception throwing operation. The provided supplier is only called when the
116    * delayed Try is evaluated. The provided supplier is called only once no
117    * matter how many times the returned delayed Try is evaluated. If the
118    * provided supplier throws an exception the evaluation of the delayed Try
119    * will return a failure wrapping the exception, otherwise a success of the
120    * supplied value will be returned.
121    *
122    * @param s a supplier that may throw an exception
123    * @param <A> the type of value s supplies
124    * @param <E> The type of exception potentially thrown
125    * @return a delayed Try. If s throws an exception this, when evaluated, will
126    * return a failure wrapping the exception, otherwise a success of the
127    * supplied value.
128    */
129   public static <A, E extends Exception> Try<A> delay(Checked.Supplier<A, E> s) {
130     return Try.delayed(() -> now(s));
131   }
132 }