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 :) 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 > >
