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