1 | /* |
2 | * @(#) $Id: SimpleServiceRegistry.java 327113 2005-10-21 06:59:15Z trustin $ |
3 | */ |
4 | package org.apache.mina.registry; |
5 | |
6 | import java.io.IOException; |
7 | import java.net.InetSocketAddress; |
8 | import java.net.SocketAddress; |
9 | import java.util.HashSet; |
10 | import java.util.Iterator; |
11 | import java.util.Set; |
12 | |
13 | import org.apache.mina.common.TransportType; |
14 | import org.apache.mina.io.IoAcceptor; |
15 | import org.apache.mina.io.IoHandler; |
16 | import org.apache.mina.io.datagram.DatagramAcceptor; |
17 | import org.apache.mina.io.filter.IoThreadPoolFilter; |
18 | import org.apache.mina.io.socket.SocketAcceptor; |
19 | import org.apache.mina.protocol.ProtocolAcceptor; |
20 | import org.apache.mina.protocol.ProtocolProvider; |
21 | import org.apache.mina.protocol.filter.ProtocolThreadPoolFilter; |
22 | import org.apache.mina.protocol.io.IoProtocolAcceptor; |
23 | import org.apache.mina.protocol.vmpipe.VmPipeAcceptor; |
24 | import org.apache.mina.protocol.vmpipe.VmPipeAddress; |
25 | |
26 | /** |
27 | * A simple implementation of {@link ServiceRegistry}. |
28 | * |
29 | * This service registry supports socket, datagram, VM-pipe transport types, |
30 | * and thread pools were added by default. |
31 | * |
32 | * @author The Apache Directory Project (dev@directory.apache.org) |
33 | * @version $Rev: 327113 $, $Date: 2005-10-21 15:59:15 +0900 $, |
34 | */ |
35 | public class SimpleServiceRegistry implements ServiceRegistry |
36 | { |
37 | protected final IoAcceptor socketIoAcceptor = new SocketAcceptor(); |
38 | |
39 | protected final IoAcceptor datagramIoAcceptor = new DatagramAcceptor(); |
40 | |
41 | protected final ProtocolAcceptor socketProtocolAcceptor = new IoProtocolAcceptor( |
42 | socketIoAcceptor ); |
43 | |
44 | protected final ProtocolAcceptor datagramProtocolAcceptor = new IoProtocolAcceptor( |
45 | datagramIoAcceptor ); |
46 | |
47 | protected final ProtocolAcceptor vmPipeAcceptor = new VmPipeAcceptor(); |
48 | |
49 | protected final IoThreadPoolFilter ioThreadPoolFilter = new IoThreadPoolFilter(); |
50 | |
51 | protected final ProtocolThreadPoolFilter protocolThreadPoolFilter = new ProtocolThreadPoolFilter(); |
52 | |
53 | private final Set services = new HashSet(); |
54 | |
55 | public SimpleServiceRegistry() |
56 | { |
57 | socketIoAcceptor.getFilterChain().addFirst( "threadPool", ioThreadPoolFilter ); |
58 | datagramIoAcceptor.getFilterChain().addFirst( "threadPool", ioThreadPoolFilter ); |
59 | socketProtocolAcceptor.getFilterChain().addFirst( "threadPool", protocolThreadPoolFilter ); |
60 | datagramProtocolAcceptor.getFilterChain().addFirst( "threadPool", protocolThreadPoolFilter ); |
61 | vmPipeAcceptor.getFilterChain().addFirst( "threadPool", protocolThreadPoolFilter ); |
62 | } |
63 | |
64 | public void bind( Service service, IoHandler ioHandler ) throws IOException |
65 | { |
66 | IoAcceptor acceptor = findIoAcceptor( service.getTransportType() ); |
67 | acceptor.bind( service.getAddress(), ioHandler ); |
68 | startThreadPools(); |
69 | services.add( service ); |
70 | } |
71 | |
72 | public synchronized void bind( Service service, |
73 | ProtocolProvider protocolProvider ) throws IOException |
74 | { |
75 | ProtocolAcceptor acceptor = findProtocolAcceptor( service.getTransportType() ); |
76 | acceptor.bind( service.getAddress(), protocolProvider ); |
77 | startThreadPools(); |
78 | services.add( service ); |
79 | } |
80 | |
81 | public synchronized void unbind( Service service ) |
82 | { |
83 | ProtocolAcceptor acceptor = findProtocolAcceptor( service |
84 | .getTransportType() ); |
85 | try |
86 | { |
87 | acceptor.unbind( service.getAddress() ); |
88 | } |
89 | catch( Exception e ) |
90 | { |
91 | // ignore |
92 | } |
93 | |
94 | try |
95 | { |
96 | acceptor.unbind( service.getAddress() ); |
97 | } |
98 | catch( Exception e ) |
99 | { |
100 | // ignore |
101 | } |
102 | |
103 | services.remove( service ); |
104 | stopThreadPools(); |
105 | } |
106 | |
107 | public synchronized void unbindAll() |
108 | { |
109 | Iterator it = new HashSet( services ).iterator(); |
110 | while( it.hasNext() ) |
111 | { |
112 | Service s = ( Service ) it.next(); |
113 | unbind( s ); |
114 | } |
115 | } |
116 | |
117 | public IoAcceptor getIoAcceptor( TransportType transportType ) |
118 | { |
119 | return findIoAcceptor( transportType ); |
120 | } |
121 | |
122 | public ProtocolAcceptor getProtocolAcceptor( TransportType transportType ) |
123 | { |
124 | return findProtocolAcceptor( transportType ); |
125 | } |
126 | |
127 | public synchronized Set getAllServices() |
128 | { |
129 | return new HashSet( services ); |
130 | } |
131 | |
132 | public synchronized Set getServices( String name ) |
133 | { |
134 | Set result = new HashSet(); |
135 | Iterator it = services.iterator(); |
136 | while( it.hasNext() ) |
137 | { |
138 | Service s = ( Service ) it.next(); |
139 | if( name.equals( s.getName() ) ) |
140 | { |
141 | result.add( s ); |
142 | } |
143 | } |
144 | return result; |
145 | } |
146 | |
147 | public Set getServices( TransportType transportType ) |
148 | { |
149 | Set result = new HashSet(); |
150 | Iterator it = services.iterator(); |
151 | while( it.hasNext() ) |
152 | { |
153 | Service s = ( Service ) it.next(); |
154 | if( s.getTransportType() == transportType ) |
155 | { |
156 | result.add( s ); |
157 | } |
158 | } |
159 | return result; |
160 | } |
161 | |
162 | public Set getServices( int port ) |
163 | { |
164 | Set result = new HashSet(); |
165 | Iterator it = services.iterator(); |
166 | while( it.hasNext() ) |
167 | { |
168 | Service s = ( Service ) it.next(); |
169 | SocketAddress addr = s.getAddress(); |
170 | int servicePort; |
171 | |
172 | if( addr instanceof InetSocketAddress ) |
173 | { |
174 | servicePort = ( ( InetSocketAddress ) addr ).getPort(); |
175 | } |
176 | else if( addr instanceof VmPipeAddress ) |
177 | { |
178 | servicePort = ( ( VmPipeAddress ) addr ).getPort(); |
179 | } |
180 | else |
181 | { |
182 | servicePort = -1; // this cannot happen |
183 | } |
184 | |
185 | if( servicePort == port ) |
186 | { |
187 | result.add( s ); |
188 | } |
189 | } |
190 | return result; |
191 | } |
192 | |
193 | protected IoAcceptor findIoAcceptor( TransportType transportType ) |
194 | { |
195 | if( transportType == TransportType.SOCKET ) |
196 | return socketIoAcceptor; |
197 | else if( transportType == TransportType.DATAGRAM ) |
198 | return datagramIoAcceptor; |
199 | else |
200 | throw new IllegalArgumentException( |
201 | "Unsupported transport type: " + transportType ); |
202 | |
203 | } |
204 | |
205 | protected ProtocolAcceptor findProtocolAcceptor( |
206 | TransportType transportType ) |
207 | { |
208 | if( transportType == TransportType.SOCKET ) |
209 | return socketProtocolAcceptor; |
210 | else if( transportType == TransportType.DATAGRAM ) |
211 | return datagramProtocolAcceptor; |
212 | else if( transportType == TransportType.VM_PIPE ) |
213 | return vmPipeAcceptor; |
214 | else |
215 | throw new IllegalArgumentException( |
216 | "Unsupported transport type: " + transportType ); |
217 | } |
218 | |
219 | private void startThreadPools() |
220 | { |
221 | // Start thread pools only when the first service is bound. |
222 | // If any services are bound, it means that thread pools are started |
223 | // already. |
224 | if( !services.isEmpty() ) |
225 | return; |
226 | |
227 | ioThreadPoolFilter.start(); |
228 | protocolThreadPoolFilter.start(); |
229 | } |
230 | |
231 | private void stopThreadPools() |
232 | { |
233 | // Stop thread pools only when all services are unbound. |
234 | if( !services.isEmpty() ) |
235 | return; |
236 | |
237 | ioThreadPoolFilter.stop(); |
238 | protocolThreadPoolFilter.stop(); |
239 | } |
240 | } |