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 org.jboss.netty.channel;
17
18 import static org.jboss.netty.channel.Channels.*;
19
20 /**
21 * A skeletal {@link ChannelSink} implementation.
22 */
23 public abstract class AbstractChannelSink implements ChannelSink {
24
25 /**
26 * Creates a new instance.
27 */
28 protected AbstractChannelSink() {
29 }
30
31 /**
32 * Sends an {@link ExceptionEvent} upstream with the specified
33 * {@code cause}.
34 *
35 * @param event the {@link ChannelEvent} which caused a
36 * {@link ChannelHandler} to raise an exception
37 * @param cause the exception raised by a {@link ChannelHandler}
38 */
39 public void exceptionCaught(ChannelPipeline pipeline,
40 ChannelEvent event, ChannelPipelineException cause) throws Exception {
41 Throwable actualCause = cause.getCause();
42 if (actualCause == null) {
43 actualCause = cause;
44 }
45 if (isFireExceptionCaughtLater(event, actualCause)) {
46 fireExceptionCaughtLater(event.getChannel(), actualCause);
47 } else {
48 fireExceptionCaught(event.getChannel(), actualCause);
49 }
50 }
51
52 /**
53 * Returns {@code true} if and only if the specified {@code actualCause}, which was raised while
54 * handling the specified {@code event}, must trigger an {@code exceptionCaught()} event in
55 * an I/O thread.
56 *
57 * @param event the event which raised exception
58 * @param actualCause the raised exception
59 */
60 protected boolean isFireExceptionCaughtLater(ChannelEvent event, Throwable actualCause) {
61 return false;
62 }
63
64 /**
65 * This implementation just directly call {@link Runnable#run()}.
66 * Sub-classes should override this if they can handle it in a better way
67 */
68 public ChannelFuture execute(ChannelPipeline pipeline, Runnable task) {
69 try {
70 task.run();
71 return succeededFuture(pipeline.getChannel());
72 } catch (Throwable t) {
73 return failedFuture(pipeline.getChannel(), t);
74 }
75 }
76 }