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