/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.geode.modules.session.catalina;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.Loader;
import org.apache.catalina.Pipeline;
import org.apache.catalina.Session;
import org.apache.catalina.Valve;
import org.apache.catalina.session.ManagerBase;
import org.apache.catalina.session.StandardSession;
import org.apache.catalina.util.CustomObjectInputStream;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.query.Query;
import org.apache.geode.cache.query.QueryService;
import org.apache.geode.cache.query.SelectResults;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.modules.session.catalina.internal.DeltaSessionStatistics;
import org.apache.geode.modules.util.ContextMapper;
import org.apache.geode.modules.util.RegionConfiguration;
import org.apache.geode.modules.util.RegionHelper;

public abstract class DeltaSessionManager extends ManagerBase
    implements Lifecycle, PropertyChangeListener, SessionManager {

  static final String catalinaBaseSystemProperty = "catalina.base";
  static final String javaTempDirSystemProperty = "java.io.tmpdir";
  static final String fileSeparatorSystemProperty = "file.separator";
  /**
   * The number of rejected sessions.
   */
  private AtomicInteger rejectedSessions;

  /**
   * The maximum number of active Sessions allowed, or -1 for no limit.
   */
  private int maxActiveSessions = -1;

  /**
   * Has this <code>Manager</code> been started?
   */
  protected AtomicBoolean started = new AtomicBoolean(false);

  /**
   * The name of this <code>Manager</code>
   */
  protected String name;

  private Valve jvmRouteBinderValve;

  private Valve commitSessionValve;

  private SessionCache sessionCache;

  private static final String DEFAULT_REGION_NAME = RegionHelper.NAME + "_sessions";

  private static final boolean DEFAULT_ENABLE_GATEWAY_REPLICATION = false;

  private static final boolean DEFAULT_ENABLE_DEBUG_LISTENER = false;

  private static final boolean DEFAULT_ENABLE_COMMIT_VALVE = true;

  private static final boolean DEFAULT_ENABLE_COMMIT_VALVE_FAILFAST = false;

  private static final boolean DEFAULT_PREFER_DESERIALIZED_FORM = true;

  /*
   * This *MUST* only be assigned during start/startInternal otherwise it will be associated with
   * the incorrect context class loader.
   */
  private Log LOGGER;

  protected String regionName = DEFAULT_REGION_NAME;

  private String regionAttributesId; // the default is different for client-server and
                                     // peer-to-peer

  private Boolean enableLocalCache; // the default is different for client-server and peer-to-peer

  private boolean enableCommitValve = DEFAULT_ENABLE_COMMIT_VALVE;

  private boolean enableCommitValveFailfast = DEFAULT_ENABLE_COMMIT_VALVE_FAILFAST;

  private boolean enableGatewayReplication = DEFAULT_ENABLE_GATEWAY_REPLICATION;

  private boolean enableDebugListener = DEFAULT_ENABLE_DEBUG_LISTENER;

  private boolean preferDeserializedForm = DEFAULT_PREFER_DESERIALIZED_FORM;

  private Timer timer;

  private final Set<String> sessionsToTouch;

  private static final long TIMER_TASK_PERIOD =
      Long.getLong("gemfiremodules.sessionTimerTaskPeriod", 10000);

  private static final long TIMER_TASK_DELAY =
      Long.getLong("gemfiremodules.sessionTimerTaskDelay", 10000);

  public DeltaSessionManager() {
    this.rejectedSessions = new AtomicInteger(0);
    // Create the set to store sessions to be touched after get attribute requests
    this.sessionsToTouch = Collections.newSetFromMap(new ConcurrentHashMap<>());
  }

  @Override
  public String getRegionName() {
    return this.regionName;
  }

  public void setRegionName(String regionName) {
    this.regionName = regionName;
  }

  @Override
  public void setMaxInactiveInterval(final int interval) {
    super.setMaxInactiveInterval(interval);
  }

  @Override
  public String getRegionAttributesId() {
    // This property will be null if it hasn't been set in the context.xml file.
    // Since its default is dependent on the session cache, get the default from
    // the session cache.
    if (this.regionAttributesId == null) {
      this.regionAttributesId = getSessionCache().getDefaultRegionAttributesId();
    }
    return this.regionAttributesId;
  }

  @SuppressWarnings("unused")
  public void setRegionAttributesId(String regionType) {
    this.regionAttributesId = regionType;
  }

  @Override
  public boolean getEnableLocalCache() {
    // This property will be null if it hasn't been set in the context.xml file.
    // Since its default is dependent on the session cache, get the default from
    // the session cache.
    if (this.enableLocalCache == null) {
      this.enableLocalCache = getSessionCache().getDefaultEnableLocalCache();
    }
    return this.enableLocalCache;
  }

  @SuppressWarnings("unused")
  public void setEnableLocalCache(boolean enableLocalCache) {
    this.enableLocalCache = enableLocalCache;
  }

  @SuppressWarnings("unused")
  public int getMaxActiveSessions() {
    return this.maxActiveSessions;
  }

  @SuppressWarnings("unused")
  public void setMaxActiveSessions(int maxActiveSessions) {
    int oldMaxActiveSessions = this.maxActiveSessions;
    this.maxActiveSessions = maxActiveSessions;
    support.firePropertyChange("maxActiveSessions", new Integer(oldMaxActiveSessions),
        new Integer(this.maxActiveSessions));
  }

  @Override
  public boolean getEnableGatewayDeltaReplication() {
    // return this.enableGatewayDeltaReplication;
    return false; // disabled
  }

  @SuppressWarnings("unused")
  public void setEnableGatewayDeltaReplication(boolean enableGatewayDeltaReplication) {
    // this.enableGatewayDeltaReplication = enableGatewayDeltaReplication;
    // Disabled. Keeping the method for backward compatibility.
  }

  @Override
  public boolean getEnableGatewayReplication() {
    return this.enableGatewayReplication;
  }

  @SuppressWarnings("unused")
  public void setEnableGatewayReplication(boolean enableGatewayReplication) {
    this.enableGatewayReplication = enableGatewayReplication;
  }

  @Override
  public boolean getEnableDebugListener() {
    return this.enableDebugListener;
  }

  @SuppressWarnings("unused")
  public void setEnableDebugListener(boolean enableDebugListener) {
    this.enableDebugListener = enableDebugListener;
  }

  @Override
  public boolean isCommitValveEnabled() {
    return this.enableCommitValve;
  }

  public void setEnableCommitValve(boolean enable) {
    this.enableCommitValve = enable;
  }

  @Override
  public boolean isCommitValveFailfastEnabled() {
    return this.enableCommitValveFailfast;
  }

  @SuppressWarnings("unused")
  public void setEnableCommitValveFailfast(boolean enable) {
    this.enableCommitValveFailfast = enable;
  }

  @Override
  public boolean isBackingCacheAvailable() {
    return sessionCache.isBackingCacheAvailable();
  }

  @SuppressWarnings("unused")
  public void setPreferDeserializedForm(boolean enable) {
    this.preferDeserializedForm = enable;
  }

  @Override
  public boolean getPreferDeserializedForm() {
    return this.preferDeserializedForm;
  }

  @Override
  public String getStatisticsName() {
    return getContextName().replace("/", "");
  }

  @Override
  public Log getLogger() {
    if (LOGGER == null) {
      LOGGER = LogFactory.getLog(DeltaSessionManager.class);
    }
    return LOGGER;
  }

  public SessionCache getSessionCache() {
    return this.sessionCache;
  }

  public DeltaSessionStatistics getStatistics() {
    return getSessionCache().getStatistics();
  }

  boolean isPeerToPeer() {
    return getSessionCache().isPeerToPeer();
  }

  @SuppressWarnings("unused")
  public boolean isClientServer() {
    return getSessionCache().isClientServer();
  }

  /**
   * This method was taken from StandardManager to set the default maxInactiveInterval based on the
   * container (to 30 minutes).
   * <p>
   * Set the Container with which this Manager has been associated. If it is a Context (the usual
   * case), listen for changes to the session timeout property.
   *
   * @param container The associated Container
   */
  @Override
  public void setContainer(Container container) {
    // De-register from the old Container (if any)
    if ((this.container != null) && (this.container instanceof Context)) {
      this.container.removePropertyChangeListener(this);
    }

    // Default processing provided by our superclass
    super.setContainer(container);

    // Register with the new Container (if any)
    if ((this.container != null) && (this.container instanceof Context)) {
      // Overwrite the max inactive interval with the context's session timeout.
      setMaxInactiveInterval(((Context) this.container).getSessionTimeout() * 60);
      this.container.addPropertyChangeListener(this);
    }
  }

  @Override
  public Session findSession(String id) throws IOException {
    if (id == null) {
      return null;
    }
    if (getLogger().isDebugEnabled()) {
      getLogger().debug(
          this + ": Finding session " + id + " in " + getSessionCache().getOperatingRegionName());
    }
    DeltaSessionInterface session = (DeltaSessionInterface) getSessionCache().getSession(id);
    /*
     * Check that the context name for this session is the same as this manager's. This comes into
     * play when multiple versions of a webapp are deployed and active at the same time; the context
     * name will contain an embedded version number; something like /test###2.
     */
    if (session != null && !session.getContextName().isEmpty()
        && !getContextName().equals(session.getContextName())) {
      getLogger()
          .info(this + ": Session " + id + " rejected as container name and context do not match: "
              + getContextName() + " != " + session.getContextName());
      session = null;
    }

    if (session == null) {
      if (getLogger().isDebugEnabled()) {
        getLogger().debug(this + ": Did not find session " + id + " in "
            + getSessionCache().getOperatingRegionName());
      }
    } else {
      if (getLogger().isDebugEnabled()) {
        getLogger().debug(this + ": Found session " + id + " in "
            + getSessionCache().getOperatingRegionName() + ": " + session);
      }
      // The session was previously stored. Set new to false.
      session.setNew(false);

      // Check the manager.
      // If the manager is null, the session was replicated and this is a
      // failover situation. Reset the manager and activate the session.
      if (session.getManager() == null) {
        session.setOwner(this);
        session.activate();
      }
    }

    return session;
  }

  protected void initializeSessionCache() {
    // Retrieve the cache
    GemFireCacheImpl cache = (GemFireCacheImpl) getAnyCacheInstance();
    if (cache == null) {
      throw new IllegalStateException(
          "No cache exists. Please configure either a PeerToPeerCacheLifecycleListener or ClientServerCacheLifecycleListener in the server.xml file.");
    }

    // Create the appropriate session cache
    this.sessionCache = cache.isClient() ? new ClientServerSessionCache(this, cache)
        : new PeerToPeerSessionCache(this, cache);

    // Initialize the session cache
    initSessionCache();
  }

  void initSessionCache() {
    this.sessionCache.initialize();
  }

  Cache getAnyCacheInstance() {
    return CacheFactory.getAnyInstance();
  }

  @Override
  protected StandardSession getNewSession() {
    return new DeltaSession(this);
  }

  @Override
  public void remove(Session session) {
    remove(session, false);
  }

  public void remove(Session session, @SuppressWarnings("unused") boolean update) {
    // super.remove(session);
    // Remove the session from the region if necessary.
    // It will have already been removed if it expired implicitly.
    DeltaSessionInterface ds = (DeltaSessionInterface) session;
    if (ds.getExpired()) {
      if (getLogger().isDebugEnabled()) {
        getLogger().debug(this + ": Expired session " + session.getId() + " from "
            + getSessionCache().getOperatingRegionName());
      }
    } else {
      if (getLogger().isDebugEnabled()) {
        getLogger().debug(this + ": Destroying session " + session.getId() + " from "
            + getSessionCache().getOperatingRegionName());
      }
      getSessionCache().destroySession(session.getId());
      if (getLogger().isDebugEnabled()) {
        getLogger().debug(this + ": Destroyed session " + session.getId() + " from "
            + getSessionCache().getOperatingRegionName());
      }
    }
  }

  @Override
  public void add(Session session) {
    // super.add(session);
    if (getLogger().isDebugEnabled()) {
      getLogger().debug(this + ": Storing session " + session.getId() + " into "
          + getSessionCache().getOperatingRegionName());
    }
    getSessionCache().putSession(session);
    if (getLogger().isDebugEnabled()) {
      getLogger().debug(this + ": Stored session " + session.getId() + " into "
          + getSessionCache().getOperatingRegionName());
    }
    getSessionCache().getStatistics().incSessionsCreated();
  }

  @Override
  public int getRejectedSessions() {
    return this.rejectedSessions.get();
  }

  @Override
  public void setRejectedSessions(int rejectedSessions) {
    this.rejectedSessions.set(rejectedSessions);
  }

  /**
   * Returns the number of active sessions
   *
   * @return number of sessions active
   */
  @Override
  public int getActiveSessions() {
    return getSessionCache().size();
  }

  /**
   * For debugging: return a list of all session ids currently active
   */
  @Override
  public String listSessionIds() {
    StringBuilder builder = new StringBuilder();
    Iterator<String> sessionIds = getSessionCache().keySet().iterator();
    while (sessionIds.hasNext()) {
      builder.append(sessionIds.next());
      if (sessionIds.hasNext()) {
        builder.append(" ");
      }
    }
    return builder.toString();
  }

  /*
   * If local caching is enabled, add the session to the set of sessions to be touched. A timer task
   * will be periodically invoked to get the session in the session region to update its last
   * accessed time. This prevents the session from expiring in the case where the application is
   * only getting attributes from the session and never putting attributes into the session. If
   * local caching is disabled. the session's last accessed time would already have been updated
   * properly in the sessions region.
   *
   * Note: Due to issues in GemFire expiry, sessions are always asynchronously touched using a
   * function regardless whether or not local caching is enabled. This prevents premature
   * expiration.
   */
  void addSessionToTouch(String sessionId) {
    this.sessionsToTouch.add(sessionId);
  }

  protected Set<String> getSessionsToTouch() {
    return this.sessionsToTouch;
  }

  boolean removeTouchedSession(String sessionId) {
    return this.sessionsToTouch.remove(sessionId);
  }

  protected void scheduleTimerTasks() {
    // Create the timer
    this.timer = new Timer("Timer for " + toString(), true);

    // Schedule the task to handle sessions to be touched
    scheduleTouchSessionsTask();

    // Schedule the task to maintain the maxActive sessions
    scheduleDetermineMaxActiveSessionsTask();
  }

  private void scheduleTouchSessionsTask() {
    TimerTask task = new TimerTask() {
      @Override
      public void run() {
        // Get the sessionIds to touch and clear the set inside synchronization
        Set<String> sessionIds;
        sessionIds = new HashSet<>(getSessionsToTouch());
        getSessionsToTouch().clear();

        // Touch the sessions we currently have
        if (!sessionIds.isEmpty()) {
          getSessionCache().touchSessions(sessionIds);
          if (getLogger().isDebugEnabled()) {
            getLogger().debug(DeltaSessionManager.this + ": Touched sessions: " + sessionIds);
          }
        }
      }
    };
    this.timer.schedule(task, TIMER_TASK_DELAY, TIMER_TASK_PERIOD);
  }

  protected void cancelTimer() {
    if (timer != null) {
      this.timer.cancel();
    }
  }

  private void scheduleDetermineMaxActiveSessionsTask() {
    TimerTask task = new TimerTask() {
      @Override
      public void run() {
        int currentActiveSessions = getSessionCache().size();
        if (currentActiveSessions > getMaxActive()) {
          setMaxActive(currentActiveSessions);
          if (getLogger().isDebugEnabled()) {
            getLogger().debug(
                DeltaSessionManager.this + ": Set max active sessions: " + currentActiveSessions);
          }
        }
      }
    };

    this.timer.schedule(task, TIMER_TASK_DELAY, TIMER_TASK_PERIOD);
  }

  @Override
  public void load() throws ClassNotFoundException, IOException {
    doLoad();
    ContextMapper.addContext(getContextName(), this);
  }

  @Override
  public void unload() throws IOException {
    doUnload();
    ContextMapper.removeContext(getContextName());
  }

  protected void registerJvmRouteBinderValve() {
    if (getLogger().isDebugEnabled()) {
      getLogger().debug(this + ": Registering JVM route binder valve");
    }
    jvmRouteBinderValve = new JvmRouteBinderValve();
    getPipeline().addValve(jvmRouteBinderValve);
  }

  Pipeline getPipeline() {
    return getContainer().getPipeline();
  }

  protected void unregisterJvmRouteBinderValve() {
    if (getLogger().isDebugEnabled()) {
      getLogger().debug(this + ": Unregistering JVM route binder valve");
    }
    if (jvmRouteBinderValve != null) {
      getPipeline().removeValve(jvmRouteBinderValve);
    }
  }

  protected void registerCommitSessionValve() {
    if (getLogger().isDebugEnabled()) {
      getLogger().debug(this + ": Registering CommitSessionValve");
    }
    commitSessionValve = new CommitSessionValve();
    getPipeline().addValve(commitSessionValve);
  }

  protected void unregisterCommitSessionValve() {
    if (getLogger().isDebugEnabled()) {
      getLogger().debug(this + ": Unregistering CommitSessionValve");
    }
    if (commitSessionValve != null) {
      getPipeline().removeValve(commitSessionValve);
    }
  }

  // ------------------------------ Lifecycle Methods

  /**
   * Process property change events from our associated Context.
   * <p>
   * Part of this method implementation was taken from StandardManager. The sessionTimeout can be
   * changed in the web.xml which is processed after the context.xml. The context (and the default
   * session timeout) would already have been set in this Manager. This is the way to get the new
   * session timeout value specified in the web.xml.
   * <p>
   * The precedence order for setting the session timeout value is:
   * <p>
   * <ol>
   * <li>the max inactive interval is set based on the Manager defined in the context.xml
   * <li>the max inactive interval is then overwritten by the value of the Context's session timeout
   * when setContainer is called
   * <li>the max inactive interval is then overwritten by the value of the session-timeout specified
   * in the web.xml (if any)
   * </ol>
   *
   * @param event The property change event that has occurred
   */
  @Override
  public void propertyChange(PropertyChangeEvent event) {

    // Validate the source of this event
    if (!(event.getSource() instanceof Context)) {
      return;
    }

    // Process a relevant property change
    if (event.getPropertyName().equals("sessionTimeout")) {
      try {
        int interval = (Integer) event.getNewValue();
        if (interval < RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL) {
          getLogger().warn("The configured session timeout of " + interval
              + " minutes is invalid. Using the original value of " + event.getOldValue()
              + " minutes.");
          interval = (Integer) event.getOldValue();
        }
        // StandardContext.setSessionTimeout passes -1 if the configured timeout
        // is 0; otherwise it passes the value set in web.xml. If the interval
        // parameter equals the default, set the max inactive interval to the
        // default (no expiration); otherwise set it in seconds.
        setMaxInactiveInterval(interval == RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL
            ? RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL : interval * 60);
      } catch (NumberFormatException e) {
        getLogger()
            .error(sm.getString("standardManager.sessionTimeout", event.getNewValue().toString()));
      }
    }
  }

  /**
   * Save any currently active sessions in the appropriate persistence mechanism, if any. If
   * persistence is not supported, this method returns without doing anything.
   *
   * @throws IOException if an input/output error occurs
   */
  private void doUnload() throws IOException {
    QueryService querySvc = getSessionCache().getCache().getQueryService();
    Context context = getTheContext();

    if (context == null) {
      return;
    }

    String regionName;
    if (getRegionName().startsWith("/")) {
      regionName = getRegionName();
    } else {
      regionName = "/" + getRegionName();
    }

    Query query = querySvc.newQuery("select s.id from " + regionName
        + " as s where s.contextName = '" + context.getPath() + "'");

    if (getLogger().isDebugEnabled()) {
      getLogger().debug("Query: " + query.getQueryString());
    }

    SelectResults results;
    try {
      results = (SelectResults) query.execute();
    } catch (Exception ex) {
      getLogger().error("Unable to perform query during doUnload", ex);
      return;
    }

    if (results.isEmpty()) {
      getLogger().debug("No sessions to unload for context " + context.getPath());
      return; // nothing to do
    }

    // Open an output stream to the specified pathname, if any
    File store = sessionStore(context.getPath());
    if (store == null) {
      return;
    }
    if (getLogger().isDebugEnabled()) {
      getLogger().debug("Unloading sessions to " + store.getAbsolutePath());
    }
    FileOutputStream fos = null;
    BufferedOutputStream bos = null;
    ObjectOutputStream oos = null;
    boolean error = false;
    try {
      fos = getFileOutputStream(store);
      bos = getBufferedOutputStream(fos);
      oos = getObjectOutputStream(bos);
    } catch (IOException e) {
      error = true;
      getLogger().error("Exception unloading sessions", e);
      throw e;
    } finally {
      if (error) {
        if (oos != null) {
          try {
            oos.close();
          } catch (IOException ioe) {
            // Ignore
          }
        }
        if (bos != null) {
          try {
            bos.close();
          } catch (IOException ioe) {
            // Ignore
          }
        }
        if (fos != null) {
          try {
            fos.close();
          } catch (IOException ioe) {
            // Ignore
          }
        }
      }
    }

    ArrayList<DeltaSessionInterface> list = new ArrayList<>();
    @SuppressWarnings("unchecked")
    Iterator<String> elements = (Iterator<String>) results.iterator();
    while (elements.hasNext()) {
      String id = elements.next();
      DeltaSessionInterface session = (DeltaSessionInterface) findSession(id);
      if (session != null) {
        list.add(session);
      }
    }

    // Write the number of active sessions, followed by the details
    if (getLogger().isDebugEnabled())
      getLogger().debug("Unloading " + list.size() + " sessions");
    try {
      writeToObjectOutputStream(oos, list);
      for (DeltaSessionInterface session : list) {
        if (session instanceof StandardSession) {
          StandardSession standardSession = (StandardSession) session;
          standardSession.passivate();
          standardSession.writeObjectData(oos);
        } else {
          // All DeltaSessionInterfaces as of Geode 1.0 should be based on StandardSession
          throw new IOException("Session should be of type StandardSession");
        }
      }
    } catch (IOException e) {
      getLogger().error("Exception unloading sessions", e);
      try {
        oos.close();
      } catch (IOException f) {
        // Ignore
      }
      throw e;
    }

    // Flush and close the output stream
    try {
      oos.flush();
    } finally {
      try {
        oos.close();
      } catch (IOException f) {
        // Ignore
      }
    }

    // Locally destroy the sessions we just wrote
    if (getSessionCache().isClientServer()) {
      for (DeltaSessionInterface session : list) {
        if (getLogger().isDebugEnabled()) {
          getLogger().debug("Locally destroying session " + session.getId());
        }
        getSessionCache().getOperatingRegion().localDestroy(session.getId());
      }
    }

    if (getLogger().isDebugEnabled()) {
      getLogger().debug("Unloading complete");
    }
  }

  /**
   * Load any currently active sessions that were previously unloaded to the appropriate persistence
   * mechanism, if any. If persistence is not supported, this method returns without doing anything.
   *
   * @throws ClassNotFoundException if a serialized class cannot be found during the reload
   * @throws IOException if an input/output error occurs
   */
  private void doLoad() throws ClassNotFoundException, IOException {
    Context context = getTheContext();
    if (context == null) {
      return;
    }

    // Open an input stream to the specified pathname, if any
    File store = sessionStore(context.getPath());
    if (store == null) {
      getLogger().debug("No session store file found");
      return;
    }
    if (getLogger().isDebugEnabled()) {
      getLogger().debug("Loading sessions from " + store.getAbsolutePath());
    }
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    ObjectInputStream ois;
    Loader loader = null;
    ClassLoader classLoader = null;
    try {
      fis = getFileInputStream(store);
      bis = getBufferedInputStream(fis);
      if (getTheContext() != null) {
        loader = getTheContext().getLoader();
      }
      if (loader != null) {
        classLoader = loader.getClassLoader();
      }
      if (classLoader != null) {
        if (getLogger().isDebugEnabled()) {
          getLogger().debug("Creating custom object input stream for class loader");
        }
        ois = new CustomObjectInputStream(bis, classLoader);
      } else {
        if (getLogger().isDebugEnabled()) {
          getLogger().debug("Creating standard object input stream");
        }
        ois = getObjectInputStream(bis);
      }
    } catch (FileNotFoundException e) {
      if (getLogger().isDebugEnabled()) {
        getLogger().debug("No persisted data file found");
      }
      return;
    } catch (IOException e) {
      getLogger().error("Exception loading sessions", e);
      try {
        fis.close();
      } catch (IOException f) {
        // Ignore
      }
      try {
        bis.close();
      } catch (IOException f) {
        // Ignore
      }
      throw e;
    }

    // Load the previously unloaded active sessions
    try {
      int n = getSessionCountFromObjectInputStream(ois);
      if (getLogger().isDebugEnabled()) {
        getLogger().debug("Loading " + n + " persisted sessions");
      }
      for (int i = 0; i < n; i++) {
        StandardSession session = getNewSession();
        session.readObjectData(ois);
        session.setManager(this);

        Region region = getSessionCache().getOperatingRegion();
        DeltaSessionInterface existingSession = (DeltaSessionInterface) region.get(session.getId());
        // Check whether the existing session is newer
        if (existingSession != null
            && existingSession.getLastAccessedTime() > session.getLastAccessedTime()) {
          if (getLogger().isDebugEnabled()) {
            getLogger().debug("Loaded session " + session.getId() + " is older than cached copy");
          }
          continue;
        }

        // Check whether the new session has already expired
        if (!session.isValid()) {
          if (getLogger().isDebugEnabled()) {
            getLogger().debug("Loaded session " + session.getId() + " is invalid");
          }
          continue;
        }

        getLogger().debug("Loading session " + session.getId());
        session.activate();
        add(session);
      }
    } catch (ClassNotFoundException | IOException e) {
      getLogger().error(e);
      try {
        ois.close();
      } catch (IOException f) {
        // Ignore
      }
      throw e;
    } finally {
      // Close the input stream
      try {
        ois.close();
      } catch (IOException f) {
        // ignored
      }

      // Delete the persistent storage file
      if (store.exists()) {
        if (!store.delete()) {
          getLogger().warn("Couldn't delete persistent storage file " + store.getAbsolutePath());
        }
      }
    }
  }

  /**
   * Return a File object representing the pathname to our persistence file, if any.
   */
  private File sessionStore(String ctxPath) {
    String storeDir = getSystemPropertyValue(catalinaBaseSystemProperty);
    if (storeDir == null || storeDir.isEmpty()) {
      storeDir = getSystemPropertyValue(javaTempDirSystemProperty);
    } else {
      storeDir += getSystemPropertyValue(fileSeparatorSystemProperty) + "temp";
    }

    return getFileAtPath(storeDir, ctxPath);
  }

  String getSystemPropertyValue(String propertyKey) {
    return System.getProperty(propertyKey);
  }

  File getFileAtPath(String storeDir, String ctxPath) {
    return (new File(storeDir, ctxPath.replaceAll("/", "_") + ".sessions.ser"));
  }

  FileInputStream getFileInputStream(File file) throws FileNotFoundException {
    return new FileInputStream(file.getAbsolutePath());
  }

  BufferedInputStream getBufferedInputStream(FileInputStream fis) {
    return new BufferedInputStream(fis);
  }

  ObjectInputStream getObjectInputStream(BufferedInputStream bis) throws IOException {
    return new ObjectInputStream(bis);
  }

  FileOutputStream getFileOutputStream(File file) throws FileNotFoundException {
    return new FileOutputStream(file.getAbsolutePath());
  }

  BufferedOutputStream getBufferedOutputStream(FileOutputStream fos) {
    return new BufferedOutputStream(fos);
  }

  ObjectOutputStream getObjectOutputStream(BufferedOutputStream bos) throws IOException {
    return new ObjectOutputStream(bos);
  }

  void writeToObjectOutputStream(ObjectOutputStream oos, List listToWrite) throws IOException {
    oos.writeObject(listToWrite.size());
  }

  int getSessionCountFromObjectInputStream(ObjectInputStream ois)
      throws IOException, ClassNotFoundException {
    return (Integer) ois.readObject();
  }

  @Override
  public String toString() {
    return getClass().getSimpleName() + "[" + "container="
        + getTheContext() + "; regionName=" + this.regionName
        + "; regionAttributesId=" + this.regionAttributesId + "]";
  }

  String getContextName() {
    return getTheContext().getName();
  }

  public Context getTheContext() {
    if (getContainer() instanceof Context) {
      return (Context) getContainer();
    } else {
      getLogger().error("Unable to unload sessions - container is of type "
          + getContainer().getClass().getName() + " instead of StandardContext");
      return null;
    }
  }
}
