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