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