1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.common.support;
21
22 import java.net.SocketAddress;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31
32 import org.apache.mina.common.ExceptionMonitor;
33 import org.apache.mina.common.IoAcceptorConfig;
34 import org.apache.mina.common.IoConnector;
35 import org.apache.mina.common.IoFuture;
36 import org.apache.mina.common.IoFutureListener;
37 import org.apache.mina.common.IoHandler;
38 import org.apache.mina.common.IoService;
39 import org.apache.mina.common.IoServiceConfig;
40 import org.apache.mina.common.IoServiceListener;
41 import org.apache.mina.common.IoSession;
42 import org.apache.mina.util.IdentityHashSet;
43
44
45
46
47
48
49
50
51 public class IoServiceListenerSupport {
52
53
54
55 private final List listeners = new ArrayList();
56
57
58
59
60 private final Set managedServiceAddresses = new HashSet();
61
62
63
64
65 private final Map managedSessions = new HashMap();
66
67
68
69
70 public IoServiceListenerSupport() {
71 }
72
73
74
75
76 public void add(IoServiceListener listener) {
77 synchronized (listeners) {
78 listeners.add(listener);
79 }
80 }
81
82
83
84
85 public void remove(IoServiceListener listener) {
86 synchronized (listeners) {
87 listeners.remove(listener);
88 }
89 }
90
91 public Set getManagedServiceAddresses() {
92 return Collections.unmodifiableSet(managedServiceAddresses);
93 }
94
95 public boolean isManaged(SocketAddress serviceAddress) {
96 synchronized (managedServiceAddresses) {
97 return managedServiceAddresses.contains(serviceAddress);
98 }
99 }
100
101 public Set getManagedSessions(SocketAddress serviceAddress) {
102 Set sessions;
103 synchronized (managedSessions) {
104 sessions = (Set) managedSessions.get(serviceAddress);
105 if (sessions == null) {
106 sessions = new IdentityHashSet();
107 }
108 }
109
110 synchronized (sessions) {
111 return new IdentityHashSet(sessions);
112 }
113 }
114
115
116
117
118
119 public void fireServiceActivated(IoService service,
120 SocketAddress serviceAddress, IoHandler handler,
121 IoServiceConfig config) {
122 synchronized (managedServiceAddresses) {
123 if (!managedServiceAddresses.add(serviceAddress)) {
124 return;
125 }
126 }
127
128 synchronized (listeners) {
129 for (Iterator i = listeners.iterator(); i.hasNext();) {
130 try {
131 ((IoServiceListener) i.next()).serviceActivated(service,
132 serviceAddress, handler, config);
133 } catch (Throwable e) {
134 ExceptionMonitor.getInstance().exceptionCaught(e);
135 }
136 }
137 }
138 }
139
140
141
142
143
144 public synchronized void fireServiceDeactivated(IoService service,
145 SocketAddress serviceAddress, IoHandler handler,
146 IoServiceConfig config) {
147 synchronized (managedServiceAddresses) {
148 if (!managedServiceAddresses.remove(serviceAddress)) {
149 return;
150 }
151 }
152
153 try {
154 synchronized (listeners) {
155 for (Iterator i = listeners.iterator(); i.hasNext();) {
156 try {
157 ((IoServiceListener) i.next()).serviceDeactivated(service,
158 serviceAddress, handler, config);
159 } catch (Throwable e) {
160 ExceptionMonitor.getInstance().exceptionCaught(e);
161 }
162 }
163 }
164 } finally {
165 disconnectSessions(serviceAddress, config);
166 }
167 }
168
169
170
171
172 public void fireSessionCreated(IoSession session) {
173 SocketAddress serviceAddress = session.getServiceAddress();
174
175
176 boolean firstSession = false;
177 Set sessions;
178 synchronized (managedSessions) {
179 sessions = (Set) managedSessions.get(serviceAddress);
180 if (sessions == null) {
181 sessions = new IdentityHashSet();
182 managedSessions.put(serviceAddress, sessions);
183 firstSession = true;
184 }
185
186
187 synchronized (sessions) {
188 if (!sessions.add(session)) {
189 return;
190 }
191 }
192 }
193
194
195 if (session.getService() instanceof IoConnector && firstSession) {
196 fireServiceActivated(session.getService(), session
197 .getServiceAddress(), session.getHandler(), session
198 .getServiceConfig());
199 }
200
201
202 session.getFilterChain().fireSessionCreated(session);
203 session.getFilterChain().fireSessionOpened(session);
204
205
206 synchronized (listeners) {
207 for (Iterator i = listeners.iterator(); i.hasNext();) {
208 try {
209 ((IoServiceListener) i.next()).sessionCreated(session);
210 } catch (Throwable e) {
211 ExceptionMonitor.getInstance().exceptionCaught(e);
212 }
213 }
214 }
215 }
216
217
218
219
220 public void fireSessionDestroyed(IoSession session) {
221 SocketAddress serviceAddress = session.getServiceAddress();
222
223
224 Set sessions;
225 boolean lastSession = false;
226 synchronized (managedSessions) {
227 sessions = (Set) managedSessions.get(serviceAddress);
228
229 if (sessions == null) {
230 return;
231 }
232
233
234 synchronized (sessions) {
235 sessions.remove(session);
236 if (sessions.isEmpty()) {
237 managedSessions.remove(serviceAddress);
238 lastSession = true;
239 }
240 }
241 }
242
243
244 session.getFilterChain().fireSessionClosed(session);
245
246
247 try {
248 synchronized (listeners) {
249 for (Iterator i = listeners.iterator(); i.hasNext();) {
250 try {
251 ((IoServiceListener) i.next()).sessionDestroyed(session);
252 } catch (Throwable e) {
253 ExceptionMonitor.getInstance().exceptionCaught(e);
254 }
255 }
256 }
257 } finally {
258
259
260 if (session.getService() instanceof IoConnector && lastSession) {
261 fireServiceDeactivated(session.getService(), session
262 .getServiceAddress(), session.getHandler(), session
263 .getServiceConfig());
264 }
265 }
266 }
267
268 private void disconnectSessions(SocketAddress serviceAddress,
269 IoServiceConfig config) {
270 if (!(config instanceof IoAcceptorConfig)) {
271 return;
272 }
273
274 if (!((IoAcceptorConfig) config).isDisconnectOnUnbind()) {
275 return;
276 }
277
278 Set sessions;
279 synchronized (managedSessions) {
280 sessions = (Set) managedSessions.get(serviceAddress);
281 }
282
283 if (sessions == null) {
284 return;
285 }
286
287 final Object lock = new Object();
288 Set sessionsCopy;
289
290
291 synchronized (sessions) {
292 sessionsCopy = new IdentityHashSet(sessions);
293 }
294
295 for (Iterator i = sessionsCopy.iterator(); i.hasNext();) {
296 ((IoSession) i.next()).close().addListener(new IoFutureListener() {
297 public void operationComplete(IoFuture future) {
298 synchronized (lock) {
299 lock.notifyAll();
300 }
301 }
302 });
303 }
304
305 try {
306 synchronized (lock) {
307 while (!managedSessions.isEmpty()) {
308 lock.wait(500);
309 }
310 }
311 } catch (InterruptedException ie) {
312
313 }
314 }
315 }