1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.engine;
18
19 import java.io.IOException;
20 import java.security.Principal;
21
22 import javax.security.auth.Subject;
23 import javax.servlet.ServletConfig;
24 import javax.servlet.ServletContext;
25 import javax.servlet.ServletException;
26 import javax.servlet.http.HttpServlet;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29 import javax.servlet.http.HttpSessionEvent;
30 import javax.servlet.http.HttpSessionListener;
31
32 import org.apache.commons.configuration.Configuration;
33 import org.apache.commons.configuration.PropertiesConfiguration;
34 import org.apache.commons.lang.exception.ExceptionUtils;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.jetspeed.Jetspeed;
38 import org.apache.jetspeed.PortalReservedParameters;
39 import org.apache.jetspeed.cache.ContentCacheKeyGenerator;
40 import org.apache.jetspeed.cache.JetspeedCache;
41 import org.apache.jetspeed.components.ComponentManager;
42 import org.apache.jetspeed.components.SpringComponentManager;
43 import org.apache.jetspeed.components.factorybeans.ServletConfigFactoryBean;
44 import org.apache.jetspeed.container.session.PortalSessionsManager;
45 import org.apache.jetspeed.engine.servlet.ServletHelper;
46 import org.apache.jetspeed.exception.JetspeedException;
47 import org.apache.jetspeed.pipeline.valve.SecurityValve;
48 import org.apache.jetspeed.request.RequestContext;
49 import org.apache.jetspeed.request.RequestContextComponent;
50 import org.apache.jetspeed.security.SecurityHelper;
51 import org.apache.jetspeed.security.UserPrincipal;
52 import org.apache.jetspeed.services.JetspeedPortletServices;
53 import org.apache.jetspeed.services.PortletServices;
54 import org.apache.jetspeed.statistics.PortalStatistics;
55
56 /***
57 * Jetspeed Servlet entry point.
58 *
59 * @author <a href="mailto:david@bluesunrise.com">David Sean Taylor </a>
60 * @version $Id: JetspeedServlet.java 553340 2007-07-04 22:00:09Z taylor $
61 */
62 public class JetspeedServlet
63 extends HttpServlet
64 implements JetspeedEngineConstants, HttpSessionListener
65 {
66 private static Log log;
67 private static Log console;
68
69 /***
70 * In certain situations the init() method is called more than once,
71 * somtimes even concurrently. This causes bad things to happen, so we use
72 * this flag to prevent it.
73 */
74 private static boolean firstInit = true;
75
76 /***
77 * Whether init succeeded or not.
78 */
79 private static Throwable initFailure = null;
80
81 /***
82 * Should initialization activities be performed during doGet() execution?
83 */
84 private static boolean firstDoGet = true;
85
86 /***
87 * The Jetspeed Engine
88 */
89 private static Engine engine;
90 private static RequestContextComponent contextComponent;
91
92 private static String webappRoot;
93
94
95
96
97 private static final String INIT_START_MSG = "Jetspeed Starting Initialization...";
98 private static final String INIT_DONE_MSG = "Jetspeed Initialization complete, Ready to service requests.";
99
100 /***
101 * Intialize Servlet.
102 */
103 public final void init( ServletConfig config ) throws ServletException
104 {
105 synchronized (this.getClass())
106 {
107 if ( log == null )
108 {
109 log = LogFactory.getLog(JetspeedServlet.class);
110 console = LogFactory.getLog(CONSOLE_LOGGER);
111 }
112
113 console.info(INIT_START_MSG);
114
115 super.init(config);
116
117 if (!firstInit)
118 {
119 log.info("Double initialization of Jetspeed was attempted!");
120 console.info("Double initialization of Jetspeed was attempted!");
121 return;
122 }
123
124
125 firstInit = false;
126
127 try
128 {
129
130 ServletContext context = config.getServletContext();
131
132 String propertiesFilename = ServletHelper.findInitParameter(context, config, JETSPEED_PROPERTIES_KEY,
133 JETSPEED_PROPERTIES_DEFAULT);
134
135 String applicationRoot = ServletHelper.findInitParameter(context, config, APPLICATION_ROOT_KEY,
136 APPLICATION_ROOT_DEFAULT);
137
138 console.info("JetspeedServlet identifying web application root...");
139 webappRoot = config.getServletContext().getRealPath("/");
140 console.info("JetspeedServlet identifed web application root as " + webappRoot);
141
142 if (applicationRoot == null || applicationRoot.equals(WEB_CONTEXT))
143 {
144 applicationRoot = webappRoot;
145 }
146
147 Configuration properties = new PropertiesConfiguration(ServletHelper.getRealPath(
148 config, propertiesFilename));
149
150 properties.setProperty(APPLICATION_ROOT_KEY, applicationRoot);
151 properties.setProperty(WEBAPP_ROOT_KEY, webappRoot);
152
153 console.info("JetspeedServlet attempting to create the portlet engine...");
154
155 engine = new JetspeedEngine(properties, applicationRoot, config, initializeComponentManager(config, applicationRoot, properties));
156
157 console.info("JetspeedServlet attempting to start the Jetspeed Portal Engine...");
158 Jetspeed.setEngine(engine);
159 engine.start();
160 console.info("JetspeedServlet has successfuly started the Jetspeed Portal Engine....");
161 contextComponent = (RequestContextComponent) Jetspeed.getComponentManager().getComponent(RequestContextComponent.class);
162 }
163 catch (Throwable e)
164 {
165
166 final String msg = "Jetspeed: init() failed: ";
167 initFailure = e;
168 log.fatal(msg, e);
169 console.fatal(msg, e);
170 }
171
172 console.info(INIT_DONE_MSG);
173 log.info(INIT_DONE_MSG);
174 }
175 }
176
177 /***
178 * Initializes the services which need <code>RunData</code> to initialize
179 * themselves (post startup).
180 *
181 * @param data
182 * The first <code>GET</code> request.
183 */
184 public final void init( HttpServletRequest request, HttpServletResponse response )
185 {
186 synchronized (JetspeedServlet.class)
187 {
188 if (firstDoGet)
189 {
190
191 firstDoGet = false;
192 }
193 }
194 }
195
196
197
198
199
200 /***
201 * The primary method invoked when the Jetspeed servlet is executed.
202 *
203 * @param req
204 * Servlet request.
205 * @param res
206 * Servlet response.
207 * @exception IOException
208 * a servlet exception.
209 * @exception ServletException
210 * a servlet exception.
211 */
212 public final void doGet( HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException
213 {
214 try
215 {
216
217 if (initFailure != null)
218 {
219 throw new ServletException("Failed to initalize jetspeed. "+initFailure.toString(), initFailure);
220 }
221
222
223
224 if (firstDoGet)
225 {
226 init(req, res);
227 }
228
229
230
231 String wasFiltered = (String) req.getAttribute("org.apache.jetspeed.content.filtered");
232 if (wasFiltered == null || !wasFiltered.equals("true"))
233 {
234
235
236 res.setHeader("Cache-Control", "no-cache,no-store,private");
237 res.setHeader("Pragma", "no-cache");
238 res.setHeader("Expires", "0");
239
240
241 RequestContext context = contextComponent.create(req, res, getServletConfig());
242 engine.service(context);
243 contextComponent.release(context);
244 }
245
246 }
247 catch (JetspeedException e)
248 {
249 final String msg = "Fatal error encountered while processing portal request: "+e.toString();
250 log.fatal(msg, e);
251 throw new ServletException(msg, e);
252 }
253 }
254
255 /***
256 * In this application doGet and doPost are the same thing.
257 *
258 * @param req
259 * Servlet request.
260 * @param res
261 * Servlet response.
262 * @exception IOException
263 * a servlet exception.
264 * @exception ServletException
265 * a servlet exception.
266 */
267 public final void doPost( HttpServletRequest req, HttpServletResponse res ) throws IOException, ServletException
268 {
269 doGet(req, res);
270 }
271
272
273
274
275
276 /***
277 * The <code>Servlet</code> destroy method. Invokes
278 * <code>ServiceBroker</code> tear down method.
279 */
280 public final void destroy()
281 {
282 try
283 {
284 Jetspeed.shutdown();
285 }
286 catch (JetspeedException e)
287 {
288 log.fatal("Jetspeed: shutdown() failed: ", e);
289 System.err.println(ExceptionUtils.getStackTrace(e));
290 }
291
292
293 firstInit = true;
294
295 log.info("Done shutting down!");
296 }
297
298 /***
299 * If you prefer to use a component manager other than Spring, you
300 * can override this method to do so. Do not explicitly call start()
301 * of the ComponentManager as the JetspeedEngine will do this within its
302 * own start() method.
303 *
304 * @param servletConfig
305 * @param appRoot
306 * @param configuration
307 * @return
308 * @throws IOException
309 */
310 protected ComponentManager initializeComponentManager(ServletConfig servletConfig, String appRoot, Configuration configuration) throws IOException
311 {
312 ServletConfigFactoryBean.setServletConfig(servletConfig);
313 final String assemblyDir = configuration.getString("assembly.dir","/WEB-INF/assembly");
314 final String assemblyFileExtension = configuration.getString("assembly.extension",".xml");
315
316 String[] bootConfigs = new String[] {"/WEB-INF/assembly/boot/*.xml"};
317 String[] appConfigs = new String[] {assemblyDir+"/*"+assemblyFileExtension, assemblyDir+"/override/*"+assemblyFileExtension};
318 ServletContext servletContext = servletConfig.getServletContext();
319 SpringComponentManager cm = new SpringComponentManager(bootConfigs, appConfigs, servletContext, appRoot);
320
321 return cm;
322 }
323
324 public void sessionCreated(HttpSessionEvent se)
325 {
326 PortletServices services = JetspeedPortletServices.getSingleton();
327 if (services != null)
328 {
329 PortalSessionsManager psm = (PortalSessionsManager)services.getService(PortalSessionsManager.SERVICE_NAME);
330 if (psm != null)
331 {
332 psm.portalSessionCreated(se.getSession());
333 }
334 }
335 }
336
337 public void sessionDestroyed(HttpSessionEvent se)
338 {
339 Subject subject = (Subject)se.getSession().getAttribute(PortalReservedParameters.SESSION_KEY_SUBJECT);
340 if (subject == null)
341 return;
342 if (firstInit)
343 {
344
345
346
347 return;
348 }
349 Principal subjectUserPrincipal = SecurityHelper.getPrincipal(subject, UserPrincipal.class);
350 PortalStatistics statistics = (PortalStatistics)engine.getComponentManager().getComponent("PortalStatistics");
351 long sessionLength = System.currentTimeMillis() - se.getSession().getCreationTime();
352 String ipAddress = (String)se.getSession().getAttribute(SecurityValve.IP_ADDRESS);
353 statistics.logUserLogout(ipAddress, subjectUserPrincipal.getName(), sessionLength);
354 JetspeedCache portletContentCache = (JetspeedCache)engine.getComponentManager().getComponent("portletContentCache");
355 JetspeedCache decorationContentCache = null;
356
357 try
358 {
359 decorationContentCache = (JetspeedCache)engine.getComponentManager().getComponent("decorationContentCache");
360 }
361 catch (Exception e)
362 {
363 }
364
365 ContentCacheKeyGenerator generator = (ContentCacheKeyGenerator)engine.getComponentManager().getComponent("ContentCacheKeyGenerator");
366
367 if (generator.isCacheBySessionId())
368 {
369 portletContentCache.evictContentForUser(se.getSession().getId());
370
371 if (decorationContentCache != null)
372 {
373 decorationContentCache.evictContentForUser(se.getSession().getId());
374 }
375 }
376 else
377 {
378 portletContentCache.evictContentForUser(subjectUserPrincipal.getName());
379
380 if (decorationContentCache != null)
381 {
382 decorationContentCache.evictContentForUser(subjectUserPrincipal.getName()); }
383 }
384 }
385 }