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      */
    154     public void channelOpen(
    155             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    156         ctx.sendUpstream(e);
    157     }
    158
    159     /**
    160      * Invoked when a {@link Channel} is open and bound to a local address,
    161      * but not connected.
    162      */
    163     public void channelBound(
    164             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    165         ctx.sendUpstream(e);
    166     }
    167
    168     /**
    169      * Invoked when a {@link Channel} is open, bound to a local address, and
    170      * connected to a remote address.
    171      */
    172     public void channelConnected(
    173             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    174         ctx.sendUpstream(e);
    175     }
    176
    177     /**
    178      * Invoked when a {@link Channel}'s {@link Channel#getInterestOps() interestOps}
    179      * was changed.
    180      */
    181     public void channelInterestChanged(
    182             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    183         ctx.sendUpstream(e);
    184     }
    185
    186     /**
    187      * Invoked when a {@link Channel} was disconnected from its remote peer.
    188      */
    189     public void channelDisconnected(
    190             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    191         ctx.sendUpstream(e);
    192     }
    193
    194     /**
    195      * Invoked when a {@link Channel} was unbound from the current local address.
    196      */
    197     public void channelUnbound(
    198             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    199         ctx.sendUpstream(e);
    200     }
    201
    202     /**
    203      * Invoked when a {@link Channel} was closed and all its related resources
    204      * were released.
    205      */
    206     public void channelClosed(
    207             ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    208         ctx.sendUpstream(e);
    209     }
    210
    211     /**
    212      * Invoked when something was written into a {@link Channel}.
    213      */
    214     public void writeComplete(
    215             ChannelHandlerContext ctx, WriteCompletionEvent e) throws Exception {
    216         ctx.sendUpstream(e);
    217     }
    218
    219     /**
    220      * Invoked when a child {@link Channel} was open.
    221      * (e.g. a server channel accepted a connection)
    222      */
    223     public void childChannelOpen(
    224             ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
    225         ctx.sendUpstream(e);
    226     }
    227
    228     /**
    229      * Invoked when a child {@link Channel} was closed.
    230      * (e.g. the accepted connection was closed)
    231      */
    232     public void childChannelClosed(
    233             ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
    234         ctx.sendUpstream(e);
    235     }
    236 }