1
22
23 package com.liferay.portal.servlet;
24
25 import com.liferay.portal.deploy.hot.PluginPackageHotDeployListener;
26 import com.liferay.portal.events.EventsProcessor;
27 import com.liferay.portal.events.StartupAction;
28 import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
29 import com.liferay.portal.kernel.plugin.PluginPackage;
30 import com.liferay.portal.kernel.servlet.HttpHeaders;
31 import com.liferay.portal.kernel.servlet.PortletSessionTracker;
32 import com.liferay.portal.kernel.util.ContentTypes;
33 import com.liferay.portal.kernel.util.GetterUtil;
34 import com.liferay.portal.kernel.util.InstancePool;
35 import com.liferay.portal.kernel.util.ParamUtil;
36 import com.liferay.portal.kernel.util.PortalInitableUtil;
37 import com.liferay.portal.lastmodified.LastModifiedAction;
38 import com.liferay.portal.model.Company;
39 import com.liferay.portal.model.Portlet;
40 import com.liferay.portal.model.User;
41 import com.liferay.portal.security.auth.CompanyThreadLocal;
42 import com.liferay.portal.security.auth.PrincipalThreadLocal;
43 import com.liferay.portal.service.CompanyLocalServiceUtil;
44 import com.liferay.portal.service.PortletLocalServiceUtil;
45 import com.liferay.portal.service.UserLocalServiceUtil;
46 import com.liferay.portal.service.impl.LayoutTemplateLocalUtil;
47 import com.liferay.portal.service.impl.ThemeLocalUtil;
48 import com.liferay.portal.struts.ActionException;
49 import com.liferay.portal.struts.PortletRequestProcessor;
50 import com.liferay.portal.struts.StrutsUtil;
51 import com.liferay.portal.util.ContentUtil;
52 import com.liferay.portal.util.InitUtil;
53 import com.liferay.portal.util.PortalInstances;
54 import com.liferay.portal.util.PortalUtil;
55 import com.liferay.portal.util.PropsUtil;
56 import com.liferay.portal.util.ReleaseInfo;
57 import com.liferay.portal.util.ShutdownUtil;
58 import com.liferay.portal.util.WebKeys;
59 import com.liferay.portal.velocity.VelocityContextPool;
60 import com.liferay.portlet.PortletInstanceFactory;
61 import com.liferay.util.CollectionFactory;
62 import com.liferay.util.Http;
63 import com.liferay.util.servlet.EncryptedServletRequest;
64 import com.liferay.util.servlet.ProtectedServletRequest;
65
66 import java.io.IOException;
67
68 import java.util.Iterator;
69 import java.util.Set;
70
71 import javax.servlet.ServletContext;
72 import javax.servlet.ServletException;
73 import javax.servlet.http.HttpServletRequest;
74 import javax.servlet.http.HttpServletResponse;
75 import javax.servlet.http.HttpSession;
76 import javax.servlet.jsp.PageContext;
77
78 import org.apache.commons.logging.Log;
79 import org.apache.commons.logging.LogFactory;
80 import org.apache.struts.Globals;
81 import org.apache.struts.action.ActionMapping;
82 import org.apache.struts.action.ActionServlet;
83 import org.apache.struts.config.ModuleConfig;
84 import org.apache.struts.tiles.TilesUtilImpl;
85
86 import org.dom4j.Document;
87 import org.dom4j.DocumentException;
88 import org.dom4j.Element;
89
90
98 public class MainServlet extends ActionServlet {
99
100 static {
101 InitUtil.init();
102 }
103
104 public void init() throws ServletException {
105
106
108 if (_log.isDebugEnabled()) {
109 _log.debug("Initialize");
110 }
111
112 super.init();
113
114
116 if (_log.isDebugEnabled()) {
117 _log.debug("Process startup events");
118 }
119
120 try {
121 EventsProcessor.process(
122 new String[] {
123 StartupAction.class.getName()
124 },
125 true);
126 }
127 catch (RuntimeException re) {
128 ShutdownUtil.shutdown(0);
129
130 throw new ServletException(re);
131 }
132 catch (ActionException ae) {
133 _log.error(ae, ae);
134 }
135
136
138 String contextPath = PortalUtil.getPathContext();
139
140 ServletContext ctx = getServletContext();
141
142 VelocityContextPool.put(contextPath, ctx);
143
144
146 if (_log.isDebugEnabled()) {
147 _log.debug("Initialize plugin package");
148 }
149
150 PluginPackage pluginPackage = null;
151
152 try {
153 pluginPackage =
154 PluginPackageHotDeployListener.readPluginPackage(ctx);
155 }
156 catch (Exception e) {
157 _log.error(e, e);
158 }
159
160
162 if (_log.isDebugEnabled()) {
163 _log.debug("Initialize portlets");
164 }
165
166 try {
167 String[] xmls = new String[] {
168 Http.URLtoString(ctx.getResource(
169 "/WEB-INF/" + PortalUtil.PORTLET_XML_FILE_NAME_CUSTOM)),
170 Http.URLtoString(ctx.getResource(
171 "/WEB-INF/portlet-ext.xml")),
172 Http.URLtoString(ctx.getResource(
173 "/WEB-INF/liferay-portlet.xml")),
174 Http.URLtoString(ctx.getResource(
175 "/WEB-INF/liferay-portlet-ext.xml")),
176 Http.URLtoString(ctx.getResource("/WEB-INF/web.xml"))
177 };
178
179 PortletLocalServiceUtil.initEAR(xmls, pluginPackage);
180 }
181 catch (Exception e) {
182 _log.error(e, e);
183 }
184
185
187 if (_log.isDebugEnabled()) {
188 _log.debug("Initialize layout templates");
189 }
190
191 try {
192 String[] xmls = new String[] {
193 Http.URLtoString(ctx.getResource(
194 "/WEB-INF/liferay-layout-templates.xml")),
195 Http.URLtoString(ctx.getResource(
196 "/WEB-INF/liferay-layout-templates-ext.xml"))
197 };
198
199 LayoutTemplateLocalUtil.init(ctx, xmls, pluginPackage);
200 }
201 catch (Exception e) {
202 _log.error(e, e);
203 }
204
205
207 if (_log.isDebugEnabled()) {
208 _log.debug("Initialize look and feel");
209 }
210
211 try {
212 String[] xmls = new String[] {
213 Http.URLtoString(ctx.getResource(
214 "/WEB-INF/liferay-look-and-feel.xml")),
215 Http.URLtoString(ctx.getResource(
216 "/WEB-INF/liferay-look-and-feel-ext.xml"))
217 };
218
219 ThemeLocalUtil.init(ctx, null, true, xmls, pluginPackage);
220 }
221 catch (Exception e) {
222 _log.error(e, e);
223 }
224
225
227 if (_log.isDebugEnabled()) {
228 _log.debug("Check web settings");
229 }
230
231 try {
232 String xml = Http.URLtoString(ctx.getResource("/WEB-INF/web.xml"));
233
234 checkWebSettings(xml);
235 }
236 catch (Exception e) {
237 _log.error(e, e);
238 }
239
240
242 if (_log.isDebugEnabled()) {
243 _log.debug("Last modified paths");
244 }
245
246 if (_lastModifiedPaths == null) {
247 _lastModifiedPaths = CollectionFactory.getHashSet();
248
249 String[] pathsArray = PropsUtil.getArray(
250 PropsUtil.LAST_MODIFIED_PATHS);
251
252 for (int i = 0; i < pathsArray.length; i++) {
253 _lastModifiedPaths.add(pathsArray[i]);
254 }
255 }
256
257
259 if (_log.isDebugEnabled()) {
260 _log.debug("Process global startup events");
261 }
262
263 try {
264 EventsProcessor.process(PropsUtil.getArray(
265 PropsUtil.GLOBAL_STARTUP_EVENTS), true);
266 }
267 catch (Exception e) {
268 _log.error(e, e);
269 }
270
271
273 String[] webIds = PortalInstances.getWebIds();
274
275 for (int i = 0; i < webIds.length; i++) {
276 PortalInstances.initCompany(ctx, webIds[i]);
277 }
278
279
282 PortalInitableUtil.flushInitables();
283 HotDeployUtil.flushEvents();
284 }
285
286 public void callParentService(
287 HttpServletRequest req, HttpServletResponse res)
288 throws IOException, ServletException {
289
290 super.service(req, res);
291 }
292
293 public void service(HttpServletRequest req, HttpServletResponse res)
294 throws IOException, ServletException {
295
296 if (_log.isDebugEnabled()) {
297 _log.debug("Process service request");
298 }
299
300 if (ShutdownUtil.isShutdown()) {
301 res.setContentType(ContentTypes.TEXT_HTML_UTF8);
302
303 String html = ContentUtil.get(
304 "com/liferay/portal/dependencies/shutdown.html");
305
306 res.getOutputStream().print(html);
307
308 return;
309 }
310
311 HttpSession ses = req.getSession();
312
313
315 long companyId = PortalInstances.getCompanyId(req);
316
317
319
321 ServletContext ctx = getServletContext();
322
323 req.setAttribute(WebKeys.CTX, ctx);
324
325
327 ModuleConfig moduleConfig = getModuleConfig(req);
328
329
331 if (GetterUtil.getBoolean(
332 PropsUtil.get(PropsUtil.LAST_MODIFIED_CHECK))) {
333
334 String path = req.getPathInfo();
335
336 if ((path != null) && _lastModifiedPaths.contains(path)) {
337 ActionMapping mapping =
338 (ActionMapping)moduleConfig.findActionConfig(path);
339
340 LastModifiedAction lastModifiedAction =
341 (LastModifiedAction)InstancePool.get(mapping.getType());
342
343 String lmKey = lastModifiedAction.getLastModifiedKey(req);
344
345 if (lmKey != null) {
346 long ifModifiedSince =
347 req.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
348
349 if (ifModifiedSince <= 0) {
350 lastModifiedAction.setLastModifiedValue(lmKey, lmKey);
351 }
352 else {
353 String lmValue =
354 lastModifiedAction.getLastModifiedValue(lmKey);
355
356 if (lmValue != null) {
357 res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
358
359 return;
360 }
361 else {
362 lastModifiedAction.setLastModifiedValue(
363 lmKey, lmKey);
364 }
365 }
366 }
367 }
368 }
369
370
372 if (ses.getAttribute(WebKeys.PORTLET_SESSION_TRACKER) == null ) {
373 ses.setAttribute(
374 WebKeys.PORTLET_SESSION_TRACKER,
375 PortletSessionTracker.getInstance());
376 }
377
378
380 PortletRequestProcessor portletReqProcessor =
381 (PortletRequestProcessor)ctx.getAttribute(
382 WebKeys.PORTLET_STRUTS_PROCESSOR);
383
384 if (portletReqProcessor == null) {
385 portletReqProcessor =
386 PortletRequestProcessor.getInstance(this, moduleConfig);
387
388 ctx.setAttribute(
389 WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
390 }
391
392
394 if (ctx.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY) == null) {
395 ctx.setAttribute(
396 TilesUtilImpl.DEFINITIONS_FACTORY,
397 ctx.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
398 }
399
400 Object applicationAssociate = ctx.getAttribute(WebKeys.ASSOCIATE_KEY);
401
402 if (ctx.getAttribute(WebKeys.ASSOCIATE_KEY) == null) {
403 ctx.setAttribute(WebKeys.ASSOCIATE_KEY, applicationAssociate);
404 }
405
406
408 if (ParamUtil.get(req, WebKeys.ENCRYPT, false)) {
409 try {
410 Company company = CompanyLocalServiceUtil.getCompanyById(
411 companyId);
412
413 req = new EncryptedServletRequest(req, company.getKeyObj());
414 }
415 catch (Exception e) {
416 }
417 }
418
419
421 PortalUtil.getCurrentURL(req);
422
423
425 long userId = PortalUtil.getUserId(req);
426 String remoteUser = req.getRemoteUser();
427
428
430 if (!GetterUtil.getBoolean(
431 PropsUtil.get(PropsUtil.PORTAL_JAAS_ENABLE))) {
432
433 String jRemoteUser = (String)ses.getAttribute("j_remoteuser");
434
435 if (jRemoteUser != null) {
436 remoteUser = jRemoteUser;
437
438 ses.removeAttribute("j_remoteuser");
439 }
440 }
441
442 if ((userId > 0) && (remoteUser == null)) {
443 remoteUser = String.valueOf(userId);
444 }
445
446
452 req = new ProtectedServletRequest(req, remoteUser);
453
454 if ((userId > 0) || (remoteUser != null)) {
455
456
458 String name = String.valueOf(userId);
459
460 if (remoteUser != null) {
461 name = remoteUser;
462 }
463
464 PrincipalThreadLocal.setName(name);
465 }
466
467 if ((userId <= 0) && (remoteUser != null)) {
468 try {
469
470
472 userId = GetterUtil.getLong(remoteUser);
473
474
476 EventsProcessor.process(PropsUtil.getArray(
477 PropsUtil.LOGIN_EVENTS_PRE), req, res);
478
479
481 User user = UserLocalServiceUtil.getUserById(userId);
482
483 UserLocalServiceUtil.updateLastLogin(
484 userId, req.getRemoteAddr());
485
486
488 ses.setAttribute(WebKeys.USER_ID, new Long(userId));
489
490
492 ses.setAttribute(Globals.LOCALE_KEY, user.getLocale());
493
494
496 EventsProcessor.process(PropsUtil.getArray(
497 PropsUtil.LOGIN_EVENTS_POST), req, res);
498 }
499 catch (Exception e) {
500 _log.error(e, e);
501 }
502 }
503
504
506 try {
507 EventsProcessor.process(PropsUtil.getArray(
508 PropsUtil.SERVLET_SERVICE_EVENTS_PRE), req, res);
509 }
510 catch (Exception e) {
511 _log.error(e, e);
512
513 req.setAttribute(PageContext.EXCEPTION, e);
514
515 StrutsUtil.forward(
516 PropsUtil.get(
517 PropsUtil.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE),
518 ctx, req, res);
519 }
520
521 try {
522
523
525 callParentService(req, res);
526 }
527 finally {
528
529
531 try {
532 EventsProcessor.process(PropsUtil.getArray(
533 PropsUtil.SERVLET_SERVICE_EVENTS_POST), req, res);
534 }
535 catch (Exception e) {
536 _log.error(e, e);
537 }
538
539 res.addHeader(
540 _LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
541
542
544 CompanyThreadLocal.setCompanyId(0);
545
546
548 PrincipalThreadLocal.setName(null);
549 }
550 }
551
552 public void destroy() {
553 long[] companyIds = PortalInstances.getCompanyIds();
554
555 for (int i = 0; i < companyIds.length; i++) {
556 destroyCompany(companyIds[i]);
557 }
558
559 try {
560 EventsProcessor.process(PropsUtil.getArray(
561 PropsUtil.GLOBAL_SHUTDOWN_EVENTS), true);
562 }
563 catch (Exception e) {
564 _log.error(e, e);
565 }
566
567
569 super.destroy();
570 }
571
572 protected void checkWebSettings(String xml) throws DocumentException {
573 Document doc = PortalUtil.readDocumentFromXML(xml);
574
575 Element root = doc.getRootElement();
576
577 int timeout = GetterUtil.getInteger(
578 PropsUtil.get(PropsUtil.SESSION_TIMEOUT));
579
580 Element sessionConfig = root.element("session-config");
581
582 if (sessionConfig != null) {
583 String sessionTimeout =
584 sessionConfig.elementText("session-timeout");
585
586 timeout = GetterUtil.getInteger(sessionTimeout, timeout);
587 }
588
589 PropsUtil.set(PropsUtil.SESSION_TIMEOUT, Integer.toString(timeout));
590 }
591
592 protected void destroyCompany(long companyId) {
593
594
596 try {
597 Iterator itr = PortletLocalServiceUtil.getPortlets(
598 companyId).iterator();
599
600 while (itr.hasNext()) {
601 Portlet portlet = (Portlet)itr.next();
602
603 PortletInstanceFactory.destroy(portlet);
604 }
605 }
606 catch (Exception e) {
607 _log.error(e, e);
608 }
609
610
612 if (_log.isDebugEnabled()) {
613 _log.debug("Process shutdown events");
614 }
615
616 try {
617 EventsProcessor.process(PropsUtil.getArray(
618 PropsUtil.APPLICATION_SHUTDOWN_EVENTS),
619 new String[] {String.valueOf(companyId)});
620 }
621 catch (Exception e) {
622 _log.error(e, e);
623 }
624 }
625
626 private static final String _LIFERAY_PORTAL_REQUEST_HEADER =
627 "Liferay-Portal";
628
629 private static Log _log = LogFactory.getLog(MainServlet.class);
630
631 private Set _lastModifiedPaths;
632
633 }