View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.handler;
    21
    22  import java.io.IOException;
    23  import java.io.InputStream;
    24  import java.io.OutputStream;
    25  import java.net.SocketTimeoutException;
    26
    27  import org.apache.mina.common.ByteBuffer;
    28  import org.apache.mina.common.IdleStatus;
    29  import org.apache.mina.common.IoHandler;
    30  import org.apache.mina.common.IoHandlerAdapter;
    31  import org.apache.mina.common.IoSession;
    32  import org.apache.mina.handler.support.IoSessionInputStream;
    33  import org.apache.mina.handler.support.IoSessionOutputStream;
    34  import org.apache.mina.util.SessionLog;
    35
    36  /**
    37   * A {@link IoHandler} that adapts asynchronous MINA events to stream I/O.
    38   * <p>
    39   * Please extend this class and implement
    40   * {@link #processStreamIo(IoSession, InputStream, OutputStream)} to
    41   * execute your stream I/O logic; <b>please note that you must forward
    42   * the process request to other thread or thread pool.</b>
    43   *
    44   * @author The Apache Directory Project (mina-dev@directory.apache.org)
    45   * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (Fri, 13 Jul 2007) $
    46   */
    47  public abstract class StreamIoHandler extends IoHandlerAdapter {
    48      private static final String KEY_IN = StreamIoHandler.class.getName()
    49              + ".in";
    50
    51      private static final String KEY_OUT = StreamIoHandler.class.getName()
    52              + ".out";
    53
    54      private int readTimeout;
    55
    56      private int writeTimeout;
    57
    58      protected StreamIoHandler() {
    59      }
    60
    61      /**
    62       * Implement this method to execute your stream I/O logic;
    63       * <b>please note that you must forward the process request to other
    64       * thread or thread pool.</b>
    65       */
    66      protected abstract void processStreamIo(IoSession session, InputStream in,
    67              OutputStream out);
    68
    69      /**
    70       * Returns read timeout in seconds.
    71       * The default value is <tt>0</tt> (disabled).
    72       */
    73      public int getReadTimeout() {
    74          return readTimeout;
    75      }
    76
    77      /**
    78       * Sets read timeout in seconds.
    79       * The default value is <tt>0</tt> (disabled).
    80       */
    81      public void setReadTimeout(int readTimeout) {
    82          this.readTimeout = readTimeout;
    83      }
    84
    85      /**
    86       * Returns write timeout in seconds.
    87       * The default value is <tt>0</tt> (disabled).
    88       */
    89      public int getWriteTimeout() {
    90          return writeTimeout;
    91      }
    92
    93      /**
    94       * Sets write timeout in seconds.
    95       * The default value is <tt>0</tt> (disabled).
    96       */
    97      public void setWriteTimeout(int writeTimeout) {
    98          this.writeTimeout = writeTimeout;
    99      }
    100
    101     /**
    102      * Initializes streams and timeout settings.
    103      */
    104     public void sessionOpened(IoSession session) {
    105         // Set timeouts
    106         session.setWriteTimeout(writeTimeout);
    107         session.setIdleTime(IdleStatus.READER_IDLE, readTimeout);
    108
    109         // Create streams
    110         InputStream in = new IoSessionInputStream();
    111         OutputStream out = new IoSessionOutputStream(session);
    112         session.setAttribute(KEY_IN, in);
    113         session.setAttribute(KEY_OUT, out);
    114         processStreamIo(session, in, out);
    115     }
    116
    117     /**
    118      * Closes streams
    119      */
    120     public void sessionClosed(IoSession session) throws Exception {
    121         final InputStream in = (InputStream) session.getAttribute(KEY_IN);
    122         final OutputStream out = (OutputStream) session.getAttribute(KEY_OUT);
    123         try {
    124             in.close();
    125         } finally {
    126             out.close();
    127         }
    128     }
    129
    130     /**
    131      * Forwards read data to input stream.
    132      */
    133     public void messageReceived(IoSession session, Object buf) {
    134         final IoSessionInputStream in = (IoSessionInputStream) session
    135                 .getAttribute(KEY_IN);
    136         in.write((ByteBuffer) buf);
    137     }
    138
    139     /**
    140      * Forwards caught exceptions to input stream.
    141      */
    142     public void exceptionCaught(IoSession session, Throwable cause) {
    143         final IoSessionInputStream in = (IoSessionInputStream) session
    144                 .getAttribute(KEY_IN);
    145
    146         IOException e = null;
    147         if (cause instanceof StreamIoException) {
    148             e = (IOException) cause.getCause();
    149         } else if (cause instanceof IOException) {
    150             e = (IOException) cause;
    151         }
    152
    153         if (e != null && in != null) {
    154             in.throwException(e);
    155         } else {
    156             SessionLog.warn(session, "Unexpected exception.", cause);
    157             session.close();
    158         }
    159     }
    160
    161     /**
    162      * Handles read timeout.
    163      */
    164     public void sessionIdle(IoSession session, IdleStatus status) {
    165         if (status == IdleStatus.READER_IDLE) {
    166             throw new StreamIoException(new SocketTimeoutException(
    167                     "Read timeout"));
    168         }
    169     }
    170
    171     private static class StreamIoException extends RuntimeException {
    172         private static final long serialVersionUID = 3976736960742503222L;
    173
    174         public StreamIoException(IOException cause) {
    175             super(cause);
    176         }
    177     }
    178 }