Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / jdbc / EmbedPooledConnection.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/jdbc/EmbedPooledConnection.java
new file mode 100644 (file)
index 0000000..5d6c0ad
--- /dev/null
@@ -0,0 +1,570 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.jdbc.EmbedPooledConnection\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.jdbc;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.reference.Property;\r
+import org.apache.derby.iapi.error.ExceptionSeverity;\r
+import org.apache.derby.iapi.reference.JDBC30Translation;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+\r
+/* import impl class */\r
+import org.apache.derby.impl.jdbc.Util;\r
+import org.apache.derby.impl.jdbc.EmbedConnection;\r
+import org.apache.derby.iapi.jdbc.BrokeredConnection;\r
+import org.apache.derby.iapi.jdbc.BrokeredConnectionControl;\r
+import org.apache.derby.iapi.jdbc.EngineConnection;\r
+import org.apache.derby.impl.jdbc.EmbedPreparedStatement;\r
+import org.apache.derby.impl.jdbc.EmbedCallableStatement;\r
+\r
+\r
+import java.sql.Connection;\r
+import java.sql.SQLException;\r
+import java.sql.Statement;\r
+import java.sql.PreparedStatement;\r
+import java.sql.CallableStatement;\r
+\r
+import java.util.Vector;\r
+import java.util.Enumeration;\r
+\r
+/* -- New jdbc 20 extension types --- */\r
+import javax.sql.DataSource;\r
+import javax.sql.PooledConnection;\r
+import javax.sql.ConnectionEventListener;\r
+import javax.sql.ConnectionEvent;\r
+import javax.sql.StatementEventListener;\r
+\r
+/** \r
+       A PooledConnection object is a connection object that provides hooks for\r
+       connection pool management.\r
+\r
+       <P>This is Derby's implementation of a PooledConnection for use in\r
+       the following environments:\r
+       <UL>\r
+       <LI> JDBC 3.0 - Java 2 - JDK 1.4, J2SE 5.0\r
+       <LI> JDBC 2.0 - Java 2 - JDK 1.2,1.3\r
+       </UL>\r
+\r
+ */\r
+class EmbedPooledConnection implements javax.sql.PooledConnection, BrokeredConnectionControl\r
+{\r
+\r
+    /** Static counter for connection ids */\r
+    private static int idCounter = 0;\r
+    \r
+    /** The id for this connection.  */\r
+    private int connectionId;\r
+    \r
+    /** the connection string */\r
+    private String connString;\r
+    \r
+       private Vector eventListener; // who wants to know I am closed or error\r
+\r
+       EmbedConnection realConnection;\r
+       int defaultIsolationLevel;\r
+       private boolean defaultReadOnly;\r
+       BrokeredConnection currentConnectionHandle;\r
+\r
+       // set up once by the data source\r
+       final ReferenceableDataSource dataSource;\r
+       private final String username;\r
+       private final String password;\r
+       /**\r
+               True if the password was passed in on the connection request, false if it came from the data source property.\r
+       */\r
+       private final boolean requestPassword;\r
+\r
+       protected boolean isActive;\r
+    \r
+    private synchronized int nextId()\r
+    {\r
+        return idCounter++;\r
+    }\r
+\r
+       EmbedPooledConnection(ReferenceableDataSource ds, String u, String p, boolean requestPassword) throws SQLException\r
+       {\r
+        connectionId = nextId();\r
+\r
+               dataSource = ds;\r
+               username = u;\r
+               password = p;\r
+               this.requestPassword = requestPassword;\r
+               isActive = true;\r
+\r
+               // open the connection up front in order to do authentication\r
+               openRealConnection();\r
+\r
+       }\r
+\r
+       String getUsername()\r
+       {\r
+               if (username == null || username.equals(""))\r
+                       return Property.DEFAULT_USER_NAME;\r
+               else\r
+                       return username;\r
+       }\r
+\r
+       String getPassword()\r
+       {\r
+               if (password == null)\r
+                       return "";\r
+               else\r
+                       return password;\r
+       }\r
+\r
+\r
+       /** \r
+               Create an object handle for a database connection.\r
+\r
+               @return a Connection object\r
+\r
+               @exception SQLException - if a database-access error occurs.\r
+       */\r
+       public synchronized Connection getConnection() throws SQLException\r
+       {\r
+               checkActive();\r
+\r
+               // need to do this in case the connection is forcibly removed without\r
+               // first being closed.\r
+               closeCurrentConnectionHandle();\r
+\r
+\r
+               // RealConnection is not null if the app server yanks a local\r
+               // connection from one client and give it to another.  In this case,\r
+               // the real connection is ready to be used.  Otherwise, set it up\r
+               if (realConnection == null)\r
+               {\r
+                       // first time we establish a connection\r
+                       openRealConnection();\r
+               }\r
+               else\r
+               {\r
+                       resetRealConnection();\r
+               }\r
+\r
+               // now make a brokered connection wrapper and give this to the user\r
+               // we reuse the EmbedConnection(ie realConnection).\r
+               Connection c = getNewCurrentConnectionHandle();         \r
+               return c;\r
+       }\r
+\r
+       final void openRealConnection() throws SQLException {\r
+               // first time we establish a connection\r
+               Connection rc = dataSource.getConnection(username, password, requestPassword);\r
+\r
+               this.realConnection = (EmbedConnection) rc;\r
+               defaultIsolationLevel = rc.getTransactionIsolation();\r
+               defaultReadOnly = rc.isReadOnly();\r
+               if (currentConnectionHandle != null)\r
+                       realConnection.setApplicationConnection(currentConnectionHandle);\r
+       }\r
+\r
+       final Connection getNewCurrentConnectionHandle() {\r
+               Connection applicationConnection = currentConnectionHandle =\r
+                       ((org.apache.derby.jdbc.Driver20) (realConnection.getLocalDriver())).newBrokeredConnection(this);\r
+               realConnection.setApplicationConnection(applicationConnection);\r
+               return applicationConnection;\r
+\r
+       }\r
+\r
+       /**\r
+               In this case the Listeners are *not* notified. JDBC 3.0 spec section 11.4\r
+       */\r
+       private void closeCurrentConnectionHandle() throws SQLException {\r
+               if (currentConnectionHandle != null)\r
+               {\r
+                       Vector tmpEventListener = eventListener;\r
+                       eventListener = null;\r
+\r
+                       try {\r
+                               currentConnectionHandle.close();\r
+                       } finally {\r
+                               eventListener = tmpEventListener;\r
+                       }\r
+\r
+                       currentConnectionHandle = null;\r
+               }\r
+       }\r
+\r
+       void resetRealConnection() throws SQLException {\r
+\r
+               // ensure any outstanding changes from the previous\r
+               // user are rolledback.\r
+               realConnection.rollback();\r
+\r
+               // clear any warnings that are left over\r
+               realConnection.clearWarnings();\r
+\r
+               // need to reset transaction isolation, autocommit, readonly, holdability states\r
+               if (realConnection.getTransactionIsolation() != defaultIsolationLevel) {\r
+\r
+                       realConnection.setTransactionIsolation(defaultIsolationLevel);\r
+               }\r
+\r
+               if (!realConnection.getAutoCommit())\r
+                       realConnection.setAutoCommit(true);\r
+\r
+               if (realConnection.isReadOnly() != defaultReadOnly)\r
+                       realConnection.setReadOnly(defaultReadOnly);\r
+\r
+               if (realConnection.getHoldability() != JDBC30Translation.HOLD_CURSORS_OVER_COMMIT)\r
+                       realConnection.setHoldability(JDBC30Translation.HOLD_CURSORS_OVER_COMMIT);\r
+\r
+               // reset any remaining state of the connection\r
+               realConnection.resetFromPool();\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(realConnection.transactionIsIdle(),\r
+                       "real connection should have been idle at this point");                         \r
+               }\r
+       }\r
+\r
+       /**\r
+               Close the Pooled connection.\r
+\r
+               @exception SQLException - if a database-access error occurs.\r
+        */\r
+       public synchronized void close() throws SQLException\r
+       {\r
+               if (!isActive)\r
+                       return;\r
+\r
+               closeCurrentConnectionHandle();\r
+               try {\r
+                       if (realConnection != null) {\r
+                               if (!realConnection.isClosed())\r
+                                       realConnection.close();\r
+                       }\r
+\r
+               } finally {\r
+\r
+                       realConnection = null;  // make sure I am not accessed again.\r
+                       isActive = false;\r
+                       eventListener = null;\r
+               }\r
+       }\r
+\r
+       /**\r
+               Add an event listener.\r
+        */\r
+       public final synchronized void addConnectionEventListener(ConnectionEventListener listener) \r
+       {\r
+               if (!isActive)\r
+                       return;\r
+               if (listener == null)\r
+                       return;\r
+               if (eventListener == null)\r
+                       eventListener = new Vector();\r
+               eventListener.addElement(listener);\r
+       }\r
+\r
+       /**\r
+               Remove an event listener.\r
+        */\r
+       public final synchronized void removeConnectionEventListener(ConnectionEventListener listener)\r
+       {\r
+               if (listener == null)\r
+                       return;\r
+               if (eventListener != null)\r
+                       eventListener.removeElement(listener);\r
+       }\r
+\r
+       /*\r
+        * class specific method\r
+        */\r
+\r
+       // called by ConnectionHandle when it needs to forward things to the\r
+       // underlying connection\r
+       public synchronized EngineConnection getRealConnection()\r
+       throws SQLException\r
+       {\r
+               checkActive();\r
+\r
+               return realConnection;\r
+       }\r
+\r
+    /**\r
+     * @return The underlying language connection.\r
+     */\r
+       public synchronized LanguageConnectionContext getLanguageConnection()\r
+       throws SQLException\r
+       {\r
+               checkActive();\r
+\r
+               return realConnection.getLanguageConnection();\r
+       }\r
+\r
+\r
+       // my conneciton handle has caught an error (actually, the real connection\r
+       // has already handled the error, we just need to nofity the listener an\r
+       // error is about to be thrown to the app).\r
+       public synchronized void notifyError(SQLException exception)\r
+       {\r
+               // only report fatal error to the connection pool manager \r
+               if (exception.getErrorCode() < ExceptionSeverity.SESSION_SEVERITY)\r
+                       return;\r
+\r
+               // tell my listeners an exception is about to be thrown\r
+               if (eventListener != null && eventListener.size() > 0)\r
+               {\r
+                       ConnectionEvent errorEvent = new ConnectionEvent(this, exception);\r
+\r
+                       for (Enumeration e = eventListener.elements();\r
+                                e.hasMoreElements(); )\r
+                       {\r
+                               ConnectionEventListener l =\r
+                                       (ConnectionEventListener)e.nextElement();\r
+                               l.connectionErrorOccurred(errorEvent);\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+       \r
+\r
+       final void checkActive() throws SQLException {\r
+               if (!isActive)\r
+                       throw Util.noCurrentConnection();\r
+       }\r
+\r
+\r
+       /*\r
+       ** BrokeredConnectionControl api\r
+       */\r
+\r
+       /**\r
+               Returns true if isolation level has been set using either JDBC api or SQL\r
+        */\r
+       public boolean isIsolationLevelSetUsingSQLorJDBC() throws SQLException {\r
+               if (realConnection != null)\r
+                       return realConnection.getLanguageConnection().isIsolationLevelSetUsingSQLorJDBC();\r
+               else\r
+                       return false;\r
+       }\r
+\r
+       /**\r
+               Reset the isolation level flag used to keep state in \r
+               BrokeredConnection. It will get set to true when isolation level \r
+               is set using JDBC/SQL. It will get reset to false at the start\r
+               and the end of a global transaction.\r
+       */\r
+       public void resetIsolationLevelFlag() throws SQLException {\r
+               realConnection.getLanguageConnection().resetIsolationLevelFlagUsedForSQLandJDBC();\r
+       }\r
+       \r
+       \r
+       /**\r
+               Notify the control class that a SQLException was thrown\r
+               during a call on one of the brokered connection's methods.\r
+       */\r
+       public void notifyException(SQLException sqle) {\r
+               this.notifyError(sqle);\r
+       }\r
+\r
+\r
+       /**\r
+               Allow control over setting auto commit mode.\r
+       */\r
+       public void checkAutoCommit(boolean autoCommit) throws SQLException {\r
+       }\r
+\r
+       /**\r
+               Are held cursors allowed.\r
+       */\r
+       public int checkHoldCursors(int holdability, boolean downgrade)\r
+        throws SQLException\r
+    {\r
+        return holdability;\r
+       }\r
+\r
+       /**\r
+               Allow control over creating a Savepoint (JDBC 3.0)\r
+       */\r
+       public void checkSavepoint() throws SQLException {\r
+       }\r
+\r
+       /**\r
+               Allow control over calling rollback.\r
+       */\r
+       public void checkRollback() throws SQLException {\r
+       }\r
+\r
+       /**\r
+               Allow control over calling commit.\r
+       */\r
+       public void checkCommit() throws SQLException {\r
+       }\r
+\r
+       /**\r
+               Close called on BrokeredConnection. If this call\r
+               returns true then getRealConnection().close() will be called.\r
+               \r
+       \r
+       Notify listners that connection is closed.\r
+               Don't close the underlying real connection as\r
+               it is pooled.\r
+       */\r
+       public synchronized boolean closingConnection() throws SQLException {       \r
+               //DERBY-2142-Null out the connection handle BEFORE notifying listeners.\r
+               //At time of the callback the PooledConnection must be \r
+               //disassociated from its previous logical connection.\r
+               //If not there is a risk that the Pooled\r
+               //Connection could be returned to the pool, ready for pickup by a \r
+               //new thread. This new thread then might obtain a java.sql.Connection \r
+               //whose reference might get assigned to the currentConnectionHandle \r
+               //field, meanwhile the previous thread completes the close making \r
+               //the newly assigned currentConnectionHandle null, resulting in an NPE.\r
+               currentConnectionHandle = null;\r
+               // tell my listeners I am closed \r
+               if (eventListener != null && eventListener.size() > 0)\r
+               {\r
+                       ConnectionEvent closeEvent = new ConnectionEvent(this);\r
+\r
+                       for (Enumeration e = eventListener.elements();\r
+                                e.hasMoreElements(); )\r
+                       {\r
+                               ConnectionEventListener l =\r
+                                       (ConnectionEventListener)e.nextElement();\r
+                               l.connectionClosed(closeEvent);\r
+                       }\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+               No need to wrap statements for PooledConnections.\r
+       */\r
+       public Statement wrapStatement(Statement s) throws SQLException {\r
+               return s;\r
+       }\r
+       /**\r
+         * Call the setBrokeredConnectionControl method inside the \r
+         * EmbedPreparedStatement class to set the BrokeredConnectionControl \r
+         * variable to this instance of EmbedPooledConnection\r
+         * This will then be used to call the onStatementErrorOccurred\r
+         * and onStatementClose events when the corresponding events\r
+         * occur on the PreparedStatement\r
+         *\r
+         * @param  ps            PreparedStatment to be wrapped\r
+         * @param  sql           String\r
+         * @param  generatedKeys Object\r
+         * @return returns the wrapped PreparedStatement\r
+         * @throws java.sql.SQLException\r
+        */\r
+       public PreparedStatement wrapStatement(PreparedStatement ps, String sql, Object generatedKeys) throws SQLException {\r
+               /*\r
+                    \r
+                */\r
+                EmbedPreparedStatement ps_ = (EmbedPreparedStatement)ps;\r
+                ps_.setBrokeredConnectionControl(this);\r
+               return (PreparedStatement)ps_;\r
+       }\r
+        \r
+        /**\r
+         * Call the setBrokeredConnectionControl method inside the \r
+         * EmbedCallableStatement class to set the BrokeredConnectionControl \r
+         * variable to this instance of EmbedPooledConnection\r
+         * This will then be used to call the onStatementErrorOccurred\r
+         * and onStatementClose events when the corresponding events\r
+         * occur on the CallableStatement\r
+         *\r
+         * @param  cs            CallableStatment to be wrapped\r
+         * @param  sql           String\r
+         * @return returns the wrapped CallableStatement\r
+         * @throws java.sql.SQLException\r
+        */\r
+       public CallableStatement wrapStatement(CallableStatement cs, String sql) throws SQLException {\r
+                EmbedCallableStatement cs_ = (EmbedCallableStatement)cs;\r
+                cs_.setBrokeredConnectionControl(this);\r
+               return (CallableStatement)cs_;\r
+       }\r
+    \r
+    /** \r
+     * Get the string representation of this pooled connection.\r
+     *\r
+     * A pooled connection is assigned a separate id from a physical \r
+     * connection. When a container calls PooledConnection.toString(), \r
+     * it gets the string representation of this id. This is useful for \r
+     * developers implementing connection pools when they are trying to\r
+     * debug pooled connections. \r
+     *\r
+     * @return a string representation of the uniquie id for this pooled\r
+     *    connection.\r
+     *\r
+     */\r
+    public String toString()\r
+    {\r
+        if ( connString == null )\r
+        {\r
+            String physicalConnString = isActive ?\r
+                realConnection.toString() : "<none>";\r
+            \r
+            connString = \r
+              this.getClass().getName() + "@" + this.hashCode() + " " +\r
+                "(ID = " + connectionId + "), " +\r
+                "Physical Connection = " + physicalConnString;\r
+        }    \r
+        \r
+        return connString;\r
+    }\r
+    \r
+    /*-----------------------------------------------------------------*/\r
+    /*\r
+     * These methods are from the BrokeredConnectionControl interface. \r
+     * These methods are needed to provide StatementEvent support for \r
+     * derby. \r
+     * They are actually implemented in EmbedPooledConnection40 but have\r
+     * a dummy implementation here so that the compilation wont fail when they\r
+     * are compiled with jdk1.4\r
+     */\r
+    \r
+    /**\r
+     * Dummy implementation for the actual methods found in \r
+     * org.apache.derby.jdbc.EmbedPooledConnection40\r
+     * @param statement PreparedStatement\r
+     */\r
+    public void onStatementClose(PreparedStatement statement) {\r
+        \r
+    }\r
+    \r
+    /**\r
+     * Dummy implementation for the actual methods found in \r
+     * org.apache.derby.jdbc.EmbedPooledConnection40\r
+     * @param statement PreparedStatement\r
+     * @param sqle      SQLException \r
+     */\r
+    public void onStatementErrorOccurred(PreparedStatement statement,\r
+            SQLException sqle) {\r
+        \r
+    }\r
+\r
+       public void addStatementEventListener(StatementEventListener listener) {\r
+               // TODO Auto-generated method stub\r
+               \r
+       }\r
+\r
+       public void removeStatementEventListener(StatementEventListener listener) {\r
+               // TODO Auto-generated method stub\r
+               \r
+       }\r
+}\r