1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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.EventsProcessorUtil;
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.log.Log;
33  import com.liferay.portal.kernel.log.LogFactoryUtil;
34  import com.liferay.portal.kernel.plugin.PluginPackage;
35  import com.liferay.portal.kernel.poller.PollerProcessor;
36  import com.liferay.portal.kernel.pop.MessageListener;
37  import com.liferay.portal.kernel.search.Indexer;
38  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
39  import com.liferay.portal.kernel.servlet.PortletSessionTracker;
40  import com.liferay.portal.kernel.servlet.ProtectedServletRequest;
41  import com.liferay.portal.kernel.util.ContentTypes;
42  import com.liferay.portal.kernel.util.GetterUtil;
43  import com.liferay.portal.kernel.util.HttpUtil;
44  import com.liferay.portal.kernel.util.InstancePool;
45  import com.liferay.portal.kernel.util.ParamUtil;
46  import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
47  import com.liferay.portal.kernel.util.PortalInitableUtil;
48  import com.liferay.portal.kernel.util.PropsKeys;
49  import com.liferay.portal.kernel.util.ReleaseInfo;
50  import com.liferay.portal.kernel.util.StringPool;
51  import com.liferay.portal.kernel.util.Validator;
52  import com.liferay.portal.kernel.xml.Document;
53  import com.liferay.portal.kernel.xml.DocumentException;
54  import com.liferay.portal.kernel.xml.Element;
55  import com.liferay.portal.kernel.xml.SAXReaderUtil;
56  import com.liferay.portal.language.LanguageResources;
57  import com.liferay.portal.model.Company;
58  import com.liferay.portal.model.Group;
59  import com.liferay.portal.model.GroupConstants;
60  import com.liferay.portal.model.Layout;
61  import com.liferay.portal.model.Portlet;
62  import com.liferay.portal.model.PortletApp;
63  import com.liferay.portal.model.PortletFilter;
64  import com.liferay.portal.model.PortletURLListener;
65  import com.liferay.portal.model.User;
66  import com.liferay.portal.poller.PollerProcessorUtil;
67  import com.liferay.portal.pop.POPServerUtil;
68  import com.liferay.portal.security.auth.CompanyThreadLocal;
69  import com.liferay.portal.security.auth.PrincipalException;
70  import com.liferay.portal.security.auth.PrincipalThreadLocal;
71  import com.liferay.portal.security.permission.ResourceActionsUtil;
72  import com.liferay.portal.service.CompanyLocalServiceUtil;
73  import com.liferay.portal.service.GroupLocalServiceUtil;
74  import com.liferay.portal.service.LayoutLocalServiceUtil;
75  import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
76  import com.liferay.portal.service.PortletLocalServiceUtil;
77  import com.liferay.portal.service.ResourceActionLocalServiceUtil;
78  import com.liferay.portal.service.ResourceCodeLocalServiceUtil;
79  import com.liferay.portal.service.ThemeLocalServiceUtil;
80  import com.liferay.portal.service.UserLocalServiceUtil;
81  import com.liferay.portal.servlet.filters.i18n.I18nFilter;
82  import com.liferay.portal.struts.MultiMessageResources;
83  import com.liferay.portal.struts.PortletRequestProcessor;
84  import com.liferay.portal.struts.StrutsUtil;
85  import com.liferay.portal.util.ContentUtil;
86  import com.liferay.portal.util.MaintenanceUtil;
87  import com.liferay.portal.util.Portal;
88  import com.liferay.portal.util.PortalInstances;
89  import com.liferay.portal.util.PortalUtil;
90  import com.liferay.portal.util.PropsUtil;
91  import com.liferay.portal.util.PropsValues;
92  import com.liferay.portal.util.ShutdownUtil;
93  import com.liferay.portal.util.WebKeys;
94  import com.liferay.portal.velocity.VelocityContextPool;
95  import com.liferay.portal.webdav.WebDAVStorage;
96  import com.liferay.portal.webdav.WebDAVUtil;
97  import com.liferay.portlet.PortletConfigFactory;
98  import com.liferay.portlet.PortletFilterFactory;
99  import com.liferay.portlet.PortletInstanceFactoryUtil;
100 import com.liferay.portlet.PortletURLListenerFactory;
101 import com.liferay.portlet.social.model.SocialActivityInterpreter;
102 import com.liferay.portlet.social.model.SocialRequestInterpreter;
103 import com.liferay.portlet.social.model.impl.SocialActivityInterpreterImpl;
104 import com.liferay.portlet.social.model.impl.SocialRequestInterpreterImpl;
105 import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
106 import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
107 import com.liferay.util.servlet.DynamicServletRequest;
108 import com.liferay.util.servlet.EncryptedServletRequest;
109 
110 import java.io.IOException;
111 
112 import java.util.Iterator;
113 import java.util.List;
114 import java.util.Set;
115 
116 import javax.portlet.PortletConfig;
117 import javax.portlet.PortletContext;
118 import javax.portlet.PortletException;
119 
120 import javax.servlet.RequestDispatcher;
121 import javax.servlet.ServletContext;
122 import javax.servlet.ServletException;
123 import javax.servlet.http.HttpServletRequest;
124 import javax.servlet.http.HttpServletResponse;
125 import javax.servlet.http.HttpSession;
126 import javax.servlet.jsp.PageContext;
127 
128 import org.apache.struts.Globals;
129 import org.apache.struts.action.ActionServlet;
130 import org.apache.struts.action.RequestProcessor;
131 import org.apache.struts.config.ControllerConfig;
132 import org.apache.struts.config.ModuleConfig;
133 import org.apache.struts.tiles.TilesUtilImpl;
134 
135 /**
136  * <a href="MainServlet.java.html"><b><i>View Source</i></b></a>
137  *
138  * @author Brian Wing Shun Chan
139  * @author Jorge Ferrer
140  * @author Brian Myunghun Kim
141  */
142 public class MainServlet extends ActionServlet {
143 
144     public void init() throws ServletException {
145 
146         // Initialize
147 
148         if (_log.isDebugEnabled()) {
149             _log.debug("Initialize");
150         }
151 
152         super.init();
153 
154         // Startup events
155 
156         if (_log.isDebugEnabled()) {
157             _log.debug("Process startup events");
158         }
159 
160         try {
161             StartupAction startupAction = new StartupAction();
162 
163             startupAction.run(null);
164         }
165         catch (RuntimeException re) {
166             ShutdownUtil.shutdown(0);
167 
168             throw new ServletException(re);
169         }
170         catch (ActionException ae) {
171             _log.error(ae, ae);
172         }
173 
174         // Velocity
175 
176         String contextPath = PortalUtil.getPathContext();
177 
178         ServletContext servletContext = getServletContext();
179 
180         VelocityContextPool.put(contextPath, servletContext);
181 
182         // Plugin package
183 
184         if (_log.isDebugEnabled()) {
185             _log.debug("Initialize plugin package");
186         }
187 
188         PluginPackage pluginPackage = null;
189 
190         try {
191             pluginPackage =
192                 PluginPackageHotDeployListener.readPluginPackage(
193                     servletContext);
194         }
195         catch (Exception e) {
196             _log.error(e, e);
197         }
198 
199         // Portlets
200 
201         if (_log.isDebugEnabled()) {
202             _log.debug("Initialize portlets");
203         }
204 
205         List<Portlet> portlets = null;
206 
207         try {
208             String[] xmls = new String[] {
209                 HttpUtil.URLtoString(servletContext.getResource(
210                     "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
211                 HttpUtil.URLtoString(servletContext.getResource(
212                     "/WEB-INF/portlet-ext.xml")),
213                 HttpUtil.URLtoString(servletContext.getResource(
214                     "/WEB-INF/liferay-portlet.xml")),
215                 HttpUtil.URLtoString(servletContext.getResource(
216                     "/WEB-INF/liferay-portlet-ext.xml")),
217                 HttpUtil.URLtoString(servletContext.getResource(
218                     "/WEB-INF/web.xml"))
219             };
220 
221             PortletLocalServiceUtil.initEAR(
222                 servletContext, xmls, pluginPackage);
223 
224             portlets = PortletLocalServiceUtil.getPortlets();
225 
226             for (int i = 0; i < portlets.size(); i++) {
227                 Portlet portlet = portlets.get(i);
228 
229                 if (i == 0) {
230                     initPortletApp(portlet, servletContext);
231                 }
232 
233                 PortletInstanceFactoryUtil.create(portlet, servletContext);
234             }
235         }
236         catch (Exception e) {
237             _log.error(e, e);
238         }
239 
240         // Layout templates
241 
242         if (_log.isDebugEnabled()) {
243             _log.debug("Initialize layout templates");
244         }
245 
246         try {
247             String[] xmls = new String[] {
248                 HttpUtil.URLtoString(servletContext.getResource(
249                     "/WEB-INF/liferay-layout-templates.xml")),
250                 HttpUtil.URLtoString(servletContext.getResource(
251                     "/WEB-INF/liferay-layout-templates-ext.xml"))
252             };
253 
254             LayoutTemplateLocalServiceUtil.init(
255                 servletContext, xmls, pluginPackage);
256         }
257         catch (Exception e) {
258             _log.error(e, e);
259         }
260 
261         // Look and feel
262 
263         if (_log.isDebugEnabled()) {
264             _log.debug("Initialize look and feel");
265         }
266 
267         try {
268             String[] xmls = new String[] {
269                 HttpUtil.URLtoString(servletContext.getResource(
270                     "/WEB-INF/liferay-look-and-feel.xml")),
271                 HttpUtil.URLtoString(servletContext.getResource(
272                     "/WEB-INF/liferay-look-and-feel-ext.xml"))
273             };
274 
275             ThemeLocalServiceUtil.init(
276                 servletContext, null, true, xmls, pluginPackage);
277         }
278         catch (Exception e) {
279             _log.error(e, e);
280         }
281 
282         // Indexer
283 
284         if (_log.isDebugEnabled()) {
285             _log.debug("Indexer");
286         }
287 
288         try {
289             Iterator<Portlet> itr = portlets.iterator();
290 
291             while (itr.hasNext()) {
292                 Portlet portlet = itr.next();
293 
294                 String indexerClass = portlet.getIndexerClass();
295 
296                 if (!portlet.isActive() || Validator.isNull(indexerClass)) {
297                     continue;
298                 }
299 
300                 Indexer indexer = (Indexer)InstancePool.get(indexerClass);
301 
302                 for (String modelClassName : indexer.getClassNames()) {
303                     IndexerRegistryUtil.register(modelClassName, indexer);
304                 }
305             }
306         }
307         catch (Exception e) {
308             _log.error(e, e);
309         }
310 
311         // Scheduler
312 
313         if (_log.isDebugEnabled()) {
314             _log.debug("Scheduler");
315         }
316 
317         try {
318             if (PropsValues.SCHEDULER_ENABLED) {
319                 for (String className : PropsValues.SCHEDULER_CLASSES) {
320                     Scheduler scheduler = (Scheduler)InstancePool.get(
321                         className);
322 
323                     scheduler.schedule();
324                 }
325 
326                 Iterator<Portlet> itr = portlets.iterator();
327 
328                 while (itr.hasNext()) {
329                     Portlet portlet = itr.next();
330 
331                     String className = portlet.getSchedulerClass();
332 
333                     if (!portlet.isActive() || Validator.isNull(className)) {
334                         continue;
335                     }
336 
337                     Scheduler scheduler = (Scheduler)InstancePool.get(
338                         className);
339 
340                     scheduler.schedule();
341                 }
342             }
343         }
344         catch (Exception e) {
345             _log.error(e, e);
346         }
347 
348         // Poller processor
349 
350         if (_log.isDebugEnabled()) {
351             _log.debug("Poller processor");
352         }
353 
354         try {
355             Iterator<Portlet> itr = portlets.iterator();
356 
357             while (itr.hasNext()) {
358                 Portlet portlet = itr.next();
359 
360                 PollerProcessor pollerProcessor =
361                     portlet.getPollerProcessorInstance();
362 
363                 if (!portlet.isActive() || (pollerProcessor == null)) {
364                     continue;
365                 }
366 
367                 PollerProcessorUtil.addPollerProcessor(
368                     portlet.getPortletId(), pollerProcessor);
369             }
370         }
371         catch (Exception e) {
372             _log.error(e, e);
373         }
374 
375         // POP message listener
376 
377         if (_log.isDebugEnabled()) {
378             _log.debug("POP message listener");
379         }
380 
381         try {
382             Iterator<Portlet> itr = portlets.iterator();
383 
384             while (itr.hasNext()) {
385                 Portlet portlet = itr.next();
386 
387                 MessageListener popMessageListener =
388                     portlet.getPopMessageListenerInstance();
389 
390                 if (!portlet.isActive() || (popMessageListener == null)) {
391                     continue;
392                 }
393 
394                 POPServerUtil.addListener(popMessageListener);
395             }
396         }
397         catch (Exception e) {
398             _log.error(e, e);
399         }
400 
401         // Social activity interpreter
402 
403         if (_log.isDebugEnabled()) {
404             _log.debug("Social activity interpreter");
405         }
406 
407         try {
408             Iterator<Portlet> itr = portlets.iterator();
409 
410             while (itr.hasNext()) {
411                 Portlet portlet = itr.next();
412 
413                 SocialActivityInterpreter socialActivityInterpreter =
414                     portlet.getSocialActivityInterpreterInstance();
415 
416                 if (!portlet.isActive() ||
417                     (socialActivityInterpreter == null)) {
418 
419                     continue;
420                 }
421 
422                 socialActivityInterpreter = new SocialActivityInterpreterImpl(
423                     portlet.getPortletId(), socialActivityInterpreter);
424 
425                 SocialActivityInterpreterLocalServiceUtil.
426                     addActivityInterpreter(socialActivityInterpreter);
427             }
428         }
429         catch (Exception e) {
430             _log.error(e, e);
431         }
432 
433         // Social request interpreter
434 
435         if (_log.isDebugEnabled()) {
436             _log.debug("Social request interpreter");
437         }
438 
439         try {
440             Iterator<Portlet> itr = portlets.iterator();
441 
442             while (itr.hasNext()) {
443                 Portlet portlet = itr.next();
444 
445                 SocialRequestInterpreter socialRequestInterpreter =
446                     portlet.getSocialRequestInterpreterInstance();
447 
448                 if (!portlet.isActive() || (socialRequestInterpreter == null)) {
449                     continue;
450                 }
451 
452                 socialRequestInterpreter = new SocialRequestInterpreterImpl(
453                     portlet.getPortletId(), socialRequestInterpreter);
454 
455                 SocialRequestInterpreterLocalServiceUtil.
456                     addRequestInterpreter(socialRequestInterpreter);
457             }
458         }
459         catch (Exception e) {
460             _log.error(e, e);
461         }
462 
463         // WebDAV storage
464 
465         if (_log.isDebugEnabled()) {
466             _log.debug("WebDAV storage");
467         }
468 
469         try {
470             Iterator<Portlet> itr = portlets.iterator();
471 
472             while (itr.hasNext()) {
473                 Portlet portlet = itr.next();
474 
475                 WebDAVStorage webDAVStorage =
476                     portlet.getWebDAVStorageInstance();
477 
478                 if (!portlet.isActive() || (webDAVStorage == null)) {
479                     continue;
480                 }
481 
482                 webDAVStorage.setToken(portlet.getWebDAVStorageToken());
483 
484                 WebDAVUtil.addStorage(webDAVStorage);
485             }
486         }
487         catch (Exception e) {
488             _log.error(e, e);
489         }
490 
491         // Check web settings
492 
493         if (_log.isDebugEnabled()) {
494             _log.debug("Check web settings");
495         }
496 
497         try {
498             String xml = HttpUtil.URLtoString(
499                 servletContext.getResource("/WEB-INF/web.xml"));
500 
501             checkWebSettings(xml);
502         }
503         catch (Exception e) {
504             _log.error(e, e);
505         }
506 
507         // Global startup events
508 
509         if (_log.isDebugEnabled()) {
510             _log.debug("Process global startup events");
511         }
512 
513         try {
514             EventsProcessorUtil.process(
515                 PropsKeys.GLOBAL_STARTUP_EVENTS,
516                 PropsValues.GLOBAL_STARTUP_EVENTS);
517         }
518         catch (Exception e) {
519             _log.error(e, e);
520         }
521 
522         // Resource actions
523 
524         if (_log.isDebugEnabled()) {
525             _log.debug("Initialize resource actions");
526         }
527 
528         try {
529             Iterator<Portlet> itr = portlets.iterator();
530 
531             while (itr.hasNext()) {
532                 Portlet portlet = itr.next();
533 
534                 List<String> portletActions =
535                     ResourceActionsUtil.getPortletResourceActions(
536                         portlet.getPortletId());
537 
538                 ResourceActionLocalServiceUtil.checkResourceActions(
539                     portlet.getPortletId(), portletActions);
540 
541                 List<String> modelNames =
542                     ResourceActionsUtil.getPortletModelResources(
543                         portlet.getPortletId());
544 
545                 for (String modelName : modelNames) {
546                     List<String> modelActions =
547                         ResourceActionsUtil.getModelResourceActions(modelName);
548 
549                     ResourceActionLocalServiceUtil.checkResourceActions(
550                         modelName, modelActions);
551                 }
552             }
553         }
554         catch (Exception e) {
555             _log.error(e, e);
556         }
557 
558         // Companies
559 
560         String[] webIds = PortalInstances.getWebIds();
561 
562         for (int i = 0; i < webIds.length; i++) {
563             PortalInstances.initCompany(servletContext, webIds[i]);
564         }
565 
566         // Resource codes
567 
568         if (_log.isDebugEnabled()) {
569             _log.debug("Initialize resource codes");
570         }
571 
572         try {
573             long[] companyIds = PortalInstances.getCompanyIds();
574 
575             Iterator<Portlet> itr = portlets.iterator();
576 
577             while (itr.hasNext()) {
578                 Portlet portlet = itr.next();
579 
580                 List<String> modelNames =
581                     ResourceActionsUtil.getPortletModelResources(
582                         portlet.getPortletId());
583 
584                 for (long companyId : companyIds) {
585                     ResourceCodeLocalServiceUtil.checkResourceCodes(
586                         companyId, portlet.getPortletId());
587 
588                     for (String modelName : modelNames) {
589                         ResourceCodeLocalServiceUtil.checkResourceCodes(
590                             companyId, modelName);
591                     }
592                 }
593             }
594         }
595         catch (Exception e) {
596             _log.error(e, e);
597         }
598 
599         // Message resources
600 
601         if (_log.isDebugEnabled()) {
602             _log.debug("Initialize message resources");
603         }
604 
605         MultiMessageResources messageResources =
606             (MultiMessageResources)servletContext.getAttribute(
607                 Globals.MESSAGES_KEY);
608 
609         LanguageResources.init(messageResources);
610 
611         // See LEP-2885. Don't flush hot deploy events until after the portal
612         // has initialized.
613 
614         PortalInitableUtil.flushInitables();
615         HotDeployUtil.flushPrematureEvents();
616     }
617 
618     public void callParentService(
619             HttpServletRequest request, HttpServletResponse response)
620         throws IOException, ServletException {
621 
622         super.service(request, response);
623     }
624 
625     public void service(
626             HttpServletRequest request, HttpServletResponse response)
627         throws IOException, ServletException {
628 
629         if (_log.isDebugEnabled()) {
630             _log.debug("Process service request");
631         }
632 
633         if (ShutdownUtil.isShutdown()) {
634             response.setContentType(ContentTypes.TEXT_HTML_UTF8);
635 
636             String html = ContentUtil.get(
637                 "com/liferay/portal/dependencies/shutdown.html");
638 
639             response.getOutputStream().print(html);
640 
641             return;
642         }
643 
644         if (MaintenanceUtil.isMaintaining()) {
645             RequestDispatcher requestDispatcher = request.getRequestDispatcher(
646                 "/html/portal/maintenance.jsp");
647 
648             requestDispatcher.include(request, response);
649 
650             return;
651         }
652 
653         HttpSession session = request.getSession();
654 
655         // Company id
656 
657         long companyId = PortalInstances.getCompanyId(request);
658 
659         //CompanyThreadLocal.setCompanyId(companyId);
660 
661         // Portal port
662 
663         PortalUtil.setPortalPort(request);
664 
665         // CTX
666 
667         ServletContext servletContext = getServletContext();
668 
669         request.setAttribute(WebKeys.CTX, servletContext);
670 
671         // Struts module config
672 
673         ModuleConfig moduleConfig = getModuleConfig(request);
674 
675         // Portlet session tracker
676 
677         if (session.getAttribute(WebKeys.PORTLET_SESSION_TRACKER) == null ) {
678             session.setAttribute(
679                 WebKeys.PORTLET_SESSION_TRACKER,
680                 PortletSessionTracker.getInstance());
681         }
682 
683         // Portlet Request Processor
684 
685         PortletRequestProcessor portletReqProcessor =
686             (PortletRequestProcessor)servletContext.getAttribute(
687                 WebKeys.PORTLET_STRUTS_PROCESSOR);
688 
689         if (portletReqProcessor == null) {
690             portletReqProcessor =
691                 PortletRequestProcessor.getInstance(this, moduleConfig);
692 
693             servletContext.setAttribute(
694                 WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
695         }
696 
697         // Tiles definitions factory
698 
699         if (servletContext.getAttribute(
700                 TilesUtilImpl.DEFINITIONS_FACTORY) == null) {
701 
702             servletContext.setAttribute(
703                 TilesUtilImpl.DEFINITIONS_FACTORY,
704                 servletContext.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
705         }
706 
707         Object applicationAssociate = servletContext.getAttribute(
708             WebKeys.ASSOCIATE_KEY);
709 
710         if (servletContext.getAttribute(WebKeys.ASSOCIATE_KEY) == null) {
711             servletContext.setAttribute(
712                 WebKeys.ASSOCIATE_KEY, applicationAssociate);
713         }
714 
715         // Encrypt request
716 
717         if (ParamUtil.get(request, WebKeys.ENCRYPT, false)) {
718             try {
719                 Company company = CompanyLocalServiceUtil.getCompanyById(
720                     companyId);
721 
722                 request = new EncryptedServletRequest(
723                     request, company.getKeyObj());
724             }
725             catch (Exception e) {
726             }
727         }
728 
729         // Login
730 
731         long userId = PortalUtil.getUserId(request);
732         String remoteUser = request.getRemoteUser();
733 
734         // Is JAAS enabled?
735 
736         if (!PropsValues.PORTAL_JAAS_ENABLE) {
737             String jRemoteUser = (String)session.getAttribute("j_remoteuser");
738 
739             if (jRemoteUser != null) {
740                 remoteUser = jRemoteUser;
741 
742                 session.removeAttribute("j_remoteuser");
743             }
744         }
745 
746         if ((userId > 0) && (remoteUser == null)) {
747             remoteUser = String.valueOf(userId);
748         }
749 
750         // WebSphere will not return the remote user unless you are
751         // authenticated AND accessing a protected path. Other servers will
752         // return the remote user for all threads associated with an
753         // authenticated user. We use ProtectedServletRequest to ensure we get
754         // similar behavior across all servers.
755 
756         request = new ProtectedServletRequest(request, remoteUser);
757 
758         if ((userId > 0) || (remoteUser != null)) {
759 
760             // Set the principal associated with this thread
761 
762             String name = String.valueOf(userId);
763 
764             if (remoteUser != null) {
765                 name = remoteUser;
766             }
767 
768             PrincipalThreadLocal.setName(name);
769         }
770 
771         if ((userId <= 0) && (remoteUser != null)) {
772             try {
773 
774                 // User id
775 
776                 userId = GetterUtil.getLong(remoteUser);
777 
778                 // Pre login events
779 
780                 EventsProcessorUtil.process(
781                     PropsKeys.LOGIN_EVENTS_PRE, PropsValues.LOGIN_EVENTS_PRE,
782                     request, response);
783 
784                 // User
785 
786                 User user = UserLocalServiceUtil.getUserById(userId);
787 
788                 if (PropsValues.USERS_UPDATE_LAST_LOGIN) {
789                     UserLocalServiceUtil.updateLastLogin(
790                         userId, request.getRemoteAddr());
791                 }
792 
793                 // User id
794 
795                 session.setAttribute(WebKeys.USER_ID, new Long(userId));
796 
797                 // User locale
798 
799                 session.setAttribute(Globals.LOCALE_KEY, user.getLocale());
800 
801                 // Post login events
802 
803                 EventsProcessorUtil.process(
804                     PropsKeys.LOGIN_EVENTS_POST, PropsValues.LOGIN_EVENTS_POST,
805                     request, response);
806             }
807             catch (Exception e) {
808                 _log.error(e, e);
809             }
810         }
811 
812         // Pre service events
813 
814         try {
815             EventsProcessorUtil.process(
816                 PropsKeys.SERVLET_SERVICE_EVENTS_PRE,
817                 PropsValues.SERVLET_SERVICE_EVENTS_PRE, request, response);
818         }
819         catch (Exception e) {
820             Throwable cause = e.getCause();
821 
822             if (cause instanceof NoSuchLayoutException) {
823                 sendError(
824                     HttpServletResponse.SC_NOT_FOUND, cause, request, response);
825 
826                 return;
827             }
828             else if (cause instanceof PrincipalException) {
829                 processServicePrePrincipalException(
830                     cause, userId, request, response);
831 
832                 return;
833             }
834 
835             _log.error(e, e);
836 
837             request.setAttribute(PageContext.EXCEPTION, e);
838 
839             StrutsUtil.forward(
840                 PropsValues.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE,
841                 servletContext, request, response);
842 
843             return;
844         }
845 
846         if (request.getAttribute(
847                 AbsoluteRedirectsResponse.class.getName()) != null) {
848 
849             return;
850         }
851 
852         if (request.getAttribute(WebKeys.THEME_DISPLAY) == null) {
853             return;
854         }
855 
856         try {
857 
858             // Struts service
859 
860             callParentService(request, response);
861         }
862         finally {
863 
864             // Post service events
865 
866             try {
867                 EventsProcessorUtil.process(
868                     PropsKeys.SERVLET_SERVICE_EVENTS_POST,
869                     PropsValues.SERVLET_SERVICE_EVENTS_POST, request, response);
870             }
871             catch (Exception e) {
872                 _log.error(e, e);
873             }
874 
875             response.addHeader(
876                 _LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
877 
878             // Clear the company id associated with this thread
879 
880             CompanyThreadLocal.setCompanyId(0);
881 
882             // Clear the principal associated with this thread
883 
884             PrincipalThreadLocal.setName(null);
885         }
886     }
887 
888     public void destroy() {
889         List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
890 
891         // Scheduler
892 
893         if (_log.isDebugEnabled()) {
894             _log.debug("Scheduler");
895         }
896 
897         try {
898             if (PropsValues.SCHEDULER_ENABLED) {
899                 for (String className : PropsValues.SCHEDULER_CLASSES) {
900                     Scheduler scheduler = (Scheduler)InstancePool.get(
901                         className, false);
902 
903                     if (scheduler != null) {
904                         scheduler.unschedule();
905                     }
906                 }
907 
908                 Iterator<Portlet> itr = portlets.iterator();
909 
910                 while (itr.hasNext()) {
911                     Portlet portlet = itr.next();
912 
913                     String className = portlet.getSchedulerClass();
914 
915                     if (!portlet.isActive() || Validator.isNull(className)) {
916                         continue;
917                     }
918 
919                     Scheduler scheduler = (Scheduler)InstancePool.get(
920                         className, false);
921 
922                     if (scheduler != null) {
923                         scheduler.unschedule();
924                     }
925                 }
926             }
927         }
928         catch (Exception e) {
929             _log.error(e, e);
930         }
931 
932         // Portlets
933 
934         try {
935             Iterator<Portlet> itr = portlets.iterator();
936 
937             while (itr.hasNext()) {
938                 Portlet portlet = itr.next();
939 
940                 PortletInstanceFactoryUtil.destroy(portlet);
941             }
942         }
943         catch (Exception e) {
944             _log.error(e, e);
945         }
946 
947         // Companies
948 
949         long[] companyIds = PortalInstances.getCompanyIds();
950 
951         for (int i = 0; i < companyIds.length; i++) {
952             destroyCompany(companyIds[i]);
953         }
954 
955         // Global shutdown events
956 
957         if (_log.isDebugEnabled()) {
958             _log.debug("Process global shutdown events");
959         }
960 
961         try {
962             EventsProcessorUtil.process(
963                 PropsKeys.GLOBAL_SHUTDOWN_EVENTS,
964                 PropsValues.GLOBAL_SHUTDOWN_EVENTS);
965         }
966         catch (Exception e) {
967             _log.error(e, e);
968         }
969 
970         super.destroy();
971     }
972 
973     protected void checkWebSettings(String xml) throws DocumentException {
974         Document doc = SAXReaderUtil.read(xml);
975 
976         Element root = doc.getRootElement();
977 
978         int timeout = PropsValues.SESSION_TIMEOUT;
979 
980         Element sessionConfig = root.element("session-config");
981 
982         if (sessionConfig != null) {
983             String sessionTimeout = sessionConfig.elementText(
984                 "session-timeout");
985 
986             timeout = GetterUtil.getInteger(sessionTimeout, timeout);
987         }
988 
989         PropsUtil.set(PropsKeys.SESSION_TIMEOUT, String.valueOf(timeout));
990 
991         PropsValues.SESSION_TIMEOUT = timeout;
992 
993         I18nServlet.setLanguageIds(root);
994         I18nFilter.setLanguageIds(I18nServlet.getLanguageIds());
995     }
996 
997     protected void destroyCompany(long companyId) {
998         if (_log.isDebugEnabled()) {
999             _log.debug("Process shutdown events");
1000        }
1001
1002        try {
1003            EventsProcessorUtil.process(
1004                PropsKeys.APPLICATION_SHUTDOWN_EVENTS,
1005                PropsValues.APPLICATION_SHUTDOWN_EVENTS,
1006                new String[] {String.valueOf(companyId)});
1007        }
1008        catch (Exception e) {
1009            _log.error(e, e);
1010        }
1011    }
1012
1013    protected synchronized RequestProcessor getRequestProcessor(
1014            ModuleConfig moduleConfig)
1015        throws ServletException {
1016
1017        ServletContext servletContext = getServletContext();
1018
1019        String key = Globals.REQUEST_PROCESSOR_KEY + moduleConfig.getPrefix();
1020
1021        RequestProcessor processor =
1022            (RequestProcessor)servletContext.getAttribute(key);
1023
1024        if (processor == null) {
1025            ControllerConfig controllerConfig =
1026                moduleConfig.getControllerConfig();
1027
1028            String processorClass = controllerConfig.getProcessorClass();
1029
1030            ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
1031
1032            try {
1033                processor = (RequestProcessor)classLoader.loadClass(
1034                    processorClass).newInstance();
1035            }
1036            catch (Exception e) {
1037                throw new ServletException(e);
1038            }
1039
1040            processor.init(this, moduleConfig);
1041
1042            servletContext.setAttribute(key, processor);
1043        }
1044
1045        return processor;
1046    }
1047
1048    protected void initPortletApp(
1049            Portlet portlet, ServletContext servletContext)
1050        throws PortletException {
1051
1052        PortletApp portletApp = portlet.getPortletApp();
1053
1054        PortletConfig portletConfig = PortletConfigFactory.create(
1055            portlet, servletContext);
1056
1057        PortletContext portletContext = portletConfig.getPortletContext();
1058
1059        Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
1060
1061        for (PortletFilter portletFilter : portletFilters) {
1062            PortletFilterFactory.create(portletFilter, portletContext);
1063        }
1064
1065        Set<PortletURLListener> portletURLListeners =
1066            portletApp.getPortletURLListeners();
1067
1068        for (PortletURLListener portletURLListener : portletURLListeners) {
1069            PortletURLListenerFactory.create(portletURLListener);
1070        }
1071    }
1072
1073    protected void processServicePrePrincipalException(
1074            Throwable t, long userId, HttpServletRequest request,
1075            HttpServletResponse response)
1076        throws IOException, ServletException {
1077
1078        if (userId > 0) {
1079            sendError(
1080                HttpServletResponse.SC_UNAUTHORIZED, t, request, response);
1081
1082            return;
1083        }
1084
1085        String redirect =
1086            request.getContextPath() + Portal.PATH_MAIN + "/portal/login";
1087
1088        String currentURL = PortalUtil.getCurrentURL(request);
1089
1090        redirect = HttpUtil.addParameter(redirect, "redirect", currentURL);
1091
1092        long plid = ParamUtil.getLong(request, "p_l_id");
1093
1094        if (plid > 0) {
1095            try {
1096                Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1097
1098                if (layout.getGroup().isStagingGroup()) {
1099                    Group group = GroupLocalServiceUtil.getGroup(
1100                        layout.getCompanyId(), GroupConstants.GUEST);
1101
1102                    plid = group.getDefaultPublicPlid();
1103                }
1104                else if (layout.isPrivateLayout()) {
1105                    plid = LayoutLocalServiceUtil.getDefaultPlid(
1106                        layout.getGroupId(), false);
1107                }
1108
1109                redirect = HttpUtil.addParameter(redirect, "p_l_id", plid);
1110            }
1111            catch (Exception e) {
1112            }
1113        }
1114
1115        response.sendRedirect(redirect);
1116    }
1117
1118    protected void sendError(
1119            int status, Throwable t, HttpServletRequest request,
1120            HttpServletResponse response)
1121        throws IOException, ServletException {
1122
1123        DynamicServletRequest dynamicRequest = new DynamicServletRequest(
1124            request);
1125
1126        // Reset p_l_id or there will be an infinite loop
1127
1128        dynamicRequest.setParameter("p_l_id", StringPool.BLANK);
1129
1130        PortalUtil.sendError(status, (Exception)t, dynamicRequest, response);
1131    }
1132
1133    private static final String _LIFERAY_PORTAL_REQUEST_HEADER =
1134        "Liferay-Portal";
1135
1136    private static Log _log = LogFactoryUtil.getLog(MainServlet.class);
1137
1138}