⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocolcodecfilter.java

📁 mina是以Java实现的一个开源的网络程序框架
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* *  Licensed to the Apache Software Foundation (ASF) under one *  or more contributor license agreements.  See the NOTICE file *  distributed with this work for additional information *  regarding copyright ownership.  The ASF licenses this file *  to you under the Apache License, Version 2.0 (the *  "License"); you may not use this file except in compliance *  with the License.  You may obtain a copy of the License at * *    http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, *  software distributed under the License is distributed on an *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *  KIND, either express or implied.  See the License for the *  specific language governing permissions and limitations *  under the License. * */package org.apache.mina.filter.codec;import java.net.SocketAddress;import java.util.Queue;import org.apache.mina.core.buffer.IoBuffer;import org.apache.mina.core.file.FileRegion;import org.apache.mina.core.filterchain.IoFilter;import org.apache.mina.core.filterchain.IoFilterAdapter;import org.apache.mina.core.filterchain.IoFilterChain;import org.apache.mina.core.future.DefaultWriteFuture;import org.apache.mina.core.future.WriteFuture;import org.apache.mina.core.session.AttributeKey;import org.apache.mina.core.session.IoSession;import org.apache.mina.core.write.DefaultWriteRequest;import org.apache.mina.core.write.NothingWrittenException;import org.apache.mina.core.write.WriteRequest;import org.apache.mina.core.write.WriteRequestWrapper;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * An {@link IoFilter} which translates binary or protocol specific data into * message object and vice versa using {@link ProtocolCodecFactory}, * {@link ProtocolEncoder}, or {@link ProtocolDecoder}. * * @author The Apache MINA Project (dev@mina.apache.org) * @version $Rev: 756234 $, $Date: 2009-03-19 23:07:05 +0100 (Thu, 19 Mar 2009) $ * @org.apache.xbean.XBean */public class ProtocolCodecFilter extends IoFilterAdapter {    private static final Class<?>[] EMPTY_PARAMS = new Class[0];    private static final IoBuffer EMPTY_BUFFER = IoBuffer.wrap(new byte[0]);    private final AttributeKey ENCODER = new AttributeKey(getClass(), "encoder");    private final AttributeKey DECODER = new AttributeKey(getClass(), "decoder");    private final AttributeKey DECODER_OUT = new AttributeKey(getClass(), "decoderOut");    private final AttributeKey ENCODER_OUT = new AttributeKey(getClass(), "encoderOut");        /** The factory responsible for creating the encoder and decoder */    private final ProtocolCodecFactory factory;    private final Logger logger = LoggerFactory.getLogger(getClass());    /**     *      * Creates a new instance of ProtocolCodecFilter, associating a factory     * for the creation of the encoder and decoder.     *     * @param factory The associated factory     */    public ProtocolCodecFilter(ProtocolCodecFactory factory) {        if (factory == null) {            throw new NullPointerException("factory");        }        this.factory = factory;    }        /**     * Creates a new instance of ProtocolCodecFilter, without any factory.     * The encoder/decoder factory will be created as an inner class, using     * the two parameters (encoder and decoder).      *      * @param encoder The class responsible for encoding the message     * @param decoder The class responsible for decoding the message     */    public ProtocolCodecFilter(final ProtocolEncoder encoder,            final ProtocolDecoder decoder) {        if (encoder == null) {            throw new NullPointerException("encoder");        }        if (decoder == null) {            throw new NullPointerException("decoder");        }        // Create the inner Factory based on the two parameters        this.factory = new ProtocolCodecFactory() {            public ProtocolEncoder getEncoder(IoSession session) {                return encoder;            }            public ProtocolDecoder getDecoder(IoSession session) {                return decoder;            }        };    }    /**     * Creates a new instance of ProtocolCodecFilter, without any factory.     * The encoder/decoder factory will be created as an inner class, using     * the two parameters (encoder and decoder), which are class names. Instances     * for those classes will be created in this constructor.     *      * @param encoder The class responsible for encoding the message     * @param decoder The class responsible for decoding the message     */    public ProtocolCodecFilter(            final Class<? extends ProtocolEncoder> encoderClass,            final Class<? extends ProtocolDecoder> decoderClass) {        if (encoderClass == null) {            throw new NullPointerException("encoderClass");        }        if (decoderClass == null) {            throw new NullPointerException("decoderClass");        }        if (!ProtocolEncoder.class.isAssignableFrom(encoderClass)) {            throw new IllegalArgumentException("encoderClass: "                    + encoderClass.getName());        }        if (!ProtocolDecoder.class.isAssignableFrom(decoderClass)) {            throw new IllegalArgumentException("decoderClass: "                    + decoderClass.getName());        }        try {            encoderClass.getConstructor(EMPTY_PARAMS);        } catch (NoSuchMethodException e) {            throw new IllegalArgumentException(                    "encoderClass doesn't have a public default constructor.");        }        try {            decoderClass.getConstructor(EMPTY_PARAMS);        } catch (NoSuchMethodException e) {            throw new IllegalArgumentException(                    "decoderClass doesn't have a public default constructor.");        }        // Create the inner Factory based on the two parameters. We instanciate        // the encoder and decoder locally.        this.factory = new ProtocolCodecFactory() {            public ProtocolEncoder getEncoder(IoSession session) throws Exception {                return encoderClass.newInstance();            }            public ProtocolDecoder getDecoder(IoSession session) throws Exception {                return decoderClass.newInstance();            }        };    }        /**     * Get the encoder instance from a given session.     *     * @param session The associated session we will get the encoder from     * @return The encoder instance, if any     */    public ProtocolEncoder getEncoder(IoSession session) {        return (ProtocolEncoder) session.getAttribute(ENCODER);    }    @Override    public void onPreAdd(IoFilterChain parent, String name,            NextFilter nextFilter) throws Exception {        if (parent.contains(this)) {            throw new IllegalArgumentException(                    "You can't add the same filter instance more than once.  Create another instance and add it.");        }                // Initialize the encoder and decoder        initCodec(parent.getSession());    }    @Override    public void onPostRemove(IoFilterChain parent, String name,            NextFilter nextFilter) throws Exception {        // Clean everything        disposeCodec(parent.getSession());    }    /**     * Process the incoming message, calling the session decoder. As the incoming     * buffer might contains more than one messages, we have to loop until the decoder     * throws an exception.     *      *  while ( buffer not empty )     *    try      *      decode ( buffer )     *    catch     *      break;     *         */    @Override    public void messageReceived(NextFilter nextFilter, IoSession session,            Object message) throws Exception {        if (!(message instanceof IoBuffer)) {            nextFilter.messageReceived(session, message);            return;        }        IoBuffer in = (IoBuffer) message;        ProtocolDecoder decoder = getDecoder(session);        ProtocolDecoderOutput decoderOut = getDecoderOut(session, nextFilter);                // Loop until we don't have anymore byte in the buffer,        // or until the decoder throws an unrecoverable exception or         // can't decoder a message, because there are not enough         // data in the buffer        while (in.hasRemaining()) {            int oldPos = in.position();            try {                synchronized (decoderOut) {                    // Call the decoder with the read bytes                    decoder.decode(session, in, decoderOut);                }                                // Finish decoding if no exception was thrown.                decoderOut.flush(nextFilter, session);            } catch (Throwable t) {                ProtocolDecoderException pde;                if (t instanceof ProtocolDecoderException) {                    pde = (ProtocolDecoderException) t;                } else {                    pde = new ProtocolDecoderException(t);                }                                if (pde.getHexdump() == null) {                    // Generate a message hex dump                    int curPos = in.position();                    in.position(oldPos);                    pde.setHexdump(in.getHexDump());                    in.position(curPos);                }                // Fire the exceptionCaught event.                decoderOut.flush(nextFilter, session);                nextFilter.exceptionCaught(session, pde);                // Retry only if the type of the caught exception is                // recoverable and the buffer position has changed.                // We check buffer position additionally to prevent an                // infinite loop.                if (!(t instanceof RecoverableProtocolDecoderException) ||                        (in.position() == oldPos)) {                    break;                }            }        }    }    @Override    public void messageSent(NextFilter nextFilter, IoSession session,            WriteRequest writeRequest) throws Exception {        if (writeRequest instanceof EncodedWriteRequest) {            return;        }        if (!(writeRequest instanceof MessageWriteRequest)) {            nextFilter.messageSent(session, writeRequest);            return;        }        MessageWriteRequest wrappedRequest = (MessageWriteRequest) writeRequest;        nextFilter.messageSent(session, wrappedRequest.getParentRequest());    }    @Override    public void filterWrite(NextFilter nextFilter, IoSession session,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -