View Javadoc

1   /*
2    * Copyright 2009 Red Hat, Inc.
3    *
4    * Red Hat licenses this file to you under the Apache License, version 2.0
5    * (the "License"); you may not use this file except in compliance with the
6    * 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 org.jboss.netty.buffer.ChannelBuffer;
19  import org.jboss.netty.logging.InternalLogger;
20  import org.jboss.netty.logging.InternalLoggerFactory;
21  
22  
23  /**
24   * A {@link ChannelUpstreamHandler} which provides an individual handler method
25   * for each event type.  This handler down-casts the received upstream event
26   * into more meaningful sub-type event and calls an appropriate handler method
27   * with the down-cast event.  The names of the methods are identical to the
28   * upstream event names, as introduced in the {@link ChannelEvent} documentation.
29   * <p>
30   * Please use {@link SimpleChannelHandler} if you need to implement both
31   * {@link ChannelUpstreamHandler} and {@link ChannelDownstreamHandler}.
32   *
33   * <h3>Overriding the {@link #handleUpstream(ChannelHandlerContext, ChannelEvent) handleUpstream} method</h3>
34   * <p>
35   * You can override the {@link #handleUpstream(ChannelHandlerContext, ChannelEvent) handleUpstream}
36   * method just like overriding an ordinary Java method.  Please make sure to
37   * call {@code super.handleUpstream()} so that other handler methods are invoked
38   * properly:
39   * </p>
40   * <pre>public class MyChannelHandler extends {@link SimpleChannelUpstreamHandler} {
41   *
42   *     {@code @Override}
43   *     public void handleUpstream({@link ChannelHandlerContext} ctx, {@link ChannelEvent} e) throws Exception {
44   *
45   *         // Log all channel state changes.
46   *         if (e instanceof {@link ChannelStateEvent}) {
47   *             logger.info("Channel state changed: " + e);
48   *         }
49   *
50   *         <strong>super.handleUpstream(ctx, e);</strong>
51   *     }
52   * }</pre>
53   *
54   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
55   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
56   *
57   * @version $Rev: 2122 $, $Date: 2010-02-02 11:00:04 +0900 (Tue, 02 Feb 2010) $
58   */
59  public class SimpleChannelUpstreamHandler implements ChannelUpstreamHandler {
60  
61      private static final InternalLogger logger =
62          InternalLoggerFactory.getInstance(SimpleChannelUpstreamHandler.class.getName());
63  
64      /**
65       * Creates a new instance.
66       */
67      public SimpleChannelUpstreamHandler() {
68          super();
69      }
70  
71      /**
72       * {@inheritDoc}  Down-casts the received upstream event into more
73       * meaningful sub-type event and calls an appropriate handler method with
74       * the down-casted event.
75       */
76      public void handleUpstream(
77              ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
78  
79          if (e instanceof MessageEvent) {
80              messageReceived(ctx, (MessageEvent) e);
81          } else if (e instanceof WriteCompletionEvent) {
82              WriteCompletionEvent evt = (WriteCompletionEvent) e;
83              writeComplete(ctx, evt);
84          } else if (e instanceof ChildChannelStateEvent) {
85              ChildChannelStateEvent evt = (ChildChannelStateEvent) e;
86              if (evt.getChildChannel().isOpen()) {
87                  childChannelOpen(ctx, evt);
88              } else {
89                  childChannelClosed(ctx, evt);
90              }
91          } else if (e instanceof ChannelStateEvent) {
92              ChannelStateEvent evt = (ChannelStateEvent) e;
93              switch (evt.getState()) {
94              case OPEN:
95                  if (Boolean.TRUE.equals(evt.getValue())) {
96                      channelOpen(ctx, evt);
97                  } else {
98                      channelClosed(ctx, evt);
99                  }
100                 break;
101             case BOUND:
102                 if (evt.getValue() != null) {
103                     channelBound(ctx, evt);
104                 } else {
105                     channelUnbound(ctx, evt);
106                 }
107                 break;
108             case CONNECTED:
109                 if (evt.getValue() != null) {
110                     channelConnected(ctx, evt);
111                 } else {
112                     channelDisconnected(ctx, evt);
113                 }
114                 break;
115             case INTEREST_OPS:
116                 channelInterestChanged(ctx, evt);
117                 break;
118             default:
119                 ctx.sendUpstream(e);
120             }
121         } else if (e instanceof ExceptionEvent) {
122             exceptionCaught(ctx, (ExceptionEvent) e);
123         } else {
124             ctx.sendUpstream(e);
125         }
126     }
127 
128     /**
129      * Invoked when a message object (e.g: {@link ChannelBuffer}) was received
130      * from a remote peer.
131      */
132     public void messageReceived(
133             ChannelHandlerContext ctx, MessageEvent e) throws Exception {
134         ctx.sendUpstream(e);
135     }
136 
137     /**
138      * Invoked when an exception was raised by an I/O thread or a
139      * {@link ChannelHandler}.
140      */
141     public void exceptionCaught(
142             ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
143         if (this == ctx.getPipeline().getLast()) {
144             logger.warn(
145                     "EXCEPTION, please implement " + getClass().getName() +
146                     ".exceptionCaught() for proper handling.", e.getCause());
147         }
148         ctx.sendUpstream(e);
149     }
150 
151     /**
152      * Invoked when a {@link Channel} is open, but not bound nor connected.
153      * <br/>
154      * 
155      * <strong>Be aware that this event is fired from within the Boss-Thread so you should not execute any heavy operation in there as it will block the dispatching to other workers!</strong>
156      */
157     public void channelOpen(
158             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
159         ctx.sendUpstream(e);
160     }
161 
162     /**
163      * Invoked when a {@link Channel} is open and bound to a local address,
164      * but not connected.
165      * <br/>
166      * 
167      * <strong>Be aware that this event is fired from within the Boss-Thread so you should not execute any heavy operation in there as it will block the dispatching to other workers!</strong>
168      */
169     public void channelBound(
170             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
171         ctx.sendUpstream(e);
172     }
173 
174     /**
175      * Invoked when a {@link Channel} is open, bound to a local address, and
176      * connected to a remote address.
177      * <br/>
178      * 
179      * <strong>Be aware that this event is fired from within the Boss-Thread so you should not execute any heavy operation in there as it will block the dispatching to other workers!</strong>
180      */
181     public void channelConnected(
182             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
183         ctx.sendUpstream(e);
184     }
185 
186     /**
187      * Invoked when a {@link Channel}'s {@link Channel#getInterestOps() interestOps}
188      * was changed.
189      */
190     public void channelInterestChanged(
191             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
192         ctx.sendUpstream(e);
193     }
194 
195     /**
196      * Invoked when a {@link Channel} was disconnected from its remote peer.
197      */
198     public void channelDisconnected(
199             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
200         ctx.sendUpstream(e);
201     }
202 
203     /**
204      * Invoked when a {@link Channel} was unbound from the current local address.
205      */
206     public void channelUnbound(
207             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
208         ctx.sendUpstream(e);
209     }
210 
211     /**
212      * Invoked when a {@link Channel} was closed and all its related resources
213      * were released.
214      */
215     public void channelClosed(
216             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
217         ctx.sendUpstream(e);
218     }
219 
220     /**
221      * Invoked when something was written into a {@link Channel}.
222      */
223     public void writeComplete(
224             ChannelHandlerContext ctx, WriteCompletionEvent e) throws Exception {
225         ctx.sendUpstream(e);
226     }
227 
228     /**
229      * Invoked when a child {@link Channel} was open.
230      * (e.g. a server channel accepted a connection)
231      */
232     public void childChannelOpen(
233             ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
234         ctx.sendUpstream(e);
235     }
236 
237     /**
238      * Invoked when a child {@link Channel} was closed.
239      * (e.g. the accepted connection was closed)
240      */
241     public void childChannelClosed(
242             ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
243         ctx.sendUpstream(e);
244     }
245 }