View Javadoc

1   //========================================================================
2   //Copyright 2011-2012 Mort Bay Consulting Pty. Ltd.
3   //------------------------------------------------------------------------
4   //All rights reserved. This program and the accompanying materials
5   //are made available under the terms of the Eclipse Public License v1.0
6   //and Apache License v2.0 which accompanies this distribution.
7   //The Eclipse Public License is available at
8   //http://www.eclipse.org/legal/epl-v10.html
9   //The Apache License v2.0 is available at
10  //http://www.opensource.org/licenses/apache2.0.php
11  //You may elect to redistribute this code under either of these licenses.
12  //========================================================================
13  
14  package org.eclipse.jetty.spdy;
15  
16  import java.util.concurrent.CancellationException;
17  import java.util.concurrent.CountDownLatch;
18  import java.util.concurrent.ExecutionException;
19  import java.util.concurrent.Future;
20  import java.util.concurrent.TimeUnit;
21  import java.util.concurrent.TimeoutException;
22  
23  import org.eclipse.jetty.spdy.api.Handler;
24  
25  /**
26   * <p>A {@link Promise} is a {@link Future} that allows a result or a failure to be set,
27   * so that the {@link Future} will be {@link #isDone() done}.</p>
28   *
29   * @param <T> the type of the result object
30   */
31  public class Promise<T> implements Handler<T>, Future<T>
32  {
33      private final CountDownLatch latch = new CountDownLatch(1);
34      private boolean cancelled;
35      private Throwable failure;
36      private T promise;
37  
38      @Override
39      public void completed(T result)
40      {
41          this.promise = result;
42          latch.countDown();
43      }
44  
45      @Override
46      public void failed(T context, Throwable x)
47      {
48          this.failure = x;
49          latch.countDown();
50      }
51  
52      @Override
53      public boolean cancel(boolean mayInterruptIfRunning)
54      {
55          cancelled = true;
56          latch.countDown();
57          return true;
58      }
59  
60      @Override
61      public boolean isCancelled()
62      {
63          return cancelled;
64      }
65  
66      @Override
67      public boolean isDone()
68      {
69          return cancelled || latch.getCount() == 0;
70      }
71  
72      @Override
73      public T get() throws InterruptedException, ExecutionException
74      {
75          latch.await();
76          return result();
77      }
78  
79      @Override
80      public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
81      {
82          boolean elapsed = !latch.await(timeout, unit);
83          if (elapsed)
84              throw new TimeoutException();
85          return result();
86      }
87  
88      private T result() throws ExecutionException
89      {
90          if (isCancelled())
91              throw new CancellationException();
92          Throwable failure = this.failure;
93          if (failure != null)
94              throw new ExecutionException(failure);
95          return promise;
96      }
97  }