Author: niklas Date: Thu Dec 1 13:05:16 2005 New Revision: 351469 URL: http://svn.apache.org/viewcvs?rev=351469&view=rev Log: Spring support for configuration of per port filters. Cleaned up javadoc comments. Added: directory/network/trunk/src/java/org/apache/mina/integration/spring/Binding.java (with props) Modified: directory/network/trunk/src/java/org/apache/mina/integration/spring/DatagramAcceptorFactoryBean.java directory/network/trunk/src/java/org/apache/mina/integration/spring/IoFilterMapping.java directory/network/trunk/src/java/org/apache/mina/integration/spring/SocketAcceptorFactoryBean.java directory/network/trunk/src/java/org/apache/mina/integration/spring/VmPipeAcceptorFactoryBean.java directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBean.java directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoConnectorFactoryBean.java directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBean.java directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBeanTest.java directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBeanTest.java Added: directory/network/trunk/src/java/org/apache/mina/integration/spring/Binding.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/integration/spring/Binding.java?rev=351469&view=auto ============================================================================== --- directory/network/trunk/src/java/org/apache/mina/integration/spring/Binding.java (added) +++ directory/network/trunk/src/java/org/apache/mina/integration/spring/Binding.java Thu Dec 1 13:05:16 2005 @@ -0,0 +1,219 @@ +/* + * @(#) $Id$ + * + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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.integration.spring; + +import org.apache.mina.common.IoFilter; +import org.apache.mina.common.IoHandler; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; + +/** + * Defines an address to {@link org.apache.mina.common.IoHandler} binding. + * This is used when specifying the addresses to accept new connections on when + * creating {@link org.apache.mina.common.IoAcceptor} objects using one of the + * {@link org.apache.mina.integration.spring.support.AbstractIoAcceptorFactoryBean} + * sub-classes. + *

+ * This class also allows for an optional list of filters to be associated with + * the address. The {@link org.apache.mina.common.IoAcceptor} will add + * all these filters to the filter chain of sessions created for incoming + * connections on the address specified by this binding. This makes it possible + * to specify different filters depending on the port the client is connecting + * on (e.g. using an {@link org.apache.mina.filter.SSLFilter} when connecting + * on port 443 but not on port 80). + *

+ * + * @author The Apache Directory Project (dev@directory.apache.org) + * @version $Rev$, $Date$ + */ +public class Binding implements InitializingBean +{ + private String address = null; + private IoHandler handler = null; + private IoFilterMapping[] filterMappings = new IoFilterMapping[ 0 ]; + + /** + * Creates a new empty instance. + */ + public Binding() + { + } + + /** + * Creates a new instance using the specified values. + * + * @param address the address. See {@link #setAddress(String)} for + * information on the format. + * @param handler the handler. + * @throws IllegalArgumentException if the any of the specified values are + * null. + */ + public Binding( String address, IoHandler handler ) + { + setAddress( address ); + setHandler( handler ); + } + + /** + * Creates a new instance using the specified values. + * + * @param address the address. See {@link #setAddress(String)} for + * information on the format. + * @param handler the handler. + * @param filterMappings the filter mappigns. + * @throws IllegalArgumentException if the any of the specified values are + * null. + */ + public Binding( String address, IoHandler handler, + IoFilterMapping[] filterMappings ) + { + setAddress( address ); + setHandler( handler ); + setFilterMappings( filterMappings ); + } + + /** + * Creates a new instance using the specified values. + * + * @param address the address. See {@link #setAddress(String)} for + * information on the format. + * @param handler the handler. + * @param filters the filters. + * @throws IllegalArgumentException if the any of the specified values are + * null. + */ + public Binding( String address, IoHandler handler, + IoFilter[] filters ) + { + setAddress( address ); + setHandler( handler ); + setFilters( filters ); + } + + /** + * Returns the address the handler of this object will be bound to. + * See {@link #setAddress(String)} for more information on the format of this + * string. + * + * @return the textual representation of the transport type specific address. + */ + public String getAddress() + { + return address; + } + + /** + * Sets the address the handler of this object will be bound to. + * The format of this address depends on the transport type of the + * {@link org.apache.mina.common.IoAcceptor} this binding will be used for. + * When creating a {@link org.apache.mina.transport.socket.nio.SocketAcceptor} + * using {@link SocketAcceptorFactoryBean} the format looks like + * [<interface>:]port, e.g. 127.0.0.1:8080. + * {@link #getAddress()} + * + * @param address the textual representation of the transport type specific + * address. + * @throws IllegalArgumentException if the specified value is + * null. + */ + public void setAddress( String address ) + { + Assert.notNull( address, "Property 'address' may not be null" ); + this.address = address; + } + + /** + * Returns the handler of this binding object. + * + * @return the handler. + */ + public IoHandler getHandler() + { + return handler; + } + + /** + * Sets the handler of this binding object. + * + * @param handler the handler. + * @throws IllegalArgumentException if the specified value is + * null. + */ + public void setHandler( IoHandler handler ) + { + Assert.notNull( handler, "Property 'handler' may not be null" ); + this.handler = handler; + } + + /** + * Sets a number of unnamed filters. These will be added to the filter chain + * of sessions created when a connection is made on the address specified by + * this binding. The filters will be assigned automatically generated names + * (portFilter0, portFilter1, etc). + * + * @param filters the filters. + * @throws IllegalArgumentException if the specified value is + * null. + */ + public void setFilters( IoFilter[] filters ) + { + Assert.notNull( filters, "Property 'filters' may not be null" ); + this.filterMappings = new IoFilterMapping[ filters.length ]; + + for( int i = 0; i < filters.length; i++ ) + { + this.filterMappings[ i ] = new IoFilterMapping(); + this.filterMappings[ i ].setName( "portFilter" + i ); + this.filterMappings[ i ].setFilter( filters[ i ] ); + } + } + + /** + * Sets a number of named filters. These will be added to the filter chain + * of sessions created when a connection is made on the address specified by + * this binding. + * + * @param filterMappings the name to filter mappings. + * @throws IllegalArgumentException if the specified value is + * null. + */ + public void setFilterMappings( IoFilterMapping[] filterMappings ) + { + Assert.notNull( filterMappings, "Property 'filterMappings' may not be null" ); + this.filterMappings = filterMappings; + } + + /** + * Returns the array of {@link IoFilterMapping} objects configured for this + * binding. + * + * @return the mappings. + */ + public IoFilterMapping[] getFilterMappings() + { + return filterMappings; + } + + public void afterPropertiesSet() throws Exception + { + Assert.notNull( address, "Property 'address' may not be null" ); + Assert.notNull( handler, "Property 'handler' may not be null" ); + } + +} Propchange: directory/network/trunk/src/java/org/apache/mina/integration/spring/Binding.java ------------------------------------------------------------------------------ svn:keywords = Id Modified: directory/network/trunk/src/java/org/apache/mina/integration/spring/DatagramAcceptorFactoryBean.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/integration/spring/DatagramAcceptorFactoryBean.java?rev=351469&r1=351468&r2=351469&view=diff ============================================================================== --- directory/network/trunk/src/java/org/apache/mina/integration/spring/DatagramAcceptorFactoryBean.java (original) +++ directory/network/trunk/src/java/org/apache/mina/integration/spring/DatagramAcceptorFactoryBean.java Thu Dec 1 13:05:16 2005 @@ -36,24 +36,30 @@ * <!-- Create a thread pool filter --> * <bean id="threadPoolFilter" * class="org.apache.mina.filter.ThreadPoolFilter"> - * <!-- Threads will be named IoWorker-1, IoWorker-2, etc --> - * <constructor-arg value="IoWorker"/> - * <property name="maximumPoolSize" value="10"/> + * <!-- Threads will be named IoWorker-1, IoWorker-2, etc --> + * <constructor-arg value="IoWorker"/> + * <property name="maximumPoolSize" value="10"/> * </bean> * * <!-- Create the DatagramAcceptor --> * <bean id="datagramAcceptor" - * class="org.apache.mina.spring.DatagramAcceptorFactoryBean"> + * class="org.apache.mina.integration.spring.DatagramAcceptorFactoryBean"> * <property name="filters"> * <list> - * <ref local="threadPoolFilter"/> + * <ref local="threadPoolFilter"/> * </list> * </property> * <property name="bindings"> - * <map> - * <entry key=":9287" value-ref="myHandler"/> - * <entry key="192.168.0.1:6273" value-ref="myHandler"/> - * </map> + * <list> + * <bean class="org.apache.mina.integration.spring.Binding"> + * <property name="address" value=":9287"/> + * <property name="handler" ref="myHandler"/> + * </bean> + * <bean class="org.apache.mina.integration.spring.Binding"> + * <property name="address" value="192.168.0.1:6273"/> + * <property name="handler" ref="myHandler"/> + * </bean> + * </list> * </property> * </bean> * Modified: directory/network/trunk/src/java/org/apache/mina/integration/spring/IoFilterMapping.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/integration/spring/IoFilterMapping.java?rev=351469&r1=351468&r2=351469&view=diff ============================================================================== --- directory/network/trunk/src/java/org/apache/mina/integration/spring/IoFilterMapping.java (original) +++ directory/network/trunk/src/java/org/apache/mina/integration/spring/IoFilterMapping.java Thu Dec 1 13:05:16 2005 @@ -19,45 +19,64 @@ package org.apache.mina.integration.spring; import org.apache.mina.common.IoFilter; -import org.apache.mina.integration.spring.support.AbstractIoSessionManagerFactoryBean; +import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; /** - * Associates a name with an IoFilter. The name will be used in the call to - * {@link org.apache.mina.common.IoFilterChain#addLast(String, IoFilter)} when - * an IoSessionManager is configured by using any of the Spring FactoryBean - * implementations extending {@link AbstractIoSessionManagerFactoryBean}. + * Associates a name with an {@link IoFilter}. This makes it possible to configure + * named filters using Spring. + *

+ * Use this class when you want to configure the + * filters added to the filter chain of all sessions created from a particular + * {@link org.apache.mina.common.IoSessionManager} created using one of the + * {@link org.apache.mina.integration.spring.support.AbstractIoSessionManagerFactoryBean} + * sub-classes but you don't want the names to be generated automatically. + *

+ *

+ * This class can also be used when creating {@link Binding} objects. This lets + * one configure per-port filters. These filters will only be added to the + * filter chain of sessions for incoming connections on the port specified by + * the {@link Binding}. Note that {@link Binding} can also be configured to + * generate filter names automatically. In that case you add the {@link IoFilter} + * instances directly to the {@link Binding}. + *

* * @author The Apache Directory Project (dev@directory.apache.org) * @version $Rev$, $Date$ + * @see org.apache.mina.integration.spring.support.AbstractIoSessionManagerFactoryBean + * @see org.apache.mina.integration.spring.Binding */ -public class IoFilterMapping +public class IoFilterMapping implements InitializingBean { private String name = null; - private IoFilter filter = null; /** - * Creates a new mapping which associates the specified name with the - * specified filter. + * Creates a new empty instance. + */ + public IoFilterMapping() + { + } + + /** + * Creates a new instance using the specified name and filter. * - * @param name - * the name. - * @param filter - * the filter. - * @throws IllegalArgumentException - * if any of the parameters are null. + * @param name the name. + * @param filter the filter. + * @throws IllegalArgumentException if any of the arguments are + * null. */ public IoFilterMapping( String name, IoFilter filter ) { Assert.notNull( name, "Argument 'name' may not be null" ); Assert.notNull( filter, "Argument 'filter' may not be null" ); + this.name = name; this.filter = filter; } - + /** - * Gets the filter of this mapping. + * Returns the filter of this mapping. * * @return the filter. */ @@ -67,12 +86,44 @@ } /** - * Gets the name associated with the filter. + * Returns the name associated with the filter. * * @return the name. */ public String getName() { return name; + } + + /** + * Sets the filter of this mapping. + * + * @param filter the filter. + * @throws IllegalArgumentException if the specified value is + * null. + */ + public void setFilter( IoFilter filter ) + { + Assert.notNull( filter, "Argument 'filter' may not be null" ); + this.filter = filter; + } + + /** + * Sets the name associated with the filter. + * + * @param name the name. + * @throws IllegalArgumentException if the specified value is + * null. + */ + public void setName( String name ) + { + Assert.notNull( name, "Argument 'name' may not be null" ); + this.name = name; + } + + public void afterPropertiesSet() throws Exception + { + Assert.notNull( name, "Argument 'name' may not be null" ); + Assert.notNull( filter, "Argument 'filter' may not be null" ); } } Modified: directory/network/trunk/src/java/org/apache/mina/integration/spring/SocketAcceptorFactoryBean.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/integration/spring/SocketAcceptorFactoryBean.java?rev=351469&r1=351468&r2=351469&view=diff ============================================================================== --- directory/network/trunk/src/java/org/apache/mina/integration/spring/SocketAcceptorFactoryBean.java (original) +++ directory/network/trunk/src/java/org/apache/mina/integration/spring/SocketAcceptorFactoryBean.java Thu Dec 1 13:05:16 2005 @@ -45,27 +45,50 @@ * <!-- Create a thread pool filter --> * <bean id="threadPoolFilter" * class="org.apache.mina.filter.ThreadPoolFilter"> - * <!-- Threads will be named IoWorker-1, IoWorker-2, etc --> - * <constructor-arg value="IoWorker"/> - * <property name="maximumPoolSize" value="10"/> + * <!-- Threads will be named IoWorker-1, IoWorker-2, etc --> + * <constructor-arg value="IoWorker"/> + * <property name="maximumPoolSize" value="10"/> + * </bean> + * + * <!-- Create an SSL filter to be used for POP3 over SSL --> + * <bean id="sslFilter" class="org.apache.mina.filter.SSLFilter"> + * ... * </bean> * * <!-- Create the SocketAcceptor --> - * <bean id="socketAcceptor" - * class="org.apache.mina.spring.SocketAcceptorFactoryBean"> - * <property name="filters"> - * <list> + * <bean id="socketAcceptor" + * class="org.apache.mina.integration.spring.SocketAcceptorFactoryBean"> + * <property name="filters"> + * <list> * <ref local="threadPoolFilter"/> - * </list> - * </property> - * <property name="bindings"> - * <map> - * <entry key=":110" value-ref="pop3Handler"/> - * <entry key=":143" value-ref="imapHandler"/> - * <entry key="127.0.0.1:60987" value-ref="adminHandler"/> - * </map> - * </property> - * </bean> + * </list> + * </property> + * <property name="bindings"> + * <list> + * <bean class="org.apache.mina.spring.integration.Binding"> + * <property name="address" value=":110"/> + * <property name="handler" ref="pop3Handler"/> + * </bean> + * <bean class="org.apache.mina.spring.integration.Binding"> + * <property name="address" value=":995"/> + * <property name="handler" ref="pop3Handler"/> + * <property name="filters"> + * <list> + * <ref local="sslFilter"/> + * </list> + * </property> + * </bean> + * <bean class="org.apache.mina.spring.integration.Binding"> + * <property name="address" value=":143"/> + * <property name="handler" ref="imapHandler"/> + * </bean> + * <bean class="org.apache.mina.spring.integration.Binding"> + * <property name="address" value="127.0.0.1:60987"/> + * <property name="handler" ref="adminHandler"/> + * </bean> + * </list> + * </property> + * </bean> * * *

Modified: directory/network/trunk/src/java/org/apache/mina/integration/spring/VmPipeAcceptorFactoryBean.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/integration/spring/VmPipeAcceptorFactoryBean.java?rev=351469&r1=351468&r2=351469&view=diff ============================================================================== --- directory/network/trunk/src/java/org/apache/mina/integration/spring/VmPipeAcceptorFactoryBean.java (original) +++ directory/network/trunk/src/java/org/apache/mina/integration/spring/VmPipeAcceptorFactoryBean.java Thu Dec 1 13:05:16 2005 @@ -40,24 +40,30 @@ * <!-- Create a thread pool filter --> * <bean id="threadPoolFilter" * class="org.apache.mina.filter.ThreadPoolFilter"> - * <!-- Threads will be named IoWorker-1, IoWorker-2, etc --> - * <constructor-arg value="IoWorker"/> - * <property name="maximumPoolSize" value="10"/> + * <!-- Threads will be named IoWorker-1, IoWorker-2, etc --> + * <constructor-arg value="IoWorker"/> + * <property name="maximumPoolSize" value="10"/> * </bean> * * <!-- Create the DatagramAcceptor --> * <bean id="vmPipeAcceptor" - * class="org.apache.mina.spring.VmPipeAcceptorFactoryBean"> + * class="org.apache.mina.integration.spring.VmPipeAcceptorFactoryBean"> * <property name="filters"> * <list> - * <ref local="threadPoolFilter"/> + * <ref local="threadPoolFilter"/> * </list> * </property> * <property name="bindings"> - * <map> - * <entry key=":9287" value-ref="myHandler"/> - * <entry key=":6273" value-ref="myHandler"/> - * </map> + * <list> + * <bean class="org.apache.mina.integration.spring.Binding"> + * <property name="address" value=":9287"/> + * <property name="handler" ref="myHandler"/> + * </bean> + * <bean class="org.apache.mina.integration.spring.Binding"> + * <property name="address" value=":6273"/> + * <property name="handler" ref="myHandler"/> + * </bean> + * </list> * </property> * </bean> * Modified: directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBean.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBean.java?rev=351469&r1=351468&r2=351469&view=diff ============================================================================== --- directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBean.java (original) +++ directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBean.java Thu Dec 1 13:05:16 2005 @@ -19,25 +19,25 @@ package org.apache.mina.integration.spring.support; import java.net.SocketAddress; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; +import org.apache.mina.common.DefaultIoFilterChainBuilder; import org.apache.mina.common.IoAcceptor; +import org.apache.mina.common.IoFilterChainBuilder; import org.apache.mina.common.IoHandler; import org.apache.mina.common.IoSessionManager; +import org.apache.mina.integration.spring.Binding; +import org.apache.mina.integration.spring.IoFilterMapping; import org.springframework.util.Assert; /** - * Abstract Spring FactoryBean which creates IoAcceptor instances and enables - * their bindings and filter chain to be configured using Spring. + * Abstract Spring FactoryBean which creates {@link IoAcceptor} instances and + * enables their bindings and filters to be configured using Spring. *

* NOTE: Do NOT call {@link IoAcceptor#bind(SocketAddress, IoHandler)} on the - * created IoAcceptor. If you do add additional bindings that way + * created {@link IoAcceptor}. If you do add additional bindings that way * {@link #destroyInstance(Object)} will not be able to unbind all bindings of - * the IoAcceptor and it will not be fully shut down when the Spring BeanFactory - * is closed. + * the {@link IoAcceptor} and it will not be fully shut down when the Spring + * BeanFactory is closed. *

* * @author The Apache Directory Project (dev@directory.apache.org) @@ -47,24 +47,23 @@ AbstractIoSessionManagerFactoryBean { - protected Map bindings = Collections.EMPTY_MAP; + protected Binding[] bindings = new Binding[ 0 ]; /** - * Creates the IoAcceptor configured by this factory bean. + * Creates the {@link IoAcceptor} configured by this factory bean. * - * @return the IoAcceptor. - * @throws Exception - * on errors. + * @return the {@link IoAcceptor}. + * @throws Exception on errors. */ protected abstract IoAcceptor createIoAcceptor() throws Exception; /** - * Creates a new IoAcceptor. Calls {@link #createIoAcceptor()} to get the - * new IoAcceptor instance and then calls + * Creates a new {@link IoAcceptor}. Calls {@link #createIoAcceptor()} to + * get the new {@link IoAcceptor} instance and then calls * {@link AbstractIoSessionManagerFactoryBean#initIoSessionManager(IoSessionManager)} * followed by {@link #initIoAcceptor(IoAcceptor)}. * - * @return the IoAcceptor instance. + * @return the {@link IoAcceptor} instance. */ protected Object createInstance() throws Exception { @@ -77,12 +76,12 @@ } /** - * Initializes an IoAcceptor configured by this factory bean. + * Initializes an {@link IoAcceptor} configured by this factory bean by + * calling {@link IoAcceptor#bind(SocketAddress, IoHandler, IoFilterChainBuilder)} + * for all bindings configured using {@link #setBindings(Binding[])}. * - * @param acceptor - * the IoAcceptor. - * @throws Exception - * on errors. + * @param acceptor the {@link IoAcceptor}. + * @throws Exception on errors. */ protected void initIoAcceptor( IoAcceptor acceptor ) throws Exception { @@ -90,29 +89,37 @@ /* * Bind all. */ - for( Iterator it = bindings.keySet().iterator(); it.hasNext(); ) + for( int i = 0; i < bindings.length; i++ ) { - SocketAddress address = ( SocketAddress ) it.next(); - IoHandler handler = ( IoHandler ) bindings.get( address ); - acceptor.bind( address, handler ); + Binding b = bindings[ i ]; + DefaultIoFilterChainBuilder chainBuilder = + new DefaultIoFilterChainBuilder(); + + IoFilterMapping[] fm = b.getFilterMappings(); + for( int j = 0; j < fm.length; j++ ) + { + chainBuilder.addLast( fm[ j ].getName(), fm[ j ].getFilter() ); + } + + SocketAddress address = parseSocketAddress( b.getAddress() ); + acceptor.bind( address, b.getHandler(), chainBuilder ); } } /** - * Destroys an IoAcceptor created by the factory bean by calling + * Destroys an {@link IoAcceptor} created by the factory bean by calling * {@link #destroyIoAcceptor(IoAcceptor)} and then * {@link AbstractIoSessionManagerFactoryBean#destroyIoSessionManager(IoSessionManager)}. * This method may be overridden by extending classes if additional calls - * are necessary to shutdown the IoAcceptor or if the sequence of calls - * should be different. + * are necessary to shutdown the {@link IoAcceptor} or if the sequence of + * calls should be different. *

* This method will be called by Spring when the BeanFactory creating this * instance is closed. Spring will NOT call this method if this factory bean * has been configured for non-singleton use. *

* - * @param instance - * the IoAcceptor instance to be destroyed. + * @param instance the {@link IoAcceptor} instance to be destroyed. */ protected void destroyInstance( Object instance ) throws Exception { @@ -122,23 +129,22 @@ } /** - * Destroys an IoAcceptor created by the factory bean by unbinding all - * bindings set through {@link #setBindings(Map)}. + * Destroys an {@link IoAcceptor} created by the factory bean by unbinding all + * bindings set through {@link #setBindings(Binding[])}. * - * @param acceptor - * the IoAcceptor instance to be destroyed. + * @param acceptor the {@link IoAcceptor} instance to be destroyed. */ protected void destroyIoAcceptor( IoAcceptor acceptor ) throws Exception { /* * Unbind all. */ - for( Iterator it = bindings.keySet().iterator(); it.hasNext(); ) + for( int i = 0; i < bindings.length; i++ ) { - SocketAddress address = ( SocketAddress ) it.next(); + Binding b = bindings[ i ]; try { - acceptor.unbind( address ); + acceptor.unbind( parseSocketAddress( b.getAddress() ) ); } catch( Exception ignored ) { @@ -152,37 +158,28 @@ } /** - * Sets the bindings to be used by the IoAcceptor created by this factory - * bean. The specified map maps a String representation of the SocketAddress - * implementation supported by the concrete implementation of this class to - * an IoHandler instance. - * - * @param bindings - * the - * @throws IllegalArgumentException - * if the specified value is null. - * @see IoAcceptor#bind(SocketAddress, IoHandler) + * Sets the bindings to be used by the {@link IoAcceptor} created by this + * factory bean. + * + * @param bindings the bindings. + * @throws IllegalArgumentException if the specified value is + * null. + * @see IoAcceptor#bind(SocketAddress, IoHandler, IoFilterChainBuilder) * @see #parseSocketAddress(String) + * @see Binding */ - public void setBindings( Map bindings ) + public void setBindings( Binding[] bindings ) { Assert.notNull( bindings, "Property 'bindings' may not be null" ); - this.bindings = new HashMap(); - - for( Iterator it = bindings.keySet().iterator(); it.hasNext(); ) - { - String address = ( String ) it.next(); - IoHandler handler = ( IoHandler ) bindings.get( address ); - this.bindings.put( parseSocketAddress( address ), handler ); - } + this.bindings = bindings; } /** - * Parses the specified string and returns the corresponding SocketAddress. + * Parses the specified string and returns the corresponding + * {@link SocketAddress}. * - * @param s - * the string to parse. - * @return the SocketAddress. + * @param s the string to parse. + * @return the {@link SocketAddress}. */ protected abstract SocketAddress parseSocketAddress( String s ); } Modified: directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoConnectorFactoryBean.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoConnectorFactoryBean.java?rev=351469&r1=351468&r2=351469&view=diff ============================================================================== --- directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoConnectorFactoryBean.java (original) +++ directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoConnectorFactoryBean.java Thu Dec 1 13:05:16 2005 @@ -23,7 +23,7 @@ /** * Abstract Spring FactoryBean which creates {@link IoConnector} instances and - * enables their filter chain to be configured using Spring. + * enables their filters to be configured using Spring. * * @author The Apache Directory Project (dev@directory.apache.org) * @version $Rev$, $Date$ Modified: directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBean.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBean.java?rev=351469&r1=351468&r2=351469&view=diff ============================================================================== --- directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBean.java (original) +++ directory/network/trunk/src/java/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBean.java Thu Dec 1 13:05:16 2005 @@ -27,17 +27,20 @@ import org.springframework.util.Assert; /** - * Abstract Spring FactoryBean which creates IoSessionManager instances and - * enables their filter chain to be configured using Spring. + * Abstract Spring {@link org.springframework.beans.factory.FactoryBean} + * which creates {@link org.apache.mina.common.IoSessionManager} instances. This + * factory bean makes it possible to configure the filters to be added to all the + * sessions created by the {@link org.apache.mina.common.IoSessionManager} using + * Spring. *

- * A IoFilterChain may be set up in two ways. By creating - * {@link IoFilterMapping} objects which associate a name with an IoFilter + * The filters may be set up in two ways. By creating + * {@link IoFilterMapping} objects which associate a name with an {@link IoFilter} * instance and set them using {@link #setFilterMappings(IoFilterMapping[])} or * by using {@link #setFilters(IoFilter[])} directly which assigns automatically - * generated names to each IoFilter. + * generated names to each {@link IoFilter}. *

*

- * NOTE: Instances of this class should NOT be condigured as non-singletons. + * NOTE: Instances of this class should NOT be configured as non-singletons. * This will prevent Spring from calling the destroyInstance() * method on BeanFactory shut down. *

@@ -53,12 +56,10 @@ private IoFilterMapping[] filterMappings = new IoFilterMapping[ 0 ]; /** - * Initializes an IoSessionManager configured by this factory bean. + * Initializes an {@link IoSessionManager} configured by this factory bean. * - * @param sessionManager - * the IoSessionManager. - * @throws Exception - * on errors. + * @param sessionManager the {@link IoSessionManager}. + * @throws Exception on errors. */ protected void initIoSessionManager( IoSessionManager sessionManager ) throws Exception @@ -76,16 +77,14 @@ for( int i = 0; i < filterMappings.length; i++ ) { builder.addLast( filterMappings[ i ].getName(), - filterMappings[ i ].getFilter() ); + filterMappings[ i ].getFilter() ); } } /** - * Destroys an IoSessionManager created by the factory bean by clearing its - * IoFilterChain. + * Destroys an {@link IoSessionManager} created by the factory bean. * - * @param sessionManager - * the IoSessionManager instance to be destroyed. + * @param sessionManager the IoSessionManager instance to be destroyed. */ protected void destroyIoSessionManager( IoSessionManager sessionManager ) throws Exception @@ -98,15 +97,14 @@ } /** - * Sets a number of unnamed filters which will be used to create the filter - * chain for the IoSessionManager created by this factory bean. The filters - * will be assigned automatically generated names (filter0, - * filter1, etc). + * Sets a number of unnamed filters which will be added to the filter + * chain of all sessions created by the {@link IoSessionManager} created by + * this factory bean. The filters will be assigned automatically generated + * names (managerFilter0, managerFilter1, etc). * - * @param filters - * the filters. - * @throws IllegalArgumentException - * if the specified value is null. + * @param filters the filters. + * @throws IllegalArgumentException if the specified value is + * null. */ public void setFilters( IoFilter[] filters ) { @@ -115,24 +113,24 @@ for( int i = 0; i < filters.length; i++ ) { - this.filterMappings[ i ] = new IoFilterMapping( "filter" + i, - filters[ i ] ); + this.filterMappings[ i ] = new IoFilterMapping(); + this.filterMappings[ i ].setName( "managerFilter" + i ); + this.filterMappings[ i ].setFilter( filters[ i ] ); } } /** - * Sets a number of named filters which will be used to create the filter - * chain for the IoSessionManager created by this factory bean. + * Sets a number of named filters which will be added to the filter + * chain of all sessions created by the {@link IoSessionManager} created by + * this factory bean. * - * @param filterMappings - * the name to filter mappings. - * @throws IllegalArgumentException - * if the specified value is null. + * @param filterMappings the name to filter mappings. + * @throws IllegalArgumentException if the specified value is + * null. */ public void setFilterMappings( IoFilterMapping[] filterMappings ) { - Assert.notNull( filterMappings, - "Property 'filterMappings' may not be null" ); + Assert.notNull( filterMappings, "Property 'filterMappings' may not be null" ); this.filterMappings = filterMappings; } @@ -141,13 +139,11 @@ * created by this factory bean. If this isn't specified a default one will * be used. * - * @param exceptionMonitor - * the monitor. + * @param exceptionMonitor the monitor. */ public void setExceptionMonitor( ExceptionMonitor exceptionMonitor ) { - Assert.notNull( exceptionMonitor, - "Property 'exceptionMonitor' may not be null" ); + Assert.notNull( exceptionMonitor, "Property 'exceptionMonitor' may not be null" ); this.exceptionMonitor = exceptionMonitor; } } Modified: directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBeanTest.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBeanTest.java?rev=351469&r1=351468&r2=351469&view=diff ============================================================================== --- directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBeanTest.java (original) +++ directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoAcceptorFactoryBeanTest.java Thu Dec 1 13:05:16 2005 @@ -20,14 +20,19 @@ import java.lang.reflect.Method; import java.net.SocketAddress; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.Iterator; +import java.util.List; import junit.framework.TestCase; +import org.apache.mina.common.DefaultIoFilterChainBuilder; import org.apache.mina.common.IoAcceptor; +import org.apache.mina.common.IoFilter; import org.apache.mina.common.IoHandler; import org.apache.mina.common.IoSessionManager; +import org.apache.mina.common.IoFilterChain.Entry; +import org.apache.mina.integration.spring.Binding; +import org.easymock.AbstractMatcher; import org.easymock.MockControl; import org.easymock.classextension.MockClassControl; @@ -44,10 +49,12 @@ AbstractIoAcceptorFactoryBean factory; MockControl mockIoAcceptor; IoAcceptor ioAcceptor; - Map bindings; + Binding[] bindings; IoHandler popHandler; IoHandler sshHandler; IoHandler httpHandler; + IoFilter filter1; + IoFilter filter2; protected void setUp() throws Exception { @@ -84,34 +91,45 @@ /* * Create some IoHandlers. */ - popHandler = ( IoHandler ) MockControl.createControl( IoHandler.class ) - .getMock(); - sshHandler = ( IoHandler ) MockControl.createControl( IoHandler.class ) - .getMock(); - httpHandler = ( IoHandler ) MockControl.createControl( IoHandler.class ) - .getMock(); + popHandler = ( IoHandler ) MockControl.createControl( IoHandler.class ).getMock(); + sshHandler = ( IoHandler ) MockControl.createControl( IoHandler.class ).getMock(); + httpHandler = ( IoHandler ) MockControl.createControl( IoHandler.class ).getMock(); /* - * Create the map of bindings to use. - */ - bindings = new LinkedHashMap(); - bindings.put( ":110", popHandler ); - bindings.put( "127.0.0.1:22", sshHandler ); - bindings.put( "192.168.0.1:80", httpHandler ); + * Create the filters + */ + filter1 = ( IoFilter ) MockControl.createControl( IoFilter.class ).getMock(); + filter2 = ( IoFilter ) MockControl.createControl( IoFilter.class ).getMock(); + + /* + * Create the bindings to use. + */ + bindings = new Binding[ 3 ]; + bindings[ 0 ] = new Binding( ":110", popHandler, new IoFilter[] { filter1 } ); + bindings[ 1 ] = new Binding( "127.0.0.1:22", sshHandler, new IoFilter[] { filter1, filter2 } ); + bindings[ 2 ] = new Binding( "192.168.0.1:80", httpHandler ); } public void testCreateInstance() throws Exception { + + DefaultIoFilterChainBuilder builder1 = new DefaultIoFilterChainBuilder(); + builder1.addLast( "portFilter0", filter1 ); + DefaultIoFilterChainBuilder builder2 = new DefaultIoFilterChainBuilder(); + builder2.addLast( "portFilter0", filter1 ); + builder2.addLast( "portFilter1", filter2 ); + /* * Record expectations. */ factory.createIoAcceptor(); mockFactory.setReturnValue( ioAcceptor ); factory.initIoSessionManager( ioAcceptor ); - ioAcceptor.bind( new DummySocketAddress( ":110" ), popHandler ); - ioAcceptor.bind( new DummySocketAddress( "127.0.0.1:22" ), sshHandler ); + ioAcceptor.bind( new DummySocketAddress( ":110" ), popHandler, builder1 ); + mockIoAcceptor.setMatcher( new IoAcceptorBindArgumentsMatcher() ); + ioAcceptor.bind( new DummySocketAddress( "127.0.0.1:22" ), sshHandler, builder2 ); ioAcceptor.bind( new DummySocketAddress( "192.168.0.1:80" ), - httpHandler ); + httpHandler, new DefaultIoFilterChainBuilder() ); /* * Replay. @@ -205,5 +223,40 @@ DummySocketAddress that = ( DummySocketAddress ) o; return this.s.equals( that.s ); } + } + + public static class IoAcceptorBindArgumentsMatcher extends AbstractMatcher + { + protected boolean argumentMatches( Object expected, Object actual ) + { + if( expected instanceof DefaultIoFilterChainBuilder && + actual instanceof DefaultIoFilterChainBuilder ) + { + DefaultIoFilterChainBuilder b1 = ( DefaultIoFilterChainBuilder ) expected; + DefaultIoFilterChainBuilder b2 = ( DefaultIoFilterChainBuilder ) actual; + + List l1 = b1.getAll(); + List l2 = b2.getAll(); + if( l1.size() != l2.size() ) + return false; + + Iterator it1 = l1.iterator(); + Iterator it2 = l2.iterator(); + while( it1.hasNext() && it2.hasNext() ) + { + Entry e1 = ( Entry ) it1.next(); + Entry e2 = ( Entry ) it2.next(); + + if( !e1.getName().equals( e2.getName() ) ) + return false; + if( e1.getFilter() != e2.getFilter() ) + return false; + } + + return true; + } + return super.argumentMatches( expected, actual ); + } + } } Modified: directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBeanTest.java URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBeanTest.java?rev=351469&r1=351468&r2=351469&view=diff ============================================================================== --- directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBeanTest.java (original) +++ directory/network/trunk/src/test/org/apache/mina/integration/spring/support/AbstractIoSessionManagerFactoryBeanTest.java Thu Dec 1 13:05:16 2005 @@ -84,17 +84,17 @@ ( IoFilter ) MockControl.createControl( IoFilter.class ) .getMock() }; - IoSessionManager ioSessionManager = ( IoSessionManager ) mockIoSessionManager - .getMock(); - DefaultIoFilterChainBuilder ioFilterChainBuilder = ( DefaultIoFilterChainBuilder ) mockIoFilterChainBuilder - .getMock(); + IoSessionManager ioSessionManager = + ( IoSessionManager ) mockIoSessionManager.getMock(); + DefaultIoFilterChainBuilder ioFilterChainBuilder = + ( DefaultIoFilterChainBuilder ) mockIoFilterChainBuilder.getMock(); /* * Record expectations. */ - ioFilterChainBuilder.addLast( "filter0", filters[ 0 ] ); - ioFilterChainBuilder.addLast( "filter1", filters[ 1 ] ); - ioFilterChainBuilder.addLast( "filter2", filters[ 2 ] ); + ioFilterChainBuilder.addLast( "managerFilter0", filters[ 0 ] ); + ioFilterChainBuilder.addLast( "managerFilter1", filters[ 1 ] ); + ioFilterChainBuilder.addLast( "managerFilter2", filters[ 2 ] ); ioSessionManager.getFilterChain(); mockIoSessionManager.setReturnValue( mockIoFilterChainBuilder.getMock() );