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