FileDocCategorySizeDatePackage
StatefulSessionFilePersistenceManager.javaAPI DocJBoss 4.2.114596Fri Jul 13 20:53:48 BST 2007org.jboss.ejb3.cache.simple

StatefulSessionFilePersistenceManager

public class StatefulSessionFilePersistenceManager extends Object implements StatefulSessionPersistenceManager
A file-based stateful session bean persistence manager.

Reads and writes session bean objects to files by using the standard Java serialization mechanism.

Passivated state files are stored under: jboss-server-data-dir/storeDirectoryName/ejb-name-unique-id.

Since ejb-name is not unique across deployments we generate a unique-id to make sure that beans with the same EJB name do not collide.

author
Rickard ?berg
author
Marc Fleury
author
Sebastien Alborini
author
Jason Dillon
author
Bill Burke
version
$Revision: 61329 $
jmx:mbean
extends="org.jboss.system.ServiceMBean"

Fields Summary
private String
storeDirName
The sub-directory name under the server data directory where session data is stored.
private File
storeDir
The base directory where sessions state files are stored for our container.
private org.jboss.ejb3.Container
con
private boolean
purgeEnabled
Enable purging leftover state files at create and destroy time (default is true).
Constructors Summary
Methods Summary
public org.jboss.ejb3.stateful.StatefulBeanContextactivateSession(java.lang.Object id)
Restores session state from the serialized file & invokes {@link javax.ejb.SessionBean#ejbActivate} on the target bean.

      boolean debug = log.isDebugEnabled();
      if (debug)
      {
         log.debug("Attempting to activate; id=" + id);
      }

      // Load state
      File file = getFile(id);
      if (!file.exists()) return null;
      
      if (debug)
      {
         log.debug("Reading session state from: " + file);
      }

      StatefulBeanContext bean = null;
      try
      {
         FileInputStream fis = FISAction.open(file);
         // todo need to rewrite SessionObjectInputStream to support EJB3 classes
         ObjectInputStream in;

         in = new JBossObjectInputStream(new BufferedInputStream(fis));
         try
         {
            bean = (StatefulBeanContext) in.readObject();
         }
         finally
         {
            fis.close();
            in.close();
         }
      }
      catch (EJBException e)
      {
         throw e;
      }
      catch (Exception e)
      {
         throw new EJBException("Could not activate; failed to " +
                                "restore state", e);
      }

      removePassivated(id);

      bean.postActivate();
      return bean;
   
public voiddestroy()
Purge any data in the store, and then the store directory too.

      // Purge data and attempt to delete directory
      purgeAllSessionData();

      // Nuke the directory too if purge is enabled
      if (purgeEnabled && !storeDir.delete())
      {
         log.warn("Failed to delete session state storage directory: " + storeDir);
      }
   
private java.io.FilegetFile(java.lang.Object id)
Make a session state file for the given instance id.

      //
      // jason: may have to translate id into a os-safe string, though
      //        the format of UID is safe on Unix and win32 already...
      //

      return new File(storeDir, String.valueOf(id) + ".ser");
   
public intgetNumPassivatedBeans()

 
      return storeDir.listFiles().length;
   
public java.util.ListgetPassivatedBeans()

      List beans = new LinkedList();
      
      File[] files = storeDir.listFiles();
      for (File file : files)
      {
         try
         {
            ObjectInputStream in;
            
            FileInputStream fis = FISAction.open(file);
   
            in = new JBossObjectInputStream(new BufferedInputStream(fis));
            try
            {
               StatefulBeanContext bean = (StatefulBeanContext) in.readObject();
               beans.add(bean);
            }
            finally
            {
               fis.close();
               in.close();
            }
         }
         catch (Exception e)
         {
            log.warn("Could not read for timeout removal for file " + file.getName() + ". " + e.getMessage());
         }
      }
      
      return beans;
   
public booleangetPurgeEnabled()
Get the stale session state purge enabled flag.

return
True if purge is enabled.

      return purgeEnabled;
   
public java.io.FilegetStoreDirectory()
Returns the directory used to store session passivation state files.

return
The directory used to store session passivation state files.

      return storeDir;
   
public java.lang.StringgetStoreDirectoryName()
Get the sub-directory name under the server data directory where session data is stored.

return
A sub-directory name.
see
#setStoreDirectoryName

      return storeDirName;
   
public voidinitialize(org.jboss.ejb3.Container con)
Setup the session data storage directory.

Purges any existing session data found.

      this.con = con;
      boolean debug = log.isDebugEnabled();

      // Initialize the dataStore

      String ejbName = con.getEjbName();

      // Get the system data directory
      File dir = ServerConfigLocator.locate().getServerTempDir();

      // Setup the reference to the session data store directory
      dir = new File(dir, storeDirName);
      // ejbName is not unique across all deployments, so use a unique token
      dir = new File(dir, ejbName + "-" + new UID().toString());
      storeDir = dir;

      if (debug)
      {
         log.debug("Storing sessions for '" + ejbName + "' in: " + storeDir);
      }

      // if the directory does not exist then try to create it
      if (!storeDir.exists())
      {
         if (MkdirsFileAction.mkdirs(storeDir) == false)
         {
            throw new IOException("Failed to create directory: " + storeDir);
         }
      }

      // make sure we have a directory
      if (!storeDir.isDirectory())
      {
         throw new IOException("File exists where directory expected: " + storeDir);
      }

      // make sure we can read and write to it
      if (!storeDir.canWrite() || !storeDir.canRead())
      {
         throw new IOException("Directory must be readable and writable: " + storeDir);
      }

      // Purge state session state files, should be none, due to unique directory
      purgeAllSessionData();
   
public voidpassivateSession(org.jboss.ejb3.stateful.StatefulBeanContext ctx)
Invokes {@link javax.ejb.SessionBean#ejbPassivate} on the target bean and saves the state of the session to a file.

      boolean debug = log.isDebugEnabled();
      if (debug)
      {
         log.debug("Attempting to passivate; id=" + ctx.getId());
      }

      ctx.prePassivate();
      // Store state

      File file = getFile(ctx.getId());
      if (debug)
      {
         log.debug("Saving session state to: " + file);
      }

      try
      {
         FileOutputStream fos = FOSAction.open(file);
         // todo need to rewrite SessionObjectOutputStream to support EJB3 classes
         ObjectOutputStream out;

         out = new JBossObjectOutputStream(fos, false);

         try
         {
            out.writeObject(ctx);
            out.flush();
            fos.flush();
            fos.close();
         }
         finally
         {
            out.close();
         }
      }
      catch (EJBException e)
      {
         throw e;
      }
      catch (Exception e)
      {
         throw new EJBException("Could not passivate; failed to save state", e);
      }

      if (debug)
      {
         log.debug("Passivation complete; id=" + ctx.getId());
      }
   
public voidpurgeAllSessionData()
Removes any state files left in the storgage directory.

      if (!purgeEnabled) return;

      log.debug("Purging all session data in: " + storeDir);

      File[] sessions = storeDir.listFiles();
      for (int i = 0; i < sessions.length; i++)
      {
         if (!sessions[i].delete())
         {
            log.warn("Failed to delete session state file: " + sessions[i]);
         }
         else
         {
            log.debug("Removed stale session state: " + sessions[i]);
         }
      }
   
public voidremovePassivated(java.lang.Object id)
Removes the saved state file (if any) for the given session id.

      boolean debug = log.isDebugEnabled();

      File file = getFile(id);

      // only attempt to delete if the file exists
      if (file.exists())
      {
         if (debug)
         {
            log.debug("Removing passivated state file: " + file);
         }

         if (DeleteFileAction.delete(file) == false)
         {
            log.warn("Failed to delete passivated state file: " + file);
         }
      }
   
public voidsetContainer(org.jboss.ejb3.Container con)

      this.con = con;
   
public voidsetPurgeEnabled(boolean flag)
Set the stale session state purge enabled flag.

param
flag The toggle flag to enable or disable purging.

      this.purgeEnabled = flag;
   
public voidsetStoreDirectoryName(java.lang.String dirName)
Set the sub-directory name under the server data directory where session data will be stored.

This value will be appened to the value of jboss-server-data-dir.

This value is only used during creation and will not dynamically change the store directory when set after the create step has finished.

param
dirName A sub-directory name.


                                                                
       
   
      this.storeDirName = dirName;