1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.servlet;
16  
17  import com.liferay.portal.NoSuchLayoutException;
18  import com.liferay.portal.deploy.hot.PluginPackageHotDeployListener;
19  import com.liferay.portal.events.EventsProcessorUtil;
20  import com.liferay.portal.events.StartupAction;
21  import com.liferay.portal.kernel.cache.Lifecycle;
22  import com.liferay.portal.kernel.cache.ThreadLocalCacheManager;
23  import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
24  import com.liferay.portal.kernel.exception.PortalException;
25  import com.liferay.portal.kernel.exception.SystemException;
26  import com.liferay.portal.kernel.log.Log;
27  import com.liferay.portal.kernel.log.LogFactoryUtil;
28  import com.liferay.portal.kernel.plugin.PluginPackage;
29  import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
30  import com.liferay.portal.kernel.scheduler.SchedulerEntry;
31  import com.liferay.portal.kernel.scheduler.SchedulerEntryImpl;
32  import com.liferay.portal.kernel.scheduler.TimeUnit;
33  import com.liferay.portal.kernel.scheduler.TriggerType;
34  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
35  import com.liferay.portal.kernel.servlet.PortletSessionTracker;
36  import com.liferay.portal.kernel.servlet.ProtectedServletRequest;
37  import com.liferay.portal.kernel.servlet.ServletContextPool;
38  import com.liferay.portal.kernel.util.ContentTypes;
39  import com.liferay.portal.kernel.util.GetterUtil;
40  import com.liferay.portal.kernel.util.HttpUtil;
41  import com.liferay.portal.kernel.util.ParamUtil;
42  import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
43  import com.liferay.portal.kernel.util.PortalInitableUtil;
44  import com.liferay.portal.kernel.util.PropsKeys;
45  import com.liferay.portal.kernel.util.ReleaseInfo;
46  import com.liferay.portal.kernel.util.StringPool;
47  import com.liferay.portal.kernel.xml.Document;
48  import com.liferay.portal.kernel.xml.DocumentException;
49  import com.liferay.portal.kernel.xml.Element;
50  import com.liferay.portal.kernel.xml.SAXReaderUtil;
51  import com.liferay.portal.model.Company;
52  import com.liferay.portal.model.Group;
53  import com.liferay.portal.model.GroupConstants;
54  import com.liferay.portal.model.Layout;
55  import com.liferay.portal.model.Portlet;
56  import com.liferay.portal.model.PortletApp;
57  import com.liferay.portal.model.PortletFilter;
58  import com.liferay.portal.model.PortletURLListener;
59  import com.liferay.portal.model.User;
60  import com.liferay.portal.plugin.PluginPackageIndexer;
61  import com.liferay.portal.security.auth.PrincipalException;
62  import com.liferay.portal.security.auth.PrincipalThreadLocal;
63  import com.liferay.portal.security.permission.ResourceActionsUtil;
64  import com.liferay.portal.service.CompanyLocalServiceUtil;
65  import com.liferay.portal.service.GroupLocalServiceUtil;
66  import com.liferay.portal.service.LayoutLocalServiceUtil;
67  import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
68  import com.liferay.portal.service.PortletLocalServiceUtil;
69  import com.liferay.portal.service.ResourceActionLocalServiceUtil;
70  import com.liferay.portal.service.ResourceCodeLocalServiceUtil;
71  import com.liferay.portal.service.ThemeLocalServiceUtil;
72  import com.liferay.portal.service.UserLocalServiceUtil;
73  import com.liferay.portal.servlet.filters.i18n.I18nFilter;
74  import com.liferay.portal.struts.PortletRequestProcessor;
75  import com.liferay.portal.struts.StrutsUtil;
76  import com.liferay.portal.util.ContentUtil;
77  import com.liferay.portal.util.ExtRegistry;
78  import com.liferay.portal.util.MaintenanceUtil;
79  import com.liferay.portal.util.Portal;
80  import com.liferay.portal.util.PortalInstances;
81  import com.liferay.portal.util.PortalUtil;
82  import com.liferay.portal.util.PropsUtil;
83  import com.liferay.portal.util.PropsValues;
84  import com.liferay.portal.util.ShutdownUtil;
85  import com.liferay.portal.util.WebKeys;
86  import com.liferay.portlet.PortletBagFactory;
87  import com.liferay.portlet.PortletConfigFactory;
88  import com.liferay.portlet.PortletFilterFactory;
89  import com.liferay.portlet.PortletInstanceFactoryUtil;
90  import com.liferay.portlet.PortletURLListenerFactory;
91  import com.liferay.portlet.social.messaging.CheckEquityLogMessageListener;
92  import com.liferay.util.servlet.DynamicServletRequest;
93  import com.liferay.util.servlet.EncryptedServletRequest;
94  
95  import java.io.IOException;
96  
97  import java.util.Iterator;
98  import java.util.List;
99  import java.util.Set;
100 
101 import javax.portlet.PortletConfig;
102 import javax.portlet.PortletContext;
103 import javax.portlet.PortletException;
104 
105 import javax.servlet.RequestDispatcher;
106 import javax.servlet.ServletContext;
107 import javax.servlet.ServletException;
108 import javax.servlet.http.HttpServletRequest;
109 import javax.servlet.http.HttpServletResponse;
110 import javax.servlet.http.HttpSession;
111 import javax.servlet.jsp.PageContext;
112 
113 import org.apache.struts.Globals;
114 import org.apache.struts.action.ActionServlet;
115 import org.apache.struts.action.RequestProcessor;
116 import org.apache.struts.config.ControllerConfig;
117 import org.apache.struts.config.ModuleConfig;
118 import org.apache.struts.tiles.TilesUtilImpl;
119 
120 /**
121  * <a href="MainServlet.java.html"><b><i>View Source</i></b></a>
122  *
123  * @author Brian Wing Shun Chan
124  * @author Jorge Ferrer
125  * @author Brian Myunghun Kim
126  */
127 public class MainServlet extends ActionServlet {
128 
129     public void destroy() {
130         List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
131 
132         if (_log.isDebugEnabled()) {
133             _log.debug("Destroy schedulers");
134         }
135 
136         try {
137             destroySchedulers(portlets);
138         }
139         catch (Exception e) {
140             _log.error(e, e);
141         }
142 
143         if (_log.isDebugEnabled()) {
144             _log.debug("Destroy portlets");
145         }
146 
147         try {
148             destroyPortlets(portlets);
149         }
150         catch (Exception e) {
151             _log.error(e, e);
152         }
153 
154         if (_log.isDebugEnabled()) {
155             _log.debug("Destroy companies");
156         }
157 
158         try {
159             destroyCompanies();
160         }
161         catch (Exception e) {
162             _log.error(e, e);
163         }
164 
165         if (_log.isDebugEnabled()) {
166             _log.debug("Process global shutdown events");
167         }
168 
169         try {
170             processGlobalShutdownEvents();
171         }
172         catch (Exception e) {
173             _log.error(e, e);
174         }
175 
176         if (_log.isDebugEnabled()) {
177             _log.debug("Destroy");
178         }
179 
180         callParentDestroy();
181     }
182 
183     public void init() throws ServletException {
184         if (_log.isDebugEnabled()) {
185             _log.debug("Initialize");
186         }
187 
188         callParentInit();
189 
190         if (_log.isDebugEnabled()) {
191             _log.debug("Process startup events");
192         }
193 
194         try {
195             processStartupEvents();
196         }
197         catch (Exception e) {
198             _log.error(e, e);
199 
200             System.out.println(
201                 "Stopping the server due to unexpected startup errors");
202 
203             System.exit(0);
204         }
205 
206         if (_log.isDebugEnabled()) {
207             _log.debug("Initialize servlet context pool");
208         }
209 
210         try {
211             initServletContextPool();
212         }
213         catch (Exception e) {
214             _log.error(e, e);
215         }
216 
217         if (_log.isDebugEnabled()) {
218             _log.debug("Initialize plugin package");
219         }
220 
221         PluginPackage pluginPackage = null;
222 
223         try {
224             pluginPackage = initPluginPackage();
225         }
226         catch (Exception e) {
227             _log.error(e, e);
228         }
229 
230         if (_log.isDebugEnabled()) {
231             _log.debug("Initialize portlets");
232         }
233 
234         List<Portlet> portlets = null;
235 
236         try {
237             portlets = initPortlets(pluginPackage);
238         }
239         catch (Exception e) {
240             _log.error(e, e);
241         }
242 
243         if (_log.isDebugEnabled()) {
244             _log.debug("Initialize layout templates");
245         }
246 
247         try {
248             initLayoutTemplates(pluginPackage, portlets);
249         }
250         catch (Exception e) {
251             _log.error(e, e);
252         }
253 
254         if (_log.isDebugEnabled()) {
255             _log.debug("Initialize themes");
256         }
257 
258         try {
259             initThemes(pluginPackage, portlets);
260         }
261         catch (Exception e) {
262             _log.error(e, e);
263         }
264 
265         if (_log.isDebugEnabled()) {
266             _log.debug("Initialize social log scheduler");
267         }
268 
269         try {
270             initSocialEquityLogScheduler();
271         }
272         catch (Exception e) {
273             _log.error(e, e);
274         }
275 
276         if (_log.isDebugEnabled()) {
277             _log.debug("Initialize web settings");
278         }
279 
280         try {
281             initWebSettings();
282         }
283         catch (Exception e) {
284             _log.error(e, e);
285         }
286 
287         if (_log.isDebugEnabled()) {
288             _log.debug("Initialize extension environment");
289         }
290 
291         try {
292             initExt();
293         }
294         catch (Exception e) {
295             _log.error(e, e);
296         }
297 
298         if (_log.isDebugEnabled()) {
299             _log.debug("Process global startup events");
300         }
301 
302         try {
303             processGlobalStartupEvents();
304         }
305         catch (Exception e) {
306             _log.error(e, e);
307         }
308 
309         if (_log.isDebugEnabled()) {
310             _log.debug("Initialize resource actions");
311         }
312 
313         try {
314             initResourceActions(portlets);
315         }
316         catch (Exception e) {
317             _log.error(e, e);
318         }
319 
320         if (_log.isDebugEnabled()) {
321             _log.debug("Initialize resource codes");
322         }
323 
324         try {
325             initResourceCodes(portlets);
326         }
327         catch (Exception e) {
328             _log.error(e, e);
329         }
330 
331         if (_log.isDebugEnabled()) {
332             _log.debug("Initialize companies");
333         }
334 
335         try {
336             initCompanies();
337         }
338         catch (Exception e) {
339             _log.error(e, e);
340         }
341 
342         if (_log.isDebugEnabled()) {
343             _log.debug("Initialize message resources");
344         }
345 
346         if (_log.isDebugEnabled()) {
347             _log.debug("Initialize plugins");
348         }
349 
350         try {
351             initPlugins();
352         }
353         catch (Exception e) {
354             _log.error(e, e);
355         }
356     }
357 
358     public void service(
359             HttpServletRequest request, HttpServletResponse response)
360         throws IOException, ServletException {
361 
362         if (_log.isDebugEnabled()) {
363             _log.debug("Process service request");
364         }
365 
366         if (processShutdownRequest(request, response)) {
367             if (_log.isDebugEnabled()) {
368                 _log.debug("Processed shutdown request");
369             }
370 
371             return;
372         }
373 
374         if (processMaintenanceRequest(request, response)) {
375             if (_log.isDebugEnabled()) {
376                 _log.debug("Processed maintenance request");
377             }
378 
379             return;
380         }
381 
382         if (_log.isDebugEnabled()) {
383             _log.debug("Get company id");
384         }
385 
386         long companyId = getCompanyId(request);
387 
388         if (_log.isDebugEnabled()) {
389             _log.debug("Set portal port");
390         }
391 
392         setPortalPort(request);
393 
394         if (_log.isDebugEnabled()) {
395             _log.debug("Check variables");
396         }
397 
398         checkServletContext(request);
399         checkPortletSessionTracker(request);
400         checkPortletRequestProcessor(request);
401         checkTilesDefinitionsFactory();
402 
403         if (_log.isDebugEnabled()) {
404             _log.debug("Encrypt request");
405         }
406 
407         request = encryptRequest(request, companyId);
408 
409         long userId = getUserId(request);
410         String remoteUser = getRemoteUser(request, userId);
411 
412         if (_log.isDebugEnabled()) {
413             _log.debug("Protect request");
414         }
415 
416         request = protectRequest(request, remoteUser);
417 
418         if (_log.isDebugEnabled()) {
419             _log.debug("Set principal");
420         }
421 
422         setPrincipalName(userId, remoteUser);
423 
424         try {
425             if (_log.isDebugEnabled()) {
426                 _log.debug(
427                 "Authenticate user id " + userId + " and remote user " +
428                     remoteUser);
429             }
430 
431             userId = loginUser(request, response, userId, remoteUser);
432 
433             if (_log.isDebugEnabled()) {
434                 _log.debug("Authenticated user id " + userId);
435             }
436         }
437         catch (Exception e) {
438             _log.error(e, e);
439         }
440 
441         if (_log.isDebugEnabled()) {
442             _log.debug("Process service pre events");
443         }
444 
445         if (processServicePre(request, response, userId)) {
446             if (_log.isDebugEnabled()) {
447                 _log.debug("Processing service pre events has errors");
448             }
449 
450             return;
451         }
452 
453         if (hasAbsoluteRedirect(request)) {
454             if (_log.isDebugEnabled()) {
455                 String currentURL = PortalUtil.getCurrentURL(request);
456 
457                 _log.debug(
458                     "Current URL " + currentURL + " has absolute redirect");
459             }
460 
461             return;
462         }
463 
464         if (!hasThemeDisplay(request)) {
465             if (_log.isDebugEnabled()) {
466                 String currentURL = PortalUtil.getCurrentURL(request);
467 
468                 _log.debug(
469                     "Current URL " + currentURL +
470                         " does not have a theme display");
471             }
472 
473             return;
474         }
475 
476         try {
477             if (_log.isDebugEnabled()) {
478                 _log.debug("Call parent service");
479             }
480 
481             callParentService(request, response);
482         }
483         finally {
484             if (_log.isDebugEnabled()) {
485                 _log.debug("Process service post events");
486             }
487 
488             processServicePost(request, response);
489         }
490     }
491 
492     protected void callParentDestroy() {
493         super.destroy();
494     }
495 
496     protected void callParentInit() throws ServletException {
497         super.init();
498     }
499 
500     protected void callParentService(
501             HttpServletRequest request, HttpServletResponse response)
502         throws IOException, ServletException {
503 
504         super.service(request, response);
505     }
506 
507     protected void checkPortletRequestProcessor(HttpServletRequest request)
508         throws ServletException {
509 
510         ServletContext servletContext = getServletContext();
511 
512         PortletRequestProcessor portletReqProcessor =
513             (PortletRequestProcessor)servletContext.getAttribute(
514                 WebKeys.PORTLET_STRUTS_PROCESSOR);
515 
516         if (portletReqProcessor == null) {
517             ModuleConfig moduleConfig = getModuleConfig(request);
518 
519             portletReqProcessor =
520                 PortletRequestProcessor.getInstance(this, moduleConfig);
521 
522             servletContext.setAttribute(
523                 WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
524         }
525     }
526 
527     protected void checkPortletSessionTracker(HttpServletRequest request) {
528         HttpSession session = request.getSession();
529 
530         if (session.getAttribute(WebKeys.PORTLET_SESSION_TRACKER) != null) {
531             return;
532         }
533 
534         session.setAttribute(
535             WebKeys.PORTLET_SESSION_TRACKER,
536             PortletSessionTracker.getInstance());
537     }
538 
539     protected void checkServletContext(HttpServletRequest request) {
540         ServletContext servletContext = getServletContext();
541 
542         request.setAttribute(WebKeys.CTX, servletContext);
543     }
544 
545     protected void checkTilesDefinitionsFactory() {
546         ServletContext servletContext = getServletContext();
547 
548         if (servletContext.getAttribute(
549                 TilesUtilImpl.DEFINITIONS_FACTORY) != null) {
550 
551             return;
552         }
553 
554         servletContext.setAttribute(
555             TilesUtilImpl.DEFINITIONS_FACTORY,
556             servletContext.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
557     }
558 
559     protected void checkWebSettings(String xml) throws DocumentException {
560         Document doc = SAXReaderUtil.read(xml);
561 
562         Element root = doc.getRootElement();
563 
564         int timeout = PropsValues.SESSION_TIMEOUT;
565 
566         Element sessionConfig = root.element("session-config");
567 
568         if (sessionConfig != null) {
569             String sessionTimeout = sessionConfig.elementText(
570                 "session-timeout");
571 
572             timeout = GetterUtil.getInteger(sessionTimeout, timeout);
573         }
574 
575         PropsUtil.set(PropsKeys.SESSION_TIMEOUT, String.valueOf(timeout));
576 
577         PropsValues.SESSION_TIMEOUT = timeout;
578 
579         I18nServlet.setLanguageIds(root);
580         I18nFilter.setLanguageIds(I18nServlet.getLanguageIds());
581     }
582 
583     protected void destroyCompanies() throws Exception {
584         long[] companyIds = PortalInstances.getCompanyIds();
585 
586         for (int i = 0; i < companyIds.length; i++) {
587             destroyCompany(companyIds[i]);
588         }
589     }
590 
591     protected void destroyCompany(long companyId) {
592         if (_log.isDebugEnabled()) {
593             _log.debug("Process shutdown events");
594         }
595 
596         try {
597             EventsProcessorUtil.process(
598                 PropsKeys.APPLICATION_SHUTDOWN_EVENTS,
599                 PropsValues.APPLICATION_SHUTDOWN_EVENTS,
600                 new String[] {String.valueOf(companyId)});
601         }
602         catch (Exception e) {
603             _log.error(e, e);
604         }
605     }
606 
607     protected void destroyPortlets(List<Portlet> portlets) throws Exception {
608         Iterator<Portlet> itr = portlets.iterator();
609 
610         while (itr.hasNext()) {
611             Portlet portlet = itr.next();
612 
613             PortletInstanceFactoryUtil.destroy(portlet);
614         }
615     }
616 
617     protected void destroySchedulers(List<Portlet> portlets) throws Exception {
618         if (!PropsValues.SCHEDULER_ENABLED) {
619             return;
620         }
621 
622         for (Portlet portlet : portlets) {
623             if (!portlet.isActive()) {
624                 continue;
625             }
626 
627             List<SchedulerEntry> schedulerEntries =
628                 portlet.getSchedulerEntries();
629 
630             if ((schedulerEntries == null) || schedulerEntries.isEmpty()) {
631                 continue;
632             }
633 
634             for (SchedulerEntry schedulerEntry : schedulerEntries) {
635                 SchedulerEngineUtil.unschedule(schedulerEntry);
636             }
637         }
638     }
639 
640     protected HttpServletRequest encryptRequest(
641         HttpServletRequest request, long companyId) {
642 
643         boolean encryptRequest = ParamUtil.getBoolean(request, WebKeys.ENCRYPT);
644 
645         if (!encryptRequest) {
646             return request;
647         }
648 
649         try {
650             Company company = CompanyLocalServiceUtil.getCompanyById(
651                 companyId);
652 
653             request = new EncryptedServletRequest(
654                 request, company.getKeyObj());
655         }
656         catch (Exception e) {
657         }
658 
659         return request;
660     }
661 
662     protected long getCompanyId(HttpServletRequest request) {
663         return PortalInstances.getCompanyId(request);
664     }
665 
666     protected String getRemoteUser(
667         HttpServletRequest request, long userId) {
668 
669         String remoteUser = request.getRemoteUser();
670 
671         if (!PropsValues.PORTAL_JAAS_ENABLE) {
672             HttpSession session = request.getSession();
673 
674             String jRemoteUser = (String)session.getAttribute("j_remoteuser");
675 
676             if (jRemoteUser != null) {
677                 remoteUser = jRemoteUser;
678 
679                 session.removeAttribute("j_remoteuser");
680             }
681         }
682 
683         if ((userId > 0) && (remoteUser == null)) {
684             remoteUser = String.valueOf(userId);
685         }
686 
687         return remoteUser;
688     }
689 
690     protected synchronized RequestProcessor getRequestProcessor(
691             ModuleConfig moduleConfig)
692         throws ServletException {
693 
694         ServletContext servletContext = getServletContext();
695 
696         String key = Globals.REQUEST_PROCESSOR_KEY + moduleConfig.getPrefix();
697 
698         RequestProcessor processor =
699             (RequestProcessor)servletContext.getAttribute(key);
700 
701         if (processor == null) {
702             ControllerConfig controllerConfig =
703                 moduleConfig.getControllerConfig();
704 
705             String processorClass = controllerConfig.getProcessorClass();
706 
707             ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
708 
709             try {
710                 processor = (RequestProcessor)classLoader.loadClass(
711                     processorClass).newInstance();
712             }
713             catch (Exception e) {
714                 throw new ServletException(e);
715             }
716 
717             processor.init(this, moduleConfig);
718 
719             servletContext.setAttribute(key, processor);
720         }
721 
722         return processor;
723     }
724 
725     protected long getUserId(HttpServletRequest request) {
726         return PortalUtil.getUserId(request);
727     }
728 
729     protected boolean hasAbsoluteRedirect(HttpServletRequest request) {
730         if (request.getAttribute(
731                 AbsoluteRedirectsResponse.class.getName()) == null) {
732 
733             return false;
734         }
735         else {
736             return true;
737         }
738     }
739 
740     protected boolean hasThemeDisplay(HttpServletRequest request) {
741         if (request.getAttribute(WebKeys.THEME_DISPLAY) == null) {
742             return false;
743         }
744         else {
745             return true;
746         }
747     }
748 
749     protected void initCompanies() throws Exception {
750         ServletContext servletContext = getServletContext();
751 
752         String[] webIds = PortalInstances.getWebIds();
753 
754         for (int i = 0; i < webIds.length; i++) {
755             PortalInstances.initCompany(servletContext, webIds[i]);
756         }
757     }
758 
759     protected void initExt() throws Exception {
760         ServletContext servletContext = getServletContext();
761 
762         ExtRegistry.registerPortal(servletContext);
763     }
764 
765     protected void initLayoutTemplates(
766             PluginPackage pluginPackage, List<Portlet> portlets)
767         throws Exception {
768 
769         ServletContext servletContext = getServletContext();
770 
771         String[] xmls = new String[] {
772             HttpUtil.URLtoString(
773                 servletContext.getResource(
774                     "/WEB-INF/liferay-layout-templates.xml")),
775             HttpUtil.URLtoString(
776                 servletContext.getResource(
777                     "/WEB-INF/liferay-layout-templates-ext.xml"))
778         };
779 
780         LayoutTemplateLocalServiceUtil.init(
781             servletContext, xmls, pluginPackage);
782     }
783 
784     protected PluginPackage initPluginPackage() throws Exception {
785         ServletContext servletContext = getServletContext();
786 
787         IndexerRegistryUtil.register(new PluginPackageIndexer());
788 
789         return PluginPackageHotDeployListener.readPluginPackage(servletContext);
790     }
791 
792     protected void initPlugins() throws Exception {
793 
794         // See LEP-2885. Don't flush hot deploy events until after the portal
795         // has initialized.
796 
797         PortalInitableUtil.flushInitables();
798         HotDeployUtil.flushPrematureEvents();
799     }
800 
801     protected void initPortletApp(
802             Portlet portlet, ServletContext servletContext)
803         throws PortletException {
804 
805         PortletApp portletApp = portlet.getPortletApp();
806 
807         PortletConfig portletConfig = PortletConfigFactory.create(
808             portlet, servletContext);
809 
810         PortletContext portletContext = portletConfig.getPortletContext();
811 
812         Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
813 
814         for (PortletFilter portletFilter : portletFilters) {
815             PortletFilterFactory.create(portletFilter, portletContext);
816         }
817 
818         Set<PortletURLListener> portletURLListeners =
819             portletApp.getPortletURLListeners();
820 
821         for (PortletURLListener portletURLListener : portletURLListeners) {
822             PortletURLListenerFactory.create(portletURLListener);
823         }
824     }
825 
826     protected List<Portlet> initPortlets(PluginPackage pluginPackage)
827         throws Exception {
828 
829         ServletContext servletContext = getServletContext();
830 
831         String[] xmls = new String[] {
832             HttpUtil.URLtoString(
833                 servletContext.getResource(
834                     "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
835             HttpUtil.URLtoString(
836                 servletContext.getResource("/WEB-INF/portlet-ext.xml")),
837             HttpUtil.URLtoString(
838                 servletContext.getResource("/WEB-INF/liferay-portlet.xml")),
839             HttpUtil.URLtoString(
840                 servletContext.getResource("/WEB-INF/liferay-portlet-ext.xml")),
841             HttpUtil.URLtoString(
842                 servletContext.getResource("/WEB-INF/web.xml"))
843         };
844 
845         PortletLocalServiceUtil.initEAR(servletContext, xmls, pluginPackage);
846 
847         PortletBagFactory portletBagFactory = new PortletBagFactory();
848 
849         portletBagFactory.setClassLoader(
850             PortalClassLoaderUtil.getClassLoader());
851         portletBagFactory.setServletContext(servletContext);
852         portletBagFactory.setWARFile(false);
853 
854         List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
855 
856         for (int i = 0; i < portlets.size(); i++) {
857             Portlet portlet = portlets.get(i);
858 
859             portletBagFactory.create(portlet);
860 
861             if (i == 0) {
862                 initPortletApp(portlet, servletContext);
863             }
864         }
865 
866         return portlets;
867     }
868 
869     protected void initResourceActions(List<Portlet> portlets)
870         throws Exception {
871 
872         Iterator<Portlet> itr = portlets.iterator();
873 
874         while (itr.hasNext()) {
875             Portlet portlet = itr.next();
876 
877             List<String> portletActions =
878                 ResourceActionsUtil.getPortletResourceActions(
879                     portlet.getPortletId());
880 
881             ResourceActionLocalServiceUtil.checkResourceActions(
882                 portlet.getPortletId(), portletActions);
883 
884             List<String> modelNames =
885                 ResourceActionsUtil.getPortletModelResources(
886                     portlet.getPortletId());
887 
888             for (String modelName : modelNames) {
889                 List<String> modelActions =
890                     ResourceActionsUtil.getModelResourceActions(modelName);
891 
892                 ResourceActionLocalServiceUtil.checkResourceActions(
893                     modelName, modelActions);
894             }
895         }
896     }
897 
898     protected void initResourceCodes(List<Portlet> portlets) throws Exception {
899         long[] companyIds = PortalInstances.getCompanyIdsBySQL();
900 
901         Iterator<Portlet> itr = portlets.iterator();
902 
903         while (itr.hasNext()) {
904             Portlet portlet = itr.next();
905 
906             List<String> modelNames =
907                 ResourceActionsUtil.getPortletModelResources(
908                     portlet.getPortletId());
909 
910             for (long companyId : companyIds) {
911                 ResourceCodeLocalServiceUtil.checkResourceCodes(
912                     companyId, portlet.getPortletId());
913 
914                 for (String modelName : modelNames) {
915                     ResourceCodeLocalServiceUtil.checkResourceCodes(
916                         companyId, modelName);
917                 }
918             }
919         }
920     }
921 
922     protected void initServletContextPool() throws Exception {
923         ServletContext servletContext = getServletContext();
924 
925         String contextPath = PortalUtil.getPathContext();
926 
927         ServletContextPool.put(contextPath, servletContext);
928     }
929 
930     protected void initSocialEquityLogScheduler() throws Exception {
931         SchedulerEntry schedulerEntry = new SchedulerEntryImpl();
932 
933         schedulerEntry.setEventListenerClass(
934             CheckEquityLogMessageListener.class.getName());
935         schedulerEntry.setTimeUnit(TimeUnit.MINUTE);
936         schedulerEntry.setTriggerType(TriggerType.SIMPLE);
937         schedulerEntry.setTriggerValue(
938             PropsValues.SOCIAL_EQUITY_EQUITY_LOG_CHECK_INTERVAL);
939 
940         SchedulerEngineUtil.schedule(
941             schedulerEntry, PortalClassLoaderUtil.getClassLoader());
942     }
943 
944     protected void initThemes(
945             PluginPackage pluginPackage, List<Portlet> portlets)
946         throws Exception {
947 
948         ServletContext servletContext = getServletContext();
949 
950         String[] xmls = new String[] {
951             HttpUtil.URLtoString(
952                 servletContext.getResource(
953                     "/WEB-INF/liferay-look-and-feel.xml")),
954             HttpUtil.URLtoString(
955                 servletContext.getResource(
956                     "/WEB-INF/liferay-look-and-feel-ext.xml"))
957         };
958 
959         ThemeLocalServiceUtil.init(
960             servletContext, null, true, xmls, pluginPackage);
961     }
962 
963     protected void initWebSettings() throws Exception {
964         ServletContext servletContext = getServletContext();
965 
966         String xml = HttpUtil.URLtoString(
967             servletContext.getResource("/WEB-INF/web.xml"));
968 
969         checkWebSettings(xml);
970     }
971 
972     protected long loginUser(
973             HttpServletRequest request, HttpServletResponse response,
974             long userId, String remoteUser)
975         throws PortalException, SystemException {
976 
977         if ((userId > 0) || (remoteUser == null)) {
978             return userId;
979         }
980 
981         userId = GetterUtil.getLong(remoteUser);
982 
983         EventsProcessorUtil.process(
984             PropsKeys.LOGIN_EVENTS_PRE, PropsValues.LOGIN_EVENTS_PRE, request,
985             response);
986 
987         User user = UserLocalServiceUtil.getUserById(userId);
988 
989         if (PropsValues.USERS_UPDATE_LAST_LOGIN) {
990             UserLocalServiceUtil.updateLastLogin(
991                 userId, request.getRemoteAddr());
992         }
993 
994         HttpSession session = request.getSession();
995 
996         session.setAttribute(WebKeys.USER_ID, new Long(userId));
997         session.setAttribute(Globals.LOCALE_KEY, user.getLocale());
998 
999         EventsProcessorUtil.process(
1000            PropsKeys.LOGIN_EVENTS_POST, PropsValues.LOGIN_EVENTS_POST,
1001            request, response);
1002
1003        return userId;
1004    }
1005
1006    protected void processGlobalShutdownEvents() throws Exception {
1007        EventsProcessorUtil.process(
1008            PropsKeys.GLOBAL_SHUTDOWN_EVENTS,
1009            PropsValues.GLOBAL_SHUTDOWN_EVENTS);
1010
1011        super.destroy();
1012    }
1013
1014    protected void processGlobalStartupEvents() throws Exception {
1015        EventsProcessorUtil.process(
1016            PropsKeys.GLOBAL_STARTUP_EVENTS, PropsValues.GLOBAL_STARTUP_EVENTS);
1017    }
1018
1019    protected boolean processMaintenanceRequest(
1020            HttpServletRequest request, HttpServletResponse response)
1021        throws IOException, ServletException {
1022
1023        if (!MaintenanceUtil.isMaintaining()) {
1024            return false;
1025        }
1026
1027        RequestDispatcher requestDispatcher = request.getRequestDispatcher(
1028            "/html/portal/maintenance.jsp");
1029
1030        requestDispatcher.include(request, response);
1031
1032        return true;
1033    }
1034
1035    protected void processServicePost(
1036        HttpServletRequest request, HttpServletResponse response) {
1037
1038        try {
1039            EventsProcessorUtil.process(
1040                PropsKeys.SERVLET_SERVICE_EVENTS_POST,
1041                PropsValues.SERVLET_SERVICE_EVENTS_POST, request, response);
1042        }
1043        catch (Exception e) {
1044            _log.error(e, e);
1045        }
1046
1047        response.addHeader(
1048            _LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
1049
1050        ThreadLocalCacheManager.clearAll(Lifecycle.REQUEST);
1051    }
1052
1053    protected boolean processServicePre(
1054            HttpServletRequest request, HttpServletResponse response,
1055            long userId)
1056        throws IOException, ServletException {
1057
1058        try {
1059            EventsProcessorUtil.process(
1060                PropsKeys.SERVLET_SERVICE_EVENTS_PRE,
1061                PropsValues.SERVLET_SERVICE_EVENTS_PRE, request, response);
1062        }
1063        catch (Exception e) {
1064            Throwable cause = e.getCause();
1065
1066            if (cause instanceof NoSuchLayoutException) {
1067                sendError(
1068                    HttpServletResponse.SC_NOT_FOUND, cause, request, response);
1069
1070                return true;
1071            }
1072            else if (cause instanceof PrincipalException) {
1073                processServicePrePrincipalException(
1074                    cause, userId, request, response);
1075
1076                return true;
1077            }
1078
1079            _log.error(e, e);
1080
1081            request.setAttribute(PageContext.EXCEPTION, e);
1082
1083            ServletContext servletContext = getServletContext();
1084
1085            StrutsUtil.forward(
1086                PropsValues.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE,
1087                servletContext, request, response);
1088
1089            return true;
1090        }
1091
1092        return false;
1093    }
1094
1095    protected void processServicePrePrincipalException(
1096            Throwable t, long userId, HttpServletRequest request,
1097            HttpServletResponse response)
1098        throws IOException, ServletException {
1099
1100        if (userId > 0) {
1101            sendError(
1102                HttpServletResponse.SC_UNAUTHORIZED, t, request, response);
1103
1104            return;
1105        }
1106
1107        String redirect =
1108            request.getContextPath() + Portal.PATH_MAIN + "/portal/login";
1109
1110        String currentURL = PortalUtil.getCurrentURL(request);
1111
1112        redirect = HttpUtil.addParameter(redirect, "redirect", currentURL);
1113
1114        long plid = ParamUtil.getLong(request, "p_l_id");
1115
1116        if (plid > 0) {
1117            try {
1118                Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1119
1120                if (layout.getGroup().isStagingGroup()) {
1121                    Group group = GroupLocalServiceUtil.getGroup(
1122                        layout.getCompanyId(), GroupConstants.GUEST);
1123
1124                    plid = group.getDefaultPublicPlid();
1125                }
1126                else if (layout.isPrivateLayout()) {
1127                    plid = LayoutLocalServiceUtil.getDefaultPlid(
1128                        layout.getGroupId(), false);
1129                }
1130
1131                redirect = HttpUtil.addParameter(redirect, "p_l_id", plid);
1132            }
1133            catch (Exception e) {
1134            }
1135        }
1136
1137        response.sendRedirect(redirect);
1138    }
1139
1140    protected boolean processShutdownRequest(
1141            HttpServletRequest request, HttpServletResponse response)
1142        throws IOException {
1143
1144        if (!ShutdownUtil.isShutdown()) {
1145            return false;
1146        }
1147
1148        response.setContentType(ContentTypes.TEXT_HTML_UTF8);
1149
1150        String html = ContentUtil.get(
1151            "com/liferay/portal/dependencies/shutdown.html");
1152
1153        response.getOutputStream().print(html);
1154
1155        return true;
1156    }
1157
1158    protected void processStartupEvents() throws Exception {
1159        StartupAction startupAction = new StartupAction();
1160
1161        startupAction.run(null);
1162    }
1163
1164    protected HttpServletRequest protectRequest(
1165        HttpServletRequest request, String remoteUser) {
1166
1167        // WebSphere will not return the remote user unless you are
1168        // authenticated AND accessing a protected path. Other servers will
1169        // return the remote user for all threads associated with an
1170        // authenticated user. We use ProtectedServletRequest to ensure we get
1171        // similar behavior across all servers.
1172
1173        return new ProtectedServletRequest(request, remoteUser);
1174    }
1175
1176    protected void sendError(
1177            int status, Throwable t, HttpServletRequest request,
1178            HttpServletResponse response)
1179        throws IOException, ServletException {
1180
1181        DynamicServletRequest dynamicRequest = new DynamicServletRequest(
1182            request);
1183
1184        // Reset p_l_id or there will be an infinite loop
1185
1186        dynamicRequest.setParameter("p_l_id", StringPool.BLANK);
1187
1188        PortalUtil.sendError(status, (Exception)t, dynamicRequest, response);
1189    }
1190
1191    protected void setPortalPort(HttpServletRequest request) {
1192        PortalUtil.setPortalPort(request);
1193    }
1194
1195    protected void setPrincipalName(long userId, String remoteUser) {
1196        if ((userId == 0) && (remoteUser == null)) {
1197            return;
1198        }
1199
1200        String name = String.valueOf(userId);
1201
1202        if (remoteUser != null) {
1203            name = remoteUser;
1204        }
1205
1206        PrincipalThreadLocal.setName(name);
1207    }
1208
1209    private static final String _LIFERAY_PORTAL_REQUEST_HEADER =
1210        "Liferay-Portal";
1211
1212    private static Log _log = LogFactoryUtil.getLog(MainServlet.class);
1213
1214}