View Javadoc
1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.util;
20  
21  import java.util.concurrent.CompletableFuture;
22  
23  import org.eclipse.jetty.util.thread.Invocable;
24  
25  /**
26   * <p>A callback abstraction that handles completed/failed events of asynchronous operations.</p>
27   *
28   * <p>Semantically this is equivalent to an optimise Promise&lt;Void&gt;, but callback is a more meaningful
29   * name than EmptyPromise</p>
30   */
31  public interface Callback extends Invocable
32  {
33      /**
34       * Instance of Adapter that can be used when the callback methods need an empty
35       * implementation without incurring in the cost of allocating a new Adapter object.
36       */
37      static Callback NOOP = new Callback()
38      {
39      };
40  
41      /**
42       * <p>Callback invoked when the operation completes.</p>
43       *
44       * @see #failed(Throwable)
45       */
46      default void succeeded()
47      {
48      }
49  
50      /**
51       * <p>Callback invoked when the operation fails.</p>
52       * @param x the reason for the operation failure
53       */
54      default void failed(Throwable x)
55      {
56      }
57  
58      /**
59       * <p>Creates a non-blocking callback from the given incomplete CompletableFuture.</p>
60       * <p>When the callback completes, either succeeding or failing, the
61       * CompletableFuture is also completed, respectively via
62       * {@link CompletableFuture#complete(Object)} or
63       * {@link CompletableFuture#completeExceptionally(Throwable)}.</p>
64       *
65       * @param completable the CompletableFuture to convert into a callback
66       * @return a callback that when completed, completes the given CompletableFuture
67       */
68      static Callback from(CompletableFuture<?> completable)
69      {
70          return from(completable, InvocationType.NON_BLOCKING);
71      }
72  
73      /**
74       * <p>Creates a callback from the given incomplete CompletableFuture,
75       * with the given {@code blocking} characteristic.</p>
76       *
77       * @param completable the CompletableFuture to convert into a callback
78       * @param invocation whether the callback is blocking
79       * @return a callback that when completed, completes the given CompletableFuture
80       */
81      static Callback from(CompletableFuture<?> completable, InvocationType invocation)
82      {
83          if (completable instanceof Callback)
84              return (Callback)completable;
85  
86          return new Callback()
87          {
88              @Override
89              public void succeeded()
90              {
91                  completable.complete(null);
92              }
93  
94              @Override
95              public void failed(Throwable x)
96              {
97                  completable.completeExceptionally(x);
98              }
99  
100             @Override
101             public InvocationType getInvocationType()
102             {
103                 return invocation;
104             }
105         };
106     }
107 
108     class Nested implements Callback
109     {
110         private final Callback callback;
111 
112         public Nested(Callback callback)
113         {
114             this.callback = callback;
115         }
116 
117         public Nested(Nested nested)
118         {
119             this.callback = nested.callback;
120         }
121 
122         @Override
123         public void succeeded()
124         {
125             callback.succeeded();
126         }
127 
128         @Override
129         public void failed(Throwable x)
130         {
131             callback.failed(x);
132         }
133 
134         @Override
135         public InvocationType getInvocationType()
136         {
137             return callback.getInvocationType();
138         }
139     }
140     /**
141      * <p>A CompletableFuture that is also a Callback.</p>
142      */
143     class Completable extends CompletableFuture<Void> implements Callback
144     {
145         private final InvocationType invocation;
146 
147         public Completable()
148         {
149             this(Invocable.InvocationType.NON_BLOCKING);
150         }
151 
152         public Completable(InvocationType invocation)
153         {
154             this.invocation = invocation;
155         }
156 
157         @Override
158         public void succeeded()
159         {
160             complete(null);
161         }
162 
163         @Override
164         public void failed(Throwable x)
165         {
166             completeExceptionally(x);
167         }
168 
169         @Override
170         public InvocationType getInvocationType()
171         {
172             return invocation;
173         }
174     }
175 }