View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. 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, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.channel;
17  
18  import io.netty.util.concurrent.AbstractFuture;
19  import io.netty.util.concurrent.Future;
20  import io.netty.util.concurrent.GenericFutureListener;
21  import io.netty.util.internal.UnstableApi;
22  
23  import java.util.concurrent.TimeUnit;
24  
25  @UnstableApi
26  public final class VoidChannelPromise extends AbstractFuture<Void> implements ChannelPromise {
27  
28      private final Channel channel;
29      private final boolean fireException;
30  
31      /**
32       * Creates a new instance.
33       *
34       * @param channel the {@link Channel} associated with this future
35       */
36      public VoidChannelPromise(Channel channel, boolean fireException) {
37          if (channel == null) {
38              throw new NullPointerException("channel");
39          }
40          this.channel = channel;
41          this.fireException = fireException;
42      }
43  
44      @Override
45      public VoidChannelPromise addListener(GenericFutureListener<? extends Future<? super Void>> listener) {
46          fail();
47          return this;
48      }
49  
50      @Override
51      public VoidChannelPromise addListeners(GenericFutureListener<? extends Future<? super Void>>... listeners) {
52          fail();
53          return this;
54      }
55  
56      @Override
57      public VoidChannelPromise removeListener(GenericFutureListener<? extends Future<? super Void>> listener) {
58          // NOOP
59          return this;
60      }
61  
62      @Override
63      public VoidChannelPromise removeListeners(GenericFutureListener<? extends Future<? super Void>>... listeners) {
64          // NOOP
65          return this;
66      }
67  
68      @Override
69      public VoidChannelPromise await() throws InterruptedException {
70          if (Thread.interrupted()) {
71              throw new InterruptedException();
72          }
73          return this;
74      }
75  
76      @Override
77      public boolean await(long timeout, TimeUnit unit) {
78          fail();
79          return false;
80      }
81  
82      @Override
83      public boolean await(long timeoutMillis) {
84          fail();
85          return false;
86      }
87  
88      @Override
89      public VoidChannelPromise awaitUninterruptibly() {
90          fail();
91          return this;
92      }
93  
94      @Override
95      public boolean awaitUninterruptibly(long timeout, TimeUnit unit) {
96          fail();
97          return false;
98      }
99  
100     @Override
101     public boolean awaitUninterruptibly(long timeoutMillis) {
102         fail();
103         return false;
104     }
105 
106     @Override
107     public Channel channel() {
108         return channel;
109     }
110 
111     @Override
112     public boolean isDone() {
113         return false;
114     }
115 
116     @Override
117     public boolean isSuccess() {
118         return false;
119     }
120 
121     @Override
122     public boolean setUncancellable() {
123         return true;
124     }
125 
126     @Override
127     public boolean isCancellable() {
128         return false;
129     }
130 
131     @Override
132     public boolean isCancelled() {
133         return false;
134     }
135 
136     @Override
137     public Throwable cause() {
138         return null;
139     }
140 
141     @Override
142     public VoidChannelPromise sync() {
143         fail();
144         return this;
145     }
146 
147     @Override
148     public VoidChannelPromise syncUninterruptibly() {
149         fail();
150         return this;
151     }
152     @Override
153     public VoidChannelPromise setFailure(Throwable cause) {
154         fireException(cause);
155         return this;
156     }
157 
158     @Override
159     public VoidChannelPromise setSuccess() {
160         return this;
161     }
162 
163     @Override
164     public boolean tryFailure(Throwable cause) {
165         fireException(cause);
166         return false;
167     }
168 
169     @Override
170     public boolean cancel(boolean mayInterruptIfRunning) {
171         return false;
172     }
173 
174     @Override
175     public boolean trySuccess() {
176         return false;
177     }
178 
179     private static void fail() {
180         throw new IllegalStateException("void future");
181     }
182 
183     @Override
184     public VoidChannelPromise setSuccess(Void result) {
185         return this;
186     }
187 
188     @Override
189     public boolean trySuccess(Void result) {
190         return false;
191     }
192 
193     @Override
194     public Void getNow() {
195         return null;
196     }
197 
198     @Override
199     public ChannelPromise unvoid() {
200         ChannelPromise promise = new DefaultChannelPromise(channel);
201         if (fireException) {
202             promise.addListener(new ChannelFutureListener() {
203                 @Override
204                 public void operationComplete(ChannelFuture future) throws Exception {
205                     if (!future.isSuccess()) {
206                         fireException(future.cause());
207                     }
208                 }
209             });
210         }
211         return promise;
212     }
213 
214     @Override
215     public boolean isVoid() {
216         return true;
217     }
218 
219     private void fireException(Throwable cause) {
220         // Only fire the exception if the channel is open and registered
221         // if not the pipeline is not setup and so it would hit the tail
222         // of the pipeline.
223         // See https://github.com/netty/netty/issues/1517
224         if (fireException && channel.isRegistered()) {
225             channel.pipeline().fireExceptionCaught(cause);
226         }
227     }
228 }