/**
* Copyright (c) 2000-2005 Liferay, LLC. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.liferay.portal.servlet;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.PageContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.dotcms.cluster.common.ClusterServerActionThread;
import com.dotcms.enterprise.ClusterThreadProxy;
import com.dotcms.repackage.com.httpbridge.webproxy.http.TaskController;
import com.dotcms.repackage.org.apache.struts.Globals;
import com.dotcms.repackage.org.apache.struts.action.ActionServlet;
import com.dotcms.repackage.org.apache.struts.tiles.TilesUtilImpl;
import com.dotcms.repackage.org.dom4j.Document;
import com.dotcms.repackage.org.dom4j.DocumentException;
import com.dotcms.repackage.org.dom4j.Element;
import com.dotcms.repackage.org.dom4j.io.SAXReader;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.common.reindex.ReindexThread;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotRuntimeException;
import com.dotmarketing.servlets.InitServlet;
import com.dotmarketing.startup.StartupTasksExecutor;
import com.dotmarketing.util.Config;
import com.dotmarketing.util.Logger;
import com.liferay.portal.auth.PrincipalThreadLocal;
import com.liferay.portal.ejb.CompanyLocalManagerUtil;
import com.liferay.portal.ejb.PortletManagerUtil;
import com.liferay.portal.ejb.UserManagerUtil;
import com.liferay.portal.events.EventsProcessor;
import com.liferay.portal.events.StartupAction;
import com.liferay.portal.job.JobScheduler;
import com.liferay.portal.model.Company;
import com.liferay.portal.model.Portlet;
import com.liferay.portal.model.User;
import com.liferay.portal.struts.MultiMessageResources;
import com.liferay.portal.struts.PortletRequestProcessor;
import com.liferay.portal.struts.StrutsUtil;
import com.liferay.portal.util.ContentUtil;
import com.liferay.portal.util.CookieKeys;
import com.liferay.portal.util.PortalInstances;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portal.util.PropsUtil;
import com.liferay.portal.util.ShutdownUtil;
import com.liferay.portal.util.WebAppPool;
import com.liferay.portal.util.WebKeys;
import com.liferay.util.CookieUtil;
import com.liferay.util.GetterUtil;
import com.liferay.util.Http;
import com.liferay.util.ParamUtil;
import com.liferay.util.PwdGenerator;
import com.liferay.util.StringUtil;
import com.liferay.util.servlet.EncryptedServletRequest;
import com.liferay.util.servlet.UploadServletRequest;
/**
* <a href="MainServlet.java.html"><b><i>View Source</i></b></a>
*
* @author Brian Wing Shun Chan
* @author Jorge Ferrer
* @version $Revision: 1.41 $
*
*/
public class MainServlet extends ActionServlet {
public void init(ServletConfig config) throws ServletException {
synchronized (MainServlet.class) {
super.init(config);
Config.initializeConfig();
com.dotmarketing.util.Config.setMyApp(config.getServletContext());
// Need the plugin root dir before Hibernate comes up
try {
APILocator.getPluginAPI().setPluginJarDir(new File(config.getServletContext().getRealPath("WEB-INF/lib")));
} catch (IOException e1) {
Logger.debug(InitServlet.class, "IOException: " + e1.getMessage(), e1);
}
// Checking for execute upgrades
try {
StartupTasksExecutor.getInstance().executeUpgrades(config.getServletContext().getRealPath("."));
} catch (DotRuntimeException e1) {
throw new ServletException(e1);
} catch (DotDataException e1) {
throw new ServletException(e1);
}
// Starting the reindexation threads
ClusterThreadProxy.createThread();
if (Config.getBooleanProperty("DIST_INDEXATION_ENABLED", false)) {
ClusterThreadProxy.startThread(Config.getIntProperty("DIST_INDEXATION_SLEEP", 500), Config.getIntProperty("DIST_INDEXATION_INIT_DELAY", 5000));
}
ReindexThread.startThread(Config.getIntProperty("REINDEX_THREAD_SLEEP", 500), Config.getIntProperty("REINDEX_THREAD_INIT_DELAY", 5000));
//Start Cluster Server Action Thread.
ClusterServerActionThread.startThread(Config.getIntProperty("CLUSTER_SERVER_THREAD_SLEEP", 2000));
try {
EventsProcessor.process(new String[] { StartupAction.class.getName() }, true);
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
}
// Context path
ServletConfig sc = getServletConfig();
ServletContext ctx = getServletContext();
String ctxPath = GetterUtil.get(sc.getInitParameter("ctx_path"), "/");
ctx.setAttribute(WebKeys.CTX_PATH, StringUtil.replace(ctxPath + "/c", "//", "/"));
ctx.setAttribute(WebKeys.CAPTCHA_PATH, StringUtil.replace(ctxPath + "/captcha", "//", "/"));
ctx.setAttribute(WebKeys.IMAGE_PATH, StringUtil.replace(ctxPath + "/image", "//", "/"));
// Company id
_companyId = ctx.getInitParameter("company_id");
ctx.setAttribute(WebKeys.COMPANY_ID, _companyId);
// Initialize portlets
try {
String[] xmls = new String[] { Http.URLtoString(ctx.getResource("/WEB-INF/portlet.xml")),
Http.URLtoString(ctx.getResource("/WEB-INF/portlet-ext.xml")), Http.URLtoString(ctx.getResource("/WEB-INF/liferay-portlet.xml")),
Http.URLtoString(ctx.getResource("/WEB-INF/liferay-portlet-ext.xml")) };
PortletManagerUtil.initEAR(xmls);
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
}
// Initialize portlets display
try {
String xml = Http.URLtoString(ctx.getResource("/WEB-INF/liferay-display.xml"));
Map oldCategories = (Map) WebAppPool.get(_companyId, WebKeys.PORTLET_DISPLAY);
Map newCategories = PortletManagerUtil.getEARDisplay(xml);
Map mergedCategories = PortalUtil.mergeCategories(oldCategories, newCategories);
WebAppPool.put(_companyId, WebKeys.PORTLET_DISPLAY, mergedCategories);
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
}
// Initialize skins
//
// try {
// String[] xmls = new String[] { Http.URLtoString(ctx.getResource("/WEB-INF/liferay-skin.xml")),
// Http.URLtoString(ctx.getResource("/WEB-INF/liferay-skin-ext.xml")) };
//
// SkinManagerUtil.init(xmls);
// } catch (Exception e) {
// Logger.error(this, e.getMessage(), e);
// }
// Check company
try {
CompanyLocalManagerUtil.checkCompany(_companyId);
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
}
// Check web settings
try {
String xml = Http.URLtoString(ctx.getResource("/WEB-INF/web.xml"));
_checkWebSettings(xml);
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
}
// Scheduler
// try {
// Iterator itr =
// PortletManagerUtil.getPortlets(_companyId).iterator();
//
// while (itr.hasNext()) {
// Portlet portlet = (Portlet)itr.next();
//
// String className = portlet.getSchedulerClass();
//
// if (portlet.isActive() && className != null) {
// Scheduler scheduler =
// (Scheduler)InstancePool.get(className);
//
// scheduler.schedule();
// }
// }
// }
// catch (ObjectAlreadyExistsException oaee) {
// }
// catch (Exception e) {
// Logger.error(this,e.getMessage(),e);
// }
// Message Resources
MultiMessageResources messageResources = (MultiMessageResources) ctx.getAttribute(Globals.MESSAGES_KEY);
messageResources.setServletContext(ctx);
WebAppPool.put(_companyId, Globals.MESSAGES_KEY, messageResources);
// Current users
WebAppPool.put(_companyId, WebKeys.CURRENT_USERS, new TreeMap());
// HttpBridge
TaskController.bridgeUserServicePath = "/httpbridge/home";
TaskController.bridgeHttpServicePath = "/httpbridge/http";
TaskController.bridgeGotoTag = "(goto)";
TaskController.bridgeThenTag = "(then)";
TaskController.bridgePostTag = "(post)";
// Process startup events
try {
EventsProcessor.process(PropsUtil.getArray(PropsUtil.GLOBAL_STARTUP_EVENTS), true);
EventsProcessor.process(PropsUtil.getArray(PropsUtil.APPLICATION_STARTUP_EVENTS), new String[] { _companyId });
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
}
PortalInstances.init(_companyId);
}
}
public void callParentService(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
super.service(req, res);
}
public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
if (!PortalInstances.matches()) {
String html = ContentUtil.get("messages/en_US/init.html");
res.getOutputStream().print(html);
return;
}
if (ShutdownUtil.isShutdown()) {
String html = ContentUtil.get("messages/en_US/shutdown.html");
res.getOutputStream().print(html);
return;
}
req.setAttribute("dotcache", "no");
// Shared session
HttpSession ses = req.getSession();
if (!GetterUtil.getBoolean(PropsUtil.get(PropsUtil.TCK_URL))) {
String sharedSessionId = CookieUtil.get(req.getCookies(), CookieKeys.SHARED_SESSION_ID);
_log.debug("Shared session id is " + sharedSessionId);
if (sharedSessionId == null) {
sharedSessionId = PwdGenerator.getPassword(PwdGenerator.KEY1 + PwdGenerator.KEY2, 12);
Cookie sharedSessionIdCookie = new Cookie(CookieKeys.SHARED_SESSION_ID, sharedSessionId);
sharedSessionIdCookie.setPath("/");
sharedSessionIdCookie.setMaxAge(86400);
res.addCookie(sharedSessionIdCookie);
_log.debug("Shared session id is " + sharedSessionId);
}
// if (ses.getAttribute(WebKeys.SHARED_SESSION_ID) == null) {
ses.setAttribute(WebKeys.SHARED_SESSION_ID, sharedSessionId);
// }
HttpSession portalSes = (HttpSession) SharedSessionPool.get(sharedSessionId);
if ((portalSes == null) || (ses != portalSes)) {
if (portalSes == null) {
_log.debug("No session exists in pool");
} else {
_log.debug("Session " + portalSes.getId() + " in pool is old");
}
_log.debug("Inserting current session " + ses.getId() + " in pool");
SharedSessionPool.put(sharedSessionId, ses);
}
}
// Test CAS auto login
/*
* ses.setAttribute(
* com.liferay.portal.auth.CASAutoLogin.CAS_FILTER_USER,
* "liferay.com.1");
*/
// CTX
ServletContext ctx = getServletContext();
ServletContext portalCtx = ctx.getContext(PropsUtil.get(PropsUtil.PORTAL_CTX));
if (portalCtx == null) {
portalCtx = ctx;
}
req.setAttribute(WebKeys.CTX, portalCtx);
// CTX_PATH variable
String ctxPath = (String) ctx.getAttribute(WebKeys.CTX_PATH);
if (portalCtx.getAttribute(WebKeys.CTX_PATH) == null) {
portalCtx.setAttribute(WebKeys.CTX_PATH, ctxPath);
}
if (ses.getAttribute(WebKeys.CTX_PATH) == null) {
ses.setAttribute(WebKeys.CTX_PATH, ctxPath);
}
req.setAttribute(WebKeys.CTX_PATH, ctxPath);
// CAPTCHA_PATH variable
String captchaPath = (String) ctx.getAttribute(WebKeys.CAPTCHA_PATH);
if (portalCtx.getAttribute(WebKeys.CAPTCHA_PATH) == null) {
portalCtx.setAttribute(WebKeys.CAPTCHA_PATH, captchaPath);
}
if (ses.getAttribute(WebKeys.CAPTCHA_PATH) == null) {
ses.setAttribute(WebKeys.CAPTCHA_PATH, captchaPath);
}
req.setAttribute(WebKeys.CAPTCHA_PATH, captchaPath);
// IMAGE_PATH variable
String imagePath = (String) ctx.getAttribute(WebKeys.IMAGE_PATH);
if (portalCtx.getAttribute(WebKeys.IMAGE_PATH) == null) {
portalCtx.setAttribute(WebKeys.IMAGE_PATH, imagePath);
}
if (ses.getAttribute(WebKeys.IMAGE_PATH) == null) {
ses.setAttribute(WebKeys.IMAGE_PATH, imagePath);
}
req.setAttribute(WebKeys.IMAGE_PATH, imagePath);
// WebKeys.COMPANY_ID variable
String companyId = (String) ctx.getAttribute(WebKeys.COMPANY_ID);
if (portalCtx.getAttribute(WebKeys.COMPANY_ID) == null) {
portalCtx.setAttribute(WebKeys.COMPANY_ID, companyId);
}
if (ses.getAttribute(WebKeys.COMPANY_ID) == null) {
ses.setAttribute(WebKeys.COMPANY_ID, companyId);
}
req.setAttribute(WebKeys.COMPANY_ID, companyId);
// Portlet Request Processor
PortletRequestProcessor portletReqProcessor = (PortletRequestProcessor) portalCtx.getAttribute(WebKeys.PORTLET_STRUTS_PROCESSOR);
if (portletReqProcessor == null) {
portletReqProcessor = new PortletRequestProcessor(this, getModuleConfig(req));
portalCtx.setAttribute(WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
}
// Tiles definitions factory
if (portalCtx.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY) == null) {
portalCtx.setAttribute(TilesUtilImpl.DEFINITIONS_FACTORY, ctx.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
}
// Set character encoding
String strutsCharEncoding = PropsUtil.get(PropsUtil.STRUTS_CHAR_ENCODING);
req.setCharacterEncoding(strutsCharEncoding);
/*
* if (!BrowserSniffer.is_wml(req)) { res.setContentType(
* Constants.TEXT_HTML + "; charset=" + strutsCharEncoding); }
*/
// Determine content type
String contentType = req.getHeader("Content-Type");
if ((contentType != null) && (contentType.startsWith("multipart/form-data"))) {
req = new UploadServletRequest(req);
} else if (ParamUtil.get(req, WebKeys.ENCRYPT, false)) {
try {
Company company = CompanyLocalManagerUtil.getCompany(companyId);
req = new EncryptedServletRequest(req, company.getKeyObj());
} catch (Exception e) {
}
}
// Current URL
String completeURL = Http.getCompleteURL(req);
if (completeURL.indexOf("j_security_check") != -1) {
completeURL = ctxPath;
} else {
completeURL = completeURL.substring(completeURL.indexOf("://") + 3, completeURL.length());
completeURL = completeURL.substring(completeURL.indexOf("/"), completeURL.length());
}
req.setAttribute(WebKeys.CURRENT_URL, completeURL);
// Chat server
// Login
String userId = PortalUtil.getUserId(req);
if ((userId != null)) {
PrincipalThreadLocal.setName(userId);
}
if (userId == null) {
try {
User user = UserManagerUtil.getDefaultUser(companyId);
if(ses.getAttribute(Globals.LOCALE_KEY)==null)
ses.setAttribute(Globals.LOCALE_KEY, user.getLocale());
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
}
}
// Process pre service events
try {
EventsProcessor.process(PropsUtil.getArray(PropsUtil.SERVLET_SERVICE_EVENTS_PRE), req, res);
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
req.setAttribute(PageContext.EXCEPTION, e);
StrutsUtil.forward(PropsUtil.get(PropsUtil.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE), portalCtx, req, res);
}
// Struts service
callParentService(req, res);
// Process post service events
try {
EventsProcessor.process(PropsUtil.getArray(PropsUtil.SERVLET_SERVICE_EVENTS_POST), req, res);
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
}
// Clear the principal associated with this thread
PrincipalThreadLocal.setName(null);
}
public void destroy() {
// Destroy portlets
try {
Iterator itr = PortletManagerUtil.getPortlets(_companyId).iterator();
while (itr.hasNext()) {
Portlet portlet = (Portlet) itr.next();
PortalUtil.destroyPortletInstance(portlet);
}
} catch (Exception e) {
Logger.error(this, e.getMessage(), e);
}
// Scheduler
JobScheduler.shutdown();
// Parent
super.destroy();
}
private void _checkWebSettings(String xml) throws DocumentException {
SAXReader reader = new SAXReader();
reader.setEntityResolver(null);
Document doc = reader.read(new StringReader(xml));
Element root = doc.getRootElement();
int timeout = GetterUtil.getInteger(PropsUtil.get(PropsUtil.SESSION_TIMEOUT));
Element sessionConfig = root.element("session-config");
if (sessionConfig != null) {
String sessionTimeout = sessionConfig.elementText("session-timeout");
timeout = GetterUtil.get(sessionConfig.elementText("session-timeout"), timeout);
}
PropsUtil.set(PropsUtil.SESSION_TIMEOUT, Integer.toString(timeout));
}
private static final Log _log = LogFactory.getLog(MainServlet.class);
private String _companyId;
}