1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22 package org.jboss.web.tomcat.service.session;
23
24 import java.io.IOException;
25 import java.util.Iterator;
26 import java.util.Map;
27
28 import javax.servlet.ServletException;
29
30 import org.apache.catalina;
31 import org.apache.catalina.connector.Request;
32 import org.apache.catalina.connector.Response;
33 import org.apache.catalina.util.LifecycleSupport;
34 import org.apache.catalina.valves.ValveBase;
35
36 /**
37 * This Valve detects all sessions that were used in a request. All sessions are given to a snapshot
38 * manager that handles the distribution of modified sessions.
39 * <p/>
40 * TOMCAT 4.1.12 UPDATE: Added findLifecycleListeners() to comply with the latest
41 * Lifecycle interface.
42 *
43 * @author Thomas Peuss <jboss@peuss.de>
44 * @author Brian Stansberry
45 * @version $Revision: 56542 $
46 */
47 public class ClusteredSessionValve extends ValveBase implements Lifecycle
48 {
49 // The info string for this Valve
50 private static final String info = "ClusteredSessionValve/1.0";
51
52 // Valve-lifecycle_ helper object
53 private LifecycleSupport support = new LifecycleSupport(this);
54
55 /**
56 * Create a new Valve.
57 */
58 public ClusteredSessionValve()
59 {
60 super();
61 }
62
63 /**
64 * Get information about this Valve.
65 */
66 public String getInfo()
67 {
68 return info;
69 }
70
71 /**
72 * Valve-chain handler method.
73 * This method gets called when the request goes through the Valve-chain. Our session replication mechanism replicates the
74 * session after request got through the servlet code.
75 *
76 * @param request The request object associated with this request.
77 * @param response The response object associated with this request.
78 */
79 public void invoke(Request request, Response response) throws IOException, ServletException
80 {
81 // Initialize the context and store the request and response objects
82 // for any clustering code that has no direct access to these objects
83 SessionReplicationContext.enterWebapp(request, response, true);
84 try
85 {
86
87
88 // let the servlet invocation go through
89 getNext().invoke(request, response);
90 }
91 finally // We replicate no matter what
92 {
93 // --> We are now after the servlet invocation
94 try
95 {
96 SessionReplicationContext ctx = SessionReplicationContext.exitWebapp();
97
98 if (ctx.getSoleSnapshotManager() != null)
99 {
100 ctx.getSoleSnapshotManager().snapshot(ctx.getSoleSession());
101 }
102 else
103 {
104 // Cross-context request touched multiple sesssions;
105 // need to replicate them all
106 Map sessions = ctx.getCrossContextSessions();
107 if (sessions != null && sessions.size() > 0)
108 {
109 for (Iterator iter = sessions.entrySet().iterator(); iter.hasNext();)
110 {
111 Map.Entry entry = (Map.Entry) iter.next();
112 ((SnapshotManager) entry.getValue()).snapshot((ClusteredSession) entry.getKey());
113 }
114 }
115 }
116 }
117 finally
118 {
119 SessionReplicationContext.finishCacheActivity();
120 }
121
122 }
123 }
124
125 // Lifecylce-interface
126 public void addLifecycleListener(LifecycleListener listener)
127 {
128 support.addLifecycleListener(listener);
129 }
130
131 public void removeLifecycleListener(LifecycleListener listener)
132 {
133 support.removeLifecycleListener(listener);
134 }
135
136 public LifecycleListener[] findLifecycleListeners()
137 {
138 return support.findLifecycleListeners();
139 }
140
141 public void start() throws LifecycleException
142 {
143 support.fireLifecycleEvent(START_EVENT, this);
144 }
145
146 public void stop() throws LifecycleException
147 {
148 support.fireLifecycleEvent(STOP_EVENT, this);
149 }
150
151 }