View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.mina.integration.spring;
21  
22  import java.net.SocketAddress;
23  
24  import org.apache.mina.common.IoAcceptor;
25  import org.apache.mina.common.IoHandler;
26  import org.apache.mina.common.IoServiceConfig;
27  import org.springframework.beans.factory.DisposableBean;
28  import org.springframework.beans.factory.FactoryBean;
29  import org.springframework.beans.factory.InitializingBean;
30  import org.springframework.util.Assert;
31  
32  /**
33   * Spring {@link FactoryBean} which enables the bindings of an {@link IoAcceptor}
34   * to be configured using Spring. Example of usage:
35   * <p>
36   * 
37   * <pre>
38   *   &lt;!-- This makes it possible to specify java.net.SocketAddress values 
39   *        (e.g. :80 below) as Strings.
40   *        They will be converted into java.net.InetSocketAddress objects by Spring.  --&gt;
41   *   &lt;bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"&gt;
42   *     &lt;property name="customEditors"&gt;
43   *       &lt;map&gt;
44   *         &lt;entry key="java.net.SocketAddress"&gt;
45   *           &lt;bean class="org.apache.mina.integration.spring.InetSocketAddressEditor"/&gt;
46   *         &lt;/entry&gt;
47   *       &lt;/map&gt;
48   *     &lt;/property&gt;
49   *   &lt;/bean&gt;
50   * 
51   *   &lt;!-- The IoHandler implementation --&gt;
52   *   &lt;bean id="httpHandler" class="com.example.MyHttpHandler"&gt;
53   *     ...
54   *   &lt;/bean&gt;
55   *     
56   *   &lt;bean id="filterChainBuilder" 
57   *         class="org.apache.mina.integration.spring.DefaultIoFilterChainBuilderFactoryBean"&gt;
58   *     &lt;property name="filters"&gt;
59   *       &lt;list&gt;
60   *         &lt;bean class="org.apache.mina.filter.LoggingFilter"/&gt;
61   *       &lt;/list&gt;
62   *     &lt;/property&gt;
63   *   &lt;/bean&gt;
64   *
65   *  &lt;!-- By default MINA uses an ExecutorThreadModel. This demonstrates how to 
66   *          use your own with some non default settings. The threadModel will 
67   *          be set on the SocketAcceptorConfig defined below. To configure a 
68   *          ExecutorFilter directly you will have to use the ThreadModel.MANUAL 
69   *          ThreadModel instead. --&gt;
70   *   &lt;bean id="threadModel" class="org.apache.mina.integration.spring.ExecutorThreadModelFactoryBean"&gt;
71   *     &lt;property name="serviceName" value="HttpService"/&gt;
72   *     &lt;property name="executor"&gt;
73   *       &lt;bean class="org.apache.mina.integration.spring.ThreadPoolExecutorFactoryBean"&gt;
74   *         &lt;property name="corePoolSize" value="2"/&gt;
75   *         &lt;property name="maxPoolSize" value="10"/&gt;
76   *         &lt;property name="keepAliveSeconds" value="30"/&gt;
77   *       &lt;/bean&gt;
78   *     &lt;/property&gt;
79   *   &lt;/bean&gt;
80   *
81   *   &lt;bean id="ioAcceptor" class="org.apache.mina.integration.spring.IoAcceptorFactoryBean"&gt;
82   *     &lt;property name="target"&gt;
83   *       &lt;bean class="org.apache.mina.transport.socket.nio.SocketAcceptor"/&gt;
84   *     &lt;/property&gt;
85   *     &lt;property name="bindings"&gt;
86   *       &lt;list&gt;
87   *         &lt;bean class="org.apache.mina.integration.spring.Binding"&gt;
88   *           &lt;property name="address" value=":80"/&gt;
89   *           &lt;property name="handler" ref="httpHandler"/&gt;
90   *           &lt;property name="serviceConfig"&gt;
91   *             &lt;bean class="org.apache.mina.transport.socket.nio.SocketAcceptorConfig"&gt;
92   *               &lt;property name="filterChainBuilder" ref="filterChainBuilder"/&gt;
93   *               &lt;property name="reuseAddress" value="true"/&gt;
94   *               &lt;property name="threadModel" ref="threadModel"/&gt; 
95   *             &lt;/bean&gt;
96   *           &lt;/property&gt;
97   *         &lt;/bean&gt;
98   *       &lt;/list&gt;
99   *     &lt;/property&gt;
100  *   &lt;/bean&gt;
101  * </pre>
102  * 
103  * </p>
104  * 
105  * @author The Apache Directory Project (mina-dev@directory.apache.org)
106  * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (Fri, 13 Jul 2007) $
107  */
108 public class IoAcceptorFactoryBean implements FactoryBean, InitializingBean,
109         DisposableBean {
110     private Binding[] bindings = new Binding[0];
111 
112     private IoAcceptor target;
113 
114     /**
115      * Sets the {@link IoAcceptor} to be configured using this factory bean.
116      * 
117      * @param target the target {@link IoAcceptor}.
118      */
119     public void setTarget(IoAcceptor target) {
120         this.target = target;
121     }
122 
123     /**
124      * Sets the bindings to be used by the {@link IoAcceptor} configured by this 
125      * factory bean.
126      * 
127      * @param bindings the bindings.
128      * @throws IllegalArgumentException if the specified value is 
129      *         <code>null</code>.
130      * @see IoAcceptor#bind(SocketAddress, IoHandler)
131      * @see IoAcceptor#bind(SocketAddress, IoHandler, IoServiceConfig)
132      * @see Binding
133      */
134     public void setBindings(Binding[] bindings) {
135         Assert.notNull(bindings, "Property 'bindings' may not be null");
136         this.bindings = bindings;
137     }
138 
139     public Object getObject() throws Exception {
140         return target;
141     }
142 
143     public Class getObjectType() {
144         return IoAcceptor.class;
145     }
146 
147     public boolean isSingleton() {
148         return true;
149     }
150 
151     public void afterPropertiesSet() throws Exception {
152         Assert.notNull(target, "Property 'target' may not be null");
153 
154         /*
155          * Bind all.
156          */
157         for (int i = 0; i < bindings.length; i++) {
158             Binding b = bindings[i];
159             if (b.getServiceConfig() != null) {
160                 target.bind(b.getAddress(), b.getHandler(), b
161                         .getServiceConfig());
162             } else {
163                 target.bind(b.getAddress(), b.getHandler());
164             }
165         }
166     }
167 
168     public void destroy() throws Exception {
169         for (int i = 0; i < bindings.length; i++) {
170             Binding b = bindings[i];
171             try {
172                 target.unbind(b.getAddress());
173             } catch (Exception ignored) {
174             }
175         }
176     }
177 }