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