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