/* * 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.filterchain; import org.apache.mina.api.IoFilter; import org.apache.mina.api.IoService; import org.apache.mina.api.IoSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DefaultIoFilterController implements IoFilterController, ReadFilterChainController, WriteFilterChainController { private static final Logger LOG = LoggerFactory.getLogger(DefaultIoFilterController.class); /** * The list of {@link IoFilter} implementing this chain. */ private final IoFilter[] chain; /** * The instance of {@link DefaultIoFilterController} with the {@link IoService} chain. */ public DefaultIoFilterController(IoFilter[] chain) { this.chain = chain; } @Override public void processSessionCreated(IoSession session) { LOG.debug("processing session created event"); for (IoFilter filter : chain) { filter.sessionCreated(session); } } @Override public void processSessionOpen(IoSession session) { LOG.debug("processing session open event"); for (IoFilter filter : chain) { filter.sessionOpened(session); } } @Override public void processSessionClosed(IoSession session) { LOG.debug("processing session closed event"); for (IoFilter filter : chain) { filter.sessionClosed(session); } } private int readChainPosition; @Override public void processMessageReceived(IoSession session, Object message) { LOG.debug("processing message '{}' received event ", message); if (chain.length < 1) { LOG.debug("Nothing to do, the chain is empty"); } else { readChainPosition = 0; // we call the first filter, it's supposed to call the next ones using the filter chain controller chain[readChainPosition].messageReceived(session, message, this); } } private int writeChainPosition; @Override public void processMessageWriting(IoSession session, Object message) { LOG.debug("processing message '{}' writing event ", message); if (chain.length < 1) { LOG.debug("Nothing to do, the chain is empty, we just enqueue the message"); session.enqueueWriteRequest(message); } else { writeChainPosition = chain.length - 1; // we call the first filter, it's supposed to call the next ones using the filter chain controller chain[writeChainPosition].messageWriting(session, message, this); } } @Override public void callWriteNextFilter(IoSession session, Object message) { LOG.debug("calling next filter for writing for message '{}' position : {}", message, writeChainPosition); writeChainPosition--; if (writeChainPosition < 0 || chain.length == 0) { // end of chain processing LOG.debug("end of write chan we enque the message in the session : {}", message); session.enqueueWriteRequest(message); } else { chain[writeChainPosition].messageWriting(session, message, this); } writeChainPosition++; } @Override public void callReadNextFilter(IoSession session, Object message) { readChainPosition++; if (readChainPosition >= chain.length) { // end of chain processing } else { chain[readChainPosition].messageReceived(session, message, this); } readChainPosition--; } @Override public String toString() { StringBuilder bldr = new StringBuilder("IoFilterChain {"); int index = 0; for (IoFilter filter : chain) { bldr.append(index).append(":").append(filter).append(", "); } return bldr.append("}").toString(); } }