General comment. I don't see the need for a class IoFilterChain. List seems to be perfectly acceptable.
On Jul 3, 2011, at 10:05 PM, Ashish wrote: > Minor comments > > 1. Do we want to have a check if the filter is already added or we just > leave it to user? One may want to put debug/benchmark filters in various places in the chain. > 2. Was just trying to use the API public void insertBefore/After(int > position, IoFilter ioFilter) as an end user. > a) As a User, how do I find the index of the Filter? > Probably, we need to provide another API which can give the same or > alternatively we can pass IoFilter instance instead of index. What's the concrete use case for the API complexity in IoFilterChain? I'm very curious. :) Regards, Alan > > Good to see things are taking shape :) > > cheers > ashish > > On Sun, Jul 3, 2011 at 11:14 PM, <[email protected]> wrote: > >> Author: jvermillard >> Date: Sun Jul 3 17:44:12 2011 >> New Revision: 1142469 >> >> URL: http://svn.apache.org/viewvc?rev=1142469&view=rev >> Log: >> filter chain with default implementation for add/remove filters >> >> Added: >> mina/branches/3.0/core/src/main/java/org/apache/mina/filterchain/ >> >> mina/branches/3.0/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterChain.java >> (with props) >> mina/branches/3.0/core/src/test/java/filterchain/ >> >> mina/branches/3.0/core/src/test/java/filterchain/DefaultIoFilterChainTest.java >> (with props) >> Modified: >> mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilter.java >> mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilterChain.java >> >> Modified: >> mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilter.java >> URL: >> http://svn.apache.org/viewvc/mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilter.java?rev=1142469&r1=1142468&r2=1142469&view=diff >> >> ============================================================================== >> --- mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilter.java >> (original) >> +++ mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilter.java Sun >> Jul 3 17:44:12 2011 >> @@ -22,52 +22,42 @@ package org.apache.mina; >> >> /** >> * Filter are interceptors/processors for incoming data received/sent. >> - * >> + * >> * @author <a href="http://mina.apache.org">Apache MINA Project</a> >> */ >> public interface IoFilter { >> >> /** >> - * Returns the Name of the Filter. A name is used to uniquely identify >> - * the FIlter >> - * >> - * @return Name of the Filter >> - */ >> - String getName(); >> - >> - /** >> - * Invoked when this filter is added to a {@link IoFilterChain} >> - * at the first time, so you can initialize shared resources. >> - * >> + * Invoked when this filter is added to a {@link IoFilterChain} at the >> first time, so you can initialize shared >> + * resources. >> + * >> * @throws Exception If an initialization error occurs >> */ >> void init() throws Exception; >> >> /** >> - * Invoked when this filter is not used by any {@link IoFilterChain} >> anymore, >> - * so you can destroy shared resources. >> - * >> + * Invoked when this filter is not used by any {@link IoFilterChain} >> anymore, so you can destroy shared resources. >> + * >> * @throws Exception If an error occurs while processing >> */ >> void destroy() throws Exception; >> >> - //---- Events Functions --- >> + // ---- Events Functions --- >> /** >> - * Invoked from an I/O processor thread when a new connection has been >> created. >> - * Because this method is supposed to be called from the same thread >> that >> - * handles I/O of multiple sessions, please implement this method to >> perform >> - * tasks that consumes minimal amount of time such as socket parameter >> - * and user-defined session attribute initialization. >> - * >> + * Invoked from an I/O processor thread when a new connection has been >> created. Because this method is supposed to >> + * be called from the same thread that handles I/O of multiple >> sessions, please implement this method to perform >> + * tasks that consumes minimal amount of time such as socket parameter >> and user-defined session attribute >> + * initialization. >> + * >> * @param session {@link IoSession} associated with the invocation >> - * >> + * >> * @throws Exception Exception If an error occurs while processing >> */ >> void sessionCreated(IoSession session) throws Exception; >> >> /** >> * Invoked when a connection has been opened. >> - * >> + * >> * @param session {@link IoSession} associated with the invocation >> * @throws Exception Exception If an error occurs while processing >> */ >> @@ -75,7 +65,7 @@ public interface IoFilter { >> >> /** >> * Invoked when a connection is closed. >> - * >> + * >> * @param session {@link IoSession} associated with the invocation >> * @throws Exception Exception If an error occurs while processing >> */ >> @@ -83,7 +73,7 @@ public interface IoFilter { >> >> /** >> * Invoked with the related {@link IdleStatus} when a connection >> becomes idle. >> - * >> + * >> * @param session {@link IoSession} associated with the invocation >> * @throws Exception Exception If an error occurs while processing >> */ >> @@ -91,17 +81,25 @@ public interface IoFilter { >> >> /** >> * Invoked when a message is received. >> - * >> + * >> * @param session {@link IoSession} associated with the invocation >> * @throws Exception Exception If an error occurs while processing >> */ >> void messageReceived(IoSession session, Object message) throws >> Exception; >> >> /** >> + * Invoked when a message is under writing. The filter is supposed to >> apply the needed transformation. >> + * >> + * @param session {@link IoSession} associated with the invocation >> + * @throws Exception Exception If an error occurs while processing >> + */ >> + void messageWritting(IoSession session, Object message) throws >> Exception; >> + >> + /** >> * Invoked when an exception occurs while executing the method >> - * >> - * @param session {@link IoSession} associated with invocation >> - * @param cause Real {@link Throwable} which broke the normal >> chain processing >> + * >> + * @param session {@link IoSession} associated with invocation >> + * @param cause Real {@link Throwable} which broke the normal chain >> processing >> * @throws Exception If an error occurs while processing >> */ >> void exceptionCaught(IoSession session, Throwable cause) throws >> Exception; >> >> Modified: >> mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilterChain.java >> URL: >> http://svn.apache.org/viewvc/mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilterChain.java?rev=1142469&r1=1142468&r2=1142469&view=diff >> >> ============================================================================== >> --- mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilterChain.java >> (original) >> +++ mina/branches/3.0/core/src/main/java/org/apache/mina/IoFilterChain.java >> Sun Jul 3 17:44:12 2011 >> @@ -23,7 +23,7 @@ package org.apache.mina; >> import java.util.List; >> >> /** >> - * An implementation that is responsible for perfoming IO (network, file >> or >> + * An implementation that is responsible for performing IO (network, file >> or >> * any other kind of IO) >> * >> * The chain will look something like >> @@ -58,16 +58,10 @@ import java.util.List; >> public interface IoFilterChain { >> >> /** >> - * Returns the parent {@link IoSession} of this chain. >> - * @return {@link IoSession} >> - */ >> - IoSession getSession(); >> - >> - /** >> * Returns all the filters that are currently present in the chain. >> * Useful to the know the current processing chain. The chain is >> returned >> - * in the order of processing aka the first filter in th list shall be >> the >> - * first one to be processed >> + * in the order of processing (the first filter in the list shall be >> the >> + * first one to be processed) >> * >> * @return List of all {@link IoFilter} present in the chain >> */ >> @@ -79,12 +73,36 @@ public interface IoFilterChain { >> * >> * @param ioFilter Filter to be added in the Chain >> */ >> - void addFilter(IoFilter ioFilter); >> + void addLast(IoFilter ioFilter); >> + >> + /** >> + * Add the specified {@link IoFilter} to the beginning of the chain. >> The filter is >> + * inserted before all the other filter currently in the chain. >> + * @param ioFilter >> + */ >> + void addFirst(IoFilter ioFilter); >> + >> + /** >> + * Insert the specified {@link IoFilter} before the filter at the >> given position >> + * @param position where we want to insert before our filter >> + * @param ioFilter the filter to be inserted >> + * @throws IndexOutOfBoundsException if the position is out of this >> list >> + */ >> + void insertBefore(int position, IoFilter ioFilter) throws >> IndexOutOfBoundsException; >> + >> + /** >> + * Insert the specified {@link IoFilter} after the filter at the given >> position >> + * @param position where we want to insert before our filter >> + * @param ioFilter the filter to be inserted >> + * @throws IndexOutOfBoundsException if the position is out of this >> list >> + */ >> + void insertAfter(int position, IoFilter ioFilter); >> >> /** >> * Removes the Filter from the Chain. >> * >> * @param ioFilter Filter to be removed >> + * @return <code>true</code> if successful >> */ >> - void removeFilter(IoFilter ioFilter); >> + boolean removeFilter(IoFilter ioFilter); >> } >> \ No newline at end of file >> >> Added: >> mina/branches/3.0/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterChain.java >> URL: >> http://svn.apache.org/viewvc/mina/branches/3.0/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterChain.java?rev=1142469&view=auto >> >> ============================================================================== >> --- >> mina/branches/3.0/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterChain.java >> (added) >> +++ >> mina/branches/3.0/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterChain.java >> Sun Jul 3 17:44:12 2011 >> @@ -0,0 +1,83 @@ >> +/* >> + * 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 java.util.ArrayList; >> +import java.util.List; >> +import java.util.concurrent.CopyOnWriteArrayList; >> + >> +import org.apache.mina.IoFilter; >> +import org.apache.mina.IoFilterChain; >> + >> +public class DefaultIoFilterChain implements IoFilterChain { >> + >> + /** >> + * The list of {@link IoFilter} compounding this chain. >> + * We use a {@link CopyOnWriteArrayList} because we want to read >> quickly (and thread safely) but we don't care much about chain >> + * modification performances. >> + */ >> + private List<IoFilter> chain = new CopyOnWriteArrayList<IoFilter>(); >> + >> + //=================== >> + // CHAIN MANIPULATION >> + //=================== >> + >> + @Override >> + public List<IoFilter> getAll() { >> + // send a copy of the list >> + return new ArrayList<IoFilter>(chain); >> + } >> + >> + @Override >> + public void addFirst(IoFilter ioFilter) { >> + chain.add(0, ioFilter); >> + } >> + >> + @Override >> + public void addLast(IoFilter ioFilter) { >> + chain.add(ioFilter); >> + } >> + >> + @Override >> + public boolean removeFilter(IoFilter ioFilter) { >> + return chain.remove(ioFilter); >> + } >> + >> + @Override >> + public void insertBefore(int position, IoFilter ioFilter) throws >> IndexOutOfBoundsException { >> + chain.add(position, ioFilter); >> + } >> + >> + @Override >> + public void insertAfter(int position, IoFilter ioFilter) throws >> IndexOutOfBoundsException { >> + chain.add(position + 1, ioFilter); >> + } >> + >> + @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(); >> + } >> + >> +} >> \ No newline at end of file >> >> Propchange: >> mina/branches/3.0/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterChain.java >> >> ------------------------------------------------------------------------------ >> svn:mime-type = text/plain >> >> Added: >> mina/branches/3.0/core/src/test/java/filterchain/DefaultIoFilterChainTest.java >> URL: >> http://svn.apache.org/viewvc/mina/branches/3.0/core/src/test/java/filterchain/DefaultIoFilterChainTest.java?rev=1142469&view=auto >> >> ============================================================================== >> --- >> mina/branches/3.0/core/src/test/java/filterchain/DefaultIoFilterChainTest.java >> (added) >> +++ >> mina/branches/3.0/core/src/test/java/filterchain/DefaultIoFilterChainTest.java >> Sun Jul 3 17:44:12 2011 >> @@ -0,0 +1,147 @@ >> +/* >> + * 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 filterchain; >> + >> +import static org.junit.Assert.assertEquals; >> +import static org.junit.Assert.assertFalse; >> +import static org.junit.Assert.assertTrue; >> + >> +import java.util.List; >> + >> +import org.apache.mina.IdleStatus; >> +import org.apache.mina.IoFilter; >> +import org.apache.mina.IoSession; >> +import org.apache.mina.filterchain.DefaultIoFilterChain; >> +import org.junit.Test; >> + >> +public class DefaultIoFilterChainTest { >> + >> + @Test >> + public void testChainModification() { >> + DefaultIoFilterChain filterChain = new DefaultIoFilterChain(); >> + >> + DummyFilter filterA = new DummyFilter("A"); >> + DummyFilter filterB = new DummyFilter("B"); >> + DummyFilter filterC = new DummyFilter("C"); >> + >> + // add two filters >> + filterChain.addFirst(filterB); >> + filterChain.addFirst(filterA); >> + System.out.println(filterChain); >> + assertEquals(filterChain.getAll().size(), 2); >> + List<IoFilter> l = filterChain.getAll(); >> + >> + assertEquals(l.get(0), filterA); >> + assertEquals(l.get(1), filterB); >> + >> + assertTrue(filterChain.removeFilter(filterB)); >> + assertEquals(filterChain.getAll().size(), 1); >> + assertFalse(filterChain.removeFilter(filterB)); >> + assertEquals(filterChain.getAll().size(), 1); >> + assertTrue(filterChain.removeFilter(filterA)); >> + assertTrue(filterChain.getAll().isEmpty()); >> + >> + // add three filter >> + filterChain.addLast(filterB); >> + filterChain.addLast(filterC); >> + filterChain.addFirst(filterA); >> + assertEquals(filterChain.getAll().size(), 3); >> + l = filterChain.getAll(); >> + >> + assertEquals(l.get(0), filterA); >> + assertEquals(l.get(1), filterB); >> + assertEquals(l.get(2), filterC); >> + >> + filterChain.removeFilter(filterB); >> + assertEquals(filterChain.getAll().size(), 2); >> + l = filterChain.getAll(); >> + assertEquals(l.get(0), filterA); >> + assertEquals(l.get(1), filterC); >> + >> + filterChain.insertAfter(0, filterB); >> + assertEquals(filterChain.getAll().size(), 3); >> + l = filterChain.getAll(); >> + >> + assertEquals(l.get(0), filterA); >> + assertEquals(l.get(1), filterB); >> + assertEquals(l.get(2), filterC); >> + filterChain.removeFilter(filterB); >> + >> + filterChain.insertBefore(1, filterB); >> + >> + assertEquals(filterChain.getAll().size(), 3); >> + l = filterChain.getAll(); >> + >> + assertEquals(l.get(0), filterA); >> + assertEquals(l.get(1), filterB); >> + assertEquals(l.get(2), filterC); >> + >> + } >> + >> + private class DummyFilter implements IoFilter { >> + >> + String id; >> + >> + public DummyFilter(String id) { >> + this.id = id; >> + } >> + >> + @Override >> + public void init() throws Exception { >> + } >> + >> + @Override >> + public void destroy() throws Exception { >> + } >> + >> + @Override >> + public void sessionCreated(IoSession session) throws Exception { >> + } >> + >> + @Override >> + public void sessionOpened(IoSession session) throws Exception { >> + } >> + >> + @Override >> + public void sessionClosed(IoSession session) throws Exception { >> + } >> + >> + @Override >> + public void sessionIdle(IoSession session, IdleStatus status) >> throws Exception { >> + } >> + >> + @Override >> + public void messageReceived(IoSession session, Object message) >> throws Exception { >> + } >> + >> + @Override >> + public void messageWritting(IoSession session, Object message) >> throws Exception { >> + } >> + >> + @Override >> + public void exceptionCaught(IoSession session, Throwable cause) >> throws Exception { >> + } >> + >> + public String toString() { >> + return "DummyFilter(" + id + ")"; >> + } >> + } >> + >> +} >> >> Propchange: >> mina/branches/3.0/core/src/test/java/filterchain/DefaultIoFilterChainTest.java >> >> ------------------------------------------------------------------------------ >> svn:mime-type = text/plain >> >> >> > > > -- > thanks > ashish > > Blog: http://www.ashishpaliwal.com/blog > My Photo Galleries: http://www.pbase.com/ashishpaliwal
