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 }