FileDocCategorySizeDatePackage
JDBCStore.javaAPI DocGlassfish v2 API27214Fri May 04 22:32:18 BST 2007org.apache.catalina.session

JDBCStore

public class JDBCStore extends StoreBase implements org.apache.catalina.Store
Implementation of the Store interface that stores serialized session objects in a database. Sessions that are saved are still subject to being expired based on inactivity.
author
Bip Thelin
version
$Revision: 1.5 $, $Date: 2007/05/05 05:32:18 $

Fields Summary
protected static final String
info
The descriptive information about this implementation.
private String
name
Context name associated with this Store
protected static final String
storeName
Name to register for this Store, used for logging.
protected String
threadName
Name to register for the background thread.
protected String
connString
Connection string to use when connecting to the DB.
private Connection
conn
The database connection.
protected String
driverName
Driver to use.
protected String
sessionTable
Table to use.
protected String
sessionAppCol
Column to use for /Engine/Host/Context name
protected String
sessionIdCol
Id column to use.
protected String
sessionDataCol
Data column to use.
protected String
sessionValidCol
Is Valid column to use.
protected String
sessionMaxInactiveCol
Max Inactive column to use.
protected String
sessionLastAccessedCol
Last Accessed column to use.
protected PreparedStatement
preparedSizeSql
Variable to hold the getSize() prepared statement.
protected PreparedStatement
preparedKeysSql
Variable to hold the keys() prepared statement.
protected PreparedStatement
preparedSaveSql
Variable to hold the save() prepared statement.
protected PreparedStatement
preparedClearSql
Variable to hold the clear() prepared statement.
protected PreparedStatement
preparedRemoveSql
Variable to hold the remove() prepared statement.
protected PreparedStatement
preparedLoadSql
Variable to hold the load() prepared statement.
Constructors Summary
Methods Summary
public voidclear()
Remove all of the Sessions in this Store.

exception
IOException if an input/output error occurs

        String clearSql =
            "DELETE FROM " + sessionTable + " WHERE " + sessionAppCol + " = ?";

        synchronized(this) {
            Connection _conn = getConnection();
            if(_conn == null) {
                return;
            }

            try {
                if(preparedClearSql == null) {
                    preparedClearSql = _conn.prepareStatement(clearSql);
                }

                preparedClearSql.setString(1, getName());
                preparedClearSql.execute();
            } catch(SQLException e) {
                log(sm.getString(getStoreName()+".SQLException", e));
            } finally {
                release(_conn);
            }
        }
    
protected java.sql.ConnectiongetConnection()
Check the connection associated with this store, if it's null or closed try to reopen it. Returns null if the connection could not be established.

return
Connection if the connection suceeded

        try {
            if(conn == null || conn.isClosed()) {
                Class.forName(driverName);
                log(sm.getString(getStoreName()+".checkConnectionDBClosed"));
                conn = DriverManager.getConnection(connString);
                conn.setAutoCommit(true);

                if(conn == null || conn.isClosed()) {
                    log(sm.getString(getStoreName()+".checkConnectionDBReOpenFail"));
                }
            }
        } catch (SQLException ex){
            log(sm.getString(getStoreName()+".checkConnectionSQLException",
                             ex.toString()));
        } catch (ClassNotFoundException ex) {
            log(sm.getString(getStoreName()+".checkConnectionClassNotFoundException",
                             ex.toString()));
        }

        return conn;
    
public java.lang.StringgetConnectionURL()
Return the Connection URL for this Store.

        return(this.connString);
    
public java.lang.StringgetDriverName()
Return the driver for this Store.

        return(this.driverName);
    
public java.lang.StringgetInfo()
Return the info for this Store.


    // ------------------------------------------------------------- Properties

               
       
        return(info);
    
public java.lang.StringgetName()
Return the name for this instance (built from container name)

        if (name == null) {
            Container container = manager.getContainer();
            String contextName = container.getName();
            String hostName = "";
            String engineName = "";

            if (container.getParent() != null) {
                Container host = container.getParent();
                hostName = host.getName();
                if (host.getParent() != null) {
                    engineName = host.getParent().getName();
                }
            }
            name = "/" + engineName + "/" + hostName + contextName;
        }
        return name;
    
public java.lang.StringgetSessionAppCol()
Return the web application name column for the table.

        return(this.sessionAppCol);
    
public java.lang.StringgetSessionDataCol()
Return the data column for the table

        return(this.sessionDataCol);
    
public java.lang.StringgetSessionIdCol()
Return the Id column for the table.

        return(this.sessionIdCol);
    
public java.lang.StringgetSessionLastAccessedCol()
Return the Last Accessed column

        return(this.sessionLastAccessedCol);
    
public java.lang.StringgetSessionMaxInactiveCol()
Return the Max Inactive column

        return(this.sessionMaxInactiveCol);
    
public java.lang.StringgetSessionTable()
Return the table for this Store.

        return(this.sessionTable);
    
public java.lang.StringgetSessionValidCol()
Return the Is Valid column

        return(this.sessionValidCol);
    
public intgetSize()
Return an integer containing a count of all Sessions currently saved in this Store. If there are no Sessions, 0 is returned.

exception
IOException if an input/output error occurred

        int size = 0;
        String sizeSql = 
            "SELECT COUNT(" + sessionIdCol + ") FROM " + sessionTable +
            " WHERE " + sessionAppCol + " = ?";
        ResultSet rst = null;

        synchronized(this) {
            Connection _conn = getConnection();

            if(_conn == null) {
                return(size);
            }

            try {
                if(preparedSizeSql == null) {
                    preparedSizeSql = _conn.prepareStatement(sizeSql);
                }

                preparedSizeSql.setString(1, getName());
                rst = preparedSizeSql.executeQuery();
                if (rst.next()) {
                    size = rst.getInt(1);
                }
            } catch(SQLException e) {
                log(sm.getString(getStoreName()+".SQLException", e));
            } finally {
                try {
                    if(rst != null)
                        rst.close();
                } catch(SQLException e) {
                    ;
                }

                release(_conn);
            }
        }
        return(size);
    
public java.lang.StringgetStoreName()
Return the name for this Store, used for logging.

        return(storeName);
    
public java.lang.StringgetThreadName()
Return the thread name for this Store.

        return(threadName);
    
public java.lang.String[]keys()
Return an array containing the session identifiers of all Sessions currently saved in this Store. If there are no such Sessions, a zero-length array is returned.

exception
IOException if an input/output error occurred

        String keysSql =
            "SELECT " + sessionIdCol + " FROM " + sessionTable +
            " WHERE " + sessionAppCol + " = ?";
        ResultSet rst = null;
        String keys[] = null;
        int i;

        synchronized(this) {
            Connection _conn = getConnection();

            if(_conn == null) {
                return(new String[0]);
            }

            try {
                if(preparedKeysSql == null) {
                    preparedKeysSql = _conn.prepareStatement(keysSql);
                }

                preparedKeysSql.setString(1, getName());
                rst = preparedKeysSql.executeQuery();
                ArrayList tmpkeys = new ArrayList();
                if (rst != null) {
                    while(rst.next()) {
                        tmpkeys.add(rst.getString(1));
                    }
                }
                keys = (String[]) tmpkeys.toArray(new String[tmpkeys.size()]);
            } catch(SQLException e) {
                log(sm.getString(getStoreName()+".SQLException", e));
            } finally {
                try {
                    if(rst != null) {
                        rst.close();
                    }
                } catch(SQLException e) {
                    ;
                }

                release(_conn);
            }
        }

        return(keys);
    
public org.apache.catalina.Sessionload(java.lang.String id)
Load the Session associated with the id id. If no such session is found null is returned.

param
id a value of type String
return
the stored Session
exception
ClassNotFoundException if an error occurs
exception
IOException if an input/output error occurred

        ResultSet rst = null;
        StandardSession _session = null;
        Loader loader = null;
        ClassLoader classLoader = null;
        ObjectInputStream ois = null;
        BufferedInputStream bis = null;
        Container container = manager.getContainer();
        String loadSql =
            "SELECT " + sessionIdCol + ", " + sessionDataCol + " FROM " +
            sessionTable + " WHERE " + sessionIdCol + " = ? AND " +
            sessionAppCol + " = ?";

        synchronized(this) {
            Connection _conn = getConnection();
            if(_conn == null) {
                return(null);
            }

            try {
                if(preparedLoadSql == null) {
                    preparedLoadSql = _conn.prepareStatement(loadSql);
                }

                preparedLoadSql.setString(1, id);
                preparedLoadSql.setString(2, getName());
                rst = preparedLoadSql.executeQuery();
                if (rst.next()) {
                    bis = new BufferedInputStream(rst.getBinaryStream(2));

                    if (container != null) {
                        loader = container.getLoader();
                    }
                    if (loader != null) {
                        classLoader = loader.getClassLoader();
                    }
                    if (classLoader != null) {
                        ois = new CustomObjectInputStream(bis,
                                                          classLoader);
                    } else {
                        ois = new ObjectInputStream(bis);
                    }

                    if (debug > 0) {
                        log(sm.getString(getStoreName()+".loading",
                                         id, sessionTable));
                    }

                    _session = StandardSession.deserialize(ois, manager);
                    _session.setManager(manager);

                } else if (debug > 0) {
                    log(getStoreName()+": No persisted data object found");
                }
            } catch(SQLException e) {
                log(sm.getString(getStoreName()+".SQLException", e));
            } finally {
                try {
                    if(rst != null) {
                        rst.close();
                    }
                } catch(SQLException e) {
                    ;
                }
                if (ois != null) {
                    try {
                        ois.close();
                    } catch (IOException e) {
                        ;
                    }
                }
                release(_conn);
            }
        }

        return(_session);
    
protected voidrelease(java.sql.Connection conn)
Release the connection, not needed here since the connection is not associated with a connection pool.

param
conn The connection to be released

        ;
    
public voidremove(java.lang.String id)
Remove the Session with the specified session identifier from this Store, if present. If no such Session is present, this method takes no action.

param
id Session identifier of the Session to be removed
exception
IOException if an input/output error occurs

        String removeSql =
            "DELETE FROM " + sessionTable + " WHERE " + sessionIdCol +
            " = ?  AND " + sessionAppCol + " = ?";

        synchronized(this) {
            Connection _conn = getConnection();

            if(_conn == null) {
                return;
            }

            try {
                if(preparedRemoveSql == null) {
                    preparedRemoveSql = _conn.prepareStatement(removeSql);
                }

                preparedRemoveSql.setString(1, id);
                preparedRemoveSql.setString(2, getName());
                preparedRemoveSql.execute();
            } catch(SQLException e) {
                log(sm.getString(getStoreName()+".SQLException", e));
            } finally {
                release(_conn);
            }
        }

        if (debug > 0) {
            log(sm.getString(getStoreName()+".removing", id, sessionTable));
        }
    
public voidsave(org.apache.catalina.Session session)
Save a session to the Store.

param
session the session to be stored
exception
IOException if an input/output error occurs

        String saveSql =
            "INSERT INTO " + sessionTable + " (" + sessionIdCol + ", " +
            sessionAppCol + ", " +
            sessionDataCol + ", " +
            sessionValidCol + ", " +
            sessionMaxInactiveCol + ", " +
            sessionLastAccessedCol + ") VALUES (?, ?, ?, ?, ?, ?)";
        ObjectOutputStream oos = null;
        ByteArrayOutputStream bos = null;
        ByteArrayInputStream bis = null;
        InputStream in = null;

        synchronized(this) {
            Connection _conn = getConnection();
            if(_conn == null) {
                return;
            }

            // If sessions already exist in DB, remove and insert again.
            // TODO:
            // * Check if ID exists in database and if so use UPDATE.
            remove(session.getIdInternal());

            try {
                bos = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(new BufferedOutputStream(bos));

                oos.writeObject(session);
                oos.close();

                byte[] obs = bos.toByteArray();
                int size = obs.length;
                bis = new ByteArrayInputStream(obs, 0, size);
                in = new BufferedInputStream(bis, size);

                if(preparedSaveSql == null) {
                    preparedSaveSql = _conn.prepareStatement(saveSql);
                }

                preparedSaveSql.setString(1, session.getIdInternal());
                preparedSaveSql.setString(2, getName());
                preparedSaveSql.setBinaryStream(3, in, size);
                preparedSaveSql.setString(4, session.isValid()?"1":"0");
                preparedSaveSql.setInt(5, session.getMaxInactiveInterval());
                preparedSaveSql.setLong(6, session.getLastAccessedTime());
                preparedSaveSql.execute();
            } catch(SQLException e) {
                log(sm.getString(getStoreName()+".SQLException", e));
            } catch (IOException e) {
                ;
            } finally {
                if(bis != null) {
                    bis.close();
                }
                if(in != null) {
                    in.close();
                }

                release(_conn);
            }
        }

        if (debug > 0) {
            log(sm.getString(getStoreName()+".saving",
                             session.getIdInternal(), sessionTable));
        }
    
public voidsetConnectionURL(java.lang.String connectionURL)
Set the Connection URL for this Store.

param
connectionURL The new Connection URL

        String oldConnString = this.connString;
        this.connString = connectionURL;
        support.firePropertyChange("connString",
                                   oldConnString,
                                   this.connString);
    
public voidsetDriverName(java.lang.String driverName)
Set the driver for this Store.

param
driverName The new driver

        String oldDriverName = this.driverName;
        this.driverName = driverName;
        support.firePropertyChange("driverName",
                                   oldDriverName,
                                   this.driverName);
        this.driverName = driverName;
    
public voidsetSessionAppCol(java.lang.String sessionAppCol)
Set the App column for the table.

param
sessionAppCol the column name

        String oldSessionAppCol = this.sessionAppCol;
        this.sessionAppCol = sessionAppCol;
        support.firePropertyChange("sessionAppCol",
                                   oldSessionAppCol,
                                   this.sessionAppCol);
    
public voidsetSessionDataCol(java.lang.String sessionDataCol)
Set the Data column for the table

param
sessionDataCol the column name

        String oldSessionDataCol = this.sessionDataCol;
        this.sessionDataCol = sessionDataCol;
        support.firePropertyChange("sessionDataCol",
                                   oldSessionDataCol,
                                   this.sessionDataCol);
    
public voidsetSessionIdCol(java.lang.String sessionIdCol)
Set the Id column for the table.

param
sessionIdCol the column name

        String oldSessionIdCol = this.sessionIdCol;
        this.sessionIdCol = sessionIdCol;
        support.firePropertyChange("sessionIdCol",
                                   oldSessionIdCol,
                                   this.sessionIdCol);
    
public voidsetSessionLastAccessedCol(java.lang.String sessionLastAccessedCol)
Set the Last Accessed column for the table

param
sessionLastAccessedCol The column name

        String oldSessionLastAccessedCol = this.sessionLastAccessedCol;
        this.sessionLastAccessedCol = sessionLastAccessedCol;
        support.firePropertyChange("sessionLastAccessedCol",
                                   oldSessionLastAccessedCol,
                                   this.sessionLastAccessedCol);
    
public voidsetSessionMaxInactiveCol(java.lang.String sessionMaxInactiveCol)
Set the Max Inactive column for the table

param
sessionMaxInactiveCol The column name

        String oldSessionMaxInactiveCol = this.sessionMaxInactiveCol;
        this.sessionMaxInactiveCol = sessionMaxInactiveCol;
        support.firePropertyChange("sessionMaxInactiveCol",
                                   oldSessionMaxInactiveCol,
                                   this.sessionMaxInactiveCol);
    
public voidsetSessionTable(java.lang.String sessionTable)
Set the table for this Store.

param
sessionTable The new table

        String oldSessionTable = this.sessionTable;
        this.sessionTable = sessionTable;
        support.firePropertyChange("sessionTable",
                                   oldSessionTable,
                                   this.sessionTable);
    
public voidsetSessionValidCol(java.lang.String sessionValidCol)
Set the Is Valid column for the table

param
sessionValidCol The column name

        String oldSessionValidCol = this.sessionValidCol;
        this.sessionValidCol = sessionValidCol;
        support.firePropertyChange("sessionValidCol",
                                   oldSessionValidCol,
                                   this.sessionValidCol);
    
public voidstart()
Called once when this Store is first started.

        super.start();

        // Open connection to the database
        this.conn = getConnection();
    
public voidstop()
Gracefully terminate everything associated with our db. Called once when this Store is stoping.

        super.stop();

        // Close and release everything associated with our db.
        if(conn != null) {
            try {
                conn.commit();
            } catch (SQLException e) {
                ;
            }

            if( preparedSizeSql != null ) {
                try {
                    preparedSizeSql.close();
                } catch (SQLException e) {
                    ;
                }
            }

            if( preparedKeysSql != null ) { 
                try {
                    preparedKeysSql.close();
                } catch (SQLException e) {
                    ;
                }
            }

            if( preparedSaveSql != null ) { 
                try {
                    preparedSaveSql.close();
                } catch (SQLException e) {
                    ;
                }
            }

            if( preparedClearSql != null ) { 
                try {
                    preparedClearSql.close();
                } catch (SQLException e) {
                    ;
                }
            }

            if( preparedRemoveSql != null ) { 
                try {
                    preparedRemoveSql.close();
                } catch (SQLException e) {
                    ;
                }
            }

            if( preparedLoadSql != null ) { 
                try {
                    preparedLoadSql.close();
                } catch (SQLException e) {
                    ;
                }
            }

            try {
                conn.close();
            } catch (SQLException e) {
                ;
            }

            this.preparedSizeSql = null;
            this.preparedKeysSql = null;
            this.preparedSaveSql = null;
            this.preparedClearSql = null;
            this.preparedRemoveSql = null;
            this.preparedLoadSql = null;
            this.conn = null;
        }