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.job.Scheduler;
29 import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
30 import com.liferay.portal.kernel.events.ActionException;
31 import com.liferay.portal.kernel.plugin.PluginPackage;
32 import com.liferay.portal.kernel.pop.MessageListener;
33 import com.liferay.portal.kernel.servlet.HttpHeaders;
34 import com.liferay.portal.kernel.servlet.PortletSessionTracker;
35 import com.liferay.portal.kernel.util.ContentTypes;
36 import com.liferay.portal.kernel.util.GetterUtil;
37 import com.liferay.portal.kernel.util.InstancePool;
38 import com.liferay.portal.kernel.util.ParamUtil;
39 import com.liferay.portal.kernel.util.PortalInitableUtil;
40 import com.liferay.portal.kernel.util.ReleaseInfo;
41 import com.liferay.portal.kernel.util.Validator;
42 import com.liferay.portal.lastmodified.LastModifiedAction;
43 import com.liferay.portal.model.ActivityTrackerInterpreter;
44 import com.liferay.portal.model.Company;
45 import com.liferay.portal.model.Portlet;
46 import com.liferay.portal.model.User;
47 import com.liferay.portal.model.impl.ActivityTrackerInterpreterImpl;
48 import com.liferay.portal.pop.POPServerUtil;
49 import com.liferay.portal.security.auth.CompanyThreadLocal;
50 import com.liferay.portal.security.auth.PrincipalThreadLocal;
51 import com.liferay.portal.service.CompanyLocalServiceUtil;
52 import com.liferay.portal.service.PortletLocalServiceUtil;
53 import com.liferay.portal.service.UserLocalServiceUtil;
54 import com.liferay.portal.service.impl.LayoutTemplateLocalUtil;
55 import com.liferay.portal.service.impl.ThemeLocalUtil;
56 import com.liferay.portal.struts.PortletRequestProcessor;
57 import com.liferay.portal.struts.StrutsUtil;
58 import com.liferay.portal.util.ActivityTrackerInterpreterUtil;
59 import com.liferay.portal.util.ContentUtil;
60 import com.liferay.portal.util.InitUtil;
61 import com.liferay.portal.util.PortalInstances;
62 import com.liferay.portal.util.PortalUtil;
63 import com.liferay.portal.util.PropsUtil;
64 import com.liferay.portal.util.PropsValues;
65 import com.liferay.portal.util.ShutdownUtil;
66 import com.liferay.portal.util.WebKeys;
67 import com.liferay.portal.velocity.VelocityContextPool;
68 import com.liferay.portlet.PortletInstanceFactory;
69 import com.liferay.util.CollectionFactory;
70 import com.liferay.util.Http;
71 import com.liferay.util.servlet.EncryptedServletRequest;
72 import com.liferay.util.servlet.ProtectedServletRequest;
73
74 import java.io.IOException;
75
76 import java.util.Iterator;
77 import java.util.List;
78 import java.util.Set;
79
80 import javax.servlet.ServletContext;
81 import javax.servlet.ServletException;
82 import javax.servlet.http.HttpServletRequest;
83 import javax.servlet.http.HttpServletResponse;
84 import javax.servlet.http.HttpSession;
85 import javax.servlet.jsp.PageContext;
86
87 import org.apache.commons.logging.Log;
88 import org.apache.commons.logging.LogFactory;
89 import org.apache.struts.Globals;
90 import org.apache.struts.action.ActionMapping;
91 import org.apache.struts.action.ActionServlet;
92 import org.apache.struts.config.ModuleConfig;
93 import org.apache.struts.tiles.TilesUtilImpl;
94
95 import org.dom4j.Document;
96 import org.dom4j.DocumentException;
97 import org.dom4j.Element;
98
99 import org.quartz.ObjectAlreadyExistsException;
100
101
109 public class MainServlet extends ActionServlet {
110
111 static {
112 InitUtil.init();
113 }
114
115 public void init() throws ServletException {
116
117
119 if (_log.isDebugEnabled()) {
120 _log.debug("Initialize");
121 }
122
123 super.init();
124
125
127 if (_log.isDebugEnabled()) {
128 _log.debug("Process startup events");
129 }
130
131 try {
132 EventsProcessor.process(
133 new String[] {
134 StartupAction.class.getName()
135 },
136 true);
137 }
138 catch (RuntimeException re) {
139 ShutdownUtil.shutdown(0);
140
141 throw new ServletException(re);
142 }
143 catch (ActionException ae) {
144 _log.error(ae, ae);
145 }
146
147
149 String contextPath = PortalUtil.getPathContext();
150
151 ServletContext ctx = getServletContext();
152
153 VelocityContextPool.put(contextPath, ctx);
154
155
157 if (_log.isDebugEnabled()) {
158 _log.debug("Initialize plugin package");
159 }
160
161 PluginPackage pluginPackage = null;
162
163 try {
164 pluginPackage =
165 PluginPackageHotDeployListener.readPluginPackage(ctx);
166 }
167 catch (Exception e) {
168 _log.error(e, e);
169 }
170
171
173 if (_log.isDebugEnabled()) {
174 _log.debug("Initialize portlets");
175 }
176
177 List portlets = null;
178
179 try {
180 String[] xmls = new String[] {
181 Http.URLtoString(ctx.getResource(
182 "/WEB-INF/" + PortalUtil.PORTLET_XML_FILE_NAME_CUSTOM)),
183 Http.URLtoString(ctx.getResource(
184 "/WEB-INF/portlet-ext.xml")),
185 Http.URLtoString(ctx.getResource(
186 "/WEB-INF/liferay-portlet.xml")),
187 Http.URLtoString(ctx.getResource(
188 "/WEB-INF/liferay-portlet-ext.xml")),
189 Http.URLtoString(ctx.getResource("/WEB-INF/web.xml"))
190 };
191
192 PortletLocalServiceUtil.initEAR(xmls, pluginPackage);
193
194 portlets = PortletLocalServiceUtil.getPortlets();
195
196 Iterator itr = portlets.iterator();
197
198 while (itr.hasNext()) {
199 Portlet portlet = (Portlet)itr.next();
200
201 PortletInstanceFactory.create(portlet, ctx);
202 }
203 }
204 catch (Exception e) {
205 _log.error(e, e);
206 }
207
208
210 if (_log.isDebugEnabled()) {
211 _log.debug("Initialize layout templates");
212 }
213
214 try {
215 String[] xmls = new String[] {
216 Http.URLtoString(ctx.getResource(
217 "/WEB-INF/liferay-layout-templates.xml")),
218 Http.URLtoString(ctx.getResource(
219 "/WEB-INF/liferay-layout-templates-ext.xml"))
220 };
221
222 LayoutTemplateLocalUtil.init(ctx, xmls, pluginPackage);
223 }
224 catch (Exception e) {
225 _log.error(e, e);
226 }
227
228
230 if (_log.isDebugEnabled()) {
231 _log.debug("Initialize look and feel");
232 }
233
234 try {
235 String[] xmls = new String[] {
236 Http.URLtoString(ctx.getResource(
237 "/WEB-INF/liferay-look-and-feel.xml")),
238 Http.URLtoString(ctx.getResource(
239 "/WEB-INF/liferay-look-and-feel-ext.xml"))
240 };
241
242 ThemeLocalUtil.init(ctx, null, true, xmls, pluginPackage);
243 }
244 catch (Exception e) {
245 _log.error(e, e);
246 }
247
248
250 if (_log.isDebugEnabled()) {
251 _log.debug("Scheduler");
252 }
253
254 try {
255 if (GetterUtil.getBoolean(PropsUtil.get(
256 PropsUtil.SCHEDULER_ENABLED))) {
257
258 Iterator itr = portlets.iterator();
259
260 while (itr.hasNext()) {
261 Portlet portlet = (Portlet)itr.next();
262
263 String className = portlet.getSchedulerClass();
264
265 if (portlet.isActive() && Validator.isNotNull(className)) {
266 Scheduler scheduler =
267 (Scheduler)InstancePool.get(className);
268
269 scheduler.schedule();
270 }
271 }
272 }
273 }
274 catch (ObjectAlreadyExistsException oaee) {
275 }
276 catch (Exception e) {
277 _log.error(e, e);
278 }
279
280
282 if (_log.isDebugEnabled()) {
283 _log.debug("Activity tracker interpreter");
284 }
285
286 try {
287 Iterator itr = portlets.iterator();
288
289 while (itr.hasNext()) {
290 Portlet portlet = (Portlet)itr.next();
291
292 ActivityTrackerInterpreter activityTrackerInterpreter =
293 portlet.getActivityTrackerInterpreterInstance();
294
295 if (portlet.isActive() &&
296 (activityTrackerInterpreter != null)) {
297
298 activityTrackerInterpreter =
299 new ActivityTrackerInterpreterImpl(
300 activityTrackerInterpreter);
301
302 ActivityTrackerInterpreterUtil.
303 addActivityTrackerInterpreter(
304 activityTrackerInterpreter);
305 }
306 }
307 }
308 catch (Exception e) {
309 _log.error(e, e);
310 }
311
312
314 if (_log.isDebugEnabled()) {
315 _log.debug("POP message listener");
316 }
317
318 try {
319 Iterator itr = portlets.iterator();
320
321 while (itr.hasNext()) {
322 Portlet portlet = (Portlet)itr.next();
323
324 MessageListener popMessageListener =
325 portlet.getPopMessageListenerInstance();
326
327 if (portlet.isActive() && (popMessageListener != null)) {
328 POPServerUtil.addListener(popMessageListener);
329 }
330 }
331 }
332 catch (Exception e) {
333 _log.error(e, e);
334 }
335
336
338 if (_log.isDebugEnabled()) {
339 _log.debug("Check web settings");
340 }
341
342 try {
343 String xml = Http.URLtoString(ctx.getResource("/WEB-INF/web.xml"));
344
345 checkWebSettings(xml);
346 }
347 catch (Exception e) {
348 _log.error(e, e);
349 }
350
351
353 if (_log.isDebugEnabled()) {
354 _log.debug("Last modified paths");
355 }
356
357 if (_lastModifiedPaths == null) {
358 _lastModifiedPaths = CollectionFactory.getHashSet();
359
360 String[] pathsArray = PropsUtil.getArray(
361 PropsUtil.LAST_MODIFIED_PATHS);
362
363 for (int i = 0; i < pathsArray.length; i++) {
364 _lastModifiedPaths.add(pathsArray[i]);
365 }
366 }
367
368
370 if (_log.isDebugEnabled()) {
371 _log.debug("Process global startup events");
372 }
373
374 try {
375 EventsProcessor.process(PropsUtil.getArray(
376 PropsUtil.GLOBAL_STARTUP_EVENTS), true);
377 }
378 catch (Exception e) {
379 _log.error(e, e);
380 }
381
382
384 String[] webIds = PortalInstances.getWebIds();
385
386 for (int i = 0; i < webIds.length; i++) {
387 PortalInstances.initCompany(ctx, webIds[i]);
388 }
389
390
393 PortalInitableUtil.flushInitables();
394 HotDeployUtil.flushEvents();
395 }
396
397 public void callParentService(
398 HttpServletRequest req, HttpServletResponse res)
399 throws IOException, ServletException {
400
401 super.service(req, res);
402 }
403
404 public void service(HttpServletRequest req, HttpServletResponse res)
405 throws IOException, ServletException {
406
407 if (_log.isDebugEnabled()) {
408 _log.debug("Process service request");
409 }
410
411 if (ShutdownUtil.isShutdown()) {
412 res.setContentType(ContentTypes.TEXT_HTML_UTF8);
413
414 String html = ContentUtil.get(
415 "com/liferay/portal/dependencies/shutdown.html");
416
417 res.getOutputStream().print(html);
418
419 return;
420 }
421
422 HttpSession ses = req.getSession();
423
424
426 long companyId = PortalInstances.getCompanyId(req);
427
428
430
432 ServletContext ctx = getServletContext();
433
434 req.setAttribute(WebKeys.CTX, ctx);
435
436
438 ModuleConfig moduleConfig = getModuleConfig(req);
439
440
442 if (PropsValues.LAST_MODIFIED_CHECK) {
443 String path = req.getPathInfo();
444
445 if ((path != null) && _lastModifiedPaths.contains(path)) {
446 ActionMapping mapping =
447 (ActionMapping)moduleConfig.findActionConfig(path);
448
449 LastModifiedAction lastModifiedAction =
450 (LastModifiedAction)InstancePool.get(mapping.getType());
451
452 String lmKey = lastModifiedAction.getLastModifiedKey(req);
453
454 if (lmKey != null) {
455 long ifModifiedSince =
456 req.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
457
458 if (ifModifiedSince <= 0) {
459 lastModifiedAction.setLastModifiedValue(lmKey, lmKey);
460 }
461 else {
462 String lmValue =
463 lastModifiedAction.getLastModifiedValue(lmKey);
464
465 if (lmValue != null) {
466 res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
467
468 return;
469 }
470 else {
471 lastModifiedAction.setLastModifiedValue(
472 lmKey, lmKey);
473 }
474 }
475 }
476 }
477 }
478
479
481 if (ses.getAttribute(WebKeys.PORTLET_SESSION_TRACKER) == null ) {
482 ses.setAttribute(
483 WebKeys.PORTLET_SESSION_TRACKER,
484 PortletSessionTracker.getInstance());
485 }
486
487
489 PortletRequestProcessor portletReqProcessor =
490 (PortletRequestProcessor)ctx.getAttribute(
491 WebKeys.PORTLET_STRUTS_PROCESSOR);
492
493 if (portletReqProcessor == null) {
494 portletReqProcessor =
495 PortletRequestProcessor.getInstance(this, moduleConfig);
496
497 ctx.setAttribute(
498 WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
499 }
500
501
503 if (ctx.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY) == null) {
504 ctx.setAttribute(
505 TilesUtilImpl.DEFINITIONS_FACTORY,
506 ctx.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
507 }
508
509 Object applicationAssociate = ctx.getAttribute(WebKeys.ASSOCIATE_KEY);
510
511 if (ctx.getAttribute(WebKeys.ASSOCIATE_KEY) == null) {
512 ctx.setAttribute(WebKeys.ASSOCIATE_KEY, applicationAssociate);
513 }
514
515
517 if (ParamUtil.get(req, WebKeys.ENCRYPT, false)) {
518 try {
519 Company company = CompanyLocalServiceUtil.getCompanyById(
520 companyId);
521
522 req = new EncryptedServletRequest(req, company.getKeyObj());
523 }
524 catch (Exception e) {
525 }
526 }
527
528
530 PortalUtil.getCurrentURL(req);
531
532
534 long userId = PortalUtil.getUserId(req);
535 String remoteUser = req.getRemoteUser();
536
537
539 if (!PropsValues.PORTAL_JAAS_ENABLE) {
540 String jRemoteUser = (String)ses.getAttribute("j_remoteuser");
541
542 if (jRemoteUser != null) {
543 remoteUser = jRemoteUser;
544
545 ses.removeAttribute("j_remoteuser");
546 }
547 }
548
549 if ((userId > 0) && (remoteUser == null)) {
550 remoteUser = String.valueOf(userId);
551 }
552
553
559 req = new ProtectedServletRequest(req, remoteUser);
560
561 if ((userId > 0) || (remoteUser != null)) {
562
563
565 String name = String.valueOf(userId);
566
567 if (remoteUser != null) {
568 name = remoteUser;
569 }
570
571 PrincipalThreadLocal.setName(name);
572 }
573
574 if ((userId <= 0) && (remoteUser != null)) {
575 try {
576
577
579 userId = GetterUtil.getLong(remoteUser);
580
581
583 EventsProcessor.process(PropsValues.LOGIN_EVENTS_PRE, req, res);
584
585
587 User user = UserLocalServiceUtil.getUserById(userId);
588
589 UserLocalServiceUtil.updateLastLogin(
590 userId, req.getRemoteAddr());
591
592
594 ses.setAttribute(WebKeys.USER_ID, new Long(userId));
595
596
598 ses.setAttribute(Globals.LOCALE_KEY, user.getLocale());
599
600
602 EventsProcessor.process(
603 PropsValues.LOGIN_EVENTS_POST, req, res);
604 }
605 catch (Exception e) {
606 _log.error(e, e);
607 }
608 }
609
610
612 try {
613 EventsProcessor.process(
614 PropsValues.SERVLET_SERVICE_EVENTS_PRE, req, res);
615 }
616 catch (Exception e) {
617 _log.error(e, e);
618
619 req.setAttribute(PageContext.EXCEPTION, e);
620
621 StrutsUtil.forward(
622 PropsValues.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE, ctx, req,
623 res);
624 }
625
626 try {
627
628
630 callParentService(req, res);
631 }
632 finally {
633
634
636 try {
637 EventsProcessor.process(
638 PropsValues.SERVLET_SERVICE_EVENTS_POST, req, res);
639 }
640 catch (Exception e) {
641 _log.error(e, e);
642 }
643
644 res.addHeader(
645 _LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
646
647
649 CompanyThreadLocal.setCompanyId(0);
650
651
653 PrincipalThreadLocal.setName(null);
654 }
655 }
656
657 public void destroy() {
658 try {
659 Iterator itr = PortletLocalServiceUtil.getPortlets().iterator();
660
661 while (itr.hasNext()) {
662 Portlet portlet = (Portlet)itr.next();
663
664 PortletInstanceFactory.destroy(portlet);
665 }
666 }
667 catch (Exception e) {
668 _log.error(e, e);
669 }
670
671 long[] companyIds = PortalInstances.getCompanyIds();
672
673 for (int i = 0; i < companyIds.length; i++) {
674 destroyCompany(companyIds[i]);
675 }
676
677 try {
678 EventsProcessor.process(PropsUtil.getArray(
679 PropsUtil.GLOBAL_SHUTDOWN_EVENTS), true);
680 }
681 catch (Exception e) {
682 _log.error(e, e);
683 }
684
685 super.destroy();
686 }
687
688 protected void checkWebSettings(String xml) throws DocumentException {
689 Document doc = PortalUtil.readDocumentFromXML(xml);
690
691 Element root = doc.getRootElement();
692
693 int timeout = PropsValues.SESSION_TIMEOUT;
694
695 Element sessionConfig = root.element("session-config");
696
697 if (sessionConfig != null) {
698 String sessionTimeout =
699 sessionConfig.elementText("session-timeout");
700
701 timeout = GetterUtil.getInteger(sessionTimeout, timeout);
702 }
703
704 PropsUtil.set(PropsUtil.SESSION_TIMEOUT, String.valueOf(timeout));
705
706 PropsValues.SESSION_TIMEOUT = timeout;
707 }
708
709 protected void destroyCompany(long companyId) {
710 if (_log.isDebugEnabled()) {
711 _log.debug("Process shutdown events");
712 }
713
714 try {
715 EventsProcessor.process(PropsUtil.getArray(
716 PropsUtil.APPLICATION_SHUTDOWN_EVENTS),
717 new String[] {String.valueOf(companyId)});
718 }
719 catch (Exception e) {
720 _log.error(e, e);
721 }
722 }
723
724 private static final String _LIFERAY_PORTAL_REQUEST_HEADER =
725 "Liferay-Portal";
726
727 private static Log _log = LogFactory.getLog(MainServlet.class);
728
729 private Set _lastModifiedPaths;
730
731 }