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 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  public class SimpleChannelUpstreamHandler implements ChannelUpstreamHandler {
55  
56      private static final InternalLogger logger =
57          InternalLoggerFactory.getInstance(SimpleChannelUpstreamHandler.class.getName());
58  
59      /**
60       * Creates a new instance.
61       */
62      public SimpleChannelUpstreamHandler() {
63          super();
64      }
65  
66      /**
67       * {@inheritDoc}  Down-casts the received upstream event into more
68       * meaningful sub-type event and calls an appropriate handler method with
69       * the down-casted event.
70       */
71      public void handleUpstream(
72              ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
73  
74          if (e instanceof MessageEvent) {
75              messageReceived(ctx, (MessageEvent) e);
76          } else if (e instanceof WriteCompletionEvent) {
77              WriteCompletionEvent evt = (WriteCompletionEvent) e;
78              writeComplete(ctx, evt);
79          } else if (e instanceof ChildChannelStateEvent) {
80              ChildChannelStateEvent evt = (ChildChannelStateEvent) e;
81              if (evt.getChildChannel().isOpen()) {
82                  childChannelOpen(ctx, evt);
83              } else {
84                  childChannelClosed(ctx, evt);
85              }
86          } else if (e instanceof ChannelStateEvent) {
87              ChannelStateEvent evt = (ChannelStateEvent) e;
88              switch (evt.getState()) {
89              case OPEN:
90                  if (Boolean.TRUE.equals(evt.getValue())) {
91                      channelOpen(ctx, evt);
92                  } else {
93                      channelClosed(ctx, evt);
94                  }
95                  break;
96              case BOUND:
97                  if (evt.getValue() != null) {
98                      channelBound(ctx, evt);
99                  } else {
100                     channelUnbound(ctx, evt);
101                 }
102                 break;
103             case CONNECTED:
104                 if (evt.getValue() != null) {
105                     channelConnected(ctx, evt);
106                 } else {
107                     channelDisconnected(ctx, evt);
108                 }
109                 break;
110             case INTEREST_OPS:
111                 channelInterestChanged(ctx, evt);
112                 break;
113             default:
114                 ctx.sendUpstream(e);
115             }
116         } else if (e instanceof ExceptionEvent) {
117             exceptionCaught(ctx, (ExceptionEvent) e);
118         } else {
119             ctx.sendUpstream(e);
120         }
121     }
122 
123     /**
124      * Invoked when a message object (e.g: {@link ChannelBuffer}) was received
125      * from a remote peer.
126      */
127     public void messageReceived(
128             ChannelHandlerContext ctx, MessageEvent e) throws Exception {
129         ctx.sendUpstream(e);
130     }
131 
132     /**
133      * Invoked when an exception was raised by an I/O thread or a
134      * {@link ChannelHandler}.
135      */
136     public void exceptionCaught(
137             ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
138         if (this == ctx.getPipeline().getLast()) {
139             logger.warn(
140                     "EXCEPTION, please implement " + getClass().getName() +
141                     ".exceptionCaught() for proper handling.", e.getCause());
142         }
143         ctx.sendUpstream(e);
144     }
145 
146     /**
147      * Invoked when a {@link Channel} is open, but not bound nor connected.
148      * <br/>
149      *
150      * <strong>Be aware that this event is fired from within the Boss-Thread so you should not
151      * execute any heavy operation in there as it will block the dispatching to other workers!</strong>
152      */
153     public void channelOpen(
154             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
155         ctx.sendUpstream(e);
156     }
157 
158     /**
159      * Invoked when a {@link Channel} is open and bound to a local address,
160      * but not connected.
161      * <br/>
162      *
163      * <strong>Be aware that this event is fired from within the Boss-Thread so you should not
164      * execute any heavy operation in there as it will block the dispatching to other workers!</strong>
165      */
166     public void channelBound(
167             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
168         ctx.sendUpstream(e);
169     }
170 
171     /**
172      * Invoked when a {@link Channel} is open, bound to a local address, and
173      * connected to a remote address.
174      * <br/>
175      *
176      * <strong>Be aware that this event is fired from within the Boss-Thread so you should not
177      * execute any heavy operation in there as it will block the dispatching to other workers!</strong>
178      */
179     public void channelConnected(
180             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
181         ctx.sendUpstream(e);
182     }
183 
184     /**
185      * Invoked when a {@link Channel}'s {@link Channel#getInterestOps() interestOps}
186      * was changed.
187      */
188     public void channelInterestChanged(
189             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
190         ctx.sendUpstream(e);
191     }
192 
193     /**
194      * Invoked when a {@link Channel} was disconnected from its remote peer.
195      */
196     public void channelDisconnected(
197             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
198         ctx.sendUpstream(e);
199     }
200 
201     /**
202      * Invoked when a {@link Channel} was unbound from the current local address.
203      */
204     public void channelUnbound(
205             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
206         ctx.sendUpstream(e);
207     }
208 
209     /**
210      * Invoked when a {@link Channel} was closed and all its related resources
211      * were released.
212      */
213     public void channelClosed(
214             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
215         ctx.sendUpstream(e);
216     }
217 
218     /**
219      * Invoked when something was written into a {@link Channel}.
220      */
221     public void writeComplete(
222             ChannelHandlerContext ctx, WriteCompletionEvent e) throws Exception {
223         ctx.sendUpstream(e);
224     }
225 
226     /**
227      * Invoked when a child {@link Channel} was open.
228      * (e.g. a server channel accepted a connection)
229      */
230     public void childChannelOpen(
231             ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
232         ctx.sendUpstream(e);
233     }
234 
235     /**
236      * Invoked when a child {@link Channel} was closed.
237      * (e.g. the accepted connection was closed)
238      */
239     public void childChannelClosed(
240             ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
241         ctx.sendUpstream(e);
242     }
243 }