1
19
20 package com.liferay.portal.servlet;
21
22 import com.liferay.portal.NoSuchLayoutException;
23 import com.liferay.portal.deploy.hot.PluginPackageHotDeployListener;
24 import com.liferay.portal.events.EventsProcessor;
25 import com.liferay.portal.events.StartupAction;
26 import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
27 import com.liferay.portal.kernel.events.ActionException;
28 import com.liferay.portal.kernel.job.Scheduler;
29 import com.liferay.portal.kernel.log.Log;
30 import com.liferay.portal.kernel.log.LogFactoryUtil;
31 import com.liferay.portal.kernel.plugin.PluginPackage;
32 import com.liferay.portal.kernel.pop.MessageListener;
33 import com.liferay.portal.kernel.servlet.PortletSessionTracker;
34 import com.liferay.portal.kernel.servlet.ProtectedServletRequest;
35 import com.liferay.portal.kernel.util.ContentTypes;
36 import com.liferay.portal.kernel.util.GetterUtil;
37 import com.liferay.portal.kernel.util.HttpUtil;
38 import com.liferay.portal.kernel.util.InstancePool;
39 import com.liferay.portal.kernel.util.ParamUtil;
40 import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
41 import com.liferay.portal.kernel.util.PortalInitableUtil;
42 import com.liferay.portal.kernel.util.ReleaseInfo;
43 import com.liferay.portal.kernel.util.StringPool;
44 import com.liferay.portal.kernel.util.Validator;
45 import com.liferay.portal.kernel.xml.Document;
46 import com.liferay.portal.kernel.xml.DocumentException;
47 import com.liferay.portal.kernel.xml.Element;
48 import com.liferay.portal.kernel.xml.SAXReaderUtil;
49 import com.liferay.portal.model.Company;
50 import com.liferay.portal.model.Portlet;
51 import com.liferay.portal.model.PortletApp;
52 import com.liferay.portal.model.PortletFilter;
53 import com.liferay.portal.model.PortletURLListener;
54 import com.liferay.portal.model.User;
55 import com.liferay.portal.pop.POPServerUtil;
56 import com.liferay.portal.security.auth.CompanyThreadLocal;
57 import com.liferay.portal.security.auth.PrincipalThreadLocal;
58 import com.liferay.portal.service.CompanyLocalServiceUtil;
59 import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
60 import com.liferay.portal.service.PortletLocalServiceUtil;
61 import com.liferay.portal.service.ThemeLocalServiceUtil;
62 import com.liferay.portal.service.UserLocalServiceUtil;
63 import com.liferay.portal.struts.PortletRequestProcessor;
64 import com.liferay.portal.struts.StrutsUtil;
65 import com.liferay.portal.util.ContentUtil;
66 import com.liferay.portal.util.Portal;
67 import com.liferay.portal.util.PortalInstances;
68 import com.liferay.portal.util.PortalUtil;
69 import com.liferay.portal.util.PropsKeys;
70 import com.liferay.portal.util.PropsUtil;
71 import com.liferay.portal.util.PropsValues;
72 import com.liferay.portal.util.ShutdownUtil;
73 import com.liferay.portal.util.WebKeys;
74 import com.liferay.portal.velocity.VelocityContextPool;
75 import com.liferay.portlet.PortletConfigFactory;
76 import com.liferay.portlet.PortletFilterFactory;
77 import com.liferay.portlet.PortletInstanceFactory;
78 import com.liferay.portlet.PortletURLListenerFactory;
79 import com.liferay.portlet.social.model.SocialActivityInterpreter;
80 import com.liferay.portlet.social.model.SocialRequestInterpreter;
81 import com.liferay.portlet.social.model.impl.SocialActivityInterpreterImpl;
82 import com.liferay.portlet.social.model.impl.SocialRequestInterpreterImpl;
83 import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
84 import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
85 import com.liferay.util.servlet.DynamicServletRequest;
86 import com.liferay.util.servlet.EncryptedServletRequest;
87
88 import java.io.IOException;
89
90 import java.util.Iterator;
91 import java.util.List;
92 import java.util.Set;
93
94 import javax.portlet.PortletConfig;
95 import javax.portlet.PortletContext;
96 import javax.portlet.PortletException;
97
98 import javax.servlet.ServletContext;
99 import javax.servlet.ServletException;
100 import javax.servlet.http.HttpServletRequest;
101 import javax.servlet.http.HttpServletResponse;
102 import javax.servlet.http.HttpSession;
103 import javax.servlet.jsp.PageContext;
104
105 import org.apache.struts.Globals;
106 import org.apache.struts.action.ActionServlet;
107 import org.apache.struts.action.RequestProcessor;
108 import org.apache.struts.config.ControllerConfig;
109 import org.apache.struts.config.ModuleConfig;
110 import org.apache.struts.tiles.TilesUtilImpl;
111
112
120 public class MainServlet extends ActionServlet {
121
122 public void init() throws ServletException {
123
124
126 if (_log.isDebugEnabled()) {
127 _log.debug("Initialize");
128 }
129
130 super.init();
131
132
134 if (_log.isDebugEnabled()) {
135 _log.debug("Process startup events");
136 }
137
138 try {
139 StartupAction startupAction = new StartupAction();
140
141 startupAction.run(null);
142 }
143 catch (RuntimeException re) {
144 ShutdownUtil.shutdown(0);
145
146 throw new ServletException(re);
147 }
148 catch (ActionException ae) {
149 _log.error(ae, ae);
150 }
151
152
154 String contextPath = PortalUtil.getPathContext();
155
156 ServletContext servletContext = getServletContext();
157
158 VelocityContextPool.put(contextPath, servletContext);
159
160
162 if (_log.isDebugEnabled()) {
163 _log.debug("Initialize plugin package");
164 }
165
166 PluginPackage pluginPackage = null;
167
168 try {
169 pluginPackage =
170 PluginPackageHotDeployListener.readPluginPackage(
171 servletContext);
172 }
173 catch (Exception e) {
174 _log.error(e, e);
175 }
176
177
179 if (_log.isDebugEnabled()) {
180 _log.debug("Initialize portlets");
181 }
182
183 List<Portlet> portlets = null;
184
185 try {
186 String[] xmls = new String[] {
187 HttpUtil.URLtoString(servletContext.getResource(
188 "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
189 HttpUtil.URLtoString(servletContext.getResource(
190 "/WEB-INF/portlet-ext.xml")),
191 HttpUtil.URLtoString(servletContext.getResource(
192 "/WEB-INF/liferay-portlet.xml")),
193 HttpUtil.URLtoString(servletContext.getResource(
194 "/WEB-INF/liferay-portlet-ext.xml")),
195 HttpUtil.URLtoString(servletContext.getResource(
196 "/WEB-INF/web.xml"))
197 };
198
199 PortletLocalServiceUtil.initEAR(
200 servletContext, xmls, pluginPackage);
201
202 portlets = PortletLocalServiceUtil.getPortlets();
203
204 for (int i = 0; i < portlets.size(); i++) {
205 Portlet portlet = portlets.get(i);
206
207 if (i == 0) {
208 initPortletApp(portlet, servletContext);
209 }
210
211 PortletInstanceFactory.create(portlet, servletContext);
212 }
213 }
214 catch (Exception e) {
215 _log.error(e, e);
216 }
217
218
220 if (_log.isDebugEnabled()) {
221 _log.debug("Initialize layout templates");
222 }
223
224 try {
225 String[] xmls = new String[] {
226 HttpUtil.URLtoString(servletContext.getResource(
227 "/WEB-INF/liferay-layout-templates.xml")),
228 HttpUtil.URLtoString(servletContext.getResource(
229 "/WEB-INF/liferay-layout-templates-ext.xml"))
230 };
231
232 LayoutTemplateLocalServiceUtil.init(
233 servletContext, xmls, pluginPackage);
234 }
235 catch (Exception e) {
236 _log.error(e, e);
237 }
238
239
241 if (_log.isDebugEnabled()) {
242 _log.debug("Initialize look and feel");
243 }
244
245 try {
246 String[] xmls = new String[] {
247 HttpUtil.URLtoString(servletContext.getResource(
248 "/WEB-INF/liferay-look-and-feel.xml")),
249 HttpUtil.URLtoString(servletContext.getResource(
250 "/WEB-INF/liferay-look-and-feel-ext.xml"))
251 };
252
253 ThemeLocalServiceUtil.init(
254 servletContext, null, true, xmls, pluginPackage);
255 }
256 catch (Exception e) {
257 _log.error(e, e);
258 }
259
260
262 if (_log.isDebugEnabled()) {
263 _log.debug("Scheduler");
264 }
265
266 try {
267 if (PropsValues.SCHEDULER_ENABLED) {
268 for (String className : PropsValues.SCHEDULER_CLASSES) {
269 Scheduler scheduler = (Scheduler)InstancePool.get(
270 className);
271
272 scheduler.schedule();
273 }
274
275 Iterator<Portlet> itr = portlets.iterator();
276
277 while (itr.hasNext()) {
278 Portlet portlet = itr.next();
279
280 String className = portlet.getSchedulerClass();
281
282 if (portlet.isActive() && Validator.isNotNull(className)) {
283 Scheduler scheduler = (Scheduler)InstancePool.get(
284 className);
285
286 scheduler.schedule();
287 }
288 }
289 }
290 }
291 catch (Exception e) {
292 _log.error(e, e);
293 }
294
295
297 if (_log.isDebugEnabled()) {
298 _log.debug("POP message listener");
299 }
300
301 try {
302 Iterator<Portlet> itr = portlets.iterator();
303
304 while (itr.hasNext()) {
305 Portlet portlet = itr.next();
306
307 MessageListener popMessageListener =
308 portlet.getPopMessageListenerInstance();
309
310 if (portlet.isActive() && (popMessageListener != null)) {
311 POPServerUtil.addListener(popMessageListener);
312 }
313 }
314 }
315 catch (Exception e) {
316 _log.error(e, e);
317 }
318
319
321 if (_log.isDebugEnabled()) {
322 _log.debug("Social activity interpreter");
323 }
324
325 try {
326 Iterator<Portlet> itr = portlets.iterator();
327
328 while (itr.hasNext()) {
329 Portlet portlet = itr.next();
330
331 SocialActivityInterpreter socialActivityInterpreter =
332 portlet.getSocialActivityInterpreterInstance();
333
334 if (portlet.isActive() && (socialActivityInterpreter != null)) {
335 socialActivityInterpreter =
336 new SocialActivityInterpreterImpl(
337 portlet.getPortletId(), socialActivityInterpreter);
338
339 SocialActivityInterpreterLocalServiceUtil.
340 addActivityInterpreter(socialActivityInterpreter);
341 }
342 }
343 }
344 catch (Exception e) {
345 _log.error(e, e);
346 }
347
348
350 if (_log.isDebugEnabled()) {
351 _log.debug("Social request interpreter");
352 }
353
354 try {
355 Iterator<Portlet> itr = portlets.iterator();
356
357 while (itr.hasNext()) {
358 Portlet portlet = itr.next();
359
360 SocialRequestInterpreter socialRequestInterpreter =
361 portlet.getSocialRequestInterpreterInstance();
362
363 if (portlet.isActive() && (socialRequestInterpreter != null)) {
364 socialRequestInterpreter = new SocialRequestInterpreterImpl(
365 portlet.getPortletId(), socialRequestInterpreter);
366
367 SocialRequestInterpreterLocalServiceUtil.
368 addRequestInterpreter(socialRequestInterpreter);
369 }
370 }
371 }
372 catch (Exception e) {
373 _log.error(e, e);
374 }
375
376
378 if (_log.isDebugEnabled()) {
379 _log.debug("Check web settings");
380 }
381
382 try {
383 String xml = HttpUtil.URLtoString(
384 servletContext.getResource("/WEB-INF/web.xml"));
385
386 checkWebSettings(xml);
387 }
388 catch (Exception e) {
389 _log.error(e, e);
390 }
391
392
394 if (_log.isDebugEnabled()) {
395 _log.debug("Process global startup events");
396 }
397
398 try {
399 EventsProcessor.process(
400 PropsKeys.GLOBAL_STARTUP_EVENTS,
401 PropsValues.GLOBAL_STARTUP_EVENTS);
402 }
403 catch (Exception e) {
404 _log.error(e, e);
405 }
406
407
409 String[] webIds = PortalInstances.getWebIds();
410
411 for (int i = 0; i < webIds.length; i++) {
412 PortalInstances.initCompany(servletContext, webIds[i]);
413 }
414
415
418 PortalInitableUtil.flushInitables();
419 HotDeployUtil.flushPrematureEvents();
420 }
421
422 public void callParentService(
423 HttpServletRequest request, HttpServletResponse response)
424 throws IOException, ServletException {
425
426 super.service(request, response);
427 }
428
429 public void service(
430 HttpServletRequest request, HttpServletResponse response)
431 throws IOException, ServletException {
432
433 if (_log.isDebugEnabled()) {
434 _log.debug("Process service request");
435 }
436
437 if (ShutdownUtil.isShutdown()) {
438 response.setContentType(ContentTypes.TEXT_HTML_UTF8);
439
440 String html = ContentUtil.get(
441 "com/liferay/portal/dependencies/shutdown.html");
442
443 response.getOutputStream().print(html);
444
445 return;
446 }
447
448 HttpSession session = request.getSession();
449
450
452 long companyId = PortalInstances.getCompanyId(request);
453
454
456
458 PortalUtil.setPortalPort(request);
459
460
462 ServletContext servletContext = getServletContext();
463
464 request.setAttribute(WebKeys.CTX, servletContext);
465
466
468 ModuleConfig moduleConfig = getModuleConfig(request);
469
470
472 if (session.getAttribute(WebKeys.PORTLET_SESSION_TRACKER) == null ) {
473 session.setAttribute(
474 WebKeys.PORTLET_SESSION_TRACKER,
475 PortletSessionTracker.getInstance());
476 }
477
478
480 PortletRequestProcessor portletReqProcessor =
481 (PortletRequestProcessor)servletContext.getAttribute(
482 WebKeys.PORTLET_STRUTS_PROCESSOR);
483
484 if (portletReqProcessor == null) {
485 portletReqProcessor =
486 PortletRequestProcessor.getInstance(this, moduleConfig);
487
488 servletContext.setAttribute(
489 WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
490 }
491
492
494 if (servletContext.getAttribute(
495 TilesUtilImpl.DEFINITIONS_FACTORY) == null) {
496
497 servletContext.setAttribute(
498 TilesUtilImpl.DEFINITIONS_FACTORY,
499 servletContext.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
500 }
501
502 Object applicationAssociate = servletContext.getAttribute(
503 WebKeys.ASSOCIATE_KEY);
504
505 if (servletContext.getAttribute(WebKeys.ASSOCIATE_KEY) == null) {
506 servletContext.setAttribute(
507 WebKeys.ASSOCIATE_KEY, applicationAssociate);
508 }
509
510
512 if (ParamUtil.get(request, WebKeys.ENCRYPT, false)) {
513 try {
514 Company company = CompanyLocalServiceUtil.getCompanyById(
515 companyId);
516
517 request = new EncryptedServletRequest(
518 request, company.getKeyObj());
519 }
520 catch (Exception e) {
521 }
522 }
523
524
526 PortalUtil.getCurrentURL(request);
527
528
530 long userId = PortalUtil.getUserId(request);
531 String remoteUser = request.getRemoteUser();
532
533
535 if (!PropsValues.PORTAL_JAAS_ENABLE) {
536 String jRemoteUser = (String)session.getAttribute("j_remoteuser");
537
538 if (jRemoteUser != null) {
539 remoteUser = jRemoteUser;
540
541 session.removeAttribute("j_remoteuser");
542 }
543 }
544
545 if ((userId > 0) && (remoteUser == null)) {
546 remoteUser = String.valueOf(userId);
547 }
548
549
555 request = new ProtectedServletRequest(request, remoteUser);
556
557 if ((userId > 0) || (remoteUser != null)) {
558
559
561 String name = String.valueOf(userId);
562
563 if (remoteUser != null) {
564 name = remoteUser;
565 }
566
567 PrincipalThreadLocal.setName(name);
568 }
569
570 if ((userId <= 0) && (remoteUser != null)) {
571 try {
572
573
575 userId = GetterUtil.getLong(remoteUser);
576
577
579 EventsProcessor.process(
580 PropsKeys.LOGIN_EVENTS_PRE, PropsValues.LOGIN_EVENTS_PRE,
581 request, response);
582
583
585 User user = UserLocalServiceUtil.getUserById(userId);
586
587 if (PropsValues.USERS_UPDATE_LAST_LOGIN) {
588 UserLocalServiceUtil.updateLastLogin(
589 userId, request.getRemoteAddr());
590 }
591
592
594 session.setAttribute(WebKeys.USER_ID, new Long(userId));
595
596
598 session.setAttribute(Globals.LOCALE_KEY, user.getLocale());
599
600
602 EventsProcessor.process(
603 PropsKeys.LOGIN_EVENTS_POST, PropsValues.LOGIN_EVENTS_POST,
604 request, response);
605 }
606 catch (Exception e) {
607 _log.error(e, e);
608 }
609 }
610
611
613 try {
614 EventsProcessor.process(
615 PropsKeys.SERVLET_SERVICE_EVENTS_PRE,
616 PropsValues.SERVLET_SERVICE_EVENTS_PRE, request, response);
617 }
618 catch (Exception e) {
619 Throwable cause = e.getCause();
620
621 if (cause instanceof NoSuchLayoutException) {
622 DynamicServletRequest dynamicRequest =
623 new DynamicServletRequest(request);
624
625
627 dynamicRequest.setParameter("p_l_id", StringPool.BLANK);
628
629 PortalUtil.sendError(
630 HttpServletResponse.SC_NOT_FOUND,
631 (NoSuchLayoutException)cause, dynamicRequest, response);
632
633 return;
634 }
635
636 _log.error(e, e);
637
638 request.setAttribute(PageContext.EXCEPTION, e);
639
640 StrutsUtil.forward(
641 PropsValues.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE,
642 servletContext, request, response);
643
644 return;
645 }
646
647 if (request.getAttribute(WebKeys.THEME_DISPLAY) == null) {
648 return;
649 }
650
651 try {
652
653
655 callParentService(request, response);
656 }
657 finally {
658
659
661 try {
662 EventsProcessor.process(
663 PropsKeys.SERVLET_SERVICE_EVENTS_POST,
664 PropsValues.SERVLET_SERVICE_EVENTS_POST, request, response);
665 }
666 catch (Exception e) {
667 _log.error(e, e);
668 }
669
670 response.addHeader(
671 _LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
672
673
675 CompanyThreadLocal.setCompanyId(0);
676
677
679 PrincipalThreadLocal.setName(null);
680 }
681 }
682
683 public void destroy() {
684 List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
685
686
688 if (_log.isDebugEnabled()) {
689 _log.debug("Scheduler");
690 }
691
692 try {
693 if (PropsValues.SCHEDULER_ENABLED) {
694 for (String className : PropsValues.SCHEDULER_CLASSES) {
695 Scheduler scheduler = (Scheduler)InstancePool.get(
696 className);
697
698 scheduler.unschedule();
699 }
700
701 Iterator<Portlet> itr = portlets.iterator();
702
703 while (itr.hasNext()) {
704 Portlet portlet = itr.next();
705
706 String className = portlet.getSchedulerClass();
707
708 if (portlet.isActive() && Validator.isNotNull(className)) {
709 Scheduler scheduler = (Scheduler)InstancePool.get(
710 className);
711
712 scheduler.unschedule();
713 }
714 }
715 }
716 }
717 catch (Exception e) {
718 _log.error(e, e);
719 }
720
721
723 try {
724 Iterator<Portlet> itr = portlets.iterator();
725
726 while (itr.hasNext()) {
727 Portlet portlet = itr.next();
728
729 PortletInstanceFactory.destroy(portlet);
730 }
731 }
732 catch (Exception e) {
733 _log.error(e, e);
734 }
735
736
738 long[] companyIds = PortalInstances.getCompanyIds();
739
740 for (int i = 0; i < companyIds.length; i++) {
741 destroyCompany(companyIds[i]);
742 }
743
744
746 if (_log.isDebugEnabled()) {
747 _log.debug("Process global shutdown events");
748 }
749
750 try {
751 EventsProcessor.process(
752 PropsKeys.GLOBAL_SHUTDOWN_EVENTS,
753 PropsValues.GLOBAL_SHUTDOWN_EVENTS);
754 }
755 catch (Exception e) {
756 _log.error(e, e);
757 }
758
759 super.destroy();
760 }
761
762 protected void checkWebSettings(String xml) throws DocumentException {
763 Document doc = SAXReaderUtil.read(xml);
764
765 Element root = doc.getRootElement();
766
767 int timeout = PropsValues.SESSION_TIMEOUT;
768
769 Element sessionConfig = root.element("session-config");
770
771 if (sessionConfig != null) {
772 String sessionTimeout = sessionConfig.elementText(
773 "session-timeout");
774
775 timeout = GetterUtil.getInteger(sessionTimeout, timeout);
776 }
777
778 PropsUtil.set(PropsKeys.SESSION_TIMEOUT, String.valueOf(timeout));
779
780 PropsValues.SESSION_TIMEOUT = timeout;
781
782 I18nServlet.setLanguageIds(root);
783 }
784
785 protected void destroyCompany(long companyId) {
786 if (_log.isDebugEnabled()) {
787 _log.debug("Process shutdown events");
788 }
789
790 try {
791 EventsProcessor.process(
792 PropsKeys.APPLICATION_SHUTDOWN_EVENTS,
793 PropsValues.APPLICATION_SHUTDOWN_EVENTS,
794 new String[] {String.valueOf(companyId)});
795 }
796 catch (Exception e) {
797 _log.error(e, e);
798 }
799 }
800
801 protected synchronized RequestProcessor getRequestProcessor(
802 ModuleConfig moduleConfig)
803 throws ServletException {
804
805 ServletContext servletContext = getServletContext();
806
807 String key = Globals.REQUEST_PROCESSOR_KEY + moduleConfig.getPrefix();
808
809 RequestProcessor processor =
810 (RequestProcessor)servletContext.getAttribute(key);
811
812 if (processor == null) {
813 ControllerConfig controllerConfig =
814 moduleConfig.getControllerConfig();
815
816 String processorClass = controllerConfig.getProcessorClass();
817
818 ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
819
820 try {
821 processor = (RequestProcessor)classLoader.loadClass(
822 processorClass).newInstance();
823 }
824 catch (Exception e) {
825 throw new ServletException(e);
826 }
827
828 processor.init(this, moduleConfig);
829
830 servletContext.setAttribute(key, processor);
831 }
832
833 return processor;
834 }
835
836 protected void initPortletApp(
837 Portlet portlet, ServletContext servletContext)
838 throws PortletException {
839
840 PortletApp portletApp = portlet.getPortletApp();
841
842 PortletConfig portletConfig = PortletConfigFactory.create(
843 portlet, servletContext);
844
845 PortletContext portletContext = portletConfig.getPortletContext();
846
847 Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
848
849 for (PortletFilter portletFilter : portletFilters) {
850 PortletFilterFactory.create(portletFilter, portletContext);
851 }
852
853 Set<PortletURLListener> portletURLListeners =
854 portletApp.getPortletURLListeners();
855
856 for (PortletURLListener portletURLListener : portletURLListeners) {
857 PortletURLListenerFactory.create(portletURLListener);
858 }
859 }
860
861 private static final String _LIFERAY_PORTAL_REQUEST_HEADER =
862 "Liferay-Portal";
863
864 private static Log _log = LogFactoryUtil.getLog(MainServlet.class);
865
866 private Set<String> _lastModifiedPaths;
867
868 }