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.deploy.hot.HotDeployUtil;
22  import com.liferay.portal.kernel.exception.PortalException;
23  import com.liferay.portal.kernel.exception.SystemException;
24  import com.liferay.portal.kernel.log.Log;
25  import com.liferay.portal.kernel.log.LogFactoryUtil;
26  import com.liferay.portal.kernel.plugin.PluginPackage;
27  import com.liferay.portal.kernel.poller.PollerProcessor;
28  import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
29  import com.liferay.portal.kernel.scheduler.SchedulerEntry;
30  import com.liferay.portal.kernel.search.Indexer;
31  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
32  import com.liferay.portal.kernel.servlet.PortletSessionTracker;
33  import com.liferay.portal.kernel.servlet.ProtectedServletRequest;
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.PortalInitableUtil;
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.workflow.WorkflowHandler;
46  import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
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.kernel.xmlrpc.Method;
52  import com.liferay.portal.language.LanguageResources;
53  import com.liferay.portal.model.Company;
54  import com.liferay.portal.model.Group;
55  import com.liferay.portal.model.GroupConstants;
56  import com.liferay.portal.model.Layout;
57  import com.liferay.portal.model.Portlet;
58  import com.liferay.portal.model.PortletApp;
59  import com.liferay.portal.model.PortletFilter;
60  import com.liferay.portal.model.PortletURLListener;
61  import com.liferay.portal.model.User;
62  import com.liferay.portal.plugin.PluginPackageIndexer;
63  import com.liferay.portal.poller.PollerProcessorUtil;
64  import com.liferay.portal.pop.POPServerUtil;
65  import com.liferay.portal.security.auth.PrincipalException;
66  import com.liferay.portal.security.auth.PrincipalThreadLocal;
67  import com.liferay.portal.security.permission.ResourceActionsUtil;
68  import com.liferay.portal.service.CompanyLocalServiceUtil;
69  import com.liferay.portal.service.GroupLocalServiceUtil;
70  import com.liferay.portal.service.LayoutLocalServiceUtil;
71  import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
72  import com.liferay.portal.service.PortletLocalServiceUtil;
73  import com.liferay.portal.service.ResourceActionLocalServiceUtil;
74  import com.liferay.portal.service.ResourceCodeLocalServiceUtil;
75  import com.liferay.portal.service.ThemeLocalServiceUtil;
76  import com.liferay.portal.service.UserLocalServiceUtil;
77  import com.liferay.portal.servlet.filters.i18n.I18nFilter;
78  import com.liferay.portal.struts.MultiMessageResources;
79  import com.liferay.portal.struts.PortletRequestProcessor;
80  import com.liferay.portal.struts.StrutsUtil;
81  import com.liferay.portal.util.ContentUtil;
82  import com.liferay.portal.util.ExtRegistry;
83  import com.liferay.portal.util.MaintenanceUtil;
84  import com.liferay.portal.util.Portal;
85  import com.liferay.portal.util.PortalInstances;
86  import com.liferay.portal.util.PortalUtil;
87  import com.liferay.portal.util.PropsUtil;
88  import com.liferay.portal.util.PropsValues;
89  import com.liferay.portal.util.ShutdownUtil;
90  import com.liferay.portal.util.WebKeys;
91  import com.liferay.portal.velocity.VelocityContextPool;
92  import com.liferay.portal.webdav.WebDAVStorage;
93  import com.liferay.portal.webdav.WebDAVUtil;
94  import com.liferay.portal.xmlrpc.XmlRpcServlet;
95  import com.liferay.portlet.PortletConfigFactory;
96  import com.liferay.portlet.PortletFilterFactory;
97  import com.liferay.portlet.PortletInstanceFactoryUtil;
98  import com.liferay.portlet.PortletURLListenerFactory;
99  import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
100 import com.liferay.portlet.asset.model.AssetRendererFactory;
101 import com.liferay.portlet.social.model.SocialActivityInterpreter;
102 import com.liferay.portlet.social.model.SocialRequestInterpreter;
103 import com.liferay.portlet.social.model.impl.SocialActivityInterpreterImpl;
104 import com.liferay.portlet.social.model.impl.SocialRequestInterpreterImpl;
105 import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
106 import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
107 import com.liferay.util.servlet.DynamicServletRequest;
108 import com.liferay.util.servlet.EncryptedServletRequest;
109 
110 import java.io.IOException;
111 
112 import java.util.Iterator;
113 import java.util.List;
114 import java.util.Set;
115 
116 import javax.portlet.PortletConfig;
117 import javax.portlet.PortletContext;
118 import javax.portlet.PortletException;
119 
120 import javax.servlet.RequestDispatcher;
121 import javax.servlet.ServletContext;
122 import javax.servlet.ServletException;
123 import javax.servlet.http.HttpServletRequest;
124 import javax.servlet.http.HttpServletResponse;
125 import javax.servlet.http.HttpSession;
126 import javax.servlet.jsp.PageContext;
127 
128 import org.apache.struts.Globals;
129 import org.apache.struts.action.ActionServlet;
130 import org.apache.struts.action.RequestProcessor;
131 import org.apache.struts.config.ControllerConfig;
132 import org.apache.struts.config.ModuleConfig;
133 import org.apache.struts.tiles.TilesUtilImpl;
134 
135 /**
136  * <a href="MainServlet.java.html"><b><i>View Source</i></b></a>
137  *
138  * @author Brian Wing Shun Chan
139  * @author Jorge Ferrer
140  * @author Brian Myunghun Kim
141  */
142 public class MainServlet extends ActionServlet {
143 
144     public void destroy() {
145         List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
146 
147         if (_log.isDebugEnabled()) {
148             _log.debug("Destroy schedulers");
149         }
150 
151         try {
152             destroySchedulers(portlets);
153         }
154         catch (Exception e) {
155             _log.error(e, e);
156         }
157 
158         if (_log.isDebugEnabled()) {
159             _log.debug("Destroy portlets");
160         }
161 
162         try {
163             destroyPortlets(portlets);
164         }
165         catch (Exception e) {
166             _log.error(e, e);
167         }
168 
169         if (_log.isDebugEnabled()) {
170             _log.debug("Destroy companies");
171         }
172 
173         try {
174             destroyCompanies();
175         }
176         catch (Exception e) {
177             _log.error(e, e);
178         }
179 
180         if (_log.isDebugEnabled()) {
181             _log.debug("Process global shutdown events");
182         }
183 
184         try {
185             processGlobalShutdownEvents();
186         }
187         catch (Exception e) {
188             _log.error(e, e);
189         }
190 
191         if (_log.isDebugEnabled()) {
192             _log.debug("Destroy");
193         }
194 
195         callParentDestroy();
196     }
197 
198     public void init() throws ServletException {
199         if (_log.isDebugEnabled()) {
200             _log.debug("Initialize");
201         }
202 
203         callParentInit();
204 
205         if (_log.isDebugEnabled()) {
206             _log.debug("Process startup events");
207         }
208 
209         try {
210             processStartupEvents();
211         }
212         catch (Exception e) {
213             _log.error(e, e);
214 
215             System.out.println(
216                 "Stopping the server due to unexpected startup errors");
217 
218             System.exit(0);
219         }
220 
221         if (_log.isDebugEnabled()) {
222             _log.debug("Initialize velocity");
223         }
224 
225         try {
226             initVelocity();
227         }
228         catch (Exception e) {
229             _log.error(e, e);
230         }
231 
232         if (_log.isDebugEnabled()) {
233             _log.debug("Initialize plugin package");
234         }
235 
236         PluginPackage pluginPackage = null;
237 
238         try {
239             pluginPackage = initPluginPackage();
240         }
241         catch (Exception e) {
242             _log.error(e, e);
243         }
244 
245         if (_log.isDebugEnabled()) {
246             _log.debug("Initialize portlets");
247         }
248 
249         List<Portlet> portlets = null;
250 
251         try {
252             portlets = initPortlets(pluginPackage);
253         }
254         catch (Exception e) {
255             _log.error(e, e);
256         }
257 
258         if (_log.isDebugEnabled()) {
259             _log.debug("Initialize layout templates");
260         }
261 
262         try {
263             initLayoutTemplates(pluginPackage, portlets);
264         }
265         catch (Exception e) {
266             _log.error(e, e);
267         }
268 
269         if (_log.isDebugEnabled()) {
270             _log.debug("Initialize themes");
271         }
272 
273         try {
274             initThemes(pluginPackage, portlets);
275         }
276         catch (Exception e) {
277             _log.error(e, e);
278         }
279 
280         if (_log.isDebugEnabled()) {
281             _log.debug("Initialize indexers");
282         }
283 
284         try {
285             initIndexers(portlets);
286         }
287         catch (Exception e) {
288             _log.error(e, e);
289         }
290 
291         if (_log.isDebugEnabled()) {
292             _log.debug("Initialize schedulers");
293         }
294 
295         try {
296             initSchedulers(portlets);
297         }
298         catch (Exception e) {
299             _log.error(e, e);
300         }
301 
302         if (_log.isDebugEnabled()) {
303             _log.debug("Initialize poller processors");
304         }
305 
306         try {
307             initPollerProcessors(portlets);
308         }
309         catch (Exception e) {
310             _log.error(e, e);
311         }
312 
313         if (_log.isDebugEnabled()) {
314             _log.debug("Initialize POP message listeners");
315         }
316 
317         try {
318             initPOPMessageListeners(portlets);
319         }
320         catch (Exception e) {
321             _log.error(e, e);
322         }
323 
324         if (_log.isDebugEnabled()) {
325             _log.debug("Initialize social activity interpreters");
326         }
327 
328         try {
329             initSocialActivityInterpreters(portlets);
330         }
331         catch (Exception e) {
332             _log.error(e, e);
333         }
334 
335         if (_log.isDebugEnabled()) {
336             _log.debug("Initialize social request interpreters");
337         }
338 
339         try {
340             initSocialRequestInterpreters(portlets);
341         }
342         catch (Exception e) {
343             _log.error(e, e);
344         }
345 
346         if (_log.isDebugEnabled()) {
347             _log.debug("Initialize WebDAV storages");
348         }
349 
350         try {
351             initWebDAVStorages(portlets);
352         }
353         catch (Exception e) {
354             _log.error(e, e);
355         }
356 
357         if (_log.isDebugEnabled()) {
358             _log.debug("Initialize XML-RPC methods");
359         }
360 
361         try {
362             initXmlRpcMethods(portlets);
363         }
364         catch (Exception e) {
365             _log.error(e, e);
366         }
367 
368         if (_log.isDebugEnabled()) {
369             _log.debug("Initialize asset renderer factories");
370         }
371 
372         try {
373             initAssetRendererFactories(portlets);
374         }
375         catch (Exception e) {
376             _log.error(e, e);
377         }
378 
379         if (_log.isDebugEnabled()) {
380             _log.debug("Initialize workflow handlers");
381         }
382 
383         try {
384             initWorkflowHandlers(portlets);
385         }
386         catch (Exception e) {
387             _log.error(e, e);
388         }
389 
390         if (_log.isDebugEnabled()) {
391             _log.debug("Initialize web settings");
392         }
393 
394         try {
395             initWebSettings();
396         }
397         catch (Exception e) {
398             _log.error(e, e);
399         }
400 
401         if (_log.isDebugEnabled()) {
402             _log.debug("Initialize extension environment");
403         }
404 
405         try {
406             initExt();
407         }
408         catch (Exception e) {
409             _log.error(e, e);
410         }
411 
412         if (_log.isDebugEnabled()) {
413             _log.debug("Process global startup events");
414         }
415 
416         try {
417             processGlobalStartupEvents();
418         }
419         catch (Exception e) {
420             _log.error(e, e);
421         }
422 
423         if (_log.isDebugEnabled()) {
424             _log.debug("Initialize resource actions");
425         }
426 
427         try {
428             initResourceActions(portlets);
429         }
430         catch (Exception e) {
431             _log.error(e, e);
432         }
433 
434         if (_log.isDebugEnabled()) {
435             _log.debug("Initialize resource codes");
436         }
437 
438         try {
439             initResourceCodes(portlets);
440         }
441         catch (Exception e) {
442             _log.error(e, e);
443         }
444 
445         if (_log.isDebugEnabled()) {
446             _log.debug("Initialize companies");
447         }
448 
449         try {
450             initCompanies();
451         }
452         catch (Exception e) {
453             _log.error(e, e);
454         }
455 
456         if (_log.isDebugEnabled()) {
457             _log.debug("Initialize message resources");
458         }
459 
460         try {
461             initMessageResources();
462         }
463         catch (Exception e) {
464             _log.error(e, e);
465         }
466 
467         if (_log.isDebugEnabled()) {
468             _log.debug("Initialize plugins");
469         }
470 
471         try {
472             initPlugins();
473         }
474         catch (Exception e) {
475             _log.error(e, e);
476         }
477     }
478 
479     public void service(
480             HttpServletRequest request, HttpServletResponse response)
481         throws IOException, ServletException {
482 
483         if (_log.isDebugEnabled()) {
484             _log.debug("Process service request");
485         }
486 
487         if (processShutdownRequest(request, response)) {
488             if (_log.isDebugEnabled()) {
489                 _log.debug("Processed shutdown request");
490             }
491 
492             return;
493         }
494 
495         if (processMaintenanceRequest(request, response)) {
496             if (_log.isDebugEnabled()) {
497                 _log.debug("Processed maintenance request");
498             }
499 
500             return;
501         }
502 
503         if (_log.isDebugEnabled()) {
504             _log.debug("Get company id");
505         }
506 
507         long companyId = getCompanyId(request);
508 
509         if (_log.isDebugEnabled()) {
510             _log.debug("Set portal port");
511         }
512 
513         setPortalPort(request);
514 
515         if (_log.isDebugEnabled()) {
516             _log.debug("Check variables");
517         }
518 
519         checkServletContext(request);
520         checkPortletSessionTracker(request);
521         checkPortletRequestProcessor(request);
522         checkTilesDefinitionsFactory();
523 
524         if (_log.isDebugEnabled()) {
525             _log.debug("Encrypt request");
526         }
527 
528         request = encryptRequest(request, companyId);
529 
530         long userId = getUserId(request);
531         String remoteUser = getRemoteUser(request, userId);
532 
533         if (_log.isDebugEnabled()) {
534             _log.debug("Protect request");
535         }
536 
537         request = protectRequest(request, remoteUser);
538 
539         if (_log.isDebugEnabled()) {
540             _log.debug("Set principal");
541         }
542 
543         setPrincipalName(userId, remoteUser);
544 
545         try {
546             if (_log.isDebugEnabled()) {
547                 _log.debug(
548                 "Authenticate user id " + userId + " and remote user " +
549                     remoteUser);
550             }
551 
552             userId = loginUser(request, response, userId, remoteUser);
553 
554             if (_log.isDebugEnabled()) {
555                 _log.debug("Authenticated user id " + userId);
556             }
557         }
558         catch (Exception e) {
559             _log.error(e, e);
560         }
561 
562         if (_log.isDebugEnabled()) {
563             _log.debug("Process service pre events");
564         }
565 
566         if (processServicePre(request, response, userId)) {
567             if (_log.isDebugEnabled()) {
568                 _log.debug("Processing service pre events has errors");
569             }
570 
571             return;
572         }
573 
574         if (hasAbsoluteRedirect(request)) {
575             if (_log.isDebugEnabled()) {
576                 String currentURL = PortalUtil.getCurrentURL(request);
577 
578                 _log.debug(
579                     "Current URL " + currentURL + " has absolute redirect");
580             }
581 
582             return;
583         }
584 
585         if (!hasThemeDisplay(request)) {
586             if (_log.isDebugEnabled()) {
587                 String currentURL = PortalUtil.getCurrentURL(request);
588 
589                 _log.debug(
590                     "Current URL " + currentURL +
591                         " does not have a theme display");
592             }
593 
594             return;
595         }
596 
597         try {
598             if (_log.isDebugEnabled()) {
599                 _log.debug("Call parent service");
600             }
601 
602             callParentService(request, response);
603         }
604         finally {
605             if (_log.isDebugEnabled()) {
606                 _log.debug("Process service post events");
607             }
608 
609             processServicePost(request, response);
610         }
611     }
612 
613     protected void callParentDestroy() {
614         super.destroy();
615     }
616 
617     protected void callParentInit() throws ServletException {
618         super.init();
619     }
620 
621     protected void callParentService(
622             HttpServletRequest request, HttpServletResponse response)
623         throws IOException, ServletException {
624 
625         super.service(request, response);
626     }
627 
628     protected void checkPortletRequestProcessor(HttpServletRequest request)
629         throws ServletException {
630 
631         ServletContext servletContext = getServletContext();
632 
633         PortletRequestProcessor portletReqProcessor =
634             (PortletRequestProcessor)servletContext.getAttribute(
635                 WebKeys.PORTLET_STRUTS_PROCESSOR);
636 
637         if (portletReqProcessor == null) {
638             ModuleConfig moduleConfig = getModuleConfig(request);
639 
640             portletReqProcessor =
641                 PortletRequestProcessor.getInstance(this, moduleConfig);
642 
643             servletContext.setAttribute(
644                 WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
645         }
646     }
647 
648     protected void checkPortletSessionTracker(HttpServletRequest request) {
649         HttpSession session = request.getSession();
650 
651         if (session.getAttribute(WebKeys.PORTLET_SESSION_TRACKER) != null) {
652             return;
653         }
654 
655         session.setAttribute(
656             WebKeys.PORTLET_SESSION_TRACKER,
657             PortletSessionTracker.getInstance());
658     }
659 
660     protected void checkServletContext(HttpServletRequest request) {
661         ServletContext servletContext = getServletContext();
662 
663         request.setAttribute(WebKeys.CTX, servletContext);
664     }
665 
666     protected void checkTilesDefinitionsFactory() {
667         ServletContext servletContext = getServletContext();
668 
669         if (servletContext.getAttribute(
670                 TilesUtilImpl.DEFINITIONS_FACTORY) != null) {
671 
672             return;
673         }
674 
675         servletContext.setAttribute(
676             TilesUtilImpl.DEFINITIONS_FACTORY,
677             servletContext.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
678     }
679 
680     protected void checkWebSettings(String xml) throws DocumentException {
681         Document doc = SAXReaderUtil.read(xml);
682 
683         Element root = doc.getRootElement();
684 
685         int timeout = PropsValues.SESSION_TIMEOUT;
686 
687         Element sessionConfig = root.element("session-config");
688 
689         if (sessionConfig != null) {
690             String sessionTimeout = sessionConfig.elementText(
691                 "session-timeout");
692 
693             timeout = GetterUtil.getInteger(sessionTimeout, timeout);
694         }
695 
696         PropsUtil.set(PropsKeys.SESSION_TIMEOUT, String.valueOf(timeout));
697 
698         PropsValues.SESSION_TIMEOUT = timeout;
699 
700         I18nServlet.setLanguageIds(root);
701         I18nFilter.setLanguageIds(I18nServlet.getLanguageIds());
702     }
703 
704     protected void destroyCompanies() throws Exception {
705         long[] companyIds = PortalInstances.getCompanyIds();
706 
707         for (int i = 0; i < companyIds.length; i++) {
708             destroyCompany(companyIds[i]);
709         }
710     }
711 
712     protected void destroyCompany(long companyId) {
713         if (_log.isDebugEnabled()) {
714             _log.debug("Process shutdown events");
715         }
716 
717         try {
718             EventsProcessorUtil.process(
719                 PropsKeys.APPLICATION_SHUTDOWN_EVENTS,
720                 PropsValues.APPLICATION_SHUTDOWN_EVENTS,
721                 new String[] {String.valueOf(companyId)});
722         }
723         catch (Exception e) {
724             _log.error(e, e);
725         }
726     }
727 
728     protected void destroyPortlets(List<Portlet> portlets) throws Exception {
729         Iterator<Portlet> itr = portlets.iterator();
730 
731         while (itr.hasNext()) {
732             Portlet portlet = itr.next();
733 
734             PortletInstanceFactoryUtil.destroy(portlet);
735         }
736     }
737 
738     protected void destroySchedulers(List<Portlet> portlets) throws Exception {
739         if (!PropsValues.SCHEDULER_ENABLED) {
740             return;
741         }
742 
743         for (Portlet portlet : portlets) {
744             if (!portlet.isActive()) {
745                 continue;
746             }
747 
748             List<SchedulerEntry> schedulerEntries =
749                 portlet.getSchedulerEntries();
750 
751             if ((schedulerEntries == null) || schedulerEntries.isEmpty()) {
752                 continue;
753             }
754 
755             for (SchedulerEntry schedulerEntry : schedulerEntries) {
756                 SchedulerEngineUtil.unschedule(schedulerEntry);
757             }
758         }
759     }
760 
761     protected HttpServletRequest encryptRequest(
762         HttpServletRequest request, long companyId) {
763 
764         boolean encryptRequest = ParamUtil.getBoolean(request, WebKeys.ENCRYPT);
765 
766         if (!encryptRequest) {
767             return request;
768         }
769 
770         try {
771             Company company = CompanyLocalServiceUtil.getCompanyById(
772                 companyId);
773 
774             request = new EncryptedServletRequest(
775                 request, company.getKeyObj());
776         }
777         catch (Exception e) {
778         }
779 
780         return request;
781     }
782 
783     protected long getCompanyId(HttpServletRequest request) {
784         return PortalInstances.getCompanyId(request);
785     }
786 
787     protected String getRemoteUser(
788         HttpServletRequest request, long userId) {
789 
790         String remoteUser = request.getRemoteUser();
791 
792         if (!PropsValues.PORTAL_JAAS_ENABLE) {
793             HttpSession session = request.getSession();
794 
795             String jRemoteUser = (String)session.getAttribute("j_remoteuser");
796 
797             if (jRemoteUser != null) {
798                 remoteUser = jRemoteUser;
799 
800                 session.removeAttribute("j_remoteuser");
801             }
802         }
803 
804         if ((userId > 0) && (remoteUser == null)) {
805             remoteUser = String.valueOf(userId);
806         }
807 
808         return remoteUser;
809     }
810 
811     protected synchronized RequestProcessor getRequestProcessor(
812             ModuleConfig moduleConfig)
813         throws ServletException {
814 
815         ServletContext servletContext = getServletContext();
816 
817         String key = Globals.REQUEST_PROCESSOR_KEY + moduleConfig.getPrefix();
818 
819         RequestProcessor processor =
820             (RequestProcessor)servletContext.getAttribute(key);
821 
822         if (processor == null) {
823             ControllerConfig controllerConfig =
824                 moduleConfig.getControllerConfig();
825 
826             String processorClass = controllerConfig.getProcessorClass();
827 
828             ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
829 
830             try {
831                 processor = (RequestProcessor)classLoader.loadClass(
832                     processorClass).newInstance();
833             }
834             catch (Exception e) {
835                 throw new ServletException(e);
836             }
837 
838             processor.init(this, moduleConfig);
839 
840             servletContext.setAttribute(key, processor);
841         }
842 
843         return processor;
844     }
845 
846     protected long getUserId(HttpServletRequest request) {
847         return PortalUtil.getUserId(request);
848     }
849 
850     protected boolean hasAbsoluteRedirect(HttpServletRequest request) {
851         if (request.getAttribute(
852                 AbsoluteRedirectsResponse.class.getName()) == null) {
853 
854             return false;
855         }
856         else {
857             return true;
858         }
859     }
860 
861     protected boolean hasThemeDisplay(HttpServletRequest request) {
862         if (request.getAttribute(WebKeys.THEME_DISPLAY) == null) {
863             return false;
864         }
865         else {
866             return true;
867         }
868     }
869 
870     protected void initAssetRendererFactories(List<Portlet> portlets)
871         throws Exception {
872 
873         Iterator<Portlet> itr = portlets.iterator();
874 
875         while (itr.hasNext()) {
876             Portlet portlet = itr.next();
877 
878             List<AssetRendererFactory> assetRendererFactories =
879                 portlet.getAssetRendererFactoryInstances();
880 
881             if (assetRendererFactories == null) {
882                 continue;
883             }
884 
885             AssetRendererFactoryRegistryUtil.register(assetRendererFactories);
886         }
887     }
888 
889     protected void initCompanies() throws Exception {
890         ServletContext servletContext = getServletContext();
891 
892         String[] webIds = PortalInstances.getWebIds();
893 
894         for (int i = 0; i < webIds.length; i++) {
895             PortalInstances.initCompany(servletContext, webIds[i]);
896         }
897     }
898 
899     protected void initExt() throws Exception {
900         ServletContext servletContext = getServletContext();
901 
902         ExtRegistry.registerPortal(servletContext);
903     }
904 
905     protected void initIndexers(List<Portlet> portlets) throws Exception {
906         IndexerRegistryUtil.register(new PluginPackageIndexer());
907 
908         Iterator<Portlet> itr = portlets.iterator();
909 
910         while (itr.hasNext()) {
911             Portlet portlet = itr.next();
912 
913             String indexerClass = portlet.getIndexerClass();
914 
915             if (!portlet.isActive() || Validator.isNull(indexerClass)) {
916                 continue;
917             }
918 
919             Indexer indexer = (Indexer)InstancePool.get(indexerClass);
920 
921             IndexerRegistryUtil.register(indexer);
922         }
923     }
924 
925     protected void initLayoutTemplates(
926             PluginPackage pluginPackage, List<Portlet> portlets)
927         throws Exception {
928 
929         ServletContext servletContext = getServletContext();
930 
931         String[] xmls = new String[] {
932             HttpUtil.URLtoString(
933                 servletContext.getResource(
934                     "/WEB-INF/liferay-layout-templates.xml")),
935             HttpUtil.URLtoString(
936                 servletContext.getResource(
937                     "/WEB-INF/liferay-layout-templates-ext.xml"))
938         };
939 
940         LayoutTemplateLocalServiceUtil.init(
941             servletContext, xmls, pluginPackage);
942     }
943 
944     protected void initMessageResources() throws Exception {
945         ServletContext servletContext = getServletContext();
946 
947         MultiMessageResources messageResources =
948             (MultiMessageResources)servletContext.getAttribute(
949                 Globals.MESSAGES_KEY);
950 
951         LanguageResources.init(messageResources);
952     }
953 
954     protected PluginPackage initPluginPackage() throws Exception {
955         ServletContext servletContext = getServletContext();
956 
957         return PluginPackageHotDeployListener.readPluginPackage(servletContext);
958     }
959 
960     protected void initPlugins() throws Exception {
961 
962         // See LEP-2885. Don't flush hot deploy events until after the portal
963         // has initialized.
964 
965         PortalInitableUtil.flushInitables();
966         HotDeployUtil.flushPrematureEvents();
967     }
968 
969     protected void initPollerProcessors(List<Portlet> portlets)
970         throws Exception {
971 
972         Iterator<Portlet> itr = portlets.iterator();
973 
974         while (itr.hasNext()) {
975             Portlet portlet = itr.next();
976 
977             PollerProcessor pollerProcessor =
978                 portlet.getPollerProcessorInstance();
979 
980             if (!portlet.isActive() || (pollerProcessor == null)) {
981                 continue;
982             }
983 
984             PollerProcessorUtil.addPollerProcessor(
985                 portlet.getPortletId(), pollerProcessor);
986         }
987     }
988 
989     protected void initPOPMessageListeners(List<Portlet> portlets)
990         throws Exception {
991 
992         Iterator<Portlet> itr = portlets.iterator();
993 
994         while (itr.hasNext()) {
995             Portlet portlet = itr.next();
996 
997             com.liferay.portal.kernel.pop.MessageListener popMessageListener =
998                 portlet.getPopMessageListenerInstance();
999 
1000            if (!portlet.isActive() || (popMessageListener == null)) {
1001                continue;
1002            }
1003
1004            POPServerUtil.addListener(popMessageListener);
1005        }
1006    }
1007
1008    protected void initPortletApp(
1009            Portlet portlet, ServletContext servletContext)
1010        throws PortletException {
1011
1012        PortletApp portletApp = portlet.getPortletApp();
1013
1014        PortletConfig portletConfig = PortletConfigFactory.create(
1015            portlet, servletContext);
1016
1017        PortletContext portletContext = portletConfig.getPortletContext();
1018
1019        Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
1020
1021        for (PortletFilter portletFilter : portletFilters) {
1022            PortletFilterFactory.create(portletFilter, portletContext);
1023        }
1024
1025        Set<PortletURLListener> portletURLListeners =
1026            portletApp.getPortletURLListeners();
1027
1028        for (PortletURLListener portletURLListener : portletURLListeners) {
1029            PortletURLListenerFactory.create(portletURLListener);
1030        }
1031    }
1032
1033    protected List<Portlet> initPortlets(PluginPackage pluginPackage)
1034        throws Exception {
1035
1036        ServletContext servletContext = getServletContext();
1037
1038        String[] xmls = new String[] {
1039            HttpUtil.URLtoString(
1040                servletContext.getResource(
1041                    "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
1042            HttpUtil.URLtoString(
1043                servletContext.getResource("/WEB-INF/portlet-ext.xml")),
1044            HttpUtil.URLtoString(
1045                servletContext.getResource("/WEB-INF/liferay-portlet.xml")),
1046            HttpUtil.URLtoString(
1047                servletContext.getResource("/WEB-INF/liferay-portlet-ext.xml")),
1048            HttpUtil.URLtoString(
1049                servletContext.getResource("/WEB-INF/web.xml"))
1050        };
1051
1052        PortletLocalServiceUtil.initEAR(servletContext, xmls, pluginPackage);
1053
1054        List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
1055
1056        for (int i = 0; i < portlets.size(); i++) {
1057            Portlet portlet = portlets.get(i);
1058
1059            if (i == 0) {
1060                initPortletApp(portlet, servletContext);
1061            }
1062
1063            PortletInstanceFactoryUtil.create(portlet, servletContext);
1064        }
1065
1066        return portlets;
1067    }
1068
1069    protected void initResourceActions(List<Portlet> portlets)
1070        throws Exception {
1071
1072        Iterator<Portlet> itr = portlets.iterator();
1073
1074        while (itr.hasNext()) {
1075            Portlet portlet = itr.next();
1076
1077            List<String> portletActions =
1078                ResourceActionsUtil.getPortletResourceActions(
1079                    portlet.getPortletId());
1080
1081            ResourceActionLocalServiceUtil.checkResourceActions(
1082                portlet.getPortletId(), portletActions);
1083
1084            List<String> modelNames =
1085                ResourceActionsUtil.getPortletModelResources(
1086                    portlet.getPortletId());
1087
1088            for (String modelName : modelNames) {
1089                List<String> modelActions =
1090                    ResourceActionsUtil.getModelResourceActions(modelName);
1091
1092                ResourceActionLocalServiceUtil.checkResourceActions(
1093                    modelName, modelActions);
1094            }
1095        }
1096    }
1097
1098    protected void initResourceCodes(List<Portlet> portlets) throws Exception {
1099        long[] companyIds = PortalInstances.getCompanyIdsBySQL();
1100
1101        Iterator<Portlet> itr = portlets.iterator();
1102
1103        while (itr.hasNext()) {
1104            Portlet portlet = itr.next();
1105
1106            List<String> modelNames =
1107                ResourceActionsUtil.getPortletModelResources(
1108                    portlet.getPortletId());
1109
1110            for (long companyId : companyIds) {
1111                ResourceCodeLocalServiceUtil.checkResourceCodes(
1112                    companyId, portlet.getPortletId());
1113
1114                for (String modelName : modelNames) {
1115                    ResourceCodeLocalServiceUtil.checkResourceCodes(
1116                        companyId, modelName);
1117                }
1118            }
1119        }
1120    }
1121
1122    protected void initSchedulers(List<Portlet> portlets) throws Exception {
1123        if (!PropsValues.SCHEDULER_ENABLED) {
1124            return;
1125        }
1126
1127        for (Portlet portlet : portlets) {
1128            if (!portlet.isActive()) {
1129                continue;
1130            }
1131
1132            List<SchedulerEntry> schedulerEntries =
1133                portlet.getSchedulerEntries();
1134
1135            if ((schedulerEntries == null) || schedulerEntries.isEmpty()) {
1136                continue;
1137            }
1138
1139            for (SchedulerEntry schedulerEntry : schedulerEntries) {
1140                SchedulerEngineUtil.schedule(
1141                    schedulerEntry, PortalClassLoaderUtil.getClassLoader());
1142            }
1143        }
1144    }
1145
1146    protected void initSocialActivityInterpreters(List<Portlet> portlets)
1147        throws Exception {
1148
1149        Iterator<Portlet> itr = portlets.iterator();
1150
1151        while (itr.hasNext()) {
1152            Portlet portlet = itr.next();
1153
1154            SocialActivityInterpreter socialActivityInterpreter =
1155                portlet.getSocialActivityInterpreterInstance();
1156
1157            if (!portlet.isActive() ||
1158                (socialActivityInterpreter == null)) {
1159
1160                continue;
1161            }
1162
1163            socialActivityInterpreter = new SocialActivityInterpreterImpl(
1164                portlet.getPortletId(), socialActivityInterpreter);
1165
1166            SocialActivityInterpreterLocalServiceUtil.addActivityInterpreter(
1167                socialActivityInterpreter);
1168        }
1169    }
1170
1171    protected void initSocialRequestInterpreters(List<Portlet> portlets)
1172        throws Exception {
1173
1174        Iterator<Portlet> itr = portlets.iterator();
1175
1176        while (itr.hasNext()) {
1177            Portlet portlet = itr.next();
1178
1179            SocialRequestInterpreter socialRequestInterpreter =
1180                portlet.getSocialRequestInterpreterInstance();
1181
1182            if (!portlet.isActive() || (socialRequestInterpreter == null)) {
1183                continue;
1184            }
1185
1186            socialRequestInterpreter = new SocialRequestInterpreterImpl(
1187                portlet.getPortletId(), socialRequestInterpreter);
1188
1189            SocialRequestInterpreterLocalServiceUtil.addRequestInterpreter(
1190                socialRequestInterpreter);
1191        }
1192    }
1193
1194    protected void initThemes(
1195            PluginPackage pluginPackage, List<Portlet> portlets)
1196        throws Exception {
1197
1198        ServletContext servletContext = getServletContext();
1199
1200        String[] xmls = new String[] {
1201            HttpUtil.URLtoString(
1202                servletContext.getResource(
1203                    "/WEB-INF/liferay-look-and-feel.xml")),
1204            HttpUtil.URLtoString(
1205                servletContext.getResource(
1206                    "/WEB-INF/liferay-look-and-feel-ext.xml"))
1207        };
1208
1209        ThemeLocalServiceUtil.init(
1210            servletContext, null, true, xmls, pluginPackage);
1211    }
1212
1213    protected void initVelocity() throws Exception {
1214        ServletContext servletContext = getServletContext();
1215
1216        String contextPath = PortalUtil.getPathContext();
1217
1218        VelocityContextPool.put(contextPath, servletContext);
1219    }
1220
1221    protected void initWebDAVStorages(List<Portlet> portlets) throws Exception {
1222        Iterator<Portlet> itr = portlets.iterator();
1223
1224        while (itr.hasNext()) {
1225            Portlet portlet = itr.next();
1226
1227            WebDAVStorage webDAVStorage = portlet.getWebDAVStorageInstance();
1228
1229            if (!portlet.isActive() || (webDAVStorage == null)) {
1230                continue;
1231            }
1232
1233            webDAVStorage.setToken(portlet.getWebDAVStorageToken());
1234
1235            WebDAVUtil.addStorage(webDAVStorage);
1236        }
1237    }
1238
1239    protected void initWebSettings() throws Exception {
1240        ServletContext servletContext = getServletContext();
1241
1242        String xml = HttpUtil.URLtoString(
1243            servletContext.getResource("/WEB-INF/web.xml"));
1244
1245        checkWebSettings(xml);
1246    }
1247
1248    protected void initWorkflowHandlers(List<Portlet> portlets)
1249        throws Exception {
1250
1251        Iterator<Portlet> itr = portlets.iterator();
1252
1253        while (itr.hasNext()) {
1254            Portlet portlet = itr.next();
1255
1256            List<WorkflowHandler> workflowHandlers =
1257                portlet.getWorkflowHandlerInstances();
1258
1259            if (workflowHandlers == null) {
1260                continue;
1261            }
1262
1263            WorkflowHandlerRegistryUtil.register(workflowHandlers);
1264        }
1265    }
1266
1267    protected void initXmlRpcMethods(List<Portlet> portlets) throws Exception {
1268        Iterator<Portlet> itr = portlets.iterator();
1269
1270        while (itr.hasNext()) {
1271            Portlet portlet = itr.next();
1272
1273            Method method = portlet.getXmlRpcMethodInstance();
1274
1275            if (!portlet.isActive() || (method == null)) {
1276                continue;
1277            }
1278
1279            XmlRpcServlet.registerMethod(method);
1280        }
1281    }
1282
1283    protected long loginUser(
1284            HttpServletRequest request, HttpServletResponse response,
1285            long userId, String remoteUser)
1286        throws PortalException, SystemException {
1287
1288        if ((userId > 0) || (remoteUser == null)) {
1289            return userId;
1290        }
1291
1292        userId = GetterUtil.getLong(remoteUser);
1293
1294        EventsProcessorUtil.process(
1295            PropsKeys.LOGIN_EVENTS_PRE, PropsValues.LOGIN_EVENTS_PRE, request,
1296            response);
1297
1298        User user = UserLocalServiceUtil.getUserById(userId);
1299
1300        if (PropsValues.USERS_UPDATE_LAST_LOGIN) {
1301            UserLocalServiceUtil.updateLastLogin(
1302                userId, request.getRemoteAddr());
1303        }
1304
1305        HttpSession session = request.getSession();
1306
1307        session.setAttribute(WebKeys.USER_ID, new Long(userId));
1308        session.setAttribute(Globals.LOCALE_KEY, user.getLocale());
1309
1310        EventsProcessorUtil.process(
1311            PropsKeys.LOGIN_EVENTS_POST, PropsValues.LOGIN_EVENTS_POST,
1312            request, response);
1313
1314        return userId;
1315    }
1316
1317    protected void processGlobalShutdownEvents() throws Exception {
1318        EventsProcessorUtil.process(
1319            PropsKeys.GLOBAL_SHUTDOWN_EVENTS,
1320            PropsValues.GLOBAL_SHUTDOWN_EVENTS);
1321
1322        super.destroy();
1323    }
1324
1325    protected void processGlobalStartupEvents() throws Exception {
1326        EventsProcessorUtil.process(
1327            PropsKeys.GLOBAL_STARTUP_EVENTS, PropsValues.GLOBAL_STARTUP_EVENTS);
1328    }
1329
1330    protected boolean processMaintenanceRequest(
1331            HttpServletRequest request, HttpServletResponse response)
1332        throws IOException, ServletException {
1333
1334        if (!MaintenanceUtil.isMaintaining()) {
1335            return false;
1336        }
1337
1338        RequestDispatcher requestDispatcher = request.getRequestDispatcher(
1339            "/html/portal/maintenance.jsp");
1340
1341        requestDispatcher.include(request, response);
1342
1343        return true;
1344    }
1345
1346    protected void processServicePost(
1347        HttpServletRequest request, HttpServletResponse response) {
1348
1349        try {
1350            EventsProcessorUtil.process(
1351                PropsKeys.SERVLET_SERVICE_EVENTS_POST,
1352                PropsValues.SERVLET_SERVICE_EVENTS_POST, request, response);
1353        }
1354        catch (Exception e) {
1355            _log.error(e, e);
1356        }
1357
1358        response.addHeader(
1359            _LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
1360    }
1361
1362    protected boolean processServicePre(
1363            HttpServletRequest request, HttpServletResponse response,
1364            long userId)
1365        throws IOException, ServletException {
1366
1367        try {
1368            EventsProcessorUtil.process(
1369                PropsKeys.SERVLET_SERVICE_EVENTS_PRE,
1370                PropsValues.SERVLET_SERVICE_EVENTS_PRE, request, response);
1371        }
1372        catch (Exception e) {
1373            Throwable cause = e.getCause();
1374
1375            if (cause instanceof NoSuchLayoutException) {
1376                sendError(
1377                    HttpServletResponse.SC_NOT_FOUND, cause, request, response);
1378
1379                return true;
1380            }
1381            else if (cause instanceof PrincipalException) {
1382                processServicePrePrincipalException(
1383                    cause, userId, request, response);
1384
1385                return true;
1386            }
1387
1388            _log.error(e, e);
1389
1390            request.setAttribute(PageContext.EXCEPTION, e);
1391
1392            ServletContext servletContext = getServletContext();
1393
1394            StrutsUtil.forward(
1395                PropsValues.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE,
1396                servletContext, request, response);
1397
1398            return true;
1399        }
1400
1401        return false;
1402    }
1403
1404    protected void processServicePrePrincipalException(
1405            Throwable t, long userId, HttpServletRequest request,
1406            HttpServletResponse response)
1407        throws IOException, ServletException {
1408
1409        if (userId > 0) {
1410            sendError(
1411                HttpServletResponse.SC_UNAUTHORIZED, t, request, response);
1412
1413            return;
1414        }
1415
1416        String redirect =
1417            request.getContextPath() + Portal.PATH_MAIN + "/portal/login";
1418
1419        String currentURL = PortalUtil.getCurrentURL(request);
1420
1421        redirect = HttpUtil.addParameter(redirect, "redirect", currentURL);
1422
1423        long plid = ParamUtil.getLong(request, "p_l_id");
1424
1425        if (plid > 0) {
1426            try {
1427                Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1428
1429                if (layout.getGroup().isStagingGroup()) {
1430                    Group group = GroupLocalServiceUtil.getGroup(
1431                        layout.getCompanyId(), GroupConstants.GUEST);
1432
1433                    plid = group.getDefaultPublicPlid();
1434                }
1435                else if (layout.isPrivateLayout()) {
1436                    plid = LayoutLocalServiceUtil.getDefaultPlid(
1437                        layout.getGroupId(), false);
1438                }
1439
1440                redirect = HttpUtil.addParameter(redirect, "p_l_id", plid);
1441            }
1442            catch (Exception e) {
1443            }
1444        }
1445
1446        response.sendRedirect(redirect);
1447    }
1448
1449    protected boolean processShutdownRequest(
1450            HttpServletRequest request, HttpServletResponse response)
1451        throws IOException {
1452
1453        if (!ShutdownUtil.isShutdown()) {
1454            return false;
1455        }
1456
1457        response.setContentType(ContentTypes.TEXT_HTML_UTF8);
1458
1459        String html = ContentUtil.get(
1460            "com/liferay/portal/dependencies/shutdown.html");
1461
1462        response.getOutputStream().print(html);
1463
1464        return true;
1465    }
1466
1467    protected void processStartupEvents() throws Exception {
1468        StartupAction startupAction = new StartupAction();
1469
1470        startupAction.run(null);
1471    }
1472
1473    protected HttpServletRequest protectRequest(
1474        HttpServletRequest request, String remoteUser) {
1475
1476        // WebSphere will not return the remote user unless you are
1477        // authenticated AND accessing a protected path. Other servers will
1478        // return the remote user for all threads associated with an
1479        // authenticated user. We use ProtectedServletRequest to ensure we get
1480        // similar behavior across all servers.
1481
1482        return new ProtectedServletRequest(request, remoteUser);
1483    }
1484
1485    protected void sendError(
1486            int status, Throwable t, HttpServletRequest request,
1487            HttpServletResponse response)
1488        throws IOException, ServletException {
1489
1490        DynamicServletRequest dynamicRequest = new DynamicServletRequest(
1491            request);
1492
1493        // Reset p_l_id or there will be an infinite loop
1494
1495        dynamicRequest.setParameter("p_l_id", StringPool.BLANK);
1496
1497        PortalUtil.sendError(status, (Exception)t, dynamicRequest, response);
1498    }
1499
1500    protected void setPortalPort(HttpServletRequest request) {
1501        PortalUtil.setPortalPort(request);
1502    }
1503
1504    protected void setPrincipalName(long userId, String remoteUser) {
1505        if ((userId == 0) && (remoteUser == null)) {
1506            return;
1507        }
1508
1509        String name = String.valueOf(userId);
1510
1511        if (remoteUser != null) {
1512            name = remoteUser;
1513        }
1514
1515        PrincipalThreadLocal.setName(name);
1516    }
1517
1518    private static final String _LIFERAY_PORTAL_REQUEST_HEADER =
1519        "Liferay-Portal";
1520
1521    private static Log _log = LogFactoryUtil.getLog(MainServlet.class);
1522
1523}