1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.servlet;
24  
25  import com.liferay.portal.NoSuchLayoutException;
26  import com.liferay.portal.deploy.hot.PluginPackageHotDeployListener;
27  import com.liferay.portal.events.EventsProcessor;
28  import com.liferay.portal.events.StartupAction;
29  import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
30  import com.liferay.portal.kernel.events.ActionException;
31  import com.liferay.portal.kernel.job.Scheduler;
32  import com.liferay.portal.kernel.plugin.PluginPackage;
33  import com.liferay.portal.kernel.pop.MessageListener;
34  import com.liferay.portal.kernel.servlet.HttpHeaders;
35  import com.liferay.portal.kernel.servlet.PortletSessionTracker;
36  import com.liferay.portal.kernel.servlet.ProtectedServletRequest;
37  import com.liferay.portal.kernel.util.ContentTypes;
38  import com.liferay.portal.kernel.util.GetterUtil;
39  import com.liferay.portal.kernel.util.HttpUtil;
40  import com.liferay.portal.kernel.util.InstancePool;
41  import com.liferay.portal.kernel.util.ParamUtil;
42  import com.liferay.portal.kernel.util.PortalInitableUtil;
43  import com.liferay.portal.kernel.util.ReleaseInfo;
44  import com.liferay.portal.kernel.util.StringPool;
45  import com.liferay.portal.kernel.util.Validator;
46  import com.liferay.portal.lastmodified.LastModifiedAction;
47  import com.liferay.portal.model.Company;
48  import com.liferay.portal.model.Portlet;
49  import com.liferay.portal.model.PortletApp;
50  import com.liferay.portal.model.PortletFilter;
51  import com.liferay.portal.model.PortletURLListener;
52  import com.liferay.portal.model.User;
53  import com.liferay.portal.pop.POPServerUtil;
54  import com.liferay.portal.security.auth.CompanyThreadLocal;
55  import com.liferay.portal.security.auth.PrincipalThreadLocal;
56  import com.liferay.portal.service.CompanyLocalServiceUtil;
57  import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
58  import com.liferay.portal.service.PortletLocalServiceUtil;
59  import com.liferay.portal.service.ThemeLocalServiceUtil;
60  import com.liferay.portal.service.UserLocalServiceUtil;
61  import com.liferay.portal.struts.PortletRequestProcessor;
62  import com.liferay.portal.struts.StrutsUtil;
63  import com.liferay.portal.util.ContentUtil;
64  import com.liferay.portal.util.DocumentUtil;
65  import com.liferay.portal.util.InitUtil;
66  import com.liferay.portal.util.Portal;
67  import com.liferay.portal.util.PortalInstances;
68  import com.liferay.portal.util.PortalUtil;
69  import com.liferay.portal.util.PropsKeys;
70  import com.liferay.portal.util.PropsUtil;
71  import com.liferay.portal.util.PropsValues;
72  import com.liferay.portal.util.ShutdownUtil;
73  import com.liferay.portal.util.WebKeys;
74  import com.liferay.portal.velocity.VelocityContextPool;
75  import com.liferay.portlet.PortletConfigFactory;
76  import com.liferay.portlet.PortletFilterFactory;
77  import com.liferay.portlet.PortletInstanceFactory;
78  import com.liferay.portlet.PortletURLListenerFactory;
79  import com.liferay.portlet.social.model.SocialActivityInterpreter;
80  import com.liferay.portlet.social.model.SocialRequestInterpreter;
81  import com.liferay.portlet.social.model.impl.SocialActivityInterpreterImpl;
82  import com.liferay.portlet.social.model.impl.SocialRequestInterpreterImpl;
83  import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
84  import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
85  import com.liferay.util.servlet.DynamicServletRequest;
86  import com.liferay.util.servlet.EncryptedServletRequest;
87  
88  import java.io.IOException;
89  
90  import java.util.HashSet;
91  import java.util.Iterator;
92  import java.util.List;
93  import java.util.Set;
94  
95  import javax.portlet.PortletConfig;
96  import javax.portlet.PortletContext;
97  import javax.portlet.PortletException;
98  
99  import javax.servlet.ServletContext;
100 import javax.servlet.ServletException;
101 import javax.servlet.http.HttpServletRequest;
102 import javax.servlet.http.HttpServletResponse;
103 import javax.servlet.http.HttpSession;
104 import javax.servlet.jsp.PageContext;
105 
106 import org.apache.commons.logging.Log;
107 import org.apache.commons.logging.LogFactory;
108 import org.apache.struts.Globals;
109 import org.apache.struts.action.ActionMapping;
110 import org.apache.struts.action.ActionServlet;
111 import org.apache.struts.config.ModuleConfig;
112 import org.apache.struts.tiles.TilesUtilImpl;
113 
114 import org.dom4j.Document;
115 import org.dom4j.DocumentException;
116 import org.dom4j.Element;
117 
118 /**
119  * <a href="MainServlet.java.html"><b><i>View Source</i></b></a>
120  *
121  * @author Brian Wing Shun Chan
122  * @author Jorge Ferrer
123  * @author Brian Myunghun Kim
124  *
125  */
126 public class MainServlet extends ActionServlet {
127 
128     static {
129         InitUtil.init();
130     }
131 
132     public void init() throws ServletException {
133 
134         // Initialize
135 
136         if (_log.isDebugEnabled()) {
137             _log.debug("Initialize");
138         }
139 
140         super.init();
141 
142         // Startup events
143 
144         if (_log.isDebugEnabled()) {
145             _log.debug("Process startup events");
146         }
147 
148         try {
149             StartupAction startupAction = new StartupAction();
150 
151             startupAction.run(null);
152         }
153         catch (RuntimeException re) {
154             ShutdownUtil.shutdown(0);
155 
156             throw new ServletException(re);
157         }
158         catch (ActionException ae) {
159             _log.error(ae, ae);
160         }
161 
162         // Velocity
163 
164         String contextPath = PortalUtil.getPathContext();
165 
166         ServletContext servletContext = getServletContext();
167 
168         VelocityContextPool.put(contextPath, servletContext);
169 
170         // Plugin package
171 
172         if (_log.isDebugEnabled()) {
173             _log.debug("Initialize plugin package");
174         }
175 
176         PluginPackage pluginPackage = null;
177 
178         try {
179             pluginPackage =
180                 PluginPackageHotDeployListener.readPluginPackage(
181                     servletContext);
182         }
183         catch (Exception e) {
184             _log.error(e, e);
185         }
186 
187         // Portlets
188 
189         if (_log.isDebugEnabled()) {
190             _log.debug("Initialize portlets");
191         }
192 
193         List<Portlet> portlets = null;
194 
195         try {
196             String[] xmls = new String[] {
197                 HttpUtil.URLtoString(servletContext.getResource(
198                     "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
199                 HttpUtil.URLtoString(servletContext.getResource(
200                     "/WEB-INF/portlet-ext.xml")),
201                 HttpUtil.URLtoString(servletContext.getResource(
202                     "/WEB-INF/liferay-portlet.xml")),
203                 HttpUtil.URLtoString(servletContext.getResource(
204                     "/WEB-INF/liferay-portlet-ext.xml")),
205                 HttpUtil.URLtoString(servletContext.getResource(
206                     "/WEB-INF/web.xml"))
207             };
208 
209             PortletLocalServiceUtil.initEAR(xmls, pluginPackage);
210 
211             portlets = PortletLocalServiceUtil.getPortlets();
212 
213             for (int i = 0; i < portlets.size(); i++) {
214                 Portlet portlet = portlets.get(i);
215 
216                 if (i == 0) {
217                     initPortletApp(portlet, servletContext);
218                 }
219 
220                 PortletInstanceFactory.create(portlet, servletContext);
221             }
222         }
223         catch (Exception e) {
224             _log.error(e, e);
225         }
226 
227         // Layout templates
228 
229         if (_log.isDebugEnabled()) {
230             _log.debug("Initialize layout templates");
231         }
232 
233         try {
234             String[] xmls = new String[] {
235                 HttpUtil.URLtoString(servletContext.getResource(
236                     "/WEB-INF/liferay-layout-templates.xml")),
237                 HttpUtil.URLtoString(servletContext.getResource(
238                     "/WEB-INF/liferay-layout-templates-ext.xml"))
239             };
240 
241             LayoutTemplateLocalServiceUtil.init(
242                 servletContext, xmls, pluginPackage);
243         }
244         catch (Exception e) {
245             _log.error(e, e);
246         }
247 
248         // Look and feel
249 
250         if (_log.isDebugEnabled()) {
251             _log.debug("Initialize look and feel");
252         }
253 
254         try {
255             String[] xmls = new String[] {
256                 HttpUtil.URLtoString(servletContext.getResource(
257                     "/WEB-INF/liferay-look-and-feel.xml")),
258                 HttpUtil.URLtoString(servletContext.getResource(
259                     "/WEB-INF/liferay-look-and-feel-ext.xml"))
260             };
261 
262             ThemeLocalServiceUtil.init(
263                 servletContext, null, true, xmls, pluginPackage);
264         }
265         catch (Exception e) {
266             _log.error(e, e);
267         }
268 
269         // Scheduler
270 
271         if (_log.isDebugEnabled()) {
272             _log.debug("Scheduler");
273         }
274 
275         try {
276             if (PropsValues.SCHEDULER_ENABLED) {
277                 for (String className : PropsValues.SCHEDULER_CLASSES) {
278                     Scheduler scheduler = (Scheduler)InstancePool.get(
279                         className);
280 
281                     scheduler.schedule();
282                 }
283 
284                 Iterator<Portlet> itr = portlets.iterator();
285 
286                 while (itr.hasNext()) {
287                     Portlet portlet = itr.next();
288 
289                     String className = portlet.getSchedulerClass();
290 
291                     if (portlet.isActive() && Validator.isNotNull(className)) {
292                         Scheduler scheduler = (Scheduler)InstancePool.get(
293                             className);
294 
295                         scheduler.schedule();
296                     }
297                 }
298             }
299         }
300         catch (Exception e) {
301             _log.error(e, e);
302         }
303 
304         // POP message listener
305 
306         if (_log.isDebugEnabled()) {
307             _log.debug("POP message listener");
308         }
309 
310         try {
311             Iterator<Portlet> itr = portlets.iterator();
312 
313             while (itr.hasNext()) {
314                 Portlet portlet = itr.next();
315 
316                 MessageListener popMessageListener =
317                     portlet.getPopMessageListenerInstance();
318 
319                 if (portlet.isActive() && (popMessageListener != null)) {
320                     POPServerUtil.addListener(popMessageListener);
321                 }
322             }
323         }
324         catch (Exception e) {
325             _log.error(e, e);
326         }
327 
328         // Social activity interpreter
329 
330         if (_log.isDebugEnabled()) {
331             _log.debug("Social activity interpreter");
332         }
333 
334         try {
335             Iterator<Portlet> itr = portlets.iterator();
336 
337             while (itr.hasNext()) {
338                 Portlet portlet = itr.next();
339 
340                 SocialActivityInterpreter socialActivityInterpreter =
341                     portlet.getSocialActivityInterpreterInstance();
342 
343                 if (portlet.isActive() && (socialActivityInterpreter != null)) {
344                     socialActivityInterpreter =
345                         new SocialActivityInterpreterImpl(
346                             portlet.getPortletId(), socialActivityInterpreter);
347 
348                     SocialActivityInterpreterLocalServiceUtil.
349                         addActivityInterpreter(socialActivityInterpreter);
350                 }
351             }
352         }
353         catch (Exception e) {
354             _log.error(e, e);
355         }
356 
357         // Social request interpreter
358 
359         if (_log.isDebugEnabled()) {
360             _log.debug("Social request interpreter");
361         }
362 
363         try {
364             Iterator<Portlet> itr = portlets.iterator();
365 
366             while (itr.hasNext()) {
367                 Portlet portlet = itr.next();
368 
369                 SocialRequestInterpreter socialRequestInterpreter =
370                     portlet.getSocialRequestInterpreterInstance();
371 
372                 if (portlet.isActive() && (socialRequestInterpreter != null)) {
373                     socialRequestInterpreter = new SocialRequestInterpreterImpl(
374                         portlet.getPortletId(), socialRequestInterpreter);
375 
376                     SocialRequestInterpreterLocalServiceUtil.
377                         addRequestInterpreter(socialRequestInterpreter);
378                 }
379             }
380         }
381         catch (Exception e) {
382             _log.error(e, e);
383         }
384 
385         // Check web settings
386 
387         if (_log.isDebugEnabled()) {
388             _log.debug("Check web settings");
389         }
390 
391         try {
392             String xml = HttpUtil.URLtoString(
393                 servletContext.getResource("/WEB-INF/web.xml"));
394 
395             checkWebSettings(xml);
396         }
397         catch (Exception e) {
398             _log.error(e, e);
399         }
400 
401         // Last modified paths
402 
403         if (_log.isDebugEnabled()) {
404             _log.debug("Last modified paths");
405         }
406 
407         if (_lastModifiedPaths == null) {
408             _lastModifiedPaths = new HashSet<String>();
409 
410             for (String lastModifiedPath : PropsValues.LAST_MODIFIED_PATHS) {
411                 _lastModifiedPaths.add(lastModifiedPath);
412             }
413         }
414 
415         // Global startup events
416 
417         if (_log.isDebugEnabled()) {
418             _log.debug("Process global startup events");
419         }
420 
421         try {
422             EventsProcessor.process(
423                 PropsKeys.GLOBAL_STARTUP_EVENTS,
424                 PropsValues.GLOBAL_STARTUP_EVENTS);
425         }
426         catch (Exception e) {
427             _log.error(e, e);
428         }
429 
430         // Companies
431 
432         String[] webIds = PortalInstances.getWebIds();
433 
434         for (int i = 0; i < webIds.length; i++) {
435             PortalInstances.initCompany(servletContext, webIds[i]);
436         }
437 
438         // See LEP-2885. Don't flush hot deploy events until after the portal
439         // has initialized.
440 
441         PortalInitableUtil.flushInitables();
442         HotDeployUtil.flushEvents();
443     }
444 
445     public void callParentService(
446             HttpServletRequest request, HttpServletResponse response)
447         throws IOException, ServletException {
448 
449         super.service(request, response);
450     }
451 
452     public void service(
453             HttpServletRequest request, HttpServletResponse response)
454         throws IOException, ServletException {
455 
456         if (_log.isDebugEnabled()) {
457             _log.debug("Process service request");
458         }
459 
460         if (ShutdownUtil.isShutdown()) {
461             response.setContentType(ContentTypes.TEXT_HTML_UTF8);
462 
463             String html = ContentUtil.get(
464                 "com/liferay/portal/dependencies/shutdown.html");
465 
466             response.getOutputStream().print(html);
467 
468             return;
469         }
470 
471         HttpSession session = request.getSession();
472 
473         // Company id
474 
475         long companyId = PortalInstances.getCompanyId(request);
476 
477         //CompanyThreadLocal.setCompanyId(companyId);
478 
479         // Portal port
480 
481         PortalUtil.setPortalPort(request);
482 
483         // CTX
484 
485         ServletContext servletContext = getServletContext();
486 
487         request.setAttribute(WebKeys.CTX, servletContext);
488 
489         // Struts module config
490 
491         ModuleConfig moduleConfig = getModuleConfig(request);
492 
493         // Last modified check
494 
495         if (PropsValues.LAST_MODIFIED_CHECK) {
496             String path = request.getPathInfo();
497 
498             if ((path != null) && _lastModifiedPaths.contains(path)) {
499                 ActionMapping mapping =
500                     (ActionMapping)moduleConfig.findActionConfig(path);
501 
502                 LastModifiedAction lastModifiedAction =
503                     (LastModifiedAction)InstancePool.get(mapping.getType());
504 
505                 String lmKey = lastModifiedAction.getLastModifiedKey(request);
506 
507                 if (lmKey != null) {
508                     long ifModifiedSince =
509                         request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
510 
511                     if (ifModifiedSince <= 0) {
512                         lastModifiedAction.setLastModifiedValue(lmKey, lmKey);
513                     }
514                     else {
515                         String lmValue =
516                             lastModifiedAction.getLastModifiedValue(lmKey);
517 
518                         if (lmValue != null) {
519                             response.setStatus(
520                                 HttpServletResponse.SC_NOT_MODIFIED);
521 
522                             return;
523                         }
524                         else {
525                             lastModifiedAction.setLastModifiedValue(
526                                 lmKey, lmKey);
527                         }
528                     }
529                 }
530             }
531         }
532 
533         // Portlet session tracker
534 
535         if (session.getAttribute(WebKeys.PORTLET_SESSION_TRACKER) == null ) {
536             session.setAttribute(
537                 WebKeys.PORTLET_SESSION_TRACKER,
538                 PortletSessionTracker.getInstance());
539         }
540 
541         // Portlet Request Processor
542 
543         PortletRequestProcessor portletReqProcessor =
544             (PortletRequestProcessor)servletContext.getAttribute(
545                 WebKeys.PORTLET_STRUTS_PROCESSOR);
546 
547         if (portletReqProcessor == null) {
548             portletReqProcessor =
549                 PortletRequestProcessor.getInstance(this, moduleConfig);
550 
551             servletContext.setAttribute(
552                 WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
553         }
554 
555         // Tiles definitions factory
556 
557         if (servletContext.getAttribute(
558                 TilesUtilImpl.DEFINITIONS_FACTORY) == null) {
559 
560             servletContext.setAttribute(
561                 TilesUtilImpl.DEFINITIONS_FACTORY,
562                 servletContext.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
563         }
564 
565         Object applicationAssociate = servletContext.getAttribute(
566             WebKeys.ASSOCIATE_KEY);
567 
568         if (servletContext.getAttribute(WebKeys.ASSOCIATE_KEY) == null) {
569             servletContext.setAttribute(
570                 WebKeys.ASSOCIATE_KEY, applicationAssociate);
571         }
572 
573         // Encrypt request
574 
575         if (ParamUtil.get(request, WebKeys.ENCRYPT, false)) {
576             try {
577                 Company company = CompanyLocalServiceUtil.getCompanyById(
578                     companyId);
579 
580                 request = new EncryptedServletRequest(
581                     request, company.getKeyObj());
582             }
583             catch (Exception e) {
584             }
585         }
586 
587         // Current URL
588 
589         PortalUtil.getCurrentURL(request);
590 
591         // Login
592 
593         long userId = PortalUtil.getUserId(request);
594         String remoteUser = request.getRemoteUser();
595 
596         // Is JAAS enabled?
597 
598         if (!PropsValues.PORTAL_JAAS_ENABLE) {
599             String jRemoteUser = (String)session.getAttribute("j_remoteuser");
600 
601             if (jRemoteUser != null) {
602                 remoteUser = jRemoteUser;
603 
604                 session.removeAttribute("j_remoteuser");
605             }
606         }
607 
608         if ((userId > 0) && (remoteUser == null)) {
609             remoteUser = String.valueOf(userId);
610         }
611 
612         // WebSphere will not return the remote user unless you are
613         // authenticated AND accessing a protected path. Other servers will
614         // return the remote user for all threads associated with an
615         // authenticated user. We use ProtectedServletRequest to ensure we get
616         // similar behavior across all servers.
617 
618         request = new ProtectedServletRequest(request, remoteUser);
619 
620         if ((userId > 0) || (remoteUser != null)) {
621 
622             // Set the principal associated with this thread
623 
624             String name = String.valueOf(userId);
625 
626             if (remoteUser != null) {
627                 name = remoteUser;
628             }
629 
630             PrincipalThreadLocal.setName(name);
631         }
632 
633         if ((userId <= 0) && (remoteUser != null)) {
634             try {
635 
636                 // User id
637 
638                 userId = GetterUtil.getLong(remoteUser);
639 
640                 // Pre login events
641 
642                 EventsProcessor.process(
643                     PropsKeys.LOGIN_EVENTS_PRE, PropsValues.LOGIN_EVENTS_PRE,
644                     request, response);
645 
646                 // User
647 
648                 User user = UserLocalServiceUtil.getUserById(userId);
649 
650                 if (PropsValues.USERS_UPDATE_LAST_LOGIN) {
651                     UserLocalServiceUtil.updateLastLogin(
652                         userId, request.getRemoteAddr());
653                 }
654 
655                 // User id
656 
657                 session.setAttribute(WebKeys.USER_ID, new Long(userId));
658 
659                 // User locale
660 
661                 session.setAttribute(Globals.LOCALE_KEY, user.getLocale());
662 
663                 // Post login events
664 
665                 EventsProcessor.process(
666                     PropsKeys.LOGIN_EVENTS_POST, PropsValues.LOGIN_EVENTS_POST,
667                     request, response);
668             }
669             catch (Exception e) {
670                 _log.error(e, e);
671             }
672         }
673 
674         // Pre service events
675 
676         try {
677             EventsProcessor.process(
678                 PropsKeys.SERVLET_SERVICE_EVENTS_PRE,
679                 PropsValues.SERVLET_SERVICE_EVENTS_PRE, request, response);
680         }
681         catch (Exception e) {
682             Throwable cause = e.getCause();
683 
684             if (cause instanceof NoSuchLayoutException) {
685                 DynamicServletRequest dynamicRequest =
686                     new DynamicServletRequest(request);
687 
688                 // Reset p_l_id or there will be an infinite loop
689 
690                 dynamicRequest.setParameter("p_l_id", StringPool.BLANK);
691 
692                 PortalUtil.sendError(
693                     HttpServletResponse.SC_NOT_FOUND,
694                     (NoSuchLayoutException)cause, dynamicRequest, response);
695 
696                 return;
697             }
698 
699             _log.error(e, e);
700 
701             request.setAttribute(PageContext.EXCEPTION, e);
702 
703             StrutsUtil.forward(
704                 PropsValues.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE,
705                 servletContext, request, response);
706 
707             return;
708         }
709 
710         try {
711 
712             // Struts service
713 
714             callParentService(request, response);
715         }
716         finally {
717 
718             // Post service events
719 
720             try {
721                 EventsProcessor.process(
722                     PropsKeys.SERVLET_SERVICE_EVENTS_POST,
723                     PropsValues.SERVLET_SERVICE_EVENTS_POST, request, response);
724             }
725             catch (Exception e) {
726                 _log.error(e, e);
727             }
728 
729             response.addHeader(
730                 _LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
731 
732             // Clear the company id associated with this thread
733 
734             CompanyThreadLocal.setCompanyId(0);
735 
736             // Clear the principal associated with this thread
737 
738             PrincipalThreadLocal.setName(null);
739         }
740     }
741 
742     public void destroy() {
743         List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
744 
745         // Scheduler
746 
747         if (_log.isDebugEnabled()) {
748             _log.debug("Scheduler");
749         }
750 
751         try {
752             if (PropsValues.SCHEDULER_ENABLED) {
753                 for (String className : PropsValues.SCHEDULER_CLASSES) {
754                     Scheduler scheduler = (Scheduler)InstancePool.get(
755                         className);
756 
757                     scheduler.unschedule();
758                 }
759 
760                 Iterator<Portlet> itr = portlets.iterator();
761 
762                 while (itr.hasNext()) {
763                     Portlet portlet = itr.next();
764 
765                     String className = portlet.getSchedulerClass();
766 
767                     if (portlet.isActive() && Validator.isNotNull(className)) {
768                         Scheduler scheduler = (Scheduler)InstancePool.get(
769                             className);
770 
771                         scheduler.unschedule();
772                     }
773                 }
774             }
775         }
776         catch (Exception e) {
777             _log.error(e, e);
778         }
779 
780         // Portlets
781 
782         try {
783             Iterator<Portlet> itr = portlets.iterator();
784 
785             while (itr.hasNext()) {
786                 Portlet portlet = itr.next();
787 
788                 PortletInstanceFactory.destroy(portlet);
789             }
790         }
791         catch (Exception e) {
792             _log.error(e, e);
793         }
794 
795         // Companies
796 
797         long[] companyIds = PortalInstances.getCompanyIds();
798 
799         for (int i = 0; i < companyIds.length; i++) {
800             destroyCompany(companyIds[i]);
801         }
802 
803         // Global shutdown events
804 
805         if (_log.isDebugEnabled()) {
806             _log.debug("Process global shutdown events");
807         }
808 
809         try {
810             EventsProcessor.process(
811                 PropsKeys.GLOBAL_SHUTDOWN_EVENTS,
812                 PropsValues.GLOBAL_SHUTDOWN_EVENTS);
813         }
814         catch (Exception e) {
815             _log.error(e, e);
816         }
817 
818         super.destroy();
819     }
820 
821     protected void checkWebSettings(String xml) throws DocumentException {
822         Document doc = DocumentUtil.readDocumentFromXML(xml);
823 
824         Element root = doc.getRootElement();
825 
826         int timeout = PropsValues.SESSION_TIMEOUT;
827 
828         Element sessionConfig = root.element("session-config");
829 
830         if (sessionConfig != null) {
831             String sessionTimeout = sessionConfig.elementText(
832                 "session-timeout");
833 
834             timeout = GetterUtil.getInteger(sessionTimeout, timeout);
835         }
836 
837         PropsUtil.set(PropsKeys.SESSION_TIMEOUT, String.valueOf(timeout));
838 
839         PropsValues.SESSION_TIMEOUT = timeout;
840     }
841 
842     protected void destroyCompany(long companyId) {
843         if (_log.isDebugEnabled()) {
844             _log.debug("Process shutdown events");
845         }
846 
847         try {
848             EventsProcessor.process(
849                 PropsKeys.APPLICATION_SHUTDOWN_EVENTS,
850                 PropsValues.APPLICATION_SHUTDOWN_EVENTS,
851                 new String[] {String.valueOf(companyId)});
852         }
853         catch (Exception e) {
854             _log.error(e, e);
855         }
856     }
857 
858     protected void initPortletApp(
859             Portlet portlet, ServletContext servletContext)
860         throws PortletException {
861 
862         PortletApp portletApp = portlet.getPortletApp();
863 
864         PortletConfig portletConfig = PortletConfigFactory.create(
865             portlet, servletContext);
866 
867         PortletContext portletContext = portletConfig.getPortletContext();
868 
869         Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
870 
871         for (PortletFilter portletFilter : portletFilters) {
872             PortletFilterFactory.create(portletFilter, portletContext);
873         }
874 
875         Set<PortletURLListener> portletURLListeners =
876             portletApp.getPortletURLListeners();
877 
878         for (PortletURLListener portletURLListener : portletURLListeners) {
879             PortletURLListenerFactory.create(portletURLListener);
880         }
881     }
882 
883     private static final String _LIFERAY_PORTAL_REQUEST_HEADER =
884         "Liferay-Portal";
885 
886     private static Log _log = LogFactory.getLog(MainServlet.class);
887 
888     private Set<String> _lastModifiedPaths;
889 
890 }