protected void sendHTML(
      HttpServletResponse response, String path, List<WebServerEntry> webServerEntries)
      throws Exception {

    Template template =
        TemplateManagerUtil.getTemplate(
            TemplateManager.FREEMARKER, _TEMPLATE_FTL, TemplateContextType.RESTRICTED);

    template.put("dateFormat", _dateFormat);
    template.put("entries", webServerEntries);
    template.put("path", HttpUtil.encodePath(path));

    if (_WEB_SERVER_SERVLET_VERSION_VERBOSITY_DEFAULT) {
    } else if (_WEB_SERVER_SERVLET_VERSION_VERBOSITY_PARTIAL) {
      template.put("releaseInfo", ReleaseInfo.getName());
    } else {
      template.put("releaseInfo", ReleaseInfo.getReleaseInfo());
    }

    template.put("validator", Validator_IW.getInstance());

    response.setContentType(ContentTypes.TEXT_HTML_UTF8);

    template.processTemplate(response.getWriter());
  }
  protected boolean processServicePre(
      HttpServletRequest request, HttpServletResponse response, long userId)
      throws IOException, ServletException {

    try {
      EventsProcessorUtil.process(
          PropsKeys.SERVLET_SERVICE_EVENTS_PRE,
          PropsValues.SERVLET_SERVICE_EVENTS_PRE,
          request,
          response);
    } catch (Exception e) {
      Throwable cause = e.getCause();

      if (cause instanceof NoSuchLayoutException) {
        sendError(HttpServletResponse.SC_NOT_FOUND, cause, request, response);

        return true;
      } else if (cause instanceof PrincipalException) {
        processServicePrePrincipalException(cause, userId, request, response);

        return true;
      }

      _log.error(e, e);

      request.setAttribute(PageContext.EXCEPTION, e);

      ServletContext servletContext = getServletContext();

      StrutsUtil.forward(
          PropsValues.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE, servletContext, request, response);

      return true;
    }

    if (_HTTP_HEADER_VERSION_VERBOSITY_DEFAULT) {
    } else if (_HTTP_HEADER_VERSION_VERBOSITY_PARTIAL) {
      response.addHeader(_LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getName());
    } else {
      response.addHeader(_LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
    }

    return false;
  }
  protected Response doExecuteMethod(String url, String methodName, Object[] arguments)
      throws Exception {

    if (_log.isDebugEnabled()) {
      StringBundler sb = new StringBundler();

      sb.append("XML-RPC invoking ");
      sb.append(methodName);
      sb.append(" ");

      if (arguments != null) {
        for (int i = 0; i < arguments.length; i++) {
          sb.append(arguments[i]);

          if (i < (arguments.length - 1)) {
            sb.append(", ");
          }
        }
      }

      _log.debug(sb.toString());
    }

    String requestXML = XmlRpcParser.buildMethod(methodName, arguments);

    Http.Options options = new Http.Options();

    if (_HTTP_HEADER_VERSION_VERBOSITY_DEFAULT) {
    } else if (_HTTP_HEADER_VERSION_VERBOSITY_PARTIAL) {
      options.addHeader(HttpHeaders.USER_AGENT, ReleaseInfo.getName());
    } else {
      options.addHeader(HttpHeaders.USER_AGENT, ReleaseInfo.getServerInfo());
    }

    options.setBody(requestXML, ContentTypes.TEXT_XML, StringPool.UTF8);
    options.setLocation(url);
    options.setPost(true);

    String responseXML = HttpUtil.URLtoString(options);

    return XmlRpcParser.parseResponse(responseXML);
  }
/**
 * @author Brian Wing Shun Chan
 * @author Jorge Ferrer
 * @author Brian Myunghun Kim
 */
public class MainServlet extends ActionServlet {

  @Override
  public void destroy() {
    if (_log.isDebugEnabled()) {
      _log.debug("Destroy plugins");
    }

    PortalLifecycleUtil.flushDestroys();

    List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();

    if (_log.isDebugEnabled()) {
      _log.debug("Destroy portlets");
    }

    try {
      destroyPortlets(portlets);
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Destroy companies");
    }

    try {
      destroyCompanies();
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Process global shutdown events");
    }

    try {
      processGlobalShutdownEvents();
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Destroy");
    }

    callParentDestroy();
  }

  @Override
  public void init() throws ServletException {
    if (_log.isDebugEnabled()) {
      _log.debug("Initialize");
    }

    ServletContext servletContext = getServletContext();

    servletContext.setAttribute(MainServlet.class.getName(), Boolean.TRUE);

    callParentInit();

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize servlet context pool");
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Process startup events");
    }

    try {
      processStartupEvents();
    } catch (Exception e) {
      _log.error(e, e);

      System.out.println("Stopping the server due to unexpected startup errors");

      System.exit(0);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize server detector");
    }

    try {
      initServerDetector();
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize plugin package");
    }

    PluginPackage pluginPackage = null;

    try {
      pluginPackage = initPluginPackage();
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize portlets");
    }

    List<Portlet> portlets = new ArrayList<Portlet>();

    try {
      portlets.addAll(initPortlets(pluginPackage));
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize layout templates");
    }

    try {
      initLayoutTemplates(pluginPackage, portlets);
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize social");
    }

    try {
      initSocial(pluginPackage);
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize themes");
    }

    try {
      initThemes(pluginPackage, portlets);
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize web settings");
    }

    try {
      initWebSettings();
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize extension environment");
    }

    try {
      initExt();
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Process global startup events");
    }

    try {
      processGlobalStartupEvents();
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize resource actions");
    }

    try {
      initResourceActions(portlets);
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize companies");
    }

    try {
      initCompanies();
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Initialize plugins");
    }

    try {
      initPlugins();
    } catch (Exception e) {
      _log.error(e, e);
    }

    servletContext.setAttribute(WebKeys.STARTUP_FINISHED, true);

    StartupHelperUtil.setStartupFinished(true);

    ThreadLocalCacheManager.clearAll(Lifecycle.REQUEST);
  }

  @Override
  public void service(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    if (_log.isDebugEnabled()) {
      _log.debug("Process service request");
    }

    if (processShutdownRequest(request, response)) {
      if (_log.isDebugEnabled()) {
        _log.debug("Processed shutdown request");
      }

      return;
    }

    if (processMaintenanceRequest(request, response)) {
      if (_log.isDebugEnabled()) {
        _log.debug("Processed maintenance request");
      }

      return;
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Get company id");
    }

    long companyId = getCompanyId(request);

    if (processCompanyInactiveRequest(request, response, companyId)) {
      if (_log.isDebugEnabled()) {
        _log.debug("Processed company inactive request");
      }

      return;
    }

    try {
      if (processGroupInactiveRequest(request, response)) {
        if (_log.isDebugEnabled()) {
          _log.debug("Processed site inactive request");
        }

        return;
      }
    } catch (Exception e) {
      if (e instanceof NoSuchLayoutException) {
        if (_log.isDebugEnabled()) {
          _log.debug(e, e);
        }
      } else {
        _log.error(e, e);
      }
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Set portal port");
    }

    setPortalPort(request);

    if (_log.isDebugEnabled()) {
      _log.debug("Check variables");
    }

    checkServletContext(request);
    checkPortletRequestProcessor(request);
    checkTilesDefinitionsFactory();

    if (_log.isDebugEnabled()) {
      _log.debug("Handle non-serializable request");
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Encrypt request");
    }

    request = encryptRequest(request, companyId);

    long userId = getUserId(request);

    String remoteUser = getRemoteUser(request, userId);

    if (_log.isDebugEnabled()) {
      _log.debug("Protect request");
    }

    request = protectRequest(request, remoteUser);

    if (_log.isDebugEnabled()) {
      _log.debug("Set principal");
    }

    String password = getPassword(request);

    setPrincipal(companyId, userId, remoteUser, password);

    try {
      if (_log.isDebugEnabled()) {
        _log.debug("Authenticate user id " + userId + " and remote user " + remoteUser);
      }

      userId = loginUser(request, response, companyId, userId, remoteUser);

      if (_log.isDebugEnabled()) {
        _log.debug("Authenticated user id " + userId);
      }
    } catch (Exception e) {
      _log.error(e, e);
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Set session thread local");
    }

    PortalSessionThreadLocal.setHttpSession(request.getSession());

    if (_log.isDebugEnabled()) {
      _log.debug("Process service pre events");
    }

    if (processServicePre(request, response, userId)) {
      if (_log.isDebugEnabled()) {
        _log.debug("Processing service pre events has errors");
      }

      return;
    }

    if (hasAbsoluteRedirect(request)) {
      if (_log.isDebugEnabled()) {
        String currentURL = PortalUtil.getCurrentURL(request);

        _log.debug("Current URL " + currentURL + " has absolute redirect");
      }

      return;
    }

    if (!hasThemeDisplay(request)) {
      if (_log.isDebugEnabled()) {
        String currentURL = PortalUtil.getCurrentURL(request);

        _log.debug("Current URL " + currentURL + " does not have a theme display");
      }

      return;
    }

    try {
      if (_log.isDebugEnabled()) {
        _log.debug("Call parent service");
      }

      callParentService(request, response);
    } finally {
      if (_log.isDebugEnabled()) {
        _log.debug("Process service post events");
      }

      processServicePost(request, response);
    }
  }

  protected void callParentDestroy() {
    super.destroy();
  }

  protected void callParentInit() throws ServletException {
    super.init();
  }

  protected void callParentService(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    super.service(request, response);
  }

  protected void checkPortletRequestProcessor(HttpServletRequest request) throws ServletException {

    ServletContext servletContext = getServletContext();

    PortletRequestProcessor portletReqProcessor =
        (PortletRequestProcessor) servletContext.getAttribute(WebKeys.PORTLET_STRUTS_PROCESSOR);

    if (portletReqProcessor == null) {
      ModuleConfig moduleConfig = getModuleConfig(request);

      portletReqProcessor = PortletRequestProcessor.getInstance(this, moduleConfig);

      servletContext.setAttribute(WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
    }
  }

  protected void checkServletContext(HttpServletRequest request) {
    ServletContext servletContext = getServletContext();

    request.setAttribute(WebKeys.CTX, servletContext);

    String contextPath = request.getContextPath();

    servletContext.setAttribute(WebKeys.CTX_PATH, contextPath);
  }

  protected void checkTilesDefinitionsFactory() {
    ServletContext servletContext = getServletContext();

    if (servletContext.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY) != null) {

      return;
    }

    servletContext.setAttribute(
        TilesUtilImpl.DEFINITIONS_FACTORY,
        servletContext.getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY));
  }

  protected void checkWebSettings(String xml) throws DocumentException {
    Document doc = SAXReaderUtil.read(xml);

    Element root = doc.getRootElement();

    int timeout = PropsValues.SESSION_TIMEOUT;

    Element sessionConfig = root.element("session-config");

    if (sessionConfig != null) {
      String sessionTimeout = sessionConfig.elementText("session-timeout");

      timeout = GetterUtil.getInteger(sessionTimeout, timeout);
    }

    PropsUtil.set(PropsKeys.SESSION_TIMEOUT, String.valueOf(timeout));

    PropsValues.SESSION_TIMEOUT = timeout;

    I18nServlet.setLanguageIds(root);
    I18nFilter.setLanguageIds(I18nServlet.getLanguageIds());
  }

  protected void destroyCompanies() throws Exception {
    long[] companyIds = PortalInstances.getCompanyIds();

    for (long companyId : companyIds) {
      destroyCompany(companyId);
    }
  }

  protected void destroyCompany(long companyId) {
    if (_log.isDebugEnabled()) {
      _log.debug("Process shutdown events");
    }

    try {
      EventsProcessorUtil.process(
          PropsKeys.APPLICATION_SHUTDOWN_EVENTS,
          PropsValues.APPLICATION_SHUTDOWN_EVENTS,
          new String[] {String.valueOf(companyId)});
    } catch (Exception e) {
      _log.error(e, e);
    }
  }

  protected void destroyPortlets(List<Portlet> portlets) throws Exception {
    for (Portlet portlet : portlets) {
      PortletInstanceFactoryUtil.destroy(portlet);
    }
  }

  protected HttpServletRequest encryptRequest(HttpServletRequest request, long companyId) {

    boolean encryptRequest = ParamUtil.getBoolean(request, WebKeys.ENCRYPT);

    if (!encryptRequest) {
      return request;
    }

    try {
      Company company = CompanyLocalServiceUtil.getCompanyById(companyId);

      request = new EncryptedServletRequest(request, company.getKeyObj());
    } catch (Exception e) {
    }

    return request;
  }

  protected long getCompanyId(HttpServletRequest request) {
    return PortalInstances.getCompanyId(request);
  }

  protected String getPassword(HttpServletRequest request) {
    return PortalUtil.getUserPassword(request);
  }

  protected String getRemoteUser(HttpServletRequest request, long userId) {
    String remoteUser = request.getRemoteUser();

    if (!PropsValues.PORTAL_JAAS_ENABLE) {
      HttpSession session = request.getSession();

      String jRemoteUser = (String) session.getAttribute("j_remoteuser");

      if (jRemoteUser != null) {
        remoteUser = jRemoteUser;

        session.removeAttribute("j_remoteuser");
      }
    }

    if ((userId > 0) && (remoteUser == null)) {
      remoteUser = String.valueOf(userId);
    }

    return remoteUser;
  }

  @Override
  protected synchronized RequestProcessor getRequestProcessor(ModuleConfig moduleConfig)
      throws ServletException {

    ServletContext servletContext = getServletContext();

    String key = Globals.REQUEST_PROCESSOR_KEY + moduleConfig.getPrefix();

    RequestProcessor requestProcessor = (RequestProcessor) servletContext.getAttribute(key);

    if (requestProcessor == null) {
      ControllerConfig controllerConfig = moduleConfig.getControllerConfig();

      try {
        requestProcessor =
            (RequestProcessor)
                InstanceFactory.newInstance(
                    ClassLoaderUtil.getPortalClassLoader(), controllerConfig.getProcessorClass());
      } catch (Exception e) {
        throw new ServletException(e);
      }

      requestProcessor.init(this, moduleConfig);

      servletContext.setAttribute(key, requestProcessor);
    }

    return requestProcessor;
  }

  protected long getUserId(HttpServletRequest request) {
    return PortalUtil.getUserId(request);
  }

  protected boolean hasAbsoluteRedirect(HttpServletRequest request) {
    if (request.getAttribute(AbsoluteRedirectsResponse.class.getName()) == null) {

      return false;
    } else {
      return true;
    }
  }

  protected boolean hasThemeDisplay(HttpServletRequest request) {
    if (request.getAttribute(WebKeys.THEME_DISPLAY) == null) {
      return false;
    } else {
      return true;
    }
  }

  protected void initCompanies() throws Exception {
    ServletContext servletContext = getServletContext();

    try {
      String[] webIds = PortalInstances.getWebIds();

      for (String webId : webIds) {
        PortalInstances.initCompany(servletContext, webId);
      }
    } finally {
      CompanyThreadLocal.setCompanyId(PortalInstances.getDefaultCompanyId());

      ShardDataSourceTargetSource shardDataSourceTargetSource =
          (ShardDataSourceTargetSource) InfrastructureUtil.getShardDataSourceTargetSource();

      if (shardDataSourceTargetSource != null) {
        shardDataSourceTargetSource.resetDataSource();
      }
    }
  }

  protected void initExt() throws Exception {
    ServletContext servletContext = getServletContext();

    ExtRegistry.registerPortal(servletContext);
  }

  protected void initLayoutTemplates(PluginPackage pluginPackage, List<Portlet> portlets)
      throws Exception {

    ServletContext servletContext = getServletContext();

    String[] xmls =
        new String[] {
          HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/liferay-layout-templates.xml")),
          HttpUtil.URLtoString(
              servletContext.getResource("/WEB-INF/liferay-layout-templates-ext.xml"))
        };

    List<LayoutTemplate> layoutTemplates =
        LayoutTemplateLocalServiceUtil.init(servletContext, xmls, pluginPackage);

    servletContext.setAttribute(WebKeys.PLUGIN_LAYOUT_TEMPLATES, layoutTemplates);
  }

  protected PluginPackage initPluginPackage() throws Exception {
    ServletContext servletContext = getServletContext();

    return PluginPackageUtil.readPluginPackageServletContext(servletContext);
  }

  /** @see SetupWizardUtil#_initPlugins */
  protected void initPlugins() throws Exception {

    // See LEP-2885. Don't flush hot deploy events until after the portal
    // has initialized.

    if (SetupWizardUtil.isSetupFinished()) {
      HotDeployUtil.setCapturePrematureEvents(false);

      PortalLifecycleUtil.flushInits();
    }
  }

  protected void initPortletApp(Portlet portlet, ServletContext servletContext)
      throws PortletException {

    PortletApp portletApp = portlet.getPortletApp();

    PortletConfig portletConfig = PortletConfigFactoryUtil.create(portlet, servletContext);

    PortletContext portletContext = portletConfig.getPortletContext();

    Set<PortletFilter> portletFilters = portletApp.getPortletFilters();

    for (PortletFilter portletFilter : portletFilters) {
      PortletFilterFactory.create(portletFilter, portletContext);
    }

    Set<PortletURLListener> portletURLListeners = portletApp.getPortletURLListeners();

    for (PortletURLListener portletURLListener : portletURLListeners) {
      PortletURLListenerFactory.create(portletURLListener);
    }
  }

  protected List<Portlet> initPortlets(PluginPackage pluginPackage) throws Exception {

    ServletContext servletContext = getServletContext();

    String[] xmls =
        new String[] {
          HttpUtil.URLtoString(
              servletContext.getResource("/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
          HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/portlet-ext.xml")),
          HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/liferay-portlet.xml")),
          HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/liferay-portlet-ext.xml")),
          HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/web.xml"))
        };

    PortletLocalServiceUtil.initEAR(servletContext, xmls, pluginPackage);

    PortletBagFactory portletBagFactory = new PortletBagFactory();

    portletBagFactory.setClassLoader(ClassLoaderUtil.getPortalClassLoader());
    portletBagFactory.setServletContext(servletContext);
    portletBagFactory.setWARFile(false);

    List<Portlet> portlets = PortletLocalServiceUtil.getPortlets();

    for (int i = 0; i < portlets.size(); i++) {
      Portlet portlet = portlets.get(i);

      portletBagFactory.create(portlet);

      if (i == 0) {
        initPortletApp(portlet, servletContext);
      }
    }

    servletContext.setAttribute(WebKeys.PLUGIN_PORTLETS, portlets);

    return portlets;
  }

  protected void initResourceActions(List<Portlet> portlets) throws Exception {

    for (Portlet portlet : portlets) {
      List<String> portletActions = ResourceActionsUtil.getPortletResourceActions(portlet);

      ResourceActionLocalServiceUtil.checkResourceActions(portlet.getPortletId(), portletActions);

      List<String> modelNames =
          ResourceActionsUtil.getPortletModelResources(portlet.getPortletId());

      for (String modelName : modelNames) {
        List<String> modelActions = ResourceActionsUtil.getModelResourceActions(modelName);

        ResourceActionLocalServiceUtil.checkResourceActions(modelName, modelActions);
      }
    }
  }

  protected void initServerDetector() throws Exception {
    ServerCapabilitiesUtil.determineServerCapabilities(getServletContext());
  }

  protected void initSocial(PluginPackage pluginPackage) throws Exception {
    ClassLoader classLoader = ClassLoaderUtil.getPortalClassLoader();

    ServletContext servletContext = getServletContext();

    String[] xmls =
        new String[] {
          HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/liferay-social.xml")),
          HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/liferay-social-ext.xml"))
        };

    SocialConfigurationUtil.read(classLoader, xmls);
  }

  protected void initThemes(PluginPackage pluginPackage, List<Portlet> portlets) throws Exception {

    ServletContext servletContext = getServletContext();

    String[] xmls =
        new String[] {
          HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/liferay-look-and-feel.xml")),
          HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/liferay-look-and-feel-ext.xml"))
        };

    List<Theme> themes =
        ThemeLocalServiceUtil.init(servletContext, null, true, xmls, pluginPackage);

    servletContext.setAttribute(WebKeys.PLUGIN_THEMES, themes);
  }

  protected void initWebSettings() throws Exception {
    ServletContext servletContext = getServletContext();

    String xml = HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/web.xml"));

    checkWebSettings(xml);
  }

  protected long loginUser(
      HttpServletRequest request,
      HttpServletResponse response,
      long companyId,
      long userId,
      String remoteUser)
      throws PortalException, SystemException {

    if ((userId > 0) || (remoteUser == null)) {
      return userId;
    }

    if (PropsValues.PORTAL_JAAS_ENABLE) {
      userId = JAASHelper.getJaasUserId(companyId, remoteUser);
    } else {
      userId = GetterUtil.getLong(remoteUser);
    }

    EventsProcessorUtil.process(
        PropsKeys.LOGIN_EVENTS_PRE, PropsValues.LOGIN_EVENTS_PRE, request, response);

    User user = UserLocalServiceUtil.getUserById(userId);

    if (PropsValues.USERS_UPDATE_LAST_LOGIN) {
      UserLocalServiceUtil.updateLastLogin(userId, request.getRemoteAddr());
    }

    HttpSession session = request.getSession();

    session.setAttribute(WebKeys.USER, user);
    session.setAttribute(WebKeys.USER_ID, new Long(userId));
    session.setAttribute(Globals.LOCALE_KEY, user.getLocale());

    EventsProcessorUtil.process(
        PropsKeys.LOGIN_EVENTS_POST, PropsValues.LOGIN_EVENTS_POST, request, response);

    return userId;
  }

  protected boolean processCompanyInactiveRequest(
      HttpServletRequest request, HttpServletResponse response, long companyId) throws IOException {

    if (PortalInstances.isCompanyActive(companyId)) {
      return false;
    }

    processInactiveRequest(
        request, response, "this-instance-is-inactive-please-contact-the-administrator");

    return true;
  }

  protected void processGlobalShutdownEvents() throws Exception {
    EventsProcessorUtil.process(
        PropsKeys.GLOBAL_SHUTDOWN_EVENTS, PropsValues.GLOBAL_SHUTDOWN_EVENTS);

    super.destroy();
  }

  protected void processGlobalStartupEvents() throws Exception {
    EventsProcessorUtil.process(PropsKeys.GLOBAL_STARTUP_EVENTS, PropsValues.GLOBAL_STARTUP_EVENTS);
  }

  protected boolean processGroupInactiveRequest(
      HttpServletRequest request, HttpServletResponse response)
      throws IOException, PortalException, SystemException {

    long plid = ParamUtil.getLong(request, "p_l_id");

    if (plid <= 0) {
      return false;
    }

    Layout layout = LayoutLocalServiceUtil.getLayout(plid);

    Group group = layout.getGroup();

    if (group.isActive()) {
      return false;
    }

    processInactiveRequest(
        request, response, "this-site-is-inactive-please-contact-the-administrator");

    return true;
  }

  protected void processInactiveRequest(
      HttpServletRequest request, HttpServletResponse response, String messageKey)
      throws IOException {

    response.setContentType(ContentTypes.TEXT_HTML_UTF8);

    Locale locale = LocaleUtil.getDefault();

    String message = LanguageUtil.get(locale, messageKey);

    String html = ContentUtil.get("com/liferay/portal/dependencies/inactive.html");

    html = StringUtil.replace(html, "[$MESSAGE$]", message);

    PrintWriter printWriter = response.getWriter();

    printWriter.print(html);
  }

  protected boolean processMaintenanceRequest(
      HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    if (!MaintenanceUtil.isMaintaining()) {
      return false;
    }

    RequestDispatcher requestDispatcher =
        request.getRequestDispatcher("/html/portal/maintenance.jsp");

    requestDispatcher.include(request, response);

    return true;
  }

  protected void processServicePost(HttpServletRequest request, HttpServletResponse response) {

    try {
      EventsProcessorUtil.process(
          PropsKeys.SERVLET_SERVICE_EVENTS_POST,
          PropsValues.SERVLET_SERVICE_EVENTS_POST,
          request,
          response);
    } catch (Exception e) {
      _log.error(e, e);
    }
  }

  protected boolean processServicePre(
      HttpServletRequest request, HttpServletResponse response, long userId)
      throws IOException, ServletException {

    try {
      EventsProcessorUtil.process(
          PropsKeys.SERVLET_SERVICE_EVENTS_PRE,
          PropsValues.SERVLET_SERVICE_EVENTS_PRE,
          request,
          response);
    } catch (Exception e) {
      Throwable cause = e.getCause();

      if (cause instanceof NoSuchLayoutException) {
        sendError(HttpServletResponse.SC_NOT_FOUND, cause, request, response);

        return true;
      } else if (cause instanceof PrincipalException) {
        processServicePrePrincipalException(cause, userId, request, response);

        return true;
      }

      _log.error(e, e);

      request.setAttribute(PageContext.EXCEPTION, e);

      ServletContext servletContext = getServletContext();

      StrutsUtil.forward(
          PropsValues.SERVLET_SERVICE_EVENTS_PRE_ERROR_PAGE, servletContext, request, response);

      return true;
    }

    if (_HTTP_HEADER_VERSION_VERBOSITY_DEFAULT) {
    } else if (_HTTP_HEADER_VERSION_VERBOSITY_PARTIAL) {
      response.addHeader(_LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getName());
    } else {
      response.addHeader(_LIFERAY_PORTAL_REQUEST_HEADER, ReleaseInfo.getReleaseInfo());
    }

    return false;
  }

  protected void processServicePrePrincipalException(
      Throwable t, long userId, HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    if (userId > 0) {
      sendError(HttpServletResponse.SC_UNAUTHORIZED, t, request, response);

      return;
    }

    String redirect = PortalUtil.getPathMain().concat("/portal/login");

    String currentURL = PortalUtil.getCurrentURL(request);

    redirect = HttpUtil.addParameter(redirect, "redirect", currentURL);

    long plid = ParamUtil.getLong(request, "p_l_id");

    if (plid > 0) {
      try {
        Layout layout = LayoutLocalServiceUtil.getLayout(plid);

        Group group = layout.getGroup();

        plid = group.getDefaultPublicPlid();

        if ((plid == LayoutConstants.DEFAULT_PLID) || group.isStagingGroup()) {

          Group guestGroup =
              GroupLocalServiceUtil.getGroup(layout.getCompanyId(), GroupConstants.GUEST);

          plid = guestGroup.getDefaultPublicPlid();
        }

        redirect = HttpUtil.addParameter(redirect, "p_l_id", plid);
      } catch (Exception e) {
      }
    }

    response.sendRedirect(redirect);
  }

  protected boolean processShutdownRequest(HttpServletRequest request, HttpServletResponse response)
      throws IOException {

    if (!ShutdownUtil.isShutdown()) {
      return false;
    }

    String messageKey = ShutdownUtil.getMessage();

    if (Validator.isNull(messageKey)) {
      messageKey = "the-system-is-shutdown-please-try-again-later";
    }

    processInactiveRequest(request, response, messageKey);

    return true;
  }

  protected void processStartupEvents() throws Exception {
    StartupAction startupAction = new StartupAction();

    startupAction.run(null);
  }

  protected HttpServletRequest protectRequest(HttpServletRequest request, String remoteUser) {

    // WebSphere will not return the remote user unless you are
    // authenticated AND accessing a protected path. Other servers will
    // return the remote user for all threads associated with an
    // authenticated user. We use ProtectedServletRequest to ensure we get
    // similar behavior across all servers.

    return new ProtectedServletRequest(request, remoteUser);
  }

  protected void sendError(
      int status, Throwable t, HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    DynamicServletRequest dynamicRequest = new DynamicServletRequest(request);

    // Reset layout params or there will be an infinite loop

    dynamicRequest.setParameter("p_l_id", StringPool.BLANK);

    dynamicRequest.setParameter("groupId", StringPool.BLANK);
    dynamicRequest.setParameter("layoutId", StringPool.BLANK);
    dynamicRequest.setParameter("privateLayout", StringPool.BLANK);

    PortalUtil.sendError(status, (Exception) t, dynamicRequest, response);
  }

  protected void setPortalPort(HttpServletRequest request) {
    PortalUtil.setPortalPort(request);
  }

  protected void setPrincipal(long companyId, long userId, String remoteUser, String password) {

    if ((userId == 0) && (remoteUser == null)) {
      return;
    }

    String name = String.valueOf(userId);

    if (PropsValues.PORTAL_JAAS_ENABLE) {
      long remoteUserId = 0;

      try {
        remoteUserId = JAASHelper.getJaasUserId(companyId, remoteUser);
      } catch (Exception e) {
        if (_log.isWarnEnabled()) {
          _log.warn(e);
        }
      }

      if (remoteUserId > 0) {
        name = String.valueOf(remoteUserId);
      }
    } else if (remoteUser != null) {
      name = remoteUser;
    }

    PrincipalThreadLocal.setName(name);

    PrincipalThreadLocal.setPassword(password);
  }

  private static final boolean _HTTP_HEADER_VERSION_VERBOSITY_DEFAULT =
      StringUtil.equalsIgnoreCase(PropsValues.HTTP_HEADER_VERSION_VERBOSITY, ReleaseInfo.getName());

  private static final boolean _HTTP_HEADER_VERSION_VERBOSITY_PARTIAL =
      StringUtil.equalsIgnoreCase(PropsValues.HTTP_HEADER_VERSION_VERBOSITY, "partial");

  private static final String _LIFERAY_PORTAL_REQUEST_HEADER = "Liferay-Portal";

  private static Log _log = LogFactoryUtil.getLog(MainServlet.class);
}
  private Map<String, String> _buildFrameworkProperties(Class<?> clazz) {
    Map<String, String> properties = new HashMap<String, String>();

    properties.put(Constants.BUNDLE_DESCRIPTION, ReleaseInfo.getReleaseInfo());
    properties.put(Constants.BUNDLE_NAME, ReleaseInfo.getName());
    properties.put(Constants.BUNDLE_VENDOR, ReleaseInfo.getVendor());
    properties.put(Constants.BUNDLE_VERSION, ReleaseInfo.getVersion());
    properties.put(FrameworkPropsKeys.FELIX_FILEINSTALL_DIR, _getFelixFileInstallDir());
    properties.put(FrameworkPropsKeys.FELIX_FILEINSTALL_LOG_LEVEL, _getFelixFileInstallLogLevel());
    properties.put(
        FrameworkPropsKeys.FELIX_FILEINSTALL_POLL,
        String.valueOf(PropsValues.MODULE_FRAMEWORK_AUTO_DEPLOY_INTERVAL));
    properties.put(
        FrameworkPropsKeys.FELIX_FILEINSTALL_TMPDIR,
        SystemProperties.get(SystemProperties.TMP_DIR));
    properties.put(
        Constants.FRAMEWORK_BEGINNING_STARTLEVEL,
        String.valueOf(PropsValues.MODULE_FRAMEWORK_BEGINNING_START_LEVEL));
    properties.put(Constants.FRAMEWORK_BUNDLE_PARENT, Constants.FRAMEWORK_BUNDLE_PARENT_APP);
    properties.put(Constants.FRAMEWORK_STORAGE, PropsValues.MODULE_FRAMEWORK_STATE_DIR);

    properties.put("eclipse.security", null);
    properties.put("java.security.manager", null);
    properties.put("org.osgi.framework.security", null);

    ProtectionDomain protectionDomain = clazz.getProtectionDomain();

    CodeSource codeSource = protectionDomain.getCodeSource();

    URL codeSourceURL = codeSource.getLocation();

    properties.put(FrameworkPropsKeys.OSGI_FRAMEWORK, codeSourceURL.toExternalForm());

    File frameworkFile = new File(codeSourceURL.getFile());

    properties.put(FrameworkPropsKeys.OSGI_INSTALL_AREA, frameworkFile.getParent());

    Properties extraProperties =
        PropsUtil.getProperties(PropsKeys.MODULE_FRAMEWORK_PROPERTIES, true);

    for (Map.Entry<Object, Object> entry : extraProperties.entrySet()) {
      String key = (String) entry.getKey();
      String value = (String) entry.getValue();

      // We need to support an empty string and a null value distinctly.
      // This is due to some different behaviors between OSGi
      // implementations. If a property is passed as xyz= it will be
      // treated as an empty string. Otherwise, xyz=null will be treated
      // as an explicit null value.

      if (value.equals(StringPool.NULL)) {
        value = null;
      }

      properties.put(key, value);
    }

    String systemPackagesExtra = _getSystemPackagesExtra();

    properties.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, systemPackagesExtra);

    return properties;
  }
/**
 * @author Alexander Chow
 * @author Brian Wing Shun Chan
 */
public class WebServerServlet extends HttpServlet {

  /** @see com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter */
  public static boolean hasFiles(HttpServletRequest request) {
    try {

      // Do not use permission checking since this may be called from
      // other contexts that are also managing the principal

      User user = _getUser(request);

      String path = HttpUtil.fixPath(request.getPathInfo());

      String[] pathArray = StringUtil.split(path, CharPool.SLASH);

      if (pathArray.length == 0) {
        return true;
      } else if (_PATH_DDM.equals(pathArray[0])) {
        _checkDDMRecord(pathArray);
      } else if (Validator.isNumber(pathArray[0])) {
        _checkFileEntry(pathArray);
      } else {
        long groupId = _getGroupId(user.getCompanyId(), pathArray[0]);
        long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;

        for (int i = 1; i < pathArray.length; i++) {
          try {
            Folder folder = DLAppLocalServiceUtil.getFolder(groupId, folderId, pathArray[i]);

            folderId = folder.getFolderId();
          } catch (NoSuchFolderException nsfe) {
            if (i != (pathArray.length - 1)) {
              return false;
            }

            pathArray =
                new String[] {String.valueOf(groupId), String.valueOf(folderId), pathArray[i]};

            _checkFileEntry(pathArray);
          }
        }
      }
    } catch (Exception e) {
      return false;
    }

    return true;
  }

  @Override
  public void init(ServletConfig servletConfig) throws ServletException {
    super.init(servletConfig);

    _lastModified = GetterUtil.getBoolean(servletConfig.getInitParameter("last_modified"), true);
  }

  @Override
  public void service(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    User user = null;

    try {
      user = _getUser(request);

      PrincipalThreadLocal.setName(user.getUserId());
      PrincipalThreadLocal.setPassword(PortalUtil.getUserPassword(request));

      PermissionChecker permissionChecker = PermissionCheckerFactoryUtil.create(user);

      PermissionThreadLocal.setPermissionChecker(permissionChecker);

      if (_lastModified) {
        long lastModified = getLastModified(request);

        if (lastModified > 0) {
          long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);

          if ((ifModifiedSince > 0) && (ifModifiedSince == lastModified)) {

            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);

            return;
          }
        }

        if (lastModified > 0) {
          response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModified);
        }
      }

      String path = HttpUtil.fixPath(request.getPathInfo());
      String[] pathArray = StringUtil.split(path, CharPool.SLASH);

      if (pathArray.length == 0) {
        sendGroups(response, user, request.getServletPath() + StringPool.SLASH + path);
      } else {
        if (_PATH_DDM.equals(pathArray[0])) {
          sendDDMRecordFile(request, response, pathArray);
        } else if (Validator.isNumber(pathArray[0])) {
          sendFile(request, response, user, pathArray);
        } else {
          if (isLegacyImageGalleryImageId(request, response)) {
            return;
          }

          Image image = getImage(request, true);

          if (image != null) {
            writeImage(image, request, response);
          } else {
            sendDocumentLibrary(
                request,
                response,
                user,
                request.getServletPath() + StringPool.SLASH + path,
                pathArray);
          }
        }
      }
    } catch (NoSuchFileEntryException nsfee) {
      PortalUtil.sendError(HttpServletResponse.SC_NOT_FOUND, nsfee, request, response);
    } catch (PrincipalException pe) {
      processPrincipalException(pe, user, request, response);
    } catch (Exception e) {
      PortalUtil.sendError(e, request, response);
    }
  }

  protected Image convertFileEntry(boolean smallImage, FileEntry fileEntry)
      throws PortalException, SystemException {

    try {
      Image image = new ImageImpl();

      image.setModifiedDate(fileEntry.getModifiedDate());

      InputStream is = null;

      if (smallImage) {
        is = ImageProcessorUtil.getThumbnailAsStream(fileEntry.getFileVersion(), 0);
      } else {
        is = fileEntry.getContentStream();
      }

      byte[] bytes = FileUtil.getBytes(is);

      image.setTextObj(bytes);

      image.setType(fileEntry.getExtension());

      return image;
    } catch (PortalException pe) {
      throw pe;
    } catch (SystemException se) {
      throw se;
    } catch (Exception e) {
      throw new SystemException(e);
    }
  }

  protected Image getDefaultImage(HttpServletRequest request, long imageId) {
    String path = GetterUtil.getString(request.getPathInfo());

    if (path.startsWith("/company_logo")
        || path.startsWith("/layout_set_logo")
        || path.startsWith("/logo")) {

      return ImageLocalServiceUtil.getDefaultCompanyLogo();
    } else if (path.startsWith("/organization_logo")) {
      return ImageLocalServiceUtil.getDefaultOrganizationLogo();
    } else if (path.startsWith("/user_female_portrait")) {
      return ImageLocalServiceUtil.getDefaultUserFemalePortrait();
    } else if (path.startsWith("/user_male_portrait")) {
      return ImageLocalServiceUtil.getDefaultUserMalePortrait();
    } else if (path.startsWith("/user_portrait")) {
      return ImageLocalServiceUtil.getDefaultUserMalePortrait();
    } else {
      return null;
    }
  }

  protected FileEntry getFileEntry(String[] pathArray) throws Exception {
    if (pathArray.length == 1) {
      long dlFileShortcutId = GetterUtil.getLong(pathArray[0]);

      DLFileShortcut dlFileShortcut = DLAppServiceUtil.getFileShortcut(dlFileShortcutId);

      return DLAppServiceUtil.getFileEntry(dlFileShortcut.getToFileEntryId());
    } else if (pathArray.length == 2) {
      long groupId = GetterUtil.getLong(pathArray[0]);

      return DLAppServiceUtil.getFileEntryByUuidAndGroupId(pathArray[1], groupId);
    } else if (pathArray.length == 3) {
      long groupId = GetterUtil.getLong(pathArray[0]);
      long folderId = GetterUtil.getLong(pathArray[1]);

      String fileName = pathArray[2];

      if (fileName.contains(StringPool.QUESTION)) {
        fileName = fileName.substring(0, fileName.indexOf(StringPool.QUESTION));
      }

      return DLAppServiceUtil.getFileEntry(groupId, folderId, fileName);
    } else {
      long groupId = GetterUtil.getLong(pathArray[0]);

      String uuid = pathArray[3];

      return DLAppServiceUtil.getFileEntryByUuidAndGroupId(uuid, groupId);
    }
  }

  protected Image getImage(HttpServletRequest request, boolean getDefault)
      throws PortalException, SystemException {

    Image image = null;

    long imageId = getImageId(request);

    if (imageId > 0) {
      image = ImageServiceUtil.getImage(imageId);

      String path = GetterUtil.getString(request.getPathInfo());

      if (path.startsWith("/user_female_portrait")
          || path.startsWith("/user_male_portrait")
          || path.startsWith("/user_portrait")) {

        image = getUserPortraitImageResized(image, imageId);
      }
    } else {
      String uuid = ParamUtil.getString(request, "uuid");
      long groupId = ParamUtil.getLong(request, "groupId");
      boolean igSmallImage = ParamUtil.getBoolean(request, "igSmallImage");

      if (Validator.isNotNull(uuid) && (groupId > 0)) {
        try {
          FileEntry fileEntry = DLAppServiceUtil.getFileEntryByUuidAndGroupId(uuid, groupId);

          image = convertFileEntry(igSmallImage, fileEntry);
        } catch (Exception e) {
        }
      }
    }

    if (getDefault) {
      if (image == null) {
        if (_log.isWarnEnabled()) {
          _log.warn("Get a default image for " + imageId);
        }

        image = getDefaultImage(request, imageId);
      }
    }

    return image;
  }

  protected byte[] getImageBytes(HttpServletRequest request, Image image) {
    try {
      if (!PropsValues.IMAGE_AUTO_SCALE) {
        return image.getTextObj();
      }

      ImageBag imageBag = null;

      if (image.getImageId() == 0) {
        imageBag = ImageToolUtil.read(image.getTextObj());

        RenderedImage renderedImage = imageBag.getRenderedImage();

        image.setHeight(renderedImage.getHeight());
        image.setWidth(renderedImage.getWidth());
      }

      int height = ParamUtil.getInteger(request, "height", image.getHeight());
      int width = ParamUtil.getInteger(request, "width", image.getWidth());

      if ((height >= image.getHeight()) && (width >= image.getWidth())) {
        return image.getTextObj();
      }

      if (image.getImageId() != 0) {
        imageBag = ImageToolUtil.read(image.getTextObj());
      }

      RenderedImage renderedImage = ImageToolUtil.scale(imageBag.getRenderedImage(), height, width);

      return ImageToolUtil.getBytes(renderedImage, imageBag.getType());
    } catch (Exception e) {
      if (_log.isWarnEnabled()) {
        _log.warn("Error scaling image " + image.getImageId(), e);
      }
    }

    return image.getTextObj();
  }

  protected long getImageId(HttpServletRequest request) {

    // The image id may be passed in as image_id, img_id, or i_id

    long imageId = ParamUtil.getLong(request, "image_id");

    if (imageId <= 0) {
      imageId = ParamUtil.getLong(request, "img_id");
    }

    if (imageId <= 0) {
      imageId = ParamUtil.getLong(request, "i_id");
    }

    if (imageId <= 0) {
      long companyId = ParamUtil.getLong(request, "companyId");
      String screenName = ParamUtil.getString(request, "screenName");

      try {
        if ((companyId > 0) && Validator.isNotNull(screenName)) {
          User user = UserLocalServiceUtil.getUserByScreenName(companyId, screenName);

          imageId = user.getPortraitId();
        }
      } catch (Exception e) {
      }
    }

    return imageId;
  }

  @Override
  protected long getLastModified(HttpServletRequest request) {
    try {
      Date modifiedDate = null;

      Image image = getImage(request, true);

      if (image != null) {
        modifiedDate = image.getModifiedDate();
      } else {
        String path = HttpUtil.fixPath(request.getPathInfo());

        String[] pathArray = StringUtil.split(path, CharPool.SLASH);

        if (pathArray.length == 0) {
          return -1;
        }

        if (pathArray[0].equals("language")) {
          return -1;
        }

        FileEntry fileEntry = null;

        try {
          fileEntry = getFileEntry(pathArray);
        } catch (Exception e) {
        }

        if (fileEntry == null) {
          return -1;
        } else {
          String version = ParamUtil.getString(request, "version");

          if (Validator.isNotNull(version)) {
            FileVersion fileVersion = fileEntry.getFileVersion(version);

            modifiedDate = fileVersion.getModifiedDate();
          } else {
            modifiedDate = fileEntry.getModifiedDate();
          }
        }
      }

      if (modifiedDate == null) {
        modifiedDate = PortalUtil.getUptime();
      }

      // Round down and remove milliseconds

      return (modifiedDate.getTime() / 1000) * 1000;
    } catch (PrincipalException pe) {
      if (_log.isWarnEnabled()) {
        _log.warn(pe, pe);
      }
    } catch (Exception e) {
      _log.error(e, e);
    }

    return -1;
  }

  protected Image getUserPortraitImageResized(Image image, long imageId)
      throws PortalException, SystemException {

    if (image == null) {
      return null;
    }

    if ((image.getHeight() > PropsValues.USERS_IMAGE_MAX_HEIGHT)
        || (image.getWidth() > PropsValues.USERS_IMAGE_MAX_WIDTH)) {

      User user = UserLocalServiceUtil.getUserByPortraitId(imageId);

      UserLocalServiceUtil.updatePortrait(user.getUserId(), image.getTextObj());

      return ImageLocalServiceUtil.getImage(imageId);
    }

    return image;
  }

  protected boolean isLegacyImageGalleryImageId(
      HttpServletRequest request, HttpServletResponse response) {

    try {
      long imageId = getImageId(request);

      if (imageId == 0) {
        return false;
      }

      DLFileEntry dlFileEntry = DLFileEntryServiceUtil.fetchFileEntryByImageId(imageId);

      if (dlFileEntry == null) {
        return false;
      }

      ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);

      String queryString = StringPool.BLANK;

      if (imageId == dlFileEntry.getSmallImageId()) {
        queryString = "&imageThumbnail=1";
      } else if (imageId == dlFileEntry.getSmallImageId()) {
        queryString = "&imageThumbnail=2";
      } else if (imageId == dlFileEntry.getSmallImageId()) {
        queryString = "&imageThumbnail=3";
      }

      String url =
          DLUtil.getPreviewURL(
              new LiferayFileEntry(dlFileEntry),
              new LiferayFileVersion(dlFileEntry.getFileVersion()),
              themeDisplay,
              queryString);

      response.setHeader(HttpHeaders.LOCATION, url);
      response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);

      return true;
    } catch (Exception e) {
    }

    return false;
  }

  protected void processPrincipalException(
      Throwable t, User user, HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    if (!user.isDefaultUser()) {
      PortalUtil.sendError(HttpServletResponse.SC_UNAUTHORIZED, (Exception) t, request, response);

      return;
    }

    String redirect = request.getContextPath() + Portal.PATH_MAIN + "/portal/login";

    String currentURL = PortalUtil.getCurrentURL(request);

    redirect = HttpUtil.addParameter(redirect, "redirect", currentURL);

    response.sendRedirect(redirect);
  }

  protected void sendDDMRecordFile(
      HttpServletRequest request, HttpServletResponse response, String[] pathArray)
      throws Exception {

    if (pathArray.length == 4) {
      String className = GetterUtil.getString(pathArray[1]);
      long classPK = GetterUtil.getLong(pathArray[2]);
      String fieldName = GetterUtil.getString(pathArray[3]);

      Field field = null;

      if (className.equals(DDLRecord.class.getName())) {
        DDLRecord ddlRecord = DDLRecordLocalServiceUtil.getRecord(classPK);

        field = ddlRecord.getField(fieldName);
      } else if (className.equals(DLFileEntryMetadata.class.getName())) {
        DLFileEntryMetadata fileEntryMetadata =
            DLFileEntryMetadataLocalServiceUtil.getDLFileEntryMetadata(classPK);

        Fields fields = StorageEngineUtil.getFields(fileEntryMetadata.getDDMStorageId());

        field = fields.get(fieldName);
      }

      DDMUtil.sendFieldFile(request, response, field);
    }
  }

  protected void sendDocumentLibrary(
      HttpServletRequest request,
      HttpServletResponse response,
      User user,
      String path,
      String[] pathArray)
      throws Exception {

    if (!PropsValues.WEB_SERVER_SERVLET_DIRECTORY_INDEXING_ENABLED) {
      response.setStatus(HttpServletResponse.SC_FORBIDDEN);

      return;
    }

    long groupId = _getGroupId(user.getCompanyId(), pathArray[0]);
    long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;

    for (int i = 1; i < pathArray.length; i++) {
      String name = pathArray[i];

      try {
        Folder folder = DLAppServiceUtil.getFolder(groupId, folderId, name);

        folderId = folder.getFolderId();
      } catch (NoSuchFolderException nsfe) {
        if (i != (pathArray.length - 1)) {
          throw nsfe;
        }

        String title = name;

        sendFile(response, user, groupId, folderId, title);

        return;
      }
    }

    try {
      sendFile(response, user, groupId, folderId, "index.html");

      return;
    } catch (Exception e) {
      if ((e instanceof NoSuchFileEntryException) || (e instanceof PrincipalException)) {

        try {
          sendFile(response, user, groupId, folderId, "index.htm");

          return;
        } catch (NoSuchFileEntryException nsfee) {
        } catch (PrincipalException pe) {
        }
      } else {
        throw e;
      }
    }

    List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();

    webServerEntries.add(new WebServerEntry(path, "../"));

    List<Folder> folders = DLAppServiceUtil.getFolders(groupId, folderId);

    for (Folder folder : folders) {
      WebServerEntry webServerEntry =
          new WebServerEntry(
              path,
              folder.getName() + StringPool.SLASH,
              folder.getCreateDate(),
              folder.getModifiedDate(),
              folder.getDescription(),
              0);

      webServerEntries.add(webServerEntry);
    }

    List<FileEntry> fileEntries = DLAppServiceUtil.getFileEntries(groupId, folderId);

    for (FileEntry fileEntry : fileEntries) {
      WebServerEntry webServerEntry =
          new WebServerEntry(
              path,
              fileEntry.getTitle(),
              fileEntry.getCreateDate(),
              fileEntry.getModifiedDate(),
              fileEntry.getDescription(),
              fileEntry.getSize());

      webServerEntries.add(webServerEntry);
    }

    sendHTML(response, path, webServerEntries);
  }

  protected void sendFile(
      HttpServletRequest request, HttpServletResponse response, User user, String[] pathArray)
      throws Exception {

    // Retrieve file details

    FileEntry fileEntry = getFileEntry(pathArray);

    if (fileEntry == null) {
      throw new NoSuchFileEntryException();
    }

    String version = ParamUtil.getString(request, "version");

    if (Validator.isNull(version)) {
      if (Validator.isNotNull(fileEntry.getVersion())) {
        version = fileEntry.getVersion();
      }
    }

    String tempFileId = DLUtil.getTempFileId(fileEntry.getFileEntryId(), version);

    FileVersion fileVersion = fileEntry.getFileVersion(version);

    String fileName = fileVersion.getTitle();

    String extension = fileVersion.getExtension();

    if (Validator.isNotNull(extension) && !fileName.endsWith(StringPool.PERIOD + extension)) {

      fileName += StringPool.PERIOD + extension;
    }

    // Handle requested conversion

    boolean converted = false;

    String targetExtension = ParamUtil.getString(request, "targetExtension");
    int imageThumbnail = ParamUtil.getInteger(request, "imageThumbnail");
    int documentThumbnail = ParamUtil.getInteger(request, "documentThumbnail");
    int previewFileIndex = ParamUtil.getInteger(request, "previewFileIndex");
    boolean audioPreview = ParamUtil.getBoolean(request, "audioPreview");
    boolean imagePreview = ParamUtil.getBoolean(request, "imagePreview");
    boolean videoPreview = ParamUtil.getBoolean(request, "videoPreview");
    int videoThumbnail = ParamUtil.getInteger(request, "videoThumbnail");

    InputStream inputStream = null;
    long contentLength = 0;

    if ((imageThumbnail > 0) && (imageThumbnail <= 3)) {
      fileName =
          FileUtil.stripExtension(fileName)
              .concat(StringPool.PERIOD)
              .concat(ImageProcessorUtil.getThumbnailType(fileVersion));

      int thumbnailIndex = imageThumbnail - 1;

      inputStream = ImageProcessorUtil.getThumbnailAsStream(fileVersion, thumbnailIndex);
      contentLength = ImageProcessorUtil.getThumbnailFileSize(fileVersion, thumbnailIndex);

      converted = true;
    } else if ((documentThumbnail > 0) && (documentThumbnail <= 3)) {
      fileName =
          FileUtil.stripExtension(fileName)
              .concat(StringPool.PERIOD)
              .concat(PDFProcessor.THUMBNAIL_TYPE);

      int thumbnailIndex = documentThumbnail - 1;

      inputStream = PDFProcessorUtil.getThumbnailAsStream(fileVersion, thumbnailIndex);
      contentLength = PDFProcessorUtil.getThumbnailFileSize(fileVersion, thumbnailIndex);

      converted = true;
    } else if (previewFileIndex > 0) {
      fileName =
          FileUtil.stripExtension(fileName)
              .concat(StringPool.PERIOD)
              .concat(PDFProcessor.PREVIEW_TYPE);
      inputStream = PDFProcessorUtil.getPreviewAsStream(fileVersion, previewFileIndex);
      contentLength = PDFProcessorUtil.getPreviewFileSize(fileVersion, previewFileIndex);

      converted = true;
    } else if (audioPreview || videoPreview) {
      String type = ParamUtil.getString(request, "type");

      fileName = FileUtil.stripExtension(fileName).concat(StringPool.PERIOD).concat(type);

      if (audioPreview) {
        inputStream = AudioProcessorUtil.getPreviewAsStream(fileVersion, type);
        contentLength = AudioProcessorUtil.getPreviewFileSize(fileVersion, type);
      } else {
        inputStream = VideoProcessorUtil.getPreviewAsStream(fileVersion, type);
        contentLength = VideoProcessorUtil.getPreviewFileSize(fileVersion, type);
      }

      converted = true;
    } else if (imagePreview) {
      String type = ImageProcessorUtil.getPreviewType(fileVersion);

      fileName = FileUtil.stripExtension(fileName).concat(StringPool.PERIOD).concat(type);

      inputStream = ImageProcessorUtil.getPreviewAsStream(fileVersion);

      contentLength = ImageProcessorUtil.getPreviewFileSize(fileVersion);

      converted = true;
    } else if ((videoThumbnail > 0) && (videoThumbnail <= 3)) {
      fileName =
          FileUtil.stripExtension(fileName)
              .concat(StringPool.PERIOD)
              .concat(VideoProcessor.THUMBNAIL_TYPE);

      int thumbnailIndex = videoThumbnail - 1;

      inputStream = VideoProcessorUtil.getThumbnailAsStream(fileVersion, thumbnailIndex);
      contentLength = VideoProcessorUtil.getThumbnailFileSize(fileVersion, thumbnailIndex);

      converted = true;
    } else {
      inputStream = fileVersion.getContentStream(true);
      contentLength = fileVersion.getSize();

      if (Validator.isNotNull(targetExtension)) {
        File convertedFile =
            DocumentConversionUtil.convert(tempFileId, inputStream, extension, targetExtension);

        if (convertedFile != null) {
          fileName =
              FileUtil.stripExtension(fileName).concat(StringPool.PERIOD).concat(targetExtension);
          inputStream = new FileInputStream(convertedFile);
          contentLength = convertedFile.length();

          converted = true;
        }
      }
    }

    // Determine proper content type

    String contentType = null;

    if (converted) {
      contentType = MimeTypesUtil.getContentType(fileName);
    } else {
      contentType = fileVersion.getMimeType();
    }

    // Support range HTTP header

    response.setHeader(HttpHeaders.ACCEPT_RANGES, HttpHeaders.ACCEPT_RANGES_BYTES_VALUE);

    List<Range> ranges = null;

    try {
      ranges = ServletResponseUtil.getRanges(request, response, contentLength);
    } catch (IOException ioe) {
      if (_log.isErrorEnabled()) {
        _log.error(ioe);
      }

      response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + contentLength);

      response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);

      return;
    }

    if ((ranges == null) || ranges.isEmpty()) {
      ServletResponseUtil.sendFile(
          request, response, fileName, inputStream, contentLength, contentType);
    } else {
      if (_log.isDebugEnabled()) {
        _log.debug("Request has range header " + request.getHeader(HttpHeaders.RANGE));
      }

      ServletResponseUtil.write(
          request, response, fileName, ranges, inputStream, contentLength, contentType);
    }
  }

  protected void sendFile(
      HttpServletResponse response, User user, long groupId, long folderId, String title)
      throws Exception {

    FileEntry fileEntry = DLAppServiceUtil.getFileEntry(groupId, folderId, title);

    String contentType = fileEntry.getMimeType();

    response.setContentType(contentType);

    InputStream inputStream = fileEntry.getContentStream();

    ServletResponseUtil.write(response, inputStream);
  }

  protected void sendGroups(HttpServletResponse response, User user, String path) throws Exception {

    if (!PropsValues.WEB_SERVER_SERVLET_DIRECTORY_INDEXING_ENABLED) {
      response.setStatus(HttpServletResponse.SC_FORBIDDEN);

      return;
    }

    List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();

    List<Group> groups = WebDAVUtil.getGroups(user);

    for (Group group : groups) {
      String name = HttpUtil.fixPath(group.getFriendlyURL());

      WebServerEntry webServerEntry =
          new WebServerEntry(path, name + StringPool.SLASH, null, null, group.getDescription(), 0);

      webServerEntries.add(webServerEntry);
    }

    sendHTML(response, path, webServerEntries);
  }

  protected void sendHTML(
      HttpServletResponse response, String path, List<WebServerEntry> webServerEntries)
      throws Exception {

    Template template =
        TemplateManagerUtil.getTemplate(
            TemplateManager.FREEMARKER, _TEMPLATE_FTL, TemplateContextType.RESTRICTED);

    template.put("dateFormat", _dateFormat);
    template.put("entries", webServerEntries);
    template.put("path", HttpUtil.encodePath(path));

    if (_WEB_SERVER_SERVLET_VERSION_VERBOSITY_DEFAULT) {
    } else if (_WEB_SERVER_SERVLET_VERSION_VERBOSITY_PARTIAL) {
      template.put("releaseInfo", ReleaseInfo.getName());
    } else {
      template.put("releaseInfo", ReleaseInfo.getReleaseInfo());
    }

    template.put("validator", Validator_IW.getInstance());

    response.setContentType(ContentTypes.TEXT_HTML_UTF8);

    template.processTemplate(response.getWriter());
  }

  protected void writeImage(Image image, HttpServletRequest request, HttpServletResponse response) {

    if (image == null) {
      return;
    }

    String contentType = null;

    String type = image.getType();

    if (!type.equals(ImageConstants.TYPE_NOT_AVAILABLE)) {
      contentType = MimeTypesUtil.getContentType("A." + type);

      response.setContentType(contentType);
    }

    String fileName = ParamUtil.getString(request, "fileName");

    try {
      byte[] bytes = getImageBytes(request, image);

      if (Validator.isNotNull(fileName)) {
        ServletResponseUtil.sendFile(request, response, fileName, bytes, contentType);
      } else {
        ServletResponseUtil.write(response, bytes);
      }
    } catch (Exception e) {
      if (_log.isWarnEnabled()) {
        _log.warn(e, e);
      }
    }
  }

  private static void _checkDDMRecord(String[] pathArray) throws Exception {
    if (pathArray.length == 3) {
      String className = GetterUtil.getString(pathArray[1]);
      long classPK = GetterUtil.getLong(pathArray[2]);

      if (className.equals(DDLRecord.class.getName())) {
        DDLRecordLocalServiceUtil.getRecord(classPK);
      } else if (className.equals(DLFileEntryMetadata.class.getName())) {
        DLFileEntryMetadataLocalServiceUtil.getDLFileEntryMetadata(classPK);
      }
    }
  }

  private static void _checkFileEntry(String[] pathArray) throws Exception {
    if (pathArray.length == 1) {
      long dlFileShortcutId = GetterUtil.getLong(pathArray[0]);

      DLFileShortcut dlFileShortcut = DLAppLocalServiceUtil.getFileShortcut(dlFileShortcutId);

      DLAppLocalServiceUtil.getFileEntry(dlFileShortcut.getToFileEntryId());
    } else if (pathArray.length == 2) {

      // Unable to check with UUID because of multiple repositories

    } else if (pathArray.length == 3) {
      long groupId = GetterUtil.getLong(pathArray[0]);
      long folderId = GetterUtil.getLong(pathArray[1]);
      String fileName = pathArray[2];

      try {
        DLAppLocalServiceUtil.getFileEntry(groupId, folderId, fileName);
      } catch (RepositoryException re) {
      }
    } else {
      long groupId = GetterUtil.getLong(pathArray[0]);

      String uuid = pathArray[3];

      try {
        DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(uuid, groupId);
      } catch (RepositoryException re) {
      }
    }
  }

  private static long _getGroupId(long companyId, String name) throws Exception {

    try {
      Group group = GroupLocalServiceUtil.getFriendlyURLGroup(companyId, StringPool.SLASH + name);

      return group.getGroupId();
    } catch (NoSuchGroupException nsge) {
    }

    User user = UserLocalServiceUtil.getUserByScreenName(companyId, name);

    Group group = user.getGroup();

    return group.getGroupId();
  }

  private static User _getUser(HttpServletRequest request) throws Exception {
    HttpSession session = request.getSession();

    if (PortalSessionThreadLocal.getHttpSession() == null) {
      PortalSessionThreadLocal.setHttpSession(session);
    }

    User user = PortalUtil.getUser(request);

    if (user != null) {
      return user;
    }

    String userIdString = (String) session.getAttribute("j_username");
    String password = (String) session.getAttribute("j_password");

    if ((userIdString != null) && (password != null)) {
      long userId = GetterUtil.getLong(userIdString);

      user = UserLocalServiceUtil.getUser(userId);
    } else {
      long companyId = PortalUtil.getCompanyId(request);

      Company company = CompanyLocalServiceUtil.getCompany(companyId);

      user = company.getDefaultUser();
    }

    return user;
  }

  private static final String _DATE_FORMAT_PATTERN = "d MMM yyyy HH:mm z";

  private static final String _PATH_DDM = "ddm";

  private static final String _TEMPLATE_FTL =
      "com/liferay/portal/webserver/dependencies/template.ftl";

  private static final boolean _WEB_SERVER_SERVLET_VERSION_VERBOSITY_DEFAULT =
      PropsValues.WEB_SERVER_SERVLET_VERSION_VERBOSITY.equalsIgnoreCase(ReleaseInfo.getName());

  private static final boolean _WEB_SERVER_SERVLET_VERSION_VERBOSITY_PARTIAL =
      PropsValues.WEB_SERVER_SERVLET_VERSION_VERBOSITY.equalsIgnoreCase("partial");

  private static Log _log = LogFactoryUtil.getLog(WebServerServlet.class);

  private static Format _dateFormat =
      FastDateFormatFactoryUtil.getSimpleDateFormat(_DATE_FORMAT_PATTERN);

  private boolean _lastModified = true;
}
/**
 * @author Alexander Chow
 * @author Brian Wing Shun Chan
 */
public class XmlRpcImpl implements XmlRpc {

  @Override
  public Fault createFault(int code, String description) {
    return new FaultImpl(code, description);
  }

  @Override
  public Success createSuccess(String description) {
    return new SuccessImpl(description);
  }

  @Override
  public Response executeMethod(String url, String methodName, Object[] arguments)
      throws XmlRpcException {

    try {
      return doExecuteMethod(url, methodName, arguments);
    } catch (Exception e) {
      throw new XmlRpcException(e);
    }
  }

  protected Response doExecuteMethod(String url, String methodName, Object[] arguments)
      throws Exception {

    if (_log.isDebugEnabled()) {
      StringBundler sb = new StringBundler();

      sb.append("XML-RPC invoking ");
      sb.append(methodName);
      sb.append(" ");

      if (arguments != null) {
        for (int i = 0; i < arguments.length; i++) {
          sb.append(arguments[i]);

          if (i < (arguments.length - 1)) {
            sb.append(", ");
          }
        }
      }

      _log.debug(sb.toString());
    }

    String requestXML = XmlRpcParser.buildMethod(methodName, arguments);

    Http.Options options = new Http.Options();

    if (_HTTP_HEADER_VERSION_VERBOSITY_DEFAULT) {
    } else if (_HTTP_HEADER_VERSION_VERBOSITY_PARTIAL) {
      options.addHeader(HttpHeaders.USER_AGENT, ReleaseInfo.getName());
    } else {
      options.addHeader(HttpHeaders.USER_AGENT, ReleaseInfo.getServerInfo());
    }

    options.setBody(requestXML, ContentTypes.TEXT_XML, StringPool.UTF8);
    options.setLocation(url);
    options.setPost(true);

    String responseXML = HttpUtil.URLtoString(options);

    return XmlRpcParser.parseResponse(responseXML);
  }

  private static final boolean _HTTP_HEADER_VERSION_VERBOSITY_DEFAULT =
      StringUtil.equalsIgnoreCase(PropsValues.HTTP_HEADER_VERSION_VERBOSITY, ReleaseInfo.getName());

  private static final boolean _HTTP_HEADER_VERSION_VERBOSITY_PARTIAL =
      StringUtil.equalsIgnoreCase(PropsValues.HTTP_HEADER_VERSION_VERBOSITY, "partial");

  private static Log _log = LogFactoryUtil.getLog(XmlRpcImpl.class);
}