001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.servlet;
016    
017    import com.liferay.portal.events.EventsProcessorUtil;
018    import com.liferay.portal.events.StartupAction;
019    import com.liferay.portal.events.StartupHelperUtil;
020    import com.liferay.portal.kernel.cache.thread.local.Lifecycle;
021    import com.liferay.portal.kernel.cache.thread.local.ThreadLocalCacheManager;
022    import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
023    import com.liferay.portal.kernel.exception.NoSuchLayoutException;
024    import com.liferay.portal.kernel.exception.PortalException;
025    import com.liferay.portal.kernel.language.LanguageUtil;
026    import com.liferay.portal.kernel.log.Log;
027    import com.liferay.portal.kernel.log.LogFactoryUtil;
028    import com.liferay.portal.kernel.model.Company;
029    import com.liferay.portal.kernel.model.Group;
030    import com.liferay.portal.kernel.model.GroupConstants;
031    import com.liferay.portal.kernel.model.Layout;
032    import com.liferay.portal.kernel.model.LayoutConstants;
033    import com.liferay.portal.kernel.model.LayoutTemplate;
034    import com.liferay.portal.kernel.model.Portlet;
035    import com.liferay.portal.kernel.model.PortletApp;
036    import com.liferay.portal.kernel.model.PortletFilter;
037    import com.liferay.portal.kernel.model.PortletURLListener;
038    import com.liferay.portal.kernel.model.Theme;
039    import com.liferay.portal.kernel.model.User;
040    import com.liferay.portal.kernel.module.framework.ModuleServiceLifecycle;
041    import com.liferay.portal.kernel.patcher.PatchInconsistencyException;
042    import com.liferay.portal.kernel.patcher.PatcherUtil;
043    import com.liferay.portal.kernel.plugin.PluginPackage;
044    import com.liferay.portal.kernel.portlet.PortletConfigFactoryUtil;
045    import com.liferay.portal.kernel.portlet.PortletInstanceFactoryUtil;
046    import com.liferay.portal.kernel.security.auth.CompanyThreadLocal;
047    import com.liferay.portal.kernel.security.auth.PrincipalException;
048    import com.liferay.portal.kernel.security.permission.ResourceActionsUtil;
049    import com.liferay.portal.kernel.service.CompanyLocalServiceUtil;
050    import com.liferay.portal.kernel.service.GroupLocalServiceUtil;
051    import com.liferay.portal.kernel.service.LayoutLocalServiceUtil;
052    import com.liferay.portal.kernel.service.LayoutTemplateLocalServiceUtil;
053    import com.liferay.portal.kernel.service.PortletLocalServiceUtil;
054    import com.liferay.portal.kernel.service.ResourceActionLocalServiceUtil;
055    import com.liferay.portal.kernel.service.ThemeLocalServiceUtil;
056    import com.liferay.portal.kernel.service.UserLocalServiceUtil;
057    import com.liferay.portal.kernel.servlet.DynamicServletRequest;
058    import com.liferay.portal.kernel.servlet.PortalSessionThreadLocal;
059    import com.liferay.portal.kernel.template.TemplateConstants;
060    import com.liferay.portal.kernel.template.TemplateManager;
061    import com.liferay.portal.kernel.util.ClassLoaderUtil;
062    import com.liferay.portal.kernel.util.ContentTypes;
063    import com.liferay.portal.kernel.util.GetterUtil;
064    import com.liferay.portal.kernel.util.HtmlUtil;
065    import com.liferay.portal.kernel.util.HttpUtil;
066    import com.liferay.portal.kernel.util.InstanceFactory;
067    import com.liferay.portal.kernel.util.ParamUtil;
068    import com.liferay.portal.kernel.util.PortalLifecycleUtil;
069    import com.liferay.portal.kernel.util.PortalUtil;
070    import com.liferay.portal.kernel.util.PropsKeys;
071    import com.liferay.portal.kernel.util.ReleaseInfo;
072    import com.liferay.portal.kernel.util.StringPool;
073    import com.liferay.portal.kernel.util.StringUtil;
074    import com.liferay.portal.kernel.util.Validator;
075    import com.liferay.portal.kernel.util.WebKeys;
076    import com.liferay.portal.kernel.xml.Document;
077    import com.liferay.portal.kernel.xml.DocumentException;
078    import com.liferay.portal.kernel.xml.Element;
079    import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
080    import com.liferay.portal.plugin.PluginPackageUtil;
081    import com.liferay.portal.servlet.filters.absoluteredirects.AbsoluteRedirectsResponse;
082    import com.liferay.portal.servlet.filters.i18n.I18nFilter;
083    import com.liferay.portal.setup.SetupWizardSampleDataUtil;
084    import com.liferay.portal.struts.PortletRequestProcessor;
085    import com.liferay.portal.struts.StrutsUtil;
086    import com.liferay.portal.util.ExtRegistry;
087    import com.liferay.portal.util.MaintenanceUtil;
088    import com.liferay.portal.util.PortalInstances;
089    import com.liferay.portal.util.PropsUtil;
090    import com.liferay.portal.util.PropsValues;
091    import com.liferay.portal.util.ShutdownUtil;
092    import com.liferay.portlet.PortletBagFactory;
093    import com.liferay.portlet.PortletFilterFactory;
094    import com.liferay.portlet.PortletURLListenerFactory;
095    import com.liferay.registry.Filter;
096    import com.liferay.registry.Registry;
097    import com.liferay.registry.RegistryUtil;
098    import com.liferay.registry.ServiceRegistration;
099    import com.liferay.registry.dependency.ServiceDependencyListener;
100    import com.liferay.registry.dependency.ServiceDependencyManager;
101    import com.liferay.social.kernel.util.SocialConfigurationUtil;
102    import com.liferay.util.ContentUtil;
103    import com.liferay.util.servlet.EncryptedServletRequest;
104    
105    import java.io.IOException;
106    import java.io.PrintWriter;
107    
108    import java.util.ArrayList;
109    import java.util.HashMap;
110    import java.util.List;
111    import java.util.Locale;
112    import java.util.Map;
113    import java.util.Set;
114    
115    import javax.portlet.PortletConfig;
116    import javax.portlet.PortletContext;
117    import javax.portlet.PortletException;
118    
119    import javax.servlet.RequestDispatcher;
120    import javax.servlet.ServletContext;
121    import javax.servlet.ServletException;
122    import javax.servlet.http.HttpServletRequest;
123    import javax.servlet.http.HttpServletResponse;
124    import javax.servlet.http.HttpSession;
125    import javax.servlet.jsp.PageContext;
126    
127    import org.apache.struts.Globals;
128    import org.apache.struts.action.ActionServlet;
129    import org.apache.struts.action.RequestProcessor;
130    import org.apache.struts.config.ControllerConfig;
131    import org.apache.struts.config.ModuleConfig;
132    import org.apache.struts.tiles.TilesUtilImpl;
133    
134    /**
135     * @author Brian Wing Shun Chan
136     * @author Jorge Ferrer
137     * @author Brian Myunghun Kim
138     */
139    public class MainServlet extends ActionServlet {
140    
141            @Override
142            public void destroy() {
143                    if (_log.isDebugEnabled()) {
144                            _log.debug("Destroy plugins");
145                    }
146    
147                    _moduleServiceLifecycleServiceRegistration.unregister();
148                    _servletContextServiceRegistration.unregister();
149    
150                    PortalLifecycleUtil.flushDestroys();
151    
152                    List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
153    
154                    if (_log.isDebugEnabled()) {
155                            _log.debug("Destroy portlets");
156                    }
157    
158                    try {
159                            destroyPortlets(portlets);
160                    }
161                    catch (Exception e) {
162                            _log.error(e, e);
163                    }
164    
165                    if (_log.isDebugEnabled()) {
166                            _log.debug("Destroy companies");
167                    }
168    
169                    try {
170                            destroyCompanies();
171                    }
172                    catch (Exception e) {
173                            _log.error(e, e);
174                    }
175    
176                    if (_log.isDebugEnabled()) {
177                            _log.debug("Process global shutdown events");
178                    }
179    
180                    try {
181                            processGlobalShutdownEvents();
182                    }
183                    catch (Exception e) {
184                            _log.error(e, e);
185                    }
186    
187                    if (_log.isDebugEnabled()) {
188                            _log.debug("Destroy");
189                    }
190    
191                    callParentDestroy();
192            }
193    
194            @Override
195            public void init() throws ServletException {
196                    if (_log.isDebugEnabled()) {
197                            _log.debug("Initialize");
198                    }
199    
200                    ServletContext servletContext = getServletContext();
201    
202                    servletContext.setAttribute(MainServlet.class.getName(), Boolean.TRUE);
203    
204                    callParentInit();
205    
206                    if (_log.isDebugEnabled()) {
207                            _log.debug("Verify patch levels");
208                    }
209    
210                    try {
211                            PatcherUtil.verifyPatchLevels();
212                    }
213                    catch (PatchInconsistencyException pie) {
214                            if (!PropsValues.VERIFY_PATCH_LEVELS_DISABLED) {
215                                    _log.error(
216                                            "Stopping the server due to the inconsistent patch levels");
217    
218                                    if (_log.isWarnEnabled()) {
219                                            _log.warn(
220                                                    "Set the property \"verify.patch.levels.disabled\" " +
221                                                            "to override stopping the server due to the " +
222                                                                    "inconsistent patch levels");
223                                    }
224    
225                                    System.exit(0);
226                            }
227                    }
228    
229                    if (_log.isDebugEnabled()) {
230                            _log.debug("Process startup events");
231                    }
232    
233                    try {
234                            processStartupEvents();
235                    }
236                    catch (Exception e) {
237                            _log.error(e, e);
238    
239                            System.out.println(
240                                    "Stopping the server due to unexpected startup errors");
241    
242                            System.exit(0);
243                    }
244    
245                    if (_log.isDebugEnabled()) {
246                            _log.debug("Initialize server detector");
247                    }
248    
249                    try {
250                            initServerDetector();
251                    }
252                    catch (Exception e) {
253                            _log.error(e, e);
254                    }
255    
256                    if (_log.isDebugEnabled()) {
257                            _log.debug("Initialize plugin package");
258                    }
259    
260                    PluginPackage pluginPackage = null;
261    
262                    try {
263                            pluginPackage = initPluginPackage();
264                    }
265                    catch (Exception e) {
266                            _log.error(e, e);
267                    }
268    
269                    if (_log.isDebugEnabled()) {
270                            _log.debug("Initialize portlets");
271                    }
272    
273                    List<Portlet> portlets = new ArrayList<>();
274    
275                    try {
276                            portlets.addAll(initPortlets(pluginPackage));
277                    }
278                    catch (Exception e) {
279                            _log.error(e, e);
280                    }
281    
282                    try {
283                            initLayoutTemplates(pluginPackage);
284                    }
285                    catch (Exception e) {
286                            _log.error(e, e);
287                    }
288    
289                    if (_log.isDebugEnabled()) {
290                            _log.debug("Initialize social");
291                    }
292    
293                    try {
294                            initSocial(pluginPackage);
295                    }
296                    catch (Exception e) {
297                            _log.error(e, e);
298                    }
299    
300                    if (_log.isDebugEnabled()) {
301                            _log.debug("Initialize themes");
302                    }
303    
304                    try {
305                            initThemes(pluginPackage, portlets);
306                    }
307                    catch (Exception e) {
308                            _log.error(e, e);
309                    }
310    
311                    if (_log.isDebugEnabled()) {
312                            _log.debug("Initialize web settings");
313                    }
314    
315                    try {
316                            initWebSettings();
317                    }
318                    catch (Exception e) {
319                            _log.error(e, e);
320                    }
321    
322                    if (_log.isDebugEnabled()) {
323                            _log.debug("Initialize extension environment");
324                    }
325    
326                    try {
327                            initExt();
328                    }
329                    catch (Exception e) {
330                            _log.error(e, e);
331                    }
332    
333                    if (_log.isDebugEnabled()) {
334                            _log.debug("Process global startup events");
335                    }
336    
337                    try {
338                            processGlobalStartupEvents();
339                    }
340                    catch (Exception e) {
341                            _log.error(e, e);
342                    }
343    
344                    if (_log.isDebugEnabled()) {
345                            _log.debug("Initialize resource actions");
346                    }
347    
348                    try {
349                            initResourceActions(portlets);
350                    }
351                    catch (Exception e) {
352                            _log.error(e, e);
353                    }
354    
355                    try {
356                            initCompanies();
357                    }
358                    catch (Exception e) {
359                            _log.error(e, e);
360                    }
361    
362                    if (StartupHelperUtil.isDBNew() &&
363                            PropsValues.SETUP_WIZARD_ADD_SAMPLE_DATA) {
364    
365                            try {
366                                    SetupWizardSampleDataUtil.addSampleData(
367                                            PortalInstances.getDefaultCompanyId());
368                            }
369                            catch (Exception e) {
370                                    _log.error(e, e);
371                            }
372                    }
373    
374                    if (_log.isDebugEnabled()) {
375                            _log.debug("Initialize plugins");
376                    }
377    
378                    try {
379                            initPlugins();
380                    }
381                    catch (Exception e) {
382                            _log.error(e, e);
383                    }
384    
385                    servletContext.setAttribute(WebKeys.STARTUP_FINISHED, true);
386    
387                    StartupHelperUtil.setStartupFinished(true);
388    
389                    registerPortalInitialized();
390    
391                    ThreadLocalCacheManager.clearAll(Lifecycle.REQUEST);
392            }
393    
394            @Override
395            public void service(
396                            HttpServletRequest request, HttpServletResponse response)
397                    throws IOException, ServletException {
398    
399                    if (_log.isDebugEnabled()) {
400                            _log.debug("Process service request");
401                    }
402    
403                    if (processShutdownRequest(request, response)) {
404                            if (_log.isDebugEnabled()) {
405                                    _log.debug("Processed shutdown request");
406                            }
407    
408                            return;
409                    }
410    
411                    if (processMaintenanceRequest(request, response)) {
412                            if (_log.isDebugEnabled()) {
413                                    _log.debug("Processed maintenance request");
414                            }
415    
416                            return;
417                    }
418    
419                    if (_log.isDebugEnabled()) {
420                            _log.debug("Get company id");
421                    }
422    
423                    long companyId = getCompanyId(request);
424    
425                    if (processCompanyInactiveRequest(request, response, companyId)) {
426                            if (_log.isDebugEnabled()) {
427                                    _log.debug("Processed company inactive request");
428                            }
429    
430                            return;
431                    }
432    
433                    try {
434                            if (processGroupInactiveRequest(request, response)) {
435                                    if (_log.isDebugEnabled()) {
436                                            _log.debug("Processed site inactive request");
437                                    }
438    
439                                    return;
440                            }
441                    }
442                    catch (Exception e) {
443                            if (e instanceof NoSuchLayoutException) {
444                                    if (_log.isDebugEnabled()) {
445                                            _log.debug(e, e);
446                                    }
447                            }
448                            else {
449                                    _log.error(e, e);
450                            }
451                    }
452    
453                    if (_log.isDebugEnabled()) {
454                            _log.debug("Set portal port");
455                    }
456    
457                    setPortalInetSocketAddresses(request);
458    
459                    if (_log.isDebugEnabled()) {
460                            _log.debug("Check variables");
461                    }
462    
463                    checkServletContext(request);
464                    checkPortletRequestProcessor(request);
465                    checkTilesDefinitionsFactory();
466    
467                    if (_log.isDebugEnabled()) {
468                            _log.debug("Handle non-serializable request");
469                    }
470    
471                    if (_log.isDebugEnabled()) {
472                            _log.debug("Encrypt request");
473                    }
474    
475                    request = encryptRequest(request, companyId);
476    
477                    long userId = getUserId(request);
478    
479                    String remoteUser = getRemoteUser(request, userId);
480    
481                    try {
482                            if (_log.isDebugEnabled()) {
483                                    _log.debug(
484                                            "Authenticate user id " + userId + " and remote user " +
485                                                    remoteUser);
486                            }
487    
488                            userId = loginUser(
489                                    request, response, companyId, userId, remoteUser);
490    
491                            if (_log.isDebugEnabled()) {
492                                    _log.debug("Authenticated user id " + userId);
493                            }
494                    }
495                    catch (Exception e) {
496                            _log.error(e, e);
497                    }
498    
499                    if (_log.isDebugEnabled()) {
500                            _log.debug("Set session thread local");
501                    }
502    
503                    PortalSessionThreadLocal.setHttpSession(request.getSession());
504    
505                    if (_log.isDebugEnabled()) {
506                            _log.debug("Process service pre events");
507                    }
508    
509                    if (processServicePre(request, response, userId)) {
510                            if (_log.isDebugEnabled()) {
511                                    _log.debug("Processing service pre events has errors");
512                            }
513    
514                            return;
515                    }
516    
517                    if (hasAbsoluteRedirect(request)) {
518                            if (_log.isDebugEnabled()) {
519                                    String currentURL = PortalUtil.getCurrentURL(request);
520    
521                                    _log.debug(
522                                            "Current URL " + currentURL + " has absolute redirect");
523                            }
524    
525                            return;
526                    }
527    
528                    if (!hasThemeDisplay(request)) {
529                            if (_log.isDebugEnabled()) {
530                                    String currentURL = PortalUtil.getCurrentURL(request);
531    
532                                    _log.debug(
533                                            "Current URL " + currentURL +
534                                                    " does not have a theme display");
535                            }
536    
537                            return;
538                    }
539    
540                    try {
541                            if (_log.isDebugEnabled()) {
542                                    _log.debug("Call parent service");
543                            }
544    
545                            callParentService(request, response);
546                    }
547                    finally {
548                            if (_log.isDebugEnabled()) {
549                                    _log.debug("Process service post events");
550                            }
551    
552                            processServicePost(request, response);
553                    }
554            }
555    
556            protected void callParentDestroy() {
557                    super.destroy();
558            }
559    
560            protected void callParentInit() throws ServletException {
561                    super.init();
562            }
563    
564            protected void callParentService(
565                            HttpServletRequest request, HttpServletResponse response)
566                    throws IOException, ServletException {
567    
568                    super.service(request, response);
569            }
570    
571            protected void checkPortletRequestProcessor(HttpServletRequest request)
572                    throws ServletException {
573    
574                    ServletContext servletContext = getServletContext();
575    
576                    PortletRequestProcessor portletReqProcessor =
577                            (PortletRequestProcessor)servletContext.getAttribute(
578                                    WebKeys.PORTLET_STRUTS_PROCESSOR);
579    
580                    if (portletReqProcessor == null) {
581                            ModuleConfig moduleConfig = getModuleConfig(request);
582    
583                            portletReqProcessor = PortletRequestProcessor.getInstance(
584                                    this, moduleConfig);
585    
586                            servletContext.setAttribute(
587                                    WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
588                    }
589            }
590    
591            protected void checkServletContext(HttpServletRequest request) {
592                    ServletContext servletContext = getServletContext();
593    
594                    request.setAttribute(WebKeys.CTX, servletContext);
595    
596                    String contextPath = request.getContextPath();
597    
598                    servletContext.setAttribute(WebKeys.CTX_PATH, contextPath);
599            }
600    
601            protected void checkTilesDefinitionsFactory() {
602                    ServletContext servletContext = getServletContext();
603    
604                    if (servletContext.getAttribute(
605                                    TilesUtilImpl.DEFINITIONS_FACTORY) != null) {
606    
607                            return;
608                    }
609    
610                    servletContext.setAttribute(
611                            TilesUtilImpl.DEFINITIONS_FACTORY,
612                            servletContext.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
613            }
614    
615            protected void checkWebSettings(String xml) throws DocumentException {
616                    Document doc = UnsecureSAXReaderUtil.read(xml);
617    
618                    Element root = doc.getRootElement();
619    
620                    int timeout = PropsValues.SESSION_TIMEOUT;
621    
622                    Element sessionConfig = root.element("session-config");
623    
624                    if (sessionConfig != null) {
625                            String sessionTimeout = sessionConfig.elementText(
626                                    "session-timeout");
627    
628                            timeout = GetterUtil.getInteger(sessionTimeout, timeout);
629                    }
630    
631                    PropsUtil.set(PropsKeys.SESSION_TIMEOUT, String.valueOf(timeout));
632    
633                    PropsValues.SESSION_TIMEOUT = timeout;
634    
635                    I18nServlet.setLanguageIds(root);
636                    I18nFilter.setLanguageIds(I18nServlet.getLanguageIds());
637            }
638    
639            protected void destroyCompanies() throws Exception {
640                    long[] companyIds = PortalInstances.getCompanyIds();
641    
642                    for (long companyId : companyIds) {
643                            destroyCompany(companyId);
644                    }
645            }
646    
647            protected void destroyCompany(long companyId) {
648                    if (_log.isDebugEnabled()) {
649                            _log.debug("Process shutdown events");
650                    }
651    
652                    try {
653                            EventsProcessorUtil.process(
654                                    PropsKeys.APPLICATION_SHUTDOWN_EVENTS,
655                                    PropsValues.APPLICATION_SHUTDOWN_EVENTS,
656                                    new String[] {String.valueOf(companyId)});
657                    }
658                    catch (Exception e) {
659                            _log.error(e, e);
660                    }
661            }
662    
663            protected void destroyPortlets(List<Portlet> portlets) throws Exception {
664                    for (Portlet portlet : portlets) {
665                            PortletInstanceFactoryUtil.destroy(portlet);
666    
667                            Map<String, PortletFilter> portletFilters =
668                                    portlet.getPortletFilters();
669    
670                            for (PortletFilter portletFilter : portletFilters.values()) {
671                                    PortletFilterFactory.destroy(portletFilter);
672                            }
673                    }
674            }
675    
676            protected HttpServletRequest encryptRequest(
677                    HttpServletRequest request, long companyId) {
678    
679                    boolean encryptRequest = ParamUtil.getBoolean(request, WebKeys.ENCRYPT);
680    
681                    if (!encryptRequest) {
682                            return request;
683                    }
684    
685                    try {
686                            Company company = CompanyLocalServiceUtil.getCompanyById(companyId);
687    
688                            request = new EncryptedServletRequest(request, company.getKeyObj());
689                    }
690                    catch (Exception e) {
691                    }
692    
693                    return request;
694            }
695    
696            protected long getCompanyId(HttpServletRequest request) {
697                    return PortalInstances.getCompanyId(request);
698            }
699    
700            protected String getRemoteUser(HttpServletRequest request, long userId) {
701                    String remoteUser = request.getRemoteUser();
702    
703                    if (!PropsValues.PORTAL_JAAS_ENABLE) {
704                            HttpSession session = request.getSession();
705    
706                            String jRemoteUser = (String)session.getAttribute("j_remoteuser");
707    
708                            if (jRemoteUser != null) {
709                                    remoteUser = jRemoteUser;
710                            }
711                    }
712    
713                    if ((userId > 0) && (remoteUser == null)) {
714                            remoteUser = String.valueOf(userId);
715                    }
716    
717                    return remoteUser;
718            }
719    
720            @Override
721            protected synchronized RequestProcessor getRequestProcessor(
722                            ModuleConfig moduleConfig)
723                    throws ServletException {
724    
725                    ServletContext servletContext = getServletContext();
726    
727                    String key = Globals.REQUEST_PROCESSOR_KEY + moduleConfig.getPrefix();
728    
729                    RequestProcessor requestProcessor =
730                            (RequestProcessor)servletContext.getAttribute(key);
731    
732                    if (requestProcessor == null) {
733                            ControllerConfig controllerConfig =
734                                    moduleConfig.getControllerConfig();
735    
736                            try {
737                                    requestProcessor =
738                                            (RequestProcessor)InstanceFactory.newInstance(
739                                                    ClassLoaderUtil.getPortalClassLoader(),
740                                                    controllerConfig.getProcessorClass());
741                            }
742                            catch (Exception e) {
743                                    throw new ServletException(e);
744                            }
745    
746                            requestProcessor.init(this, moduleConfig);
747    
748                            servletContext.setAttribute(key, requestProcessor);
749                    }
750    
751                    return requestProcessor;
752            }
753    
754            protected long getUserId(HttpServletRequest request) {
755                    return PortalUtil.getUserId(request);
756            }
757    
758            protected boolean hasAbsoluteRedirect(HttpServletRequest request) {
759                    if (request.getAttribute(
760                                    AbsoluteRedirectsResponse.class.getName()) == null) {
761    
762                            return false;
763                    }
764                    else {
765                            return true;
766                    }
767            }
768    
769            protected boolean hasThemeDisplay(HttpServletRequest request) {
770                    if (request.getAttribute(WebKeys.THEME_DISPLAY) == null) {
771                            return false;
772                    }
773                    else {
774                            return true;
775                    }
776            }
777    
778            protected void initCompanies() throws Exception {
779                    if (_log.isDebugEnabled()) {
780                            _log.debug("Initialize companies");
781                    }
782    
783                    ServletContext servletContext = getServletContext();
784    
785                    try {
786                            String[] webIds = PortalInstances.getWebIds();
787    
788                            for (String webId : webIds) {
789                                    PortalInstances.initCompany(servletContext, webId);
790                            }
791                    }
792                    finally {
793                            CompanyThreadLocal.setCompanyId(
794                                    PortalInstances.getDefaultCompanyId());
795                    }
796            }
797    
798            protected void initExt() throws Exception {
799                    ServletContext servletContext = getServletContext();
800    
801                    ExtRegistry.registerPortal(servletContext);
802            }
803    
804            protected void initLayoutTemplates(final PluginPackage pluginPackage) {
805                    ServiceDependencyManager serviceDependencyManager =
806                            new ServiceDependencyManager();
807    
808                    serviceDependencyManager.addServiceDependencyListener(
809                            new ServiceDependencyListener() {
810    
811                                    @Override
812                                    public void dependenciesFulfilled() {
813                                            try {
814                                                    if (_log.isDebugEnabled()) {
815                                                            _log.debug("Initialize layout templates");
816                                                    }
817    
818                                                    ServletContext servletContext = getServletContext();
819    
820                                                    String[] xmls = new String[] {
821                                                            HttpUtil.URLtoString(
822                                                                    servletContext.getResource(
823                                                                            "/WEB-INF/liferay-layout-templates.xml")),
824                                                            HttpUtil.URLtoString(
825                                                                    servletContext.getResource(
826                                                                            "/WEB-INF/" +
827                                                                                    "liferay-layout-templates-ext.xml"))
828                                                    };
829    
830                                                    List<LayoutTemplate> layoutTemplates =
831                                                            LayoutTemplateLocalServiceUtil.init(
832                                                                    servletContext, xmls, pluginPackage);
833    
834                                                    servletContext.setAttribute(
835                                                            WebKeys.PLUGIN_LAYOUT_TEMPLATES, layoutTemplates);
836                                            }
837                                            catch (Exception e) {
838                                                    _log.error(e, e);
839                                            }
840                                    }
841    
842                                    @Override
843                                    public void destroy() {
844                                    }
845    
846                            });
847    
848                    Registry registry = RegistryUtil.getRegistry();
849    
850                    Filter freeMarkerFilter = registry.getFilter(
851                            "(&(language.type=" + TemplateConstants.LANG_TYPE_FTL +
852                                    ")(objectClass=" + TemplateManager.class.getName() + "))");
853                    Filter velocityFilter = registry.getFilter(
854                            "(&(language.type=" + TemplateConstants.LANG_TYPE_VM +
855                                    ")(objectClass=" + TemplateManager.class.getName() + "))");
856    
857                    serviceDependencyManager.registerDependencies(
858                            freeMarkerFilter, velocityFilter);
859            }
860    
861            protected PluginPackage initPluginPackage() throws Exception {
862                    ServletContext servletContext = getServletContext();
863    
864                    return PluginPackageUtil.readPluginPackageServletContext(
865                            servletContext);
866            }
867    
868            /**
869             * @see SetupWizardUtil#_initPlugins
870             */
871            protected void initPlugins() throws Exception {
872    
873                    // See LEP-2885. Don't flush hot deploy events until after the portal
874                    // has initialized.
875    
876                    if (!PropsValues.SETUP_WIZARD_ENABLED) {
877                            HotDeployUtil.setCapturePrematureEvents(false);
878    
879                            PortalLifecycleUtil.flushInits();
880                    }
881            }
882    
883            protected void initPortletApp(
884                            Portlet portlet, ServletContext servletContext)
885                    throws PortletException {
886    
887                    PortletApp portletApp = portlet.getPortletApp();
888    
889                    PortletConfig portletConfig = PortletConfigFactoryUtil.create(
890                            portlet, servletContext);
891    
892                    PortletContext portletContext = portletConfig.getPortletContext();
893    
894                    Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
895    
896                    for (PortletFilter portletFilter : portletFilters) {
897                            PortletFilterFactory.create(portletFilter, portletContext);
898                    }
899    
900                    Set<PortletURLListener> portletURLListeners =
901                            portletApp.getPortletURLListeners();
902    
903                    for (PortletURLListener portletURLListener : portletURLListeners) {
904                            PortletURLListenerFactory.create(portletURLListener);
905                    }
906            }
907    
908            protected List<Portlet> initPortlets(PluginPackage pluginPackage)
909                    throws Exception {
910    
911                    ServletContext servletContext = getServletContext();
912    
913                    String[] xmls = new String[PropsValues.PORTLET_CONFIGS.length];
914    
915                    for (int i = 0; i < PropsValues.PORTLET_CONFIGS.length; i++) {
916                            xmls[i] = HttpUtil.URLtoString(
917                                    servletContext.getResource(PropsValues.PORTLET_CONFIGS[i]));
918                    }
919    
920                    PortletLocalServiceUtil.initEAR(servletContext, xmls, pluginPackage);
921    
922                    PortletBagFactory portletBagFactory = new PortletBagFactory();
923    
924                    portletBagFactory.setClassLoader(
925                            ClassLoaderUtil.getPortalClassLoader());
926                    portletBagFactory.setServletContext(servletContext);
927                    portletBagFactory.setWARFile(false);
928    
929                    List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
930    
931                    for (int i = 0; i < portlets.size(); i++) {
932                            Portlet portlet = portlets.get(i);
933    
934                            portletBagFactory.create(portlet);
935    
936                            if (i == 0) {
937                                    initPortletApp(portlet, servletContext);
938                            }
939                    }
940    
941                    servletContext.setAttribute(WebKeys.PLUGIN_PORTLETS, portlets);
942    
943                    return portlets;
944            }
945    
946            protected void initResourceActions(List<Portlet> portlets)
947                    throws Exception {
948    
949                    for (Portlet portlet : portlets) {
950                            List<String> portletActions =
951                                    ResourceActionsUtil.getPortletResourceActions(portlet);
952    
953                            ResourceActionLocalServiceUtil.checkResourceActions(
954                                    portlet.getPortletId(), portletActions);
955    
956                            List<String> modelNames =
957                                    ResourceActionsUtil.getPortletModelResources(
958                                            portlet.getPortletId());
959    
960                            for (String modelName : modelNames) {
961                                    List<String> modelActions =
962                                            ResourceActionsUtil.getModelResourceActions(modelName);
963    
964                                    ResourceActionLocalServiceUtil.checkResourceActions(
965                                            modelName, modelActions);
966                            }
967                    }
968            }
969    
970            /**
971             * @deprecated As of 7.0.0, with no direct replacement
972             */
973            @Deprecated
974            protected void initServerDetector() throws Exception {
975            }
976    
977            protected void initSocial(PluginPackage pluginPackage) throws Exception {
978                    ClassLoader classLoader = ClassLoaderUtil.getPortalClassLoader();
979    
980                    ServletContext servletContext = getServletContext();
981    
982                    String[] xmls = new String[] {
983                            HttpUtil.URLtoString(
984                                    servletContext.getResource("/WEB-INF/liferay-social.xml")),
985                            HttpUtil.URLtoString(
986                                    servletContext.getResource("/WEB-INF/liferay-social-ext.xml"))
987                    };
988    
989                    SocialConfigurationUtil.read(classLoader, xmls);
990            }
991    
992            protected void initThemes(
993                            PluginPackage pluginPackage, List<Portlet> portlets)
994                    throws Exception {
995    
996                    ServletContext servletContext = getServletContext();
997    
998                    String[] xmls = new String[] {
999                            HttpUtil.URLtoString(
1000                                    servletContext.getResource(
1001                                            "/WEB-INF/liferay-look-and-feel.xml")),
1002                            HttpUtil.URLtoString(
1003                                    servletContext.getResource(
1004                                            "/WEB-INF/liferay-look-and-feel-ext.xml"))
1005                    };
1006    
1007                    List<Theme> themes = ThemeLocalServiceUtil.init(
1008                            servletContext, null, true, xmls, pluginPackage);
1009    
1010                    servletContext.setAttribute(WebKeys.PLUGIN_THEMES, themes);
1011            }
1012    
1013            protected void initWebSettings() throws Exception {
1014                    ServletContext servletContext = getServletContext();
1015    
1016                    String xml = HttpUtil.URLtoString(
1017                            servletContext.getResource("/WEB-INF/web.xml"));
1018    
1019                    checkWebSettings(xml);
1020            }
1021    
1022            protected long loginUser(
1023                            HttpServletRequest request, HttpServletResponse response,
1024                            long companyId, long userId, String remoteUser)
1025                    throws PortalException {
1026    
1027                    if ((userId > 0) || (remoteUser == null)) {
1028                            return userId;
1029                    }
1030    
1031                    userId = GetterUtil.getLong(remoteUser);
1032    
1033                    User user = UserLocalServiceUtil.getUserById(userId);
1034    
1035                    if (!user.isDefaultUser()) {
1036                            EventsProcessorUtil.process(
1037                                    PropsKeys.LOGIN_EVENTS_PRE, PropsValues.LOGIN_EVENTS_PRE,
1038                                    request, response);
1039    
1040                            if (PropsValues.USERS_UPDATE_LAST_LOGIN ||
1041                                    (user.getLastLoginDate() == null)) {
1042    
1043                                    user = UserLocalServiceUtil.updateLastLogin(
1044                                            userId, request.getRemoteAddr());
1045                            }
1046                    }
1047    
1048                    HttpSession session = request.getSession();
1049    
1050                    session.setAttribute(WebKeys.USER, user);
1051                    session.setAttribute(WebKeys.USER_ID, Long.valueOf(userId));
1052                    session.setAttribute(Globals.LOCALE_KEY, user.getLocale());
1053    
1054                    session.removeAttribute("j_remoteuser");
1055    
1056                    if (!user.isDefaultUser()) {
1057                            EventsProcessorUtil.process(
1058                                    PropsKeys.LOGIN_EVENTS_POST, PropsValues.LOGIN_EVENTS_POST,
1059                                    request, response);
1060                    }
1061    
1062                    return userId;
1063            }
1064    
1065            protected boolean processCompanyInactiveRequest(
1066                            HttpServletRequest request, HttpServletResponse response,
1067                            long companyId)
1068                    throws IOException {
1069    
1070                    if (PortalInstances.isCompanyActive(companyId)) {
1071                            return false;
1072                    }
1073    
1074                    processInactiveRequest(
1075                            request, response,
1076                            "this-instance-is-inactive-please-contact-the-administrator");
1077    
1078                    return true;
1079            }
1080    
1081            protected void processGlobalShutdownEvents() throws Exception {
1082                    EventsProcessorUtil.process(
1083                            PropsKeys.GLOBAL_SHUTDOWN_EVENTS,
1084                            PropsValues.GLOBAL_SHUTDOWN_EVENTS);
1085    
1086                    super.destroy();
1087            }
1088    
1089            protected void processGlobalStartupEvents() throws Exception {
1090                    EventsProcessorUtil.process(
1091                            PropsKeys.GLOBAL_STARTUP_EVENTS, PropsValues.GLOBAL_STARTUP_EVENTS);
1092            }
1093    
1094            protected boolean processGroupInactiveRequest(
1095                            HttpServletRequest request, HttpServletResponse response)
1096                    throws IOException, PortalException {
1097    
1098                    long plid = ParamUtil.getLong(request, "p_l_id");
1099    
1100                    if (plid <= 0) {
1101                            return false;
1102                    }
1103    
1104                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1105    
1106                    Group group = layout.getGroup();
1107    
1108                    if (group.isActive()) {
1109                            return false;
1110                    }
1111    
1112                    processInactiveRequest(
1113                            request, response,
1114                            "this-site-is-inactive-please-contact-the-administrator");
1115    
1116                    return true;
1117            }
1118    
1119            protected void processInactiveRequest(
1120                            HttpServletRequest request, HttpServletResponse response,
1121                            String messageKey)
1122                    throws IOException {
1123    
1124                    response.setContentType(ContentTypes.TEXT_HTML_UTF8);
1125    
1126                    Locale locale = PortalUtil.getLocale(request);
1127    
1128                    String message = null;
1129    
1130                    if (LanguageUtil.isValidLanguageKey(locale, messageKey)) {
1131                            message = LanguageUtil.get(locale, messageKey);
1132                    }
1133                    else {
1134                            message = HtmlUtil.escape(messageKey);
1135                    }
1136    
1137                    String html = ContentUtil.get(
1138                            "com/liferay/portal/dependencies/inactive.html");
1139    
1140                    html = StringUtil.replace(html, "[$MESSAGE$]", message);
1141    
1142                    PrintWriter printWriter = response.getWriter();
1143    
1144                    printWriter.print(html);
1145            }
1146    
1147            protected boolean processMaintenanceRequest(
1148                            HttpServletRequest request, HttpServletResponse response)
1149                    throws IOException, ServletException {
1150    
1151                    if (!MaintenanceUtil.isMaintaining()) {
1152                            return false;
1153                    }
1154    
1155                    RequestDispatcher requestDispatcher = request.getRequestDispatcher(
1156                            "/html/portal/maintenance.jsp");
1157    
1158                    requestDispatcher.include(request, response);
1159    
1160                    return true;
1161            }
1162    
1163            protected void processServicePost(
1164                    HttpServletRequest request, HttpServletResponse response) {
1165    
1166                    try {
1167                            EventsProcessorUtil.process(
1168                                    PropsKeys.SERVLET_SERVICE_EVENTS_POST,
1169                                    PropsValues.SERVLET_SERVICE_EVENTS_POST, request, response);
1170                    }
1171                    catch (Exception e) {
1172                            _log.error(e, e);
1173                    }
1174            }
1175    
1176            protected boolean processServicePre(
1177                            HttpServletRequest request, HttpServletResponse response,
1178                            long userId)
1179                    throws IOException, ServletException {
1180    
1181                    try {
1182                            EventsProcessorUtil.process(
1183                                    PropsKeys.SERVLET_SERVICE_EVENTS_PRE,
1184                                    PropsValues.SERVLET_SERVICE_EVENTS_PRE, request, response);
1185                    }
1186                    catch (Exception e) {
1187                            Throwable cause = e.getCause();
1188    
1189                            if (cause instanceof NoSuchLayoutException) {
1190                                    sendError(
1191                                            HttpServletResponse.SC_NOT_FOUND, cause, request, response);
1192    
1193                                    return true;
1194                            }
1195                            else if (cause instanceof PrincipalException) {
1196                                    processServicePrePrincipalException(
1197                                            cause, userId, request, response);
1198    
1199                                    return true;
1200                            }
1201    
1202                            _log.error(e, e);
1203    
1204                            request.setAttribute(PageContext.EXCEPTION, e);
1205    
1206                            ServletContext servletContext = getServletContext();
1207    
1208                            StrutsUtil.forward(
1209                                    PropsValues.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE,
1210                                    servletContext, request, response);
1211    
1212                            return true;
1213                    }
1214    
1215                    if (_HTTP_HEADER_VERSION_VERBOSITY_DEFAULT) {
1216                    }
1217                    else if (_HTTP_HEADER_VERSION_VERBOSITY_PARTIAL) {
1218                            response.addHeader(
1219                                    _LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getName());
1220                    }
1221                    else {
1222                            response.addHeader(
1223                                    _LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
1224                    }
1225    
1226                    return false;
1227            }
1228    
1229            protected void processServicePrePrincipalException(
1230                            Throwable t, long userId, HttpServletRequest request,
1231                            HttpServletResponse response)
1232                    throws IOException, ServletException {
1233    
1234                    if (userId > 0) {
1235                            sendError(
1236                                    HttpServletResponse.SC_UNAUTHORIZED, t, request, response);
1237    
1238                            return;
1239                    }
1240    
1241                    String redirect = PortalUtil.getPathMain().concat("/portal/login");
1242    
1243                    String currentURL = PortalUtil.getCurrentURL(request);
1244    
1245                    redirect = HttpUtil.addParameter(redirect, "redirect", currentURL);
1246    
1247                    long plid = ParamUtil.getLong(request, "p_l_id");
1248    
1249                    if (plid > 0) {
1250                            try {
1251                                    redirect = HttpUtil.addParameter(redirect, "refererPlid", plid);
1252    
1253                                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1254    
1255                                    Group group = layout.getGroup();
1256    
1257                                    plid = group.getDefaultPublicPlid();
1258    
1259                                    if ((plid == LayoutConstants.DEFAULT_PLID) ||
1260                                            group.isStagingGroup()) {
1261    
1262                                            Group guestGroup = GroupLocalServiceUtil.getGroup(
1263                                                    layout.getCompanyId(), GroupConstants.GUEST);
1264    
1265                                            plid = guestGroup.getDefaultPublicPlid();
1266                                    }
1267    
1268                                    redirect = HttpUtil.addParameter(redirect, "p_l_id", plid);
1269                            }
1270                            catch (Exception e) {
1271                            }
1272                    }
1273    
1274                    response.sendRedirect(redirect);
1275            }
1276    
1277            protected boolean processShutdownRequest(
1278                            HttpServletRequest request, HttpServletResponse response)
1279                    throws IOException {
1280    
1281                    if (!ShutdownUtil.isShutdown()) {
1282                            return false;
1283                    }
1284    
1285                    String messageKey = ShutdownUtil.getMessage();
1286    
1287                    if (Validator.isNull(messageKey)) {
1288                            messageKey = "the-system-is-shutdown-please-try-again-later";
1289                    }
1290    
1291                    processInactiveRequest(request, response, messageKey);
1292    
1293                    return true;
1294            }
1295    
1296            protected void processStartupEvents() throws Exception {
1297                    StartupAction startupAction = new StartupAction();
1298    
1299                    startupAction.run(null);
1300            }
1301    
1302            protected void registerPortalInitialized() {
1303                    Registry registry = RegistryUtil.getRegistry();
1304    
1305                    Map<String, Object> properties = new HashMap<>();
1306    
1307                    properties.put("module.service.lifecycle", "portal.initialized");
1308                    properties.put("service.vendor", ReleaseInfo.getVendor());
1309                    properties.put("service.version", ReleaseInfo.getVersion());
1310    
1311                    _moduleServiceLifecycleServiceRegistration = registry.registerService(
1312                            ModuleServiceLifecycle.class, new ModuleServiceLifecycle() {},
1313                            properties);
1314    
1315                    properties = new HashMap<>();
1316    
1317                    properties.put("bean.id", ServletContext.class.getName());
1318                    properties.put("original.bean", Boolean.TRUE);
1319                    properties.put("service.vendor", ReleaseInfo.getVendor());
1320    
1321                    _servletContextServiceRegistration = registry.registerService(
1322                            ServletContext.class, getServletContext(), properties);
1323            }
1324    
1325            protected void sendError(
1326                            int status, Throwable t, HttpServletRequest request,
1327                            HttpServletResponse response)
1328                    throws IOException, ServletException {
1329    
1330                    DynamicServletRequest dynamicRequest = new DynamicServletRequest(
1331                            request);
1332    
1333                    // Reset layout params or there will be an infinite loop
1334    
1335                    dynamicRequest.setParameter("p_l_id", StringPool.BLANK);
1336    
1337                    dynamicRequest.setParameter("groupId", StringPool.BLANK);
1338                    dynamicRequest.setParameter("layoutId", StringPool.BLANK);
1339                    dynamicRequest.setParameter("privateLayout", StringPool.BLANK);
1340    
1341                    PortalUtil.sendError(status, (Exception)t, dynamicRequest, response);
1342            }
1343    
1344            protected void setPortalInetSocketAddresses(HttpServletRequest request) {
1345                    PortalUtil.setPortalInetSocketAddresses(request);
1346            }
1347    
1348            private static final boolean _HTTP_HEADER_VERSION_VERBOSITY_DEFAULT =
1349                    StringUtil.equalsIgnoreCase(
1350                            PropsValues.HTTP_HEADER_VERSION_VERBOSITY, ReleaseInfo.getName());
1351    
1352            private static final boolean _HTTP_HEADER_VERSION_VERBOSITY_PARTIAL =
1353                    StringUtil.equalsIgnoreCase(
1354                            PropsValues.HTTP_HEADER_VERSION_VERBOSITY, "partial");
1355    
1356            private static final String _LIFERAY_PORTAL_REQUEST_HEADER =
1357                    "Liferay-Portal";
1358    
1359            private static final Log _log = LogFactoryUtil.getLog(MainServlet.class);
1360    
1361            private ServiceRegistration<ModuleServiceLifecycle>
1362                    _moduleServiceLifecycleServiceRegistration;
1363            private ServiceRegistration<ServletContext>
1364                    _servletContextServiceRegistration;
1365    
1366    }