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 * <!-- 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. -->
41 * <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
42 * <property name="customEditors">
43 * <map>
44 * <entry key="java.net.SocketAddress">
45 * <bean class="org.apache.mina.integration.spring.InetSocketAddressEditor"/>
46 * </entry>
47 * </map>
48 * </property>
49 * </bean>
50 *
51 * <!-- The IoHandler implementation -->
52 * <bean id="httpHandler" class="com.example.MyHttpHandler">
53 * ...
54 * </bean>
55 *
56 * <bean id="filterChainBuilder"
57 * class="org.apache.mina.integration.spring.DefaultIoFilterChainBuilderFactoryBean">
58 * <property name="filters">
59 * <list>
60 * <bean class="org.apache.mina.filter.LoggingFilter"/>
61 * </list>
62 * </property>
63 * </bean>
64 *
65 * <!-- 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. -->
70 * <bean id="threadModel" class="org.apache.mina.integration.spring.ExecutorThreadModelFactoryBean">
71 * <property name="serviceName" value="HttpService"/>
72 * <property name="executor">
73 * <bean class="org.apache.mina.integration.spring.ThreadPoolExecutorFactoryBean">
74 * <property name="corePoolSize" value="2"/>
75 * <property name="maxPoolSize" value="10"/>
76 * <property name="keepAliveSeconds" value="30"/>
77 * </bean>
78 * </property>
79 * </bean>
80 *
81 * <bean id="ioAcceptor" class="org.apache.mina.integration.spring.IoAcceptorFactoryBean">
82 * <property name="target">
83 * <bean class="org.apache.mina.transport.socket.nio.SocketAcceptor"/>
84 * </property>
85 * <property name="bindings">
86 * <list>
87 * <bean class="org.apache.mina.integration.spring.Binding">
88 * <property name="address" value=":80"/>
89 * <property name="handler" ref="httpHandler"/>
90 * <property name="serviceConfig">
91 * <bean class="org.apache.mina.transport.socket.nio.SocketAcceptorConfig">
92 * <property name="filterChainBuilder" ref="filterChainBuilder"/>
93 * <property name="reuseAddress" value="true"/>
94 * <property name="threadModel" ref="threadModel"/>
95 * </bean>
96 * </property>
97 * </bean>
98 * </list>
99 * </property>
100 * </bean>
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 }