1
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
124 public class MainServlet extends ActionServlet {
125
126 public void init() throws ServletException {
127
128
130 if (_log.isDebugEnabled()) {
131 _log.debug("Initialize");
132 }
133
134 super.init();
135
136
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
158 String contextPath = PortalUtil.getPathContext();
159
160 ServletContext servletContext = getServletContext();
161
162 VelocityContextPool.put(contextPath, servletContext);
163
164
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
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
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
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
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
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
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
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
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
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
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
426 String[] webIds = PortalInstances.getWebIds();
427
428 for (int i = 0; i < webIds.length; i++) {
429 PortalInstances.initCompany(servletContext, webIds[i]);
430 }
431
432
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
469 long companyId = PortalInstances.getCompanyId(request);
470
471
473
475 PortalUtil.setPortalPort(request);
476
477
479 ServletContext servletContext = getServletContext();
480
481 request.setAttribute(WebKeys.CTX, servletContext);
482
483
485 ModuleConfig moduleConfig = getModuleConfig(request);
486
487
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
529 if (session.getAttribute(WebKeys.PORTLET_SESSION_TRACKER) == null ) {
530 session.setAttribute(
531 WebKeys.PORTLET_SESSION_TRACKER,
532 PortletSessionTracker.getInstance());
533 }
534
535
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
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
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
583 PortalUtil.getCurrentURL(request);
584
585
587 long userId = PortalUtil.getUserId(request);
588 String remoteUser = request.getRemoteUser();
589
590
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
612 request = new ProtectedServletRequest(request, remoteUser);
613
614 if ((userId > 0) || (remoteUser != null)) {
615
616
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
632 userId = GetterUtil.getLong(remoteUser);
633
634
636 EventsProcessor.process(
637 PropsKeys.LOGIN_EVENTS_PRE, PropsValues.LOGIN_EVENTS_PRE,
638 request, response);
639
640
642 User user = UserLocalServiceUtil.getUserById(userId);
643
644 if (PropsValues.USERS_UPDATE_LAST_LOGIN) {
645 UserLocalServiceUtil.updateLastLogin(
646 userId, request.getRemoteAddr());
647 }
648
649
651 session.setAttribute(WebKeys.USER_ID, new Long(userId));
652
653
655 session.setAttribute(Globals.LOCALE_KEY, user.getLocale());
656
657
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
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
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
708 callParentService(request, response);
709 }
710 finally {
711
712
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
728 CompanyThreadLocal.setCompanyId(0);
729
730
732 PrincipalThreadLocal.setName(null);
733 }
734 }
735
736 public void destroy() {
737 List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();
738
739
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
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
791 long[] companyIds = PortalInstances.getCompanyIds();
792
793 for (int i = 0; i < companyIds.length; i++) {
794 destroyCompany(companyIds[i]);
795 }
796
797
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 }