Home » apache-tomcat-6.0.26-src » org.apache » catalina » session » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.catalina.session;
   19   
   20   import org.apache.catalina.Container;
   21   import org.apache.catalina.LifecycleException;
   22   import org.apache.catalina.Loader;
   23   import org.apache.catalina.Session;
   24   import org.apache.catalina.Store;
   25   import org.apache.catalina.util.CustomObjectInputStream;
   26   import java.io.BufferedInputStream;
   27   import java.io.BufferedOutputStream;
   28   import java.io.ByteArrayInputStream;
   29   import java.io.ByteArrayOutputStream;
   30   import java.io.IOException;
   31   import java.io.InputStream;
   32   import java.io.ObjectInputStream;
   33   import java.io.ObjectOutputStream;
   34   import java.sql.Connection;
   35   import java.sql.Driver;
   36   import java.sql.PreparedStatement;
   37   import java.sql.ResultSet;
   38   import java.sql.SQLException;
   39   import java.util.ArrayList;
   40   import java.util.Properties;
   41   
   42   /**
   43    * Implementation of the <code>Store</code> interface that stores
   44    * serialized session objects in a database.  Sessions that are
   45    * saved are still subject to being expired based on inactivity.
   46    *
   47    * @author Bip Thelin
   48    * @version $Revision: 554109 $, $Date: 2007-07-07 03:40:19 +0200 (Sat, 07 Jul 2007) $
   49    */
   50   
   51   public class JDBCStore
   52           extends StoreBase implements Store {
   53   
   54       /**
   55        * The descriptive information about this implementation.
   56        */
   57       protected static String info = "JDBCStore/1.0";
   58   
   59       /**
   60        * Context name associated with this Store
   61        */
   62       private String name = null;
   63   
   64       /**
   65        * Name to register for this Store, used for logging.
   66        */
   67       protected static String storeName = "JDBCStore";
   68   
   69       /**
   70        * Name to register for the background thread.
   71        */
   72       protected String threadName = "JDBCStore";
   73   
   74       /**
   75        * The connection username to use when trying to connect to the database.
   76        */
   77       protected String connectionName = null;
   78   
   79   
   80       /**
   81        * The connection URL to use when trying to connect to the database.
   82        */
   83       protected String connectionPassword = null;
   84   
   85       /**
   86        * Connection string to use when connecting to the DB.
   87        */
   88       protected String connectionURL = null;
   89   
   90       /**
   91        * The database connection.
   92        */
   93       private Connection dbConnection = null;
   94   
   95       /**
   96        * Instance of the JDBC Driver class we use as a connection factory.
   97        */
   98       protected Driver driver = null;
   99   
  100       /**
  101        * Driver to use.
  102        */
  103       protected String driverName = null;
  104   
  105       // ------------------------------------------------------------- Table & cols
  106   
  107       /**
  108        * Table to use.
  109        */
  110       protected String sessionTable = "tomcat$sessions";
  111   
  112       /**
  113        * Column to use for /Engine/Host/Context name
  114        */
  115       protected String sessionAppCol = "app";
  116   
  117       /**
  118        * Id column to use.
  119        */
  120       protected String sessionIdCol = "id";
  121   
  122       /**
  123        * Data column to use.
  124        */
  125       protected String sessionDataCol = "data";
  126   
  127       /**
  128        * Is Valid column to use.
  129        */
  130       protected String sessionValidCol = "valid";
  131   
  132       /**
  133        * Max Inactive column to use.
  134        */
  135       protected String sessionMaxInactiveCol = "maxinactive";
  136   
  137       /**
  138        * Last Accessed column to use.
  139        */
  140       protected String sessionLastAccessedCol = "lastaccess";
  141   
  142       // ------------------------------------------------------------- SQL Variables
  143   
  144       /**
  145        * Variable to hold the <code>getSize()</code> prepared statement.
  146        */
  147       protected PreparedStatement preparedSizeSql = null;
  148   
  149       /**
  150        * Variable to hold the <code>keys()</code> prepared statement.
  151        */
  152       protected PreparedStatement preparedKeysSql = null;
  153   
  154       /**
  155        * Variable to hold the <code>save()</code> prepared statement.
  156        */
  157       protected PreparedStatement preparedSaveSql = null;
  158   
  159       /**
  160        * Variable to hold the <code>clear()</code> prepared statement.
  161        */
  162       protected PreparedStatement preparedClearSql = null;
  163   
  164       /**
  165        * Variable to hold the <code>remove()</code> prepared statement.
  166        */
  167       protected PreparedStatement preparedRemoveSql = null;
  168   
  169       /**
  170        * Variable to hold the <code>load()</code> prepared statement.
  171        */
  172       protected PreparedStatement preparedLoadSql = null;
  173   
  174       // ------------------------------------------------------------- Properties
  175   
  176       /**
  177        * Return the info for this Store.
  178        */
  179       public String getInfo() {
  180           return (info);
  181       }
  182   
  183       /**
  184        * Return the name for this instance (built from container name)
  185        */
  186       public String getName() {
  187           if (name == null) {
  188               Container container = manager.getContainer();
  189               String contextName = container.getName();
  190               String hostName = "";
  191               String engineName = "";
  192   
  193               if (container.getParent() != null) {
  194                   Container host = container.getParent();
  195                   hostName = host.getName();
  196                   if (host.getParent() != null) {
  197                       engineName = host.getParent().getName();
  198                   }
  199               }
  200               name = "/" + engineName + "/" + hostName + contextName;
  201           }
  202           return name;
  203       }
  204   
  205       /**
  206        * Return the thread name for this Store.
  207        */
  208       public String getThreadName() {
  209           return (threadName);
  210       }
  211   
  212       /**
  213        * Return the name for this Store, used for logging.
  214        */
  215       public String getStoreName() {
  216           return (storeName);
  217       }
  218   
  219       /**
  220        * Set the driver for this Store.
  221        *
  222        * @param driverName The new driver
  223        */
  224       public void setDriverName(String driverName) {
  225           String oldDriverName = this.driverName;
  226           this.driverName = driverName;
  227           support.firePropertyChange("driverName",
  228                   oldDriverName,
  229                   this.driverName);
  230           this.driverName = driverName;
  231       }
  232   
  233       /**
  234        * Return the driver for this Store.
  235        */
  236       public String getDriverName() {
  237           return (this.driverName);
  238       }
  239   
  240       /**
  241        * Return the username to use to connect to the database.
  242        *
  243        */
  244       public String getConnectionName() {
  245           return connectionName;
  246       }
  247   
  248       /**
  249        * Set the username to use to connect to the database.
  250        *
  251        * @param connectionName Username
  252        */
  253       public void setConnectionName(String connectionName) {
  254           this.connectionName = connectionName;
  255       }
  256   
  257       /**
  258        * Return the password to use to connect to the database.
  259        *
  260        */
  261       public String getConnectionPassword() {
  262           return connectionPassword;
  263       }
  264   
  265       /**
  266        * Set the password to use to connect to the database.
  267        *
  268        * @param connectionPassword User password
  269        */
  270       public void setConnectionPassword(String connectionPassword) {
  271           this.connectionPassword = connectionPassword;
  272       }
  273   
  274       /**
  275        * Set the Connection URL for this Store.
  276        *
  277        * @param connectionURL The new Connection URL
  278        */
  279       public void setConnectionURL(String connectionURL) {
  280           String oldConnString = this.connectionURL;
  281           this.connectionURL = connectionURL;
  282           support.firePropertyChange("connectionURL",
  283                   oldConnString,
  284                   this.connectionURL);
  285       }
  286   
  287       /**
  288        * Return the Connection URL for this Store.
  289        */
  290       public String getConnectionURL() {
  291           return (this.connectionURL);
  292       }
  293   
  294       /**
  295        * Set the table for this Store.
  296        *
  297        * @param sessionTable The new table
  298        */
  299       public void setSessionTable(String sessionTable) {
  300           String oldSessionTable = this.sessionTable;
  301           this.sessionTable = sessionTable;
  302           support.firePropertyChange("sessionTable",
  303                   oldSessionTable,
  304                   this.sessionTable);
  305       }
  306   
  307       /**
  308        * Return the table for this Store.
  309        */
  310       public String getSessionTable() {
  311           return (this.sessionTable);
  312       }
  313   
  314       /**
  315        * Set the App column for the table.
  316        *
  317        * @param sessionAppCol the column name
  318        */
  319       public void setSessionAppCol(String sessionAppCol) {
  320           String oldSessionAppCol = this.sessionAppCol;
  321           this.sessionAppCol = sessionAppCol;
  322           support.firePropertyChange("sessionAppCol",
  323                   oldSessionAppCol,
  324                   this.sessionAppCol);
  325       }
  326   
  327       /**
  328        * Return the web application name column for the table.
  329        */
  330       public String getSessionAppCol() {
  331           return (this.sessionAppCol);
  332       }
  333   
  334       /**
  335        * Set the Id column for the table.
  336        *
  337        * @param sessionIdCol the column name
  338        */
  339       public void setSessionIdCol(String sessionIdCol) {
  340           String oldSessionIdCol = this.sessionIdCol;
  341           this.sessionIdCol = sessionIdCol;
  342           support.firePropertyChange("sessionIdCol",
  343                   oldSessionIdCol,
  344                   this.sessionIdCol);
  345       }
  346   
  347       /**
  348        * Return the Id column for the table.
  349        */
  350       public String getSessionIdCol() {
  351           return (this.sessionIdCol);
  352       }
  353   
  354       /**
  355        * Set the Data column for the table
  356        *
  357        * @param sessionDataCol the column name
  358        */
  359       public void setSessionDataCol(String sessionDataCol) {
  360           String oldSessionDataCol = this.sessionDataCol;
  361           this.sessionDataCol = sessionDataCol;
  362           support.firePropertyChange("sessionDataCol",
  363                   oldSessionDataCol,
  364                   this.sessionDataCol);
  365       }
  366   
  367       /**
  368        * Return the data column for the table
  369        */
  370       public String getSessionDataCol() {
  371           return (this.sessionDataCol);
  372       }
  373   
  374       /**
  375        * Set the Is Valid column for the table
  376        *
  377        * @param sessionValidCol The column name
  378        */
  379       public void setSessionValidCol(String sessionValidCol) {
  380           String oldSessionValidCol = this.sessionValidCol;
  381           this.sessionValidCol = sessionValidCol;
  382           support.firePropertyChange("sessionValidCol",
  383                   oldSessionValidCol,
  384                   this.sessionValidCol);
  385       }
  386   
  387       /**
  388        * Return the Is Valid column
  389        */
  390       public String getSessionValidCol() {
  391           return (this.sessionValidCol);
  392       }
  393   
  394       /**
  395        * Set the Max Inactive column for the table
  396        *
  397        * @param sessionMaxInactiveCol The column name
  398        */
  399       public void setSessionMaxInactiveCol(String sessionMaxInactiveCol) {
  400           String oldSessionMaxInactiveCol = this.sessionMaxInactiveCol;
  401           this.sessionMaxInactiveCol = sessionMaxInactiveCol;
  402           support.firePropertyChange("sessionMaxInactiveCol",
  403                   oldSessionMaxInactiveCol,
  404                   this.sessionMaxInactiveCol);
  405       }
  406   
  407       /**
  408        * Return the Max Inactive column
  409        */
  410       public String getSessionMaxInactiveCol() {
  411           return (this.sessionMaxInactiveCol);
  412       }
  413   
  414       /**
  415        * Set the Last Accessed column for the table
  416        *
  417        * @param sessionLastAccessedCol The column name
  418        */
  419       public void setSessionLastAccessedCol(String sessionLastAccessedCol) {
  420           String oldSessionLastAccessedCol = this.sessionLastAccessedCol;
  421           this.sessionLastAccessedCol = sessionLastAccessedCol;
  422           support.firePropertyChange("sessionLastAccessedCol",
  423                   oldSessionLastAccessedCol,
  424                   this.sessionLastAccessedCol);
  425       }
  426   
  427       /**
  428        * Return the Last Accessed column
  429        */
  430       public String getSessionLastAccessedCol() {
  431           return (this.sessionLastAccessedCol);
  432       }
  433   
  434       // --------------------------------------------------------- Public Methods
  435   
  436       /**
  437        * Return an array containing the session identifiers of all Sessions
  438        * currently saved in this Store.  If there are no such Sessions, a
  439        * zero-length array is returned.
  440        *
  441        * @exception IOException if an input/output error occurred
  442        */
  443       public String[] keys() throws IOException {
  444           ResultSet rst = null;
  445           String keys[] = null;
  446           synchronized (this) {
  447               int numberOfTries = 2;
  448               while (numberOfTries > 0) {
  449   
  450                   Connection _conn = getConnection();
  451                   if (_conn == null) {
  452                       return (new String[0]);
  453                   }
  454                   try {
  455                       if (preparedKeysSql == null) {
  456                           String keysSql = "SELECT " + sessionIdCol + " FROM "
  457                                   + sessionTable + " WHERE " + sessionAppCol
  458                                   + " = ?";
  459                           preparedKeysSql = _conn.prepareStatement(keysSql);
  460   					}
  461   
  462                       preparedKeysSql.setString(1, getName());
  463                       rst = preparedKeysSql.executeQuery();
  464                       ArrayList tmpkeys = new ArrayList();
  465                       if (rst != null) {
  466                           while (rst.next()) {
  467                               tmpkeys.add(rst.getString(1));
  468                           }
  469                       }
  470                       keys = (String[]) tmpkeys.toArray(new String[tmpkeys.size()]);
  471                       // Break out after the finally block
  472                       numberOfTries = 0;
  473                   } catch (SQLException e) {
  474                       manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e));
  475                       keys = new String[0];
  476                       // Close the connection so that it gets reopened next time
  477                       if (dbConnection != null)
  478                           close(dbConnection);
  479                   } finally {
  480                       try {
  481                           if (rst != null) {
  482                               rst.close();
  483                           }
  484                       } catch (SQLException e) {
  485                           ;
  486                       }
  487   
  488                       release(_conn);
  489                   }
  490                   numberOfTries--;
  491               }
  492           }
  493   
  494           return (keys);
  495       }
  496   
  497       /**
  498        * Return an integer containing a count of all Sessions
  499        * currently saved in this Store.  If there are no Sessions,
  500        * <code>0</code> is returned.
  501        *
  502        * @exception IOException if an input/output error occurred
  503        */
  504       public int getSize() throws IOException {
  505           int size = 0;
  506           ResultSet rst = null;
  507   
  508           synchronized (this) {
  509               int numberOfTries = 2;
  510               while (numberOfTries > 0) {
  511                   Connection _conn = getConnection();
  512   
  513                   if (_conn == null) {
  514                       return (size);
  515                   }
  516   
  517                   try {
  518                       if (preparedSizeSql == null) {
  519                           String sizeSql = "SELECT COUNT(" + sessionIdCol
  520                                   + ") FROM " + sessionTable + " WHERE "
  521                                   + sessionAppCol + " = ?";
  522                           preparedSizeSql = _conn.prepareStatement(sizeSql);
  523   					}
  524   
  525                       preparedSizeSql.setString(1, getName());
  526                       rst = preparedSizeSql.executeQuery();
  527                       if (rst.next()) {
  528                           size = rst.getInt(1);
  529                       }
  530                       // Break out after the finally block
  531                       numberOfTries = 0;
  532                   } catch (SQLException e) {
  533                       manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e));
  534                       if (dbConnection != null)
  535                           close(dbConnection);
  536                   } finally {
  537                       try {
  538                           if (rst != null)
  539                               rst.close();
  540                       } catch (SQLException e) {
  541                           ;
  542                       }
  543   
  544                       release(_conn);
  545                   }
  546                   numberOfTries--;
  547               }
  548           }
  549           return (size);
  550       }
  551   
  552       /**
  553        * Load the Session associated with the id <code>id</code>.
  554        * If no such session is found <code>null</code> is returned.
  555        *
  556        * @param id a value of type <code>String</code>
  557        * @return the stored <code>Session</code>
  558        * @exception ClassNotFoundException if an error occurs
  559        * @exception IOException if an input/output error occurred
  560        */
  561       public Session load(String id)
  562               throws ClassNotFoundException, IOException {
  563           ResultSet rst = null;
  564           StandardSession _session = null;
  565           Loader loader = null;
  566           ClassLoader classLoader = null;
  567           ObjectInputStream ois = null;
  568           BufferedInputStream bis = null;
  569           Container container = manager.getContainer();
  570    
  571           synchronized (this) {
  572               int numberOfTries = 2;
  573               while (numberOfTries > 0) {
  574                   Connection _conn = getConnection();
  575                   if (_conn == null) {
  576                       return (null);
  577                   }
  578   
  579                   try {
  580                       if (preparedLoadSql == null) {
  581                           String loadSql = "SELECT " + sessionIdCol + ", "
  582                                   + sessionDataCol + " FROM " + sessionTable
  583                                   + " WHERE " + sessionIdCol + " = ? AND "
  584                                   + sessionAppCol + " = ?";
  585                           preparedLoadSql = _conn.prepareStatement(loadSql);
  586                       }
  587   
  588                       preparedLoadSql.setString(1, id);
  589                       preparedLoadSql.setString(2, getName());
  590                       rst = preparedLoadSql.executeQuery();
  591                       if (rst.next()) {
  592                           bis = new BufferedInputStream(rst.getBinaryStream(2));
  593   
  594                           if (container != null) {
  595                               loader = container.getLoader();
  596                           }
  597                           if (loader != null) {
  598                               classLoader = loader.getClassLoader();
  599                           }
  600                           if (classLoader != null) {
  601                               ois = new CustomObjectInputStream(bis,
  602                                       classLoader);
  603                           } else {
  604                               ois = new ObjectInputStream(bis);
  605                           }
  606   
  607                           if (manager.getContainer().getLogger().isDebugEnabled()) {
  608                               manager.getContainer().getLogger().debug(sm.getString(getStoreName() + ".loading",
  609                                       id, sessionTable));
  610                           }
  611   
  612                           _session = (StandardSession) manager.createEmptySession();
  613                           _session.readObjectData(ois);
  614                           _session.setManager(manager);
  615                         } else if (manager.getContainer().getLogger().isDebugEnabled()) {
  616                           manager.getContainer().getLogger().debug(getStoreName() + ": No persisted data object found");
  617                       }
  618                       // Break out after the finally block
  619                       numberOfTries = 0;
  620                   } catch (SQLException e) {
  621                       manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e));
  622                       if (dbConnection != null)
  623                           close(dbConnection);
  624                   } finally {
  625                       try {
  626                           if (rst != null) {
  627                               rst.close();
  628                           }
  629                       } catch (SQLException e) {
  630                           ;
  631                       }
  632                       if (ois != null) {
  633                           try {
  634                               ois.close();
  635                           } catch (IOException e) {
  636                               ;
  637                           }
  638                       }
  639                       release(_conn);
  640                   }
  641                   numberOfTries--;
  642               }
  643           }
  644   
  645           return (_session);
  646       }
  647   
  648       /**
  649        * Remove the Session with the specified session identifier from
  650        * this Store, if present.  If no such Session is present, this method
  651        * takes no action.
  652        *
  653        * @param id Session identifier of the Session to be removed
  654        *
  655        * @exception IOException if an input/output error occurs
  656        */
  657       public void remove(String id) throws IOException {
  658   
  659           synchronized (this) {
  660               int numberOfTries = 2;
  661               while (numberOfTries > 0) {
  662                   Connection _conn = getConnection();
  663   
  664                   if (_conn == null) {
  665                       return;
  666                   }
  667   
  668                   try {
  669                       if (preparedRemoveSql == null) {
  670                           String removeSql = "DELETE FROM " + sessionTable
  671                                   + " WHERE " + sessionIdCol + " = ?  AND "
  672                                   + sessionAppCol + " = ?";
  673                           preparedRemoveSql = _conn.prepareStatement(removeSql);
  674                       }
  675   
  676                       preparedRemoveSql.setString(1, id);
  677                       preparedRemoveSql.setString(2, getName());
  678                       preparedRemoveSql.execute();
  679                       // Break out after the finally block
  680                       numberOfTries = 0;
  681                   } catch (SQLException e) {
  682                       manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e));
  683                       if (dbConnection != null)
  684                           close(dbConnection);
  685                   } finally {
  686                       release(_conn);
  687                   }
  688                   numberOfTries--;
  689               }
  690           }
  691   
  692           if (manager.getContainer().getLogger().isDebugEnabled()) {
  693               manager.getContainer().getLogger().debug(sm.getString(getStoreName() + ".removing", id, sessionTable));
  694           }
  695       }
  696   
  697       /**
  698        * Remove all of the Sessions in this Store.
  699        *
  700        * @exception IOException if an input/output error occurs
  701        */
  702       public void clear() throws IOException {
  703   
  704           synchronized (this) {
  705               int numberOfTries = 2;
  706               while (numberOfTries > 0) {
  707                   Connection _conn = getConnection();
  708                   if (_conn == null) {
  709                       return;
  710                   }
  711   
  712                   try {
  713                       if (preparedClearSql == null) {
  714                           String clearSql = "DELETE FROM " + sessionTable
  715                                + " WHERE " + sessionAppCol + " = ?";
  716                           preparedClearSql = _conn.prepareStatement(clearSql);
  717                       }
  718   
  719                       preparedClearSql.setString(1, getName());
  720                       preparedClearSql.execute();
  721                       // Break out after the finally block
  722                       numberOfTries = 0;
  723                   } catch (SQLException e) {
  724                       manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e));
  725                       if (dbConnection != null)
  726                           close(dbConnection);
  727                   } finally {
  728                       release(_conn);
  729                   }
  730                   numberOfTries--;
  731               }
  732           }
  733       }
  734   
  735       /**
  736        * Save a session to the Store.
  737        *
  738        * @param session the session to be stored
  739        * @exception IOException if an input/output error occurs
  740        */
  741       public void save(Session session) throws IOException {
  742           ObjectOutputStream oos = null;
  743           ByteArrayOutputStream bos = null;
  744           ByteArrayInputStream bis = null;
  745           InputStream in = null;
  746   
  747           synchronized (this) {
  748               int numberOfTries = 2;
  749               while (numberOfTries > 0) {
  750                   Connection _conn = getConnection();
  751                   if (_conn == null) {
  752                       return;
  753                   }
  754   
  755                   // If sessions already exist in DB, remove and insert again.
  756                   // TODO:
  757                   // * Check if ID exists in database and if so use UPDATE.
  758                   remove(session.getIdInternal());
  759   
  760                   try {
  761                       bos = new ByteArrayOutputStream();
  762                       oos = new ObjectOutputStream(new BufferedOutputStream(bos));
  763   
  764                       ((StandardSession) session).writeObjectData(oos);
  765                       oos.close();
  766                       oos = null;
  767                       byte[] obs = bos.toByteArray();
  768                       int size = obs.length;
  769                       bis = new ByteArrayInputStream(obs, 0, size);
  770                       in = new BufferedInputStream(bis, size);
  771   
  772                       if (preparedSaveSql == null) {
  773                           String saveSql = "INSERT INTO " + sessionTable + " ("
  774                              + sessionIdCol + ", " + sessionAppCol + ", "
  775                              + sessionDataCol + ", " + sessionValidCol
  776                              + ", " + sessionMaxInactiveCol + ", "
  777                              + sessionLastAccessedCol
  778                              + ") VALUES (?, ?, ?, ?, ?, ?)";
  779                          preparedSaveSql = _conn.prepareStatement(saveSql);
  780   					}
  781   
  782                       preparedSaveSql.setString(1, session.getIdInternal());
  783                       preparedSaveSql.setString(2, getName());
  784                       preparedSaveSql.setBinaryStream(3, in, size);
  785                       preparedSaveSql.setString(4, session.isValid() ? "1" : "0");
  786                       preparedSaveSql.setInt(5, session.getMaxInactiveInterval());
  787                       preparedSaveSql.setLong(6, session.getLastAccessedTime());
  788                       preparedSaveSql.execute();
  789                       // Break out after the finally block
  790                       numberOfTries = 0;
  791                   } catch (SQLException e) {
  792                       manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".SQLException", e));
  793                       if (dbConnection != null)
  794                           close(dbConnection);
  795                   } catch (IOException e) {
  796                       ;
  797                   } finally {
  798                       if (oos != null) {
  799                           oos.close();
  800                       }
  801                       if (bis != null) {
  802                           bis.close();
  803                       }
  804                       if (in != null) {
  805                           in.close();
  806                       }
  807   
  808                       release(_conn);
  809                   }
  810                   numberOfTries--;
  811               }
  812           }
  813   
  814           if (manager.getContainer().getLogger().isDebugEnabled()) {
  815               manager.getContainer().getLogger().debug(sm.getString(getStoreName() + ".saving",
  816                       session.getIdInternal(), sessionTable));
  817           }
  818       }
  819   
  820       // --------------------------------------------------------- Protected Methods
  821   
  822       /**
  823        * Check the connection associated with this store, if it's
  824        * <code>null</code> or closed try to reopen it.
  825        * Returns <code>null</code> if the connection could not be established.
  826        *
  827        * @return <code>Connection</code> if the connection suceeded
  828        */
  829       protected Connection getConnection() {
  830           try {
  831               if (dbConnection == null || dbConnection.isClosed()) {
  832                   manager.getContainer().getLogger().info(sm.getString(getStoreName() + ".checkConnectionDBClosed"));
  833                   open();
  834                   if (dbConnection == null || dbConnection.isClosed()) {
  835                       manager.getContainer().getLogger().info(sm.getString(getStoreName() + ".checkConnectionDBReOpenFail"));
  836                   }
  837               }
  838           } catch (SQLException ex) {
  839               manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".checkConnectionSQLException",
  840                       ex.toString()));
  841           }
  842   
  843           return dbConnection;
  844       }
  845   
  846       /**
  847        * Open (if necessary) and return a database connection for use by
  848        * this Realm.
  849        *
  850        * @exception SQLException if a database error occurs
  851        */
  852       protected Connection open() throws SQLException {
  853   
  854           // Do nothing if there is a database connection already open
  855           if (dbConnection != null)
  856               return (dbConnection);
  857   
  858           // Instantiate our database driver if necessary
  859           if (driver == null) {
  860               try {
  861                   Class clazz = Class.forName(driverName);
  862                   driver = (Driver) clazz.newInstance();
  863               } catch (ClassNotFoundException ex) {
  864                   manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".checkConnectionClassNotFoundException",
  865                           ex.toString()));
  866               } catch (InstantiationException ex) {
  867                   manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".checkConnectionClassNotFoundException",
  868                           ex.toString()));
  869               } catch (IllegalAccessException ex) {
  870                   manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".checkConnectionClassNotFoundException",
  871                           ex.toString()));
  872               }
  873           }
  874   
  875           // Open a new connection
  876           Properties props = new Properties();
  877           if (connectionName != null)
  878               props.put("user", connectionName);
  879           if (connectionPassword != null)
  880               props.put("password", connectionPassword);
  881           dbConnection = driver.connect(connectionURL, props);
  882           dbConnection.setAutoCommit(true);
  883           return (dbConnection);
  884   
  885       }
  886   
  887       /**
  888        * Close the specified database connection.
  889        *
  890        * @param dbConnection The connection to be closed
  891        */
  892       protected void close(Connection dbConnection) {
  893   
  894           // Do nothing if the database connection is already closed
  895           if (dbConnection == null)
  896               return;
  897   
  898           // Close our prepared statements (if any)
  899           try {
  900               preparedSizeSql.close();
  901           } catch (Throwable f) {
  902               ;
  903           }
  904           this.preparedSizeSql = null;
  905   
  906           try {
  907               preparedKeysSql.close();
  908           } catch (Throwable f) {
  909               ;
  910           }
  911           this.preparedKeysSql = null;
  912   
  913           try {
  914               preparedSaveSql.close();
  915           } catch (Throwable f) {
  916               ;
  917           }
  918           this.preparedSaveSql = null;
  919   
  920           try {
  921               preparedClearSql.close();
  922           } catch (Throwable f) {
  923               ;
  924           }
  925            
  926   		try {
  927               preparedRemoveSql.close();
  928           } catch (Throwable f) {
  929               ;
  930           }
  931           this.preparedRemoveSql = null;
  932   
  933           try {
  934               preparedLoadSql.close();
  935           } catch (Throwable f) {
  936               ;
  937           }
  938           this.preparedLoadSql = null;
  939   
  940           // Close this database connection, and log any errors
  941           try {
  942               dbConnection.close();
  943           } catch (SQLException e) {
  944               manager.getContainer().getLogger().error(sm.getString(getStoreName() + ".close", e.toString())); // Just log it here
  945           } finally {
  946               this.dbConnection = null;
  947           }
  948   
  949       }
  950   
  951       /**
  952        * Release the connection, not needed here since the
  953        * connection is not associated with a connection pool.
  954        *
  955        * @param conn The connection to be released
  956        */
  957       protected void release(Connection conn) {
  958           ;
  959       }
  960   
  961       /**
  962        * Called once when this Store is first started.
  963        */
  964       public void start() throws LifecycleException {
  965           super.start();
  966   
  967           // Open connection to the database
  968           this.dbConnection = getConnection();
  969       }
  970   
  971       /**
  972        * Gracefully terminate everything associated with our db.
  973        * Called once when this Store is stopping.
  974        *
  975        */
  976       public void stop() throws LifecycleException {
  977           super.stop();
  978   
  979           // Close and release everything associated with our db.
  980           if (dbConnection != null) {
  981               try {
  982                   dbConnection.commit();
  983               } catch (SQLException e) {
  984                   ;
  985               }
  986               close(dbConnection);
  987           }
  988       }
  989   }

Home » apache-tomcat-6.0.26-src » org.apache » catalina » session » [javadoc | source]