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