On Jul 4, 2011, at 12:14 PM, Julien Vermillard wrote: > About the chain manipulation, I'm agreeing with you, we can drop the > addBefore/addLast thingy and stick to the List API. > Everybody know how to add/insert stuff in a plain old java list > > The FilterChain is needed for supporting methods for dispatching > events (write/read/open/close/exceptions) and provide some magic for > inserting SEDA in the processing chain. > But the user can just see a List, I'm really Ok if we all agree :)
You all are going to see me attempt to remove as many classes as I can from our Mina API. IMO, we have way too many of them; an artifact of pre-generics days I imagine. Hope that's ok with you all. Regards, Alan > > On Mon, Jul 4, 2011 at 8:43 PM, Alan D. Cabrera <[email protected]> wrote: >> 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 >> >>
