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