1 17 18 19 package org.apache.catalina.valves; 20 21 22 import java.io.IOException ; 23 import java.util.Iterator ; 24 import java.util.concurrent.ConcurrentHashMap ; 25 26 import javax.servlet.ServletException ; 27 import javax.servlet.http.HttpSession ; 28 import javax.servlet.http.HttpSessionEvent ; 29 import javax.servlet.http.HttpSessionListener ; 30 31 import org.apache.catalina.CometEvent; 32 import org.apache.catalina.Context; 33 import org.apache.catalina.Lifecycle; 34 import org.apache.catalina.LifecycleEvent; 35 import org.apache.catalina.LifecycleException; 36 import org.apache.catalina.LifecycleListener; 37 import org.apache.catalina.connector.CometEventImpl; 38 import org.apache.catalina.connector.Request; 39 import org.apache.catalina.connector.Response; 40 import org.apache.catalina.util.LifecycleSupport; 41 import org.apache.catalina.util.StringManager; 42 43 44 53 54 public class CometConnectionManagerValve 55 extends ValveBase 56 implements Lifecycle, HttpSessionListener , LifecycleListener { 57 58 59 61 62 65 protected static final String info = 66 "org.apache.catalina.valves.CometConnectionManagerValve/1.0"; 67 68 69 72 protected StringManager sm = 73 StringManager.getManager(Constants.Package); 74 75 76 79 protected LifecycleSupport lifecycle = new LifecycleSupport(this); 80 81 82 85 protected boolean started = false; 86 87 88 91 protected ConcurrentHashMap <String , ConnectionInfo[]> connections 92 = new ConcurrentHashMap <String , ConnectionInfo[]>(); 93 94 95 97 98 100 101 106 public void addLifecycleListener(LifecycleListener listener) { 107 108 lifecycle.addLifecycleListener(listener); 109 110 } 111 112 113 117 public LifecycleListener[] findLifecycleListeners() { 118 119 return lifecycle.findLifecycleListeners(); 120 121 } 122 123 124 129 public void removeLifecycleListener(LifecycleListener listener) { 130 131 lifecycle.removeLifecycleListener(listener); 132 133 } 134 135 136 144 public void start() throws LifecycleException { 145 146 if (started) 148 throw new LifecycleException 149 (sm.getString("semaphoreValve.alreadyStarted")); 150 lifecycle.fireLifecycleEvent(START_EVENT, null); 151 started = true; 152 153 if (container instanceof Context) { 154 ((Lifecycle) container).addLifecycleListener(this); 155 } 156 157 } 158 159 160 168 public void stop() throws LifecycleException { 169 170 if (!started) 172 throw new LifecycleException 173 (sm.getString("semaphoreValve.notStarted")); 174 lifecycle.fireLifecycleEvent(STOP_EVENT, null); 175 started = false; 176 177 if (container instanceof Context) { 178 ((Lifecycle) container).removeLifecycleListener(this); 179 } 180 181 Iterator <ConnectionInfo[]> iterator = connections.values().iterator(); 188 while (iterator.hasNext()) { 189 ConnectionInfo[] connectionInfos = iterator.next(); 190 if (connectionInfos != null) { 191 for (int i = 0; i < connectionInfos.length; i++) { 192 ConnectionInfo connectionInfo = connectionInfos[i]; 193 try { 194 connectionInfo.event.close(); 195 } catch (Exception e) { 196 container.getLogger().warn(sm.getString("cometConnectionManagerValve.event"), e); 197 } 198 } 199 } 200 } 201 connections.clear(); 202 203 } 204 205 206 public void lifecycleEvent(LifecycleEvent event) { 207 if (event.getType() == Lifecycle.BEFORE_STOP_EVENT) { 208 Iterator <ConnectionInfo[]> iterator = connections.values().iterator(); 212 while (iterator.hasNext()) { 213 ConnectionInfo[] connectionInfos = iterator.next(); 214 if (connectionInfos != null) { 215 for (int i = 0; i < connectionInfos.length; i++) { 216 ConnectionInfo connectionInfo = connectionInfos[i]; 217 try { 218 ((CometEventImpl) connectionInfo.event).setEventType(CometEvent.EventType.END); 219 ((CometEventImpl) connectionInfo.event).setEventSubType(CometEvent.EventSubType.WEBAPP_RELOAD); 220 getNext().event(connectionInfo.request, connectionInfo.response, connectionInfo.event); 221 connectionInfo.event.close(); 222 } catch (Exception e) { 223 container.getLogger().warn(sm.getString("cometConnectionManagerValve.event"), e); 224 } 225 } 226 } 227 } 228 connections.clear(); 229 } 230 } 231 232 233 235 236 239 public String getInfo() { 240 return (info); 241 } 242 243 244 253 public void invoke(Request request, Response response) 254 throws IOException , ServletException { 255 getNext().invoke(request, response); 257 258 if (request.isComet() && !response.isClosed()) { 259 HttpSession session = request.getSession(true); 262 ConnectionInfo newConnectionInfo = new ConnectionInfo(); 263 newConnectionInfo.request = request; 264 newConnectionInfo.response = response; 265 newConnectionInfo.event = request.getEvent(); 266 synchronized (session) { 267 String id = session.getId(); 268 ConnectionInfo[] connectionInfos = connections.get(id); 269 if (connectionInfos == null) { 270 connectionInfos = new ConnectionInfo[1]; 271 connectionInfos[0] = newConnectionInfo; 272 connections.put(id, connectionInfos); 273 } else { 274 ConnectionInfo[] newConnectionInfos = 275 new ConnectionInfo[connectionInfos.length + 1]; 276 for (int i = 0; i < connectionInfos.length; i++) { 277 newConnectionInfos[i] = connectionInfos[i]; 278 } 279 newConnectionInfos[connectionInfos.length] = newConnectionInfo; 280 connections.put(id, newConnectionInfos); 281 } 282 } 283 } 284 285 } 286 287 288 297 public void event(Request request, Response response, CometEvent event) 298 throws IOException , ServletException { 299 300 boolean ok = false; 302 try { 303 getNext().event(request, response, event); 304 ok = true; 305 } finally { 306 if (!ok || response.isClosed() 307 || (event.getEventType() == CometEvent.EventType.END) 308 || (event.getEventType() == CometEvent.EventType.ERROR 309 && !(event.getEventSubType() == CometEvent.EventSubType.TIMEOUT))) { 310 HttpSession session = request.getSession(true); 312 synchronized (session) { 313 ConnectionInfo[] connectionInfos = connections.get(session.getId()); 314 if (connectionInfos != null) { 315 boolean found = false; 316 for (int i = 0; !found && (i < connectionInfos.length); i++) { 317 found = (connectionInfos[i].request == request); 318 } 319 if (found) { 320 ConnectionInfo[] newConnectionInfos = 321 new ConnectionInfo[connectionInfos.length - 1]; 322 int pos = 0; 323 for (int i = 0; i < connectionInfos.length; i++) { 324 if (connectionInfos[i].request != request) { 325 newConnectionInfos[pos++] = connectionInfos[i]; 326 } 327 } 328 connections.put(session.getId(), newConnectionInfos); 329 } 330 } 331 } 332 } 333 } 334 335 } 336 337 338 public void sessionCreated(HttpSessionEvent se) { 339 } 340 341 342 public void sessionDestroyed(HttpSessionEvent se) { 343 ConnectionInfo[] connectionInfos = connections.remove(se.getSession().getId()); 345 if (connectionInfos != null) { 346 for (int i = 0; i < connectionInfos.length; i++) { 347 ConnectionInfo connectionInfo = connectionInfos[i]; 348 try { 349 ((CometEventImpl) connectionInfo.event).setEventType(CometEvent.EventType.END); 350 ((CometEventImpl) connectionInfo.event).setEventSubType(CometEvent.EventSubType.SESSION_END); 351 getNext().event(connectionInfo.request, connectionInfo.response, connectionInfo.event); 352 connectionInfo.event.close(); 353 } catch (Exception e) { 354 container.getLogger().warn(sm.getString("cometConnectionManagerValve.event"), e); 355 } 356 } 357 } 358 } 359 360 361 363 364 protected class ConnectionInfo { 365 public CometEvent event; 366 public Request request; 367 public Response response; 368 } 369 370 371 } 372 | Popular Tags |