You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by da...@apache.org on 2014/06/17 01:00:35 UTC

svn commit: r1603019 [2/3] - in /db/derby/code/trunk: ./ java/client/org/apache/derby/client/ java/client/org/apache/derby/client/am/ java/client/org/apache/derby/client/net/ java/client/org/apache/derby/jdbc/ java/engine/org/apache/derby/jdbc/ java/te...

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/BasicClientDataSource40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/BasicClientDataSource40.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/BasicClientDataSource40.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/BasicClientDataSource40.java Mon Jun 16 23:00:34 2014
@@ -21,23 +21,143 @@
 
 package org.apache.derby.jdbc;
 
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.logging.Logger;
 import javax.sql.DataSource;
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
+import org.apache.derby.client.am.ClientMessageId;
+import org.apache.derby.client.am.EncryptionManager;
+import org.apache.derby.client.am.LogWriter;
+import org.apache.derby.client.am.SQLExceptionFactory;
+import org.apache.derby.client.am.SqlException;
+import org.apache.derby.client.net.NetConfiguration;
+import org.apache.derby.client.net.NetLogWriter;
+import org.apache.derby.shared.common.error.ExceptionUtil;
+import org.apache.derby.shared.common.reference.Attribute;
+import org.apache.derby.shared.common.reference.SQLState;
 
 /**
- * This datasource is suitable for client/server use of Derby,
+ * This data source is suitable for client/server use of Derby,
  * running on Java 8 Compact Profile 2 or higher.
  * <p/>
  * BasicClientDataSource40 is similar to ClientDataSource except it
  * can not be used with JNDI, i.e. it does not implement
  * {@code javax.naming.Referenceable}.
  */
-public class BasicClientDataSource40
-    extends ClientBaseDataSourceRoot implements DataSource {
+@SuppressWarnings("ResultOfObjectAllocationIgnored")
+public class BasicClientDataSource40 
+    implements DataSource, ClientDataSourceInterface, Serializable {
 
     private final static long serialVersionUID = 1894299584216955554L;
     public final static String className__ =
             "org.apache.derby.jdbc.BasicClientDataSource40";
 
+    // ---------------------------- traceLevel -------------------------------
+    //
+
+    /**
+     * The client server protocol can be traced. The constants below define the
+     * tracing level, cf. the documentation section "Network Client Tracing" in
+     * the "Derby Server and Administration Guide". Cf. the connection
+     * attribute (or data source bean property) {@code traceLevel}.
+     *
+     * <pre>
+     * TRACE_NONE	
+     * TRACE_CONNECTION_CALLS	
+     * TRACE_STATEMENT_CALLS	
+     * TRACE_RESULT_SET_CALLS	
+     * TRACE _DRIVER_CONFIGURATION	
+     * TRACE_CONNECTS	
+     * TRACE_PROTOCOL_FLOWS	
+     * TRACE _RESULT_SET_META_DATA	
+     * TRACE _PARAMETER_META_DATA	
+     * TRACE_DIAGNOSTICS	
+     * TRACE_XA_CALLS	
+     * TRACE_ALL	
+     * </pre>
+     */
+    public final static int TRACE_NONE = 0x0;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_CONNECTION_CALLS = 0x1;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_STATEMENT_CALLS = 0x2;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_RESULT_SET_CALLS = 0x4;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_DRIVER_CONFIGURATION = 0x10;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_CONNECTS = 0x20;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_PROTOCOL_FLOWS = 0x40;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_RESULT_SET_META_DATA = 0x80;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_PARAMETER_META_DATA = 0x100;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_DIAGNOSTICS = 0x200;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_XA_CALLS = 0x800;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int TRACE_ALL = 0xFFFFFFFF;
+    /**
+     * See documentation at {@link #TRACE_NONE}.
+     */
+    public final static int propertyDefault_traceLevel = TRACE_ALL;
+
+    static
+    {
+        try {
+            // The EncryptionManager class will instantiate objects of the
+            // required security algorithms that are needed for EUSRIDPWD An
+            // exception will be thrown if support is not available in the JCE
+            // implementation in the JVM in which the client is loaded.
+            new EncryptionManager(null);
+        } catch(Exception e) {
+            // if an exception is thrown, ignore exception.
+        }
+
+    }
+
     /**
      * Creates a simple DERBY data source with default property values
      * for a non-pooling, non-distributed environment.  No particular
@@ -51,4 +171,1412 @@ public class BasicClientDataSource40
     public BasicClientDataSource40() {
         super();
     }
+
+    /**
+     * The source security mechanism to use when connecting to a client data
+     * source.
+     * <p/>
+     * Security mechanism options are:
+     * <ul>
+     *   <li> USER_ONLY_SECURITY
+     *   <li> CLEAR_TEXT_PASSWORD_SECURITY
+     *   <li> ENCRYPTED_PASSWORD_SECURITY
+     *   <li> ENCRYPTED_USER_AND_PASSWORD_SECURITY - both password and
+     *        user are encrypted
+     *   <li> STRONG_PASSWORD_SUBSTITUTE_SECURITY
+     * </ul> The default security mechanism is USER_ONLY SECURITY
+     * <p/>
+     * If the application specifies a security mechanism then it will be the
+     * only one attempted. If the specified security mechanism is not
+     * supported by the conversation then an exception will be thrown and
+     * there will be no additional retries.
+     * <p/>
+     * Both user and password need to be set for all security mechanism except
+     * USER_ONLY_SECURITY.
+     */
+    public final static short USER_ONLY_SECURITY =
+        ClientDataSourceInterface.USER_ONLY_SECURITY;
+
+    /**
+     * See documentation at {@link #USER_ONLY_SECURITY}
+     */
+    public final static short CLEAR_TEXT_PASSWORD_SECURITY =
+        ClientDataSourceInterface.CLEAR_TEXT_PASSWORD_SECURITY;
+
+    /**
+     * See documentation at {@link #USER_ONLY_SECURITY}
+     */
+    public final static short ENCRYPTED_PASSWORD_SECURITY =
+        ClientDataSourceInterface.ENCRYPTED_PASSWORD_SECURITY;
+
+    /**
+     * See documentation at {@link #USER_ONLY_SECURITY}
+     */
+    public final static short ENCRYPTED_USER_AND_PASSWORD_SECURITY =
+        ClientDataSourceInterface.ENCRYPTED_USER_AND_PASSWORD_SECURITY;
+
+    /**
+     * See documentation at {@link #USER_ONLY_SECURITY}
+     */
+    public final static short STRONG_PASSWORD_SUBSTITUTE_SECURITY =
+        ClientDataSourceInterface.STRONG_PASSWORD_SUBSTITUTE_SECURITY;
+
+    // The loginTimeout jdbc 2 data source property is not supported as a jdbc
+    // 1 connection property, because loginTimeout is set by the jdbc 1 api
+    // via java.sql.DriverManager.setLoginTimeout().  The databaseName,
+    // serverName, and portNumber data source properties are also not
+    // supported as connection properties because they are extracted from the
+    // jdbc 1 database url passed on the connection request.  However, all
+    // other data source properties should probably also be supported as
+    // connection properties.
+
+        // ---------------------------- loginTimeout ------------------------------
+    //
+    // was serialized in 1.0 release
+    /**
+     * The time in seconds to wait for a connection request on this data
+     * source. The default value of zero indicates that either the system time
+     * out be used or no timeout limit.
+     *
+     * @serial
+     */
+    private int loginTimeout;
+
+    public synchronized void setLoginTimeout(int seconds) {
+        this.loginTimeout = seconds;
+    }
+
+    public int getLoginTimeout() {
+        return this.loginTimeout;
+    }
+
+    // ---------------------------- logWriter --------------------------------
+    //
+    /**
+     * The log writer is declared transient, and is not serialized or stored
+     * under JNDI.
+     *
+     * @see #traceLevel
+     */
+    private transient PrintWriter logWriter;
+
+    public synchronized void setLogWriter(PrintWriter logWriter) {
+        this.logWriter = logWriter;
+    }
+
+    public PrintWriter getLogWriter() {
+        return this.logWriter;
+    }
+
+    // ---------------------------- databaseName ------------------------------
+    //
+    // Stores the relational database name, RDBNAME.
+    // The length of the database name may be limited to 18 bytes
+    // and therefore may throw an SQLException.
+    //
+    //
+    private String databaseName;
+
+    // databaseName is not permitted in a properties object
+
+
+    // ---------------------------- description ------------------------------
+    // A description of this data source.
+    private String description;
+
+    // ---------------------------- dataSourceName ----------------------------
+    //
+    // A data source name;
+    // used to name an underlying XADataSource,
+    // or ConnectionPoolDataSource when pooling of connections is done.
+    //
+    private String dataSourceName;
+
+    // ---------------------------- portNumber --------------------------------
+    //
+    private int portNumber = propertyDefault_portNumber;
+
+    // ---------------------------- serverName --------------------------------
+    //
+    // Derby-410 fix.
+    private String serverName = propertyDefault_serverName;
+
+    // serverName is not permitted in a properties object
+
+    //---------------------- client SSL ----------------
+
+    /** The constant indicating that SSL encryption won't be used. */
+    public final static int SSL_OFF = 0;
+    private final static String SSL_OFF_STR = "off";
+    /** The constant indicating that SSL encryption will be used. */
+    public final static int SSL_BASIC = 1;
+    private final static String SSL_BASIC_STR = "basic";
+    /**
+     * The constant indicating that SSL encryption with peer authentication
+     * will be used.
+     */
+    public final static int SSL_PEER_AUTHENTICATION = 2;
+    private final static String SSL_PEER_AUTHENTICATION_STR =
+            "peerAuthentication";
+
+    /**
+     * Parses the string and returns the corresponding constant for the SSL
+     * mode denoted.
+     * <p>
+     * Valid values are <tt>off</tt>, <tt>basic</tt> and
+     * <tt>peerAuthentication</tt>.
+     *
+     * @param s string denoting the SSL mode
+     * @return A constant indicating the SSL mode denoted by the string. If the
+     *      string is {@code null}, {@link #SSL_OFF} is returned.
+     * @throws SqlException if the string has an invalid value
+     */
+    public static int getSSLModeFromString(String s)
+        throws SqlException
+    {
+
+        if (s != null){
+            if (s.equalsIgnoreCase(SSL_OFF_STR)) {
+                return SSL_OFF;
+            } else if (s.equalsIgnoreCase(SSL_BASIC_STR)) {
+                return SSL_BASIC;
+            } else if (s.equalsIgnoreCase(SSL_PEER_AUTHENTICATION_STR)) {
+                return SSL_PEER_AUTHENTICATION;
+            } else {
+                throw new SqlException(null,
+                        new ClientMessageId(SQLState.INVALID_ATTRIBUTE),
+                        Attribute.SSL_ATTR, s, SSL_OFF_STR + ", " +
+                        SSL_BASIC_STR + ", " + SSL_PEER_AUTHENTICATION_STR);
+            }
+        } else {
+            // Default
+            return SSL_OFF;
+        }
+    }
+
+    /**
+     * Returns the SSL mode specified by the property object.
+     *
+     * @param properties data source properties
+     * @return A constant indicating the SSL mode to use. Defaults to
+     *      {@link #SSL_OFF} if the SSL attribute isn't specified.
+     * @throws SqlException if an invalid value for the SSL mode is specified
+     *      in the property object
+     */
+    public static int getClientSSLMode(Properties properties)
+        throws SqlException
+    {
+        return
+            getSSLModeFromString(properties.getProperty(Attribute.SSL_ATTR));
+    }
+
+    // ---------------------------- user -----------------------------------
+    //
+    // This property can be overwritten by specifing the
+    // username parameter on the DataSource.getConnection() method
+    // call.  If user is specified, then password must also be
+    // specified, either in the data source object or provided on
+    // the DataSource.getConnection() call.
+    //
+    // Each data source implementation subclass will maintain it's own
+    // <code>password</code> property.  This password property may or may not
+    // be declared transient, and therefore may be serialized to a file in
+    // clear-text, care must taken by the user to prevent security breaches.
+    // Derby-406 fix
+    private String user = propertyDefault_user;
+
+    public static String getUser(Properties properties) {
+        String userString = properties.getProperty(Attribute.USERNAME_ATTR);
+        return parseString(userString, propertyDefault_user);
+    }
+
+    // ---------------------------- securityMechanism -------------------------
+    //
+    // The source security mechanism to use when connecting to this data
+    // source.
+    // <p>
+    // Security mechanism options are:
+    // <ul>
+    // <li> USER_ONLY_SECURITY
+    // <li> CLEAR_TEXT_PASSWORD_SECURITY
+    // <li> ENCRYPTED_PASSWORD_SECURITY
+    // <li> ENCRYPTED_USER_AND_PASSWORD_SECURITY - both password and
+    //      user are encrypted
+    // <li> STRONG_PASSWORD_SUBSTITUTE_SECURITY
+    // </ul>
+    // The default security mechanism is USER_ONLY_SECURITY.
+    // <p>
+    // If the application specifies a security
+    // mechanism then it will be the only one attempted.
+    // If the specified security mechanism is not supported by the
+    // conversation then an exception will be thrown and there will be no
+    // additional retries.
+    // <p>
+    // This property is currently only available for the DNC driver.
+    // <p>
+    // Both user and password need to be set for all security mechanism except
+    // USER_ONLY_SECURITY When using USER_ONLY_SECURITY, only the user
+    // property needs to be specified.
+    //
+
+    // constant to indicate that the security mechanism has not been
+    // explicitly set, either on connection request when using DriverManager
+    // or on the Client DataSource object
+    private final static short SECMEC_HAS_NOT_EXPLICITLY_SET = 0;
+
+    // Security Mechanism can be specified explicitly either when obtaining a
+    // connection via a DriverManager or via Datasource.
+    // Via DriverManager, securityMechanism can be set on the connection
+    // request using the 'securityMechanism' attribute.
+    // Via DataSource, securityMechanism can be set by calling
+    // setSecurityMechanism() on the ClientDataSource
+    // If the security mechanism is not explicitly set as mentioned above, in
+    // that case the Client will try to upgrade the security mechanism to a
+    // more secure one, if possible.
+    // @see #getUpgradedSecurityMechanism
+    // Therefore, need to keep track if the securityMechanism has been
+    // explicitly set
+    private short securityMechanism = SECMEC_HAS_NOT_EXPLICITLY_SET;
+
+
+
+    // We use the NET layer constants to avoid a mapping for the NET driver.
+    /**
+     * Return security mechanism if it is set, else upgrade the security
+     * mechanism if possible and return the upgraded security mechanism
+     * @param properties Look in the properties if securityMechanism is set
+     *        or not
+     * if set, return this security mechanism
+     * @return security mechanism
+     */
+    public static short getSecurityMechanism(Properties properties) {
+        short secmec;
+        String securityMechanismString =
+            properties.getProperty(Attribute.CLIENT_SECURITY_MECHANISM);
+
+        if ( securityMechanismString != null )
+        {
+            // security mechanism has been set, do not override, but instead
+            // return the security mechanism that has been set (DERBY-962)
+            secmec = Short.parseShort(securityMechanismString);
+        }
+        else
+        {
+            // if securityMechanismString is null, this means that security
+            // mechanism has not been set explicitly and not available in
+            // properties. Hence, do an upgrade of security mechanism if
+            // possible The logic for upgrade of security mechanism uses
+            // information about if password is available or not, so pass this
+            // information also.
+            String passwordString =
+                properties.getProperty(Attribute.PASSWORD_ATTR);
+            secmec = getUpgradedSecurityMechanism(passwordString);
+        }
+        return secmec;
+    }
+
+    /**
+     * This method has logic to upgrade security mechanism to a better (more
+     * secure) one if it is possible. Currently derby server only has support
+     * for USRIDPWD, USRIDONL, EUSRIDPWD and USRSSBPWD (10.2+) - this method
+     * only considers these possibilities. USRIDPWD, EUSRIDPWD and USRSSBPWD
+     * require a password, USRIDONL is the only security mechanism which does
+     * not require password.
+     * 1. if password is not available, then security mechanism possible is
+     * USRIDONL
+     * 2. if password is available,then USRIDPWD is returned.
+     *
+     * @param password password argument
+     * @return upgraded security mechanism if possible
+     */
+    private static short getUpgradedSecurityMechanism(String password) {
+        // if password is null, in that case the only acceptable security
+        // mechanism is USRIDONL, which is the default security mechanism.
+        if ( password == null ) {
+            return propertyDefault_securityMechanism;
+        }
+
+        // when we have support for more security mechanisms on server
+        // and client, we should update this upgrade logic to pick
+        // secure security mechanisms before trying out the USRIDPWD
+
+        /*
+        // -----------------------
+        // PLEASE NOTE:
+        // When DERBY-1517, DERBY-1755 is fixed, there might be a way to use
+        // EUSRIDPWD when both client and server vm's have support for
+        // it. Hence the below if statement is commented out.
+      if (SUPPORTS_EUSRIDPWD)
+            return (short)NetConfiguration.SECMEC_EUSRIDPWD;
+        else
+            // IMPORTANT NOTE:
+            // --------------
+            // If DERBY-1517 can be fixed, we should default to
+            // SECMEC_USRSSBPWD (strong password substitute).
+            // Until then, connecting with a 10.2+ client to
+            // a derby server < 10.2, and hence does not support
+            // SECMEC_USRSSBPWD as a SECMEC, will cause a DRDA protocol
+            // exception, as described in DERBY-926).
+            //
+            // return (short)NetConfiguration.SECMEC_USRSSBPWD;
+         // ----------------------
+         */
+         return (short)NetConfiguration.SECMEC_USRIDPWD;
+
+    }
+
+    // ---------------------------- getServerMessageTextOnGetMessage ---------
+    //
+    private boolean retrieveMessageText = propertyDefault_retrieveMessageText;
+
+    public static boolean getRetrieveMessageText(Properties properties) {
+        String retrieveMessageTextString =
+            properties.getProperty(Attribute.CLIENT_RETIEVE_MESSAGE_TEXT);
+        return parseBoolean(
+            retrieveMessageTextString, propertyDefault_retrieveMessageText);
+    }
+
+    // ---------------------------- traceFile ---------------------------------
+    //
+    private String traceFile;
+
+    static String getTraceFile(Properties properties) {
+        return properties.getProperty(Attribute.CLIENT_TRACE_FILE);
+    }
+
+    // ---------------------------- traceDirectory ----------------------------
+    // For the suffix of the trace file when traceDirectory is enabled.
+    private transient int traceFileSuffixIndex_ = 0;
+    //
+    private String traceDirectory;
+
+    /**
+     * Check if derby.client.traceDirectory is provided as a JVM property.
+     * If yes, then we use that value. If not, then we look for traceDirectory
+     * in the the properties parameter.
+     *
+     * @param properties jdbc url properties
+     * @return value of traceDirectory property
+     */
+    static String getTraceDirectory(Properties properties) {
+        String traceDirectoryString;
+
+        traceDirectoryString  =
+            readSystemProperty(
+                Attribute.CLIENT_JVM_PROPERTY_PREFIX +
+                Attribute.CLIENT_TRACE_DIRECTORY);
+
+        if (traceDirectoryString == null  && properties != null) {
+            return properties.getProperty(Attribute.CLIENT_TRACE_DIRECTORY);
+        } else {
+            return traceDirectoryString;
+        }
+    }
+
+
+    /**
+     * Read the value of the passed system property.
+     * @param key name of the system property
+     * @return value of the system property, null if there is no
+     *         permission to read the property
+     */
+    private static String readSystemProperty(final String key) {
+        return AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    try {
+                        return System.getProperty(key);
+                    } catch (SecurityException se) {
+                        // We do not want the connection to fail if the user
+                        // does not have permission to read the property, so
+                        // if a security exception occurs, just return null
+                        // and continue with the connection.
+                        return null;
+                    }
+                }
+            }
+            );
+    }
+
+    // ---------------------------- traceFileAppend ---------------------------
+    //
+    private boolean traceFileAppend = propertyDefault_traceFileAppend;
+
+    static boolean getTraceFileAppend(Properties properties) {
+        String traceFileAppendString =
+            properties.getProperty(Attribute.CLIENT_TRACE_APPEND);
+        return parseBoolean(
+            traceFileAppendString, propertyDefault_traceFileAppend);
+    }
+
+    // ---------------------------- password ----------------------------------
+    //
+    // The password property is defined in subclasses, but the method
+    // getPassword (java.util.Properties properties) is in this class to
+    // eliminate dependencies on j2ee for connections that go thru the driver
+    // manager.
+
+    public static String getPassword(Properties properties) {
+        return properties.getProperty("password");
+    }
+
+    private String password;
+
+    synchronized public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+
+    // ----------------------supplemental methods------------------------------
+
+
+    //---------------------- helper methods -----------------------------------
+
+    // The java.io.PrintWriter overrides the traceFile setting.
+    // If neither traceFile nor jdbc logWriter are set, then null is returned.
+    // logWriterInUseSuffix used only for trace directories to indicate whether
+    // log writer is use is from xads, cpds, sds, ds, driver, config, reset.
+    private LogWriter computeDncLogWriterForNewConnection(
+        String logWriterInUseSuffix) throws SqlException {
+
+        return computeDncLogWriterForNewConnection(
+            logWriter,
+            traceDirectory,
+            traceFile,
+            traceFileAppend,
+            traceLevel,
+            logWriterInUseSuffix,
+            traceFileSuffixIndex_++);
+    }
+
+    // Called on for connection requests.  The java.io.PrintWriter overrides
+    // the traceFile setting.  If neither traceFile, nor logWriter, nor
+    // traceDirectory are set, then null is returned.
+    static LogWriter computeDncLogWriterForNewConnection(
+        PrintWriter logWriter,
+        String traceDirectory,
+        String traceFile,
+        boolean traceFileAppend,
+        int traceLevel,
+        String logWriterInUseSuffix,
+        int traceFileSuffixIndex) throws SqlException {
+
+        // compute regular dnc log writer if there is any
+        LogWriter dncLogWriter = computeDncLogWriter(
+            logWriter,
+            traceDirectory,
+            traceFile,
+            traceFileAppend,
+            logWriterInUseSuffix,
+            traceFileSuffixIndex,
+            traceLevel);
+
+        return dncLogWriter;
+    }
+
+    // Compute a DNC log writer before a connection is created.
+    private static LogWriter computeDncLogWriter(
+        PrintWriter logWriter,
+        String traceDirectory,
+        String traceFile,
+        boolean traceFileAppend,
+        String logWriterInUseSuffix,
+        int traceFileSuffixIndex,
+        int traceLevel) throws SqlException {
+
+        // Otherwise, the trace file will still be created even TRACE_NONE.
+        if (traceLevel == TRACE_NONE) {
+            return null;
+        }
+
+        PrintWriter printWriter = computePrintWriter(
+            logWriter,
+            traceDirectory,
+            traceFile,
+            traceFileAppend,
+            logWriterInUseSuffix,
+            traceFileSuffixIndex);
+
+        if (printWriter == null) {
+            return null;
+        }
+
+        LogWriter dncLogWriter = new NetLogWriter(printWriter, traceLevel);
+        if (printWriter != logWriter &&
+                (traceDirectory != null || traceFile != null))
+        // When printWriter is an internal trace file and
+        // traceDirectory is not null, each connection has
+        // its own trace file and the trace file is not cached,
+        // so we can close it when DNC log writer is closed.
+        {
+            dncLogWriter.printWriterNeedsToBeClosed_ = true;
+        }
+        return dncLogWriter;
+    }
+
+    // This method handles all the override semantics.  The logWriter
+    // overrides the traceFile, and traceDirectory settings.  If neither
+    // traceFile, nor logWriter, nor traceDirectory are set, then null is
+    // returned.
+    private static PrintWriter computePrintWriter(
+        PrintWriter logWriter,
+        String traceDirectory,
+        String traceFile,
+        boolean traceFileAppend,
+        String logWriterInUseSuffix,
+        int traceFileSuffixIndex) throws SqlException {
+
+        if (logWriter != null)  // java.io.PrintWriter is specified
+        {
+            return logWriter;
+        } else { // check trace file setting.
+            if (traceDirectory != null) {
+                String fileName;
+                if (traceFile == null) {
+                    fileName = traceDirectory + File.separator +
+                        logWriterInUseSuffix + "_" + traceFileSuffixIndex;
+                } else {
+                    fileName = traceDirectory + File.separator +
+                        traceFile + logWriterInUseSuffix + "_" +
+                        traceFileSuffixIndex;
+                }
+                return LogWriter.getPrintWriter(
+                    fileName, true); // no file append and not enable caching.
+            } else if (traceFile != null) {
+                return LogWriter.getPrintWriter(traceFile, traceFileAppend);
+            }
+        }
+        return null;
+    }
+
+    private static boolean parseBoolean(
+        String boolString, boolean defaultBool) {
+
+        if (boolString != null) {
+            return (boolString.equalsIgnoreCase("true") ||
+                    boolString.equalsIgnoreCase("yes"));
+        }
+        return defaultBool;
+    }
+
+    private static String parseString(String string, String defaultString) {
+        if (string != null) {
+            return string;
+        }
+        return defaultString;
+    }
+
+    private static int parseInt(String intString, int defaultInt) {
+        if (intString != null) {
+            return Integer.parseInt(intString);
+        }
+        return defaultInt;
+    }
+
+    // tokenize "property=value;property=value..." and returns new properties
+    //object This method is used both by ClientDriver to parse the url and
+    //ClientDataSource.setConnectionAttributes
+    static Properties tokenizeAttributes(
+        String attributeString, Properties properties) throws SqlException {
+
+        Properties augmentedProperties;
+
+        if (attributeString == null) {
+            return properties;
+        }
+
+        if (properties != null) {
+            augmentedProperties = (Properties) properties.clone();
+        } else {
+            augmentedProperties = new Properties();
+        }
+        try {
+            StringTokenizer attrTokenizer =
+                new StringTokenizer(attributeString, ";");
+
+            while (attrTokenizer.hasMoreTokens()) {
+                String v = attrTokenizer.nextToken();
+
+                int eqPos = v.indexOf('=');
+                if (eqPos == -1) {
+                    throw new SqlException(null,
+                        new ClientMessageId(SQLState.INVALID_ATTRIBUTE_SYNTAX),
+                        attributeString);
+                }
+
+                augmentedProperties.setProperty(
+                    (v.substring(0, eqPos)).trim(),
+                    (v.substring(eqPos + 1)).trim());
+            }
+        } catch (NoSuchElementException e) {
+            // A null log writer is passed, because jdbc 1 sqlexceptions are
+            // automatically traced
+            throw new SqlException(null,
+                new ClientMessageId(SQLState.INVALID_ATTRIBUTE_SYNTAX),
+                e, attributeString);
+        }
+        checkBoolean(augmentedProperties,
+                     Attribute.CLIENT_RETIEVE_MESSAGE_TEXT);
+        return augmentedProperties;
+
+    }
+
+    private static void checkBoolean(Properties set, String attribute)
+            throws SqlException {
+
+        final String[] booleanChoices = {"true", "false"};
+        checkEnumeration(set, attribute, booleanChoices);
+    }
+
+
+    private static void checkEnumeration(
+        Properties set,
+        String attribute,
+        String[] choices) throws SqlException {
+
+        String value = set.getProperty(attribute);
+        if (value == null) {
+            return;
+        }
+
+        for (int i = 0; i < choices.length; i++) {
+            if (value.toUpperCase(Locale.ENGLISH).equals(
+                        choices[i].toUpperCase(Locale.ENGLISH))) {
+                return;
+            }
+        }
+
+// The attribute value is invalid. Construct a string giving the choices for
+// display in the error message.
+        String choicesStr = "{";
+        for (int i = 0; i < choices.length; i++) {
+            if (i > 0) {
+                choicesStr += "|";
+            }
+            choicesStr += choices[i];
+        }
+
+        throw new SqlException(null,
+            new ClientMessageId(SQLState.INVALID_ATTRIBUTE),
+            attribute, value, choicesStr);
+    }
+
+    /*
+     * Properties to be seen by Bean - access thru reflection.
+     */
+
+    // -- Stardard JDBC DataSource Properties
+
+    public synchronized void setDatabaseName(String databaseName) {
+        this.databaseName = databaseName;
+    }
+
+    public String getDatabaseName() {
+        return this.databaseName;
+    }
+
+
+    public synchronized void setDataSourceName(String dataSourceName) {
+        this.dataSourceName = dataSourceName;
+    }
+
+    public String getDataSourceName() {
+        return this.dataSourceName;
+    }
+
+    public synchronized void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getDescription() {
+        return this.description;
+    }
+
+
+    public synchronized void setPortNumber(int portNumber) {
+        this.portNumber = portNumber;
+    }
+
+    public int getPortNumber() {
+        return this.portNumber;
+    }
+
+    public synchronized void setServerName(String serverName) {
+        this.serverName = serverName;
+    }
+
+    public String getServerName() {
+        return this.serverName;
+    }
+
+
+    public synchronized void setUser(String user) {
+        this.user = user;
+    }
+
+    public String getUser() {
+        return this.user;
+    }
+
+    synchronized public void setRetrieveMessageText(
+        boolean retrieveMessageText) {
+
+        this.retrieveMessageText = retrieveMessageText;
+    }
+
+    public boolean getRetrieveMessageText() {
+        return this.retrieveMessageText;
+    }
+
+
+    /**
+     * Sets the security mechanism.
+     * @param securityMechanism to set
+     */
+    synchronized public void setSecurityMechanism(short securityMechanism) {
+        this.securityMechanism = securityMechanism;
+    }
+
+    /**
+     * Return the security mechanism.
+     * If security mechanism has not been set explicitly on datasource,
+     * then upgrade the security mechanism to a more secure one if possible.
+     * @see #getUpgradedSecurityMechanism(String)
+     * @return the security mechanism
+     */
+    public short getSecurityMechanism() {
+        return getSecurityMechanism(getPassword());
+    }
+
+    /**
+     * Return the security mechanism for this datasource object.
+     * If security mechanism has not been set explicitly on datasource,
+     * then upgrade the security mechanism to a more secure one if possible.
+     * @param password  password of user
+     * @see #getUpgradedSecurityMechanism(String)
+     * @return the security mechanism
+     */
+    public short getSecurityMechanism(String password) {
+
+        // if security mechanism has not been set explicitly on
+        // datasource, then upgrade the security mechanism if possible
+        // DERBY-962
+        if ( securityMechanism == SECMEC_HAS_NOT_EXPLICITLY_SET ) {
+            return getUpgradedSecurityMechanism(password);
+        }
+
+        return securityMechanism;
+    }
+
+    // ----------------------- ssl
+
+    private int sslMode;
+
+    /**
+     * Specifies the SSL encryption mode to use.
+     * <p>
+     * Valid values are <tt>off</tt>, <tt>basic</tt> and
+     * <tt>peerAuthentication</tt>.
+     *
+     * @param mode the SSL mode to use (<tt>off</tt>, <tt>basic</tt> or
+     *      <tt>peerAuthentication</tt>)
+     * @throws SqlException if the specified mode is invalid
+     */
+    public void setSsl(String mode)
+        throws SqlException
+    {
+        sslMode = getSSLModeFromString(mode);
+    }
+
+    /**
+     * Returns the SSL encryption mode specified for the data source.
+     *
+     * @return <tt>off</tt>, <tt>basic</tt> or <tt>peerAuthentication</tt>.
+     */
+    public String getSsl() {
+        switch(sslMode) {
+        case SSL_OFF:
+        default:
+            return SSL_OFF_STR;
+        case SSL_BASIC:
+            return SSL_BASIC_STR;
+        case SSL_PEER_AUTHENTICATION:
+            return SSL_PEER_AUTHENTICATION_STR;
+        }
+    }
+
+    // ----------------------- set/getCreate/ShutdownDatabase -----------------
+    /**
+     * Set to true if the database should be created.
+     */
+    private boolean createDatabase;
+
+    /**
+     * Set to true if the database should be shutdown.
+     */
+    private boolean shutdownDatabase;
+
+    /**
+     * Set this property to create a new database.  If this property is not
+     * set, the database (identified by databaseName) is assumed to be already
+     * existing.
+     * @param create if set to the string "create", this data source will try
+     *               to create a new database of databaseName, or boot the
+     *               database if one by that name already exists.
+     *
+     */
+    public void setCreateDatabase(String create) {
+        if (create != null && create.equalsIgnoreCase("create")) {
+            this.createDatabase = true;
+        } else { // reset
+            this.createDatabase = false;
+        }
+    }
+
+    /** @return "create" if create is set, or null if not
+     */
+    public String getCreateDatabase() {
+        String createstr=null;
+        if (createDatabase) {
+            createstr="create";
+        }
+        return createstr;
+    }
+
+    /**
+     * Set this property if one wishes to shutdown the database identified by
+     * databaseName.
+     * @param shutdown if set to the string "shutdown", this data source will
+     *                 shutdown the database if it is running.
+     *
+     */
+    public void setShutdownDatabase(String shutdown) {
+        if (shutdown != null && shutdown.equalsIgnoreCase("shutdown")) {
+            this.shutdownDatabase = true;
+        } else { // reset
+            this.shutdownDatabase = false;
+        }
+    }
+
+    /** @return "shutdown" if shutdown is set, or null if not
+     */
+    public String getShutdownDatabase() {
+        String shutdownstr=null;
+        if (shutdownDatabase)
+        {
+            shutdownstr = "shutdown";
+        }
+        return shutdownstr;
+    }
+
+    private String connectionAttributes = null;
+
+    /**
+     * Set this property to pass in more Derby specific connection URL
+     * attributes.
+     * <BR>
+     * Any attributes that can be set using a property of this DataSource
+     * implementation (e.g user, password) should not be set in
+     * connectionAttributes. Conflicting settings in connectionAttributes and
+     * properties of the DataSource will lead to unexpected behaviour.
+     *
+     * @param prop set to the list of Derby connection attributes separated by
+     *    semi-colons.  E.g., to specify an encryption bootPassword
+     *    of "x8hhk2adf", and set upgrade to true, do the following:
+     * <br>
+     * {@code
+     *  ds.setConnectionAttributes("bootPassword=x8hhk2adf;upgrade=true");}
+     *
+     * See Derby documentation for complete list.
+     */
+    public void setConnectionAttributes(String prop) {
+        connectionAttributes = prop;
+    }
+
+    /**
+     * @return Derby specific connection URL attributes
+     */
+    public String getConnectionAttributes() {
+        return connectionAttributes;
+    }
+
+
+
+    private int traceLevel = propertyDefault_traceLevel;
+
+    /**
+     * Check if derby.client.traceLevel is provided as a JVM property.
+     * If yes, then we use that value. If not, then we look for traceLevel
+     * in the the properties parameter.
+     *
+     * @param properties jdbc url properties
+     * @return value of traceLevel property
+     */
+    static int getTraceLevel(Properties properties) {
+        String traceLevelString;
+        traceLevelString  =
+            readSystemProperty(Attribute.CLIENT_JVM_PROPERTY_PREFIX +
+                               Attribute.CLIENT_TRACE_LEVEL);
+        if (traceLevelString == null  && properties != null) {
+            traceLevelString =
+                properties.getProperty(Attribute.CLIENT_TRACE_LEVEL);
+        }
+        if (traceLevelString != null ) {
+            return parseInt(traceLevelString, propertyDefault_traceLevel);
+        } else {
+            return propertyDefault_traceLevel;
+        }
+    }
+
+    synchronized public void setTraceLevel(int traceLevel) {
+        this.traceLevel = traceLevel;
+    }
+
+    public int getTraceLevel() {
+        return this.traceLevel;
+    }
+
+    public synchronized void setTraceFile(String traceFile) {
+        this.traceFile = traceFile;
+    }
+
+    public String getTraceFile() {
+        return this.traceFile;
+    }
+
+
+    public synchronized void setTraceDirectory(String traceDirectory) {
+        this.traceDirectory = traceDirectory;
+    }
+
+    public String getTraceDirectory() {
+        return this.traceDirectory;
+    }
+
+    synchronized public void setTraceFileAppend(boolean traceFileAppend) {
+        this.traceFileAppend = traceFileAppend;
+    }
+
+    public boolean getTraceFileAppend() {
+        return this.traceFileAppend;
+    }
+
+    /**
+     * Returns the maximum number of JDBC prepared statements a connection is
+     * allowed to cache.
+     * <p>
+     * A basic data source will always return zero. If statement caching is
+     * required, use a {@link javax.sql.ConnectionPoolDataSource}.
+     * <p>
+     * This method is used internally by Derby to determine if statement
+     * pooling is to be enabled or not.
+     * Not part of public API, so not present in
+     * {@link org.apache.derby.jdbc.ClientDataSourceInterface}.
+     *
+     * @return Maximum number of statements to cache, or <code>0</code> if
+     *      caching is disabled (default).
+     */
+    public int maxStatementsToPool() {
+        return 0;
+    }
+
+    // --- private helper methods
+
+
+    /**
+     * The dataSource keeps individual fields for the values that are relevant
+     * to the client. These need to be updated when set connection attributes
+     * is called.
+     */
+    private void updateDataSourceValues(Properties prop)
+        throws SqlException
+    {
+        // DERBY-5553. System properties derby.client.traceDirectory
+        // and derby.client.traceLevel do not work for ClientXADataSource
+        // or ClientConnectionPoolDataSource
+        // Trace level and trace directory will be read from system
+        // properties if they are not specified in the Properties
+        // argument, so we check for them first to avoid getting cut
+        // off by the (prop == null) check below.
+        String traceDir = getTraceDirectory(prop);
+        if (traceDir != null) {
+            setTraceDirectory(traceDir);
+        }
+        
+        int traceLevel = getTraceLevel(prop);
+        if (traceLevel != propertyDefault_traceLevel) {
+            setTraceLevel(traceLevel);
+        }
+        if (prop == null) {
+            return;
+        }
+
+        if (prop.containsKey(Attribute.USERNAME_ATTR)) {
+            setUser(getUser(prop));
+        }
+        if (prop.containsKey(Attribute.CLIENT_SECURITY_MECHANISM)) {
+            setSecurityMechanism(getSecurityMechanism(prop));
+        }
+        if (prop.containsKey(Attribute.CLIENT_TRACE_FILE)) {
+            setTraceFile(getTraceFile(prop));
+        }
+        if (prop.containsKey(Attribute.CLIENT_TRACE_APPEND)) {
+            setTraceFileAppend(getTraceFileAppend(prop));
+        }
+        if (prop.containsKey(Attribute.CLIENT_RETIEVE_MESSAGE_TEXT)) {
+            setRetrieveMessageText(getRetrieveMessageText(prop));
+        }
+        if (prop.containsKey(Attribute.SSL_ATTR)) {
+            sslMode = getClientSSLMode(prop);
+        }
+    }
+
+    /**
+     * Handles common error situations that can happen when trying to
+     * obtain a physical connection to the server, and which require special
+     * handling.
+     * <p>
+     * If this method returns normally, the exception wasn't handled and should
+     * be handled elsewhere or be re-thrown.
+     *
+     * @param logWriter log writer, may be {@code null}
+     * @param sqle exception to handle
+     * @throws SQLException handled exception (if any)
+     */
+    private void handleConnectionException(LogWriter logWriter,
+                                                   SqlException sqle)
+            throws SQLException {
+        // See DERBY-4070
+        if (sqle.getSQLState().equals(
+                ExceptionUtil.getSQLStateFromIdentifier(
+                    SQLState.INVALID_ATTRIBUTE_SYNTAX))) {
+            // Wrap this in SQLState.MALFORMED_URL exception to be
+            // consistent with the embedded driver.
+            throw new SqlException(logWriter,
+                    new ClientMessageId(SQLState.MALFORMED_URL),
+                    sqle, constructUrl()).getSQLException();
+
+        }
+    }
+
+    /**
+     * Constructs the JDBC connection URL from the state of the data source.
+     *
+     * @return The JDBC connection URL.
+     */
+    private String constructUrl() {
+        StringBuilder sb = new StringBuilder(64);
+        // To support subSubProtocols, the protocol addition below must be
+        // changed.
+        sb.append(Attribute.DNC_PROTOCOL);
+        sb.append(serverName);
+        sb.append(':');
+        sb.append(portNumber);
+        sb.append('/');
+        sb.append(databaseName);
+        if (connectionAttributes != null) {
+            sb.append(';');
+            sb.append(connectionAttributes);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Attempt to establish a database connection in a non-pooling,
+     * non-distributed environment.
+     *
+     * @return a Connection to the database
+     *
+     * @throws java.sql.SQLException if a database-access error occurs.
+     */
+    public Connection getConnection() throws SQLException {
+        LogWriter dncLogWriter = null;
+        try {
+            updateDataSourceValues(
+                    tokenizeAttributes(getConnectionAttributes(), null));
+            dncLogWriter = computeDncLogWriterForNewConnection("_sds");
+            return getConnectionX(dncLogWriter, getUser(), getPassword());
+        } catch (SqlException se) {
+            // The method below may throw an exception.
+            handleConnectionException(dncLogWriter, se);
+            // If the exception wasn't handled so far, re-throw it.
+            throw se.getSQLException();
+        }
+    }
+
+    /**
+     * Attempt to establish a database connection in a non-pooling,
+     * non-distributed environment.
+     *
+     * @param user the database user on whose behalf the Connection is being
+     *        made
+     * @param password the user's password
+     *
+     * @return a Connection to the database
+     *
+     * @throws java.sql.SQLException if a database-access error occurs.
+     */
+    public Connection getConnection(String user, String password)
+            throws SQLException {
+        // Jdbc 2 connections will write driver trace info on a
+        // datasource-wide basis using the jdbc 2 data source log writer.
+        // This log writer may be narrowed to the connection-level
+        // This log writer will be passed to the agent constructor.
+
+        LogWriter dncLogWriter = null;
+        try
+        {
+            updateDataSourceValues(
+                    tokenizeAttributes(getConnectionAttributes(), null));
+            dncLogWriter = computeDncLogWriterForNewConnection("_sds");
+            return getConnectionX(dncLogWriter, user, password);
+        }
+        catch(SqlException se)
+        {
+            // The method below may throw an exception.
+            handleConnectionException(dncLogWriter, se);
+            // If the exception wasn't handled so far, re-throw it.
+            throw se.getSQLException();
+        }
+
+    }
+
+    private Connection getConnectionX(LogWriter dncLogWriter,
+                                      String user, String password)
+            throws SqlException {
+        return ClientDriver.getFactory().newNetConnection(
+                dncLogWriter, user, password, this, -1, false);
+
+    }
+
+    // JDBC 4.0 java.sql.Wrapper interface methods
+
+    /**
+     * Check whether this instance wraps an object that implements the
+     * interface specified by {@code iface}.
+     *
+     * @param iface a class defining an interface
+     * @return {@code true} if this instance implements {@code iface}, or
+     * {@code false} otherwise
+     * @throws SQLException if an error occurs while determining if this
+     * instance implements {@code iface}
+     */
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return iface.isInstance(this);
+    }
+
+    /**
+     * Returns {@code this} if this class implements the specified interface.
+     *
+     * @param  iface a class defining an interface
+     * @return an object that implements the interface
+     * @throws SQLException if no object is found that implements the
+     * interface
+     */
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        try {
+            return iface.cast(this);
+        } catch (ClassCastException cce) {
+            throw new SqlException(null,
+                    new ClientMessageId(SQLState.UNABLE_TO_UNWRAP),
+                    iface).getSQLException();
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////
+    //
+    // INTRODUCED BY JDBC 4.1 IN JAVA 7
+    //
+    ////////////////////////////////////////////////////////////////////
+
+    public Logger getParentLogger()
+            throws SQLFeatureNotSupportedException {
+        throw SQLExceptionFactory.notImplemented("getParentLogger");
+    }
+
+    // Helper methods
+
+    protected final PooledConnection getPooledConnectionMinion()
+            throws SQLException {
+        LogWriter dncLogWriter = null;
+
+        try {
+            updateDataSourceValues(
+                    tokenizeAttributes(getConnectionAttributes(), null));
+            dncLogWriter = computeDncLogWriterForNewConnection("_cpds");
+
+            if (dncLogWriter != null) {
+                dncLogWriter.traceEntry(this, "getPooledConnection");
+            }
+
+            PooledConnection pooledConnection = getPooledConnectionX(
+                    dncLogWriter, this, getUser(), getPassword());
+
+            if (dncLogWriter != null) {
+                dncLogWriter.traceExit(
+                        this, "getPooledConnection", pooledConnection);
+            }
+
+            return pooledConnection;
+        }
+        catch (SqlException se) {
+            // The method below may throw an exception.
+            handleConnectionException(dncLogWriter, se);
+            // If the exception wasn't handled so far, re-throw it.
+            throw se.getSQLException();
+        }
+    }
+
+    protected final PooledConnection getPooledConnectionMinion(
+            String user, String password) throws SQLException {
+
+        LogWriter dncLogWriter = null;
+
+        try {
+            updateDataSourceValues(
+                    tokenizeAttributes(getConnectionAttributes(), null));
+            dncLogWriter = computeDncLogWriterForNewConnection("_cpds");
+
+            if (dncLogWriter != null) {
+                dncLogWriter.traceEntry(
+                        this, "getPooledConnection", user, "<escaped>");
+            }
+
+            PooledConnection pooledConnection = getPooledConnectionX(
+                    dncLogWriter, this, user, password);
+
+            if (dncLogWriter != null) {
+                dncLogWriter.traceExit(
+                        this, "getPooledConnection", pooledConnection);
+            }
+
+            return pooledConnection;
+
+        } catch (SqlException se) {
+            // The method below may throw an exception.
+            handleConnectionException(dncLogWriter, se);
+            // If the exception wasn't handled so far, re-throw it.
+            throw se.getSQLException();
+        }
+    }
+
+    // Minion method that establishes the initial physical connection
+    // using DS properties instead of CPDS properties.
+    private static PooledConnection getPooledConnectionX(
+            LogWriter dncLogWriter,
+            BasicClientDataSource40 ds,
+            String user,
+            String password) throws SQLException {
+
+            return ClientDriver.getFactory().newClientPooledConnection(ds,
+                    dncLogWriter, user, password);
+    }
+
+    protected final XAConnection getXAConnectionMinion() throws SQLException {
+        LogWriter dncLogWriter = null;
+        try {
+            updateDataSourceValues(
+                    tokenizeAttributes(getConnectionAttributes(), null));
+            dncLogWriter = computeDncLogWriterForNewConnection("_xads");
+            return getXAConnectionX(
+                    dncLogWriter, this, getUser(), getPassword());
+        } catch (SqlException se) {
+            // The method below may throw an exception.
+            handleConnectionException(dncLogWriter, se);
+            // If the exception wasn't handled so far, re-throw it.
+            throw se.getSQLException();
+        }
+    }
+
+    protected final XAConnection getXAConnectionMinion(
+            String user, String password) throws SQLException {
+
+        LogWriter dncLogWriter = null;
+        try
+        {
+            updateDataSourceValues(
+                    tokenizeAttributes(getConnectionAttributes(), null));
+            dncLogWriter = computeDncLogWriterForNewConnection("_xads");
+            return getXAConnectionX(dncLogWriter, this, user, password);
+        }
+        catch ( SqlException se )
+        {
+            // The method below may throw an exception.
+            handleConnectionException(dncLogWriter, se);
+            // If the exception wasn't handled so far, re-throw it.
+            throw se.getSQLException();
+        }
+    }
+
+    /**
+     * Method that establishes the initial physical connection
+     * using DS properties instead of CPDS properties.
+     */
+    private static XAConnection getXAConnectionX(LogWriter dncLogWriter,
+        BasicClientDataSource40 ds, String user, String password)
+        throws SQLException
+    {
+        return ClientDriver.getFactory().newClientXAConnection(ds,
+                dncLogWriter, user, password);
+    }
+
+    public static Properties getProperties(BasicClientDataSource40 ths) {
+        Properties properties = new Properties();
+
+        // Look for all the getXXX methods in the class that take no arguments.
+        Method[] methods = ths.getClass().getMethods();
+
+        for (int i = 0; i < methods.length; i++) {
+
+            Method m = methods[i];
+
+            // only look for simple getter methods.
+            if (m.getParameterTypes().length != 0) {
+                continue;
+            }
+
+            // only non-static methods
+            if (Modifier.isStatic(m.getModifiers())) {
+                continue;
+            }
+
+            // Only getXXX methods
+            String methodName = m.getName();
+            if ((methodName.length() < 5) || !methodName.startsWith("get")) {
+                continue;
+            }
+
+            Class returnType = m.getReturnType();
+
+            if (Integer.TYPE.equals(returnType)
+                    || Short.TYPE.equals(returnType)
+                    || String.class.equals(returnType)
+                    || Boolean.TYPE.equals(returnType)) {
+
+                // E.g. "getSomeProperty"
+                //          s                 to lower case (3,4)
+                //           omeProperty      use as is (4->)
+                String propertyName = methodName.substring(3, 4).toLowerCase(
+                        Locale.ENGLISH).concat(
+                        methodName.substring(4));
+
+                try {
+                    Object ov = m.invoke(ths, (Object[])null);
+                    // Need to check if property value is null, otherwise
+                    // "null" string gets stored.
+                    if (ov != null) {
+                        properties.setProperty(propertyName, ov.toString());
+                    }
+                } catch (IllegalAccessException iae) {
+                } catch (InvocationTargetException ite) {
+                }
+
+            }
+        }
+
+        return properties;
+    }
 }

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/BasicClientXADataSource40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/BasicClientXADataSource40.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/BasicClientXADataSource40.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/BasicClientXADataSource40.java Mon Jun 16 23:00:34 2014
@@ -26,7 +26,7 @@ import javax.sql.XAConnection;
 import javax.sql.XADataSource;
 
 /**
- * This datasource is suitable for client/server use of Derby,
+ * This data source is suitable for client/server use of Derby,
  * running on Java 8 Compact Profile 2 or higher.
  * <p/>
  * Similar to ClientXADataSource except it does not support JNDI,

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientConnectionPoolDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientConnectionPoolDataSource.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientConnectionPoolDataSource.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientConnectionPoolDataSource.java Mon Jun 16 23:00:34 2014
@@ -104,7 +104,7 @@ public class ClientConnectionPoolDataSou
     /**
      * Internally used method.
      *
-     * @see ClientBaseDataSource#maxStatementsToPool
+     * @see BasicClientDataSource40#maxStatementsToPool
      */
     public int maxStatementsToPool() {
         return this.maxStatements;

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDataSource.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDataSource.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDataSource.java Mon Jun 16 23:00:34 2014
@@ -21,8 +21,16 @@
 
 package org.apache.derby.jdbc;
 
+import java.util.Enumeration;
+import java.util.Properties;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.Referenceable;
+import javax.naming.StringRefAddr;
+import org.apache.derby.client.ClientDataSourceFactory;
+
 /**
- * This datasource is suitable for a client/server use of Derby,
+ * This data source is suitable for a client/server use of Derby,
  * running on full Java SE 6 and higher, corresponding to JDBC 4.0 and higher.
  * <p/>
  * ClientDataSource is a simple data source implementation
@@ -75,7 +83,7 @@ package org.apache.derby.jdbc;
  * the last line, the DataSource.getConnection() method
  * is called to produce a database connection.
  * <p/>
- * This simple data source subclass of ClientBaseDataSource maintains
+ * This simple data source subclass of BasicClientDataSource40 maintains
  * it's own private <code>password</code> property.
  * <p/>
  * The specified password, along with the user, is validated by DERBY.
@@ -89,7 +97,8 @@ package org.apache.derby.jdbc;
  * breaches.
  * <p/>
  */
-public class ClientDataSource extends ClientBaseDataSource {
+public class ClientDataSource extends BasicClientDataSource40 
+                              implements Referenceable {
 
     private final static long serialVersionUID = 1894299584216955553L;
     public static final String className__ = "org.apache.derby.jdbc.ClientDataSource";
@@ -138,6 +147,62 @@ public class ClientDataSource extends Cl
         super();
     }
 
+    //------------------------ Referenceable interface methods -----------------------------
+
+    @Override
+    public Reference getReference() throws NamingException {
+
+        // This method creates a new Reference object to represent this data
+        // source.  The class name of the data source object is saved in the
+        // Reference, so that an object factory will know that it should
+        // create an instance of that class when a lookup operation is
+        // performed. The class name of the object factory,
+        // org.apache.derby.client.ClientBaseDataSourceFactory, is also stored
+        // in the reference.  This is not required by JNDI, but is recommend
+        // in practice.  JNDI will always use the object factory class
+        // specified in the reference when reconstructing an object, if a
+        // class name has been specified.
+        //
+        // See the JNDI SPI documentation for further details on this topic,
+        // and for a complete description of the Reference and StringRefAddr
+        // classes.
+        //
+        // This BasicClientDataSource40 class provides several standard JDBC
+        // properties.  The names and values of the data source properties are
+        // also stored in the reference using the StringRefAddr class.  This
+        // is all the information needed to reconstruct a ClientDataSource
+        // object.
+
+        Reference ref = new Reference(this.getClass().getName(),
+                ClientDataSourceFactory.class.getName(), null);
 
+        addBeanProperties(ref);
+        return ref;
+    }
+
+    /**
+     * Add Java Bean properties to the reference using
+     * StringRefAddr for each property. List of bean properties
+     * is defined from the public getXXX() methods on this object
+     * that take no arguments and return short, int, boolean or String.
+     * The StringRefAddr has a key of the Java bean property name,
+     * converted from the method name. E.g. traceDirectory for
+     * traceDirectory.
+     *
+     * @param ref The referenced object
+      */
+    private void addBeanProperties(Reference ref) {
+
+        Properties p = getProperties(this);
+        Enumeration<?> e = p.propertyNames();
+
+        while (e.hasMoreElements()) {
+            String propName = (String)e.nextElement();
+            Object value = p.getProperty(propName);
+            if (value != null) {
+                ref.add(new StringRefAddr(propName, value.toString()));
+            }
+        }
+    }
 }
 

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDataSourceInterface.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDataSourceInterface.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDataSourceInterface.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDataSourceInterface.java Mon Jun 16 23:00:34 2014
@@ -134,20 +134,4 @@ public interface ClientDataSourceInterfa
     public boolean getTraceFileAppend();
 
 
-    // ---------------------------- traceLevel -------------------------------
-    //
-
-    public final static int TRACE_NONE = 0x0;
-    public final static int TRACE_CONNECTION_CALLS = 0x1;
-    public final static int TRACE_STATEMENT_CALLS = 0x2;
-    public final static int TRACE_RESULT_SET_CALLS = 0x4;
-    public final static int TRACE_DRIVER_CONFIGURATION = 0x10;
-    public final static int TRACE_CONNECTS = 0x20;
-    public final static int TRACE_PROTOCOL_FLOWS = 0x40;
-    public final static int TRACE_RESULT_SET_META_DATA = 0x80;
-    public final static int TRACE_PARAMETER_META_DATA = 0x100;
-    public final static int TRACE_DIAGNOSTICS = 0x200;
-    public final static int TRACE_XA_CALLS = 0x800;
-    public final static int TRACE_ALL = 0xFFFFFFFF;
-    public final static int propertyDefault_traceLevel = TRACE_ALL;
 }

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDriver.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDriver.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDriver.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDriver.java Mon Jun 16 23:00:34 2014
@@ -127,7 +127,7 @@ public class ClientDriver implements Dri
             String server = tokenizeServerName(urlTokenizer, url);    // "/server"
             int port = tokenizeOptionalPortNumber(urlTokenizer, url); // "[:port]/"
             if (port == 0) {
-                port = ClientBaseDataSourceRoot.propertyDefault_portNumber;
+                port = BasicClientDataSource40.propertyDefault_portNumber;
             }
 
             // database is the database name and attributes.  This will be
@@ -140,7 +140,7 @@ public class ClientDriver implements Dri
             int traceLevel;
             try {
                 traceLevel =
-                    ClientBaseDataSourceRoot.getTraceLevel(augmentedProperties);
+                    BasicClientDataSource40.getTraceLevel(augmentedProperties);
             } catch (NumberFormatException e) {
                 // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
                 throw new SqlException(null, 
@@ -152,13 +152,13 @@ public class ClientDriver implements Dri
             // This log writer may be narrowed to the connection-level
             // This log writer will be passed to the agent constructor.
             LogWriter dncLogWriter =
-                ClientBaseDataSourceRoot.computeDncLogWriterForNewConnection(
+                BasicClientDataSource40.computeDncLogWriterForNewConnection(
                     DriverManager.getLogWriter(),
-                    ClientBaseDataSourceRoot.getTraceDirectory(
+                    BasicClientDataSource40.getTraceDirectory(
                         augmentedProperties),
-                    ClientBaseDataSourceRoot.getTraceFile(
+                    BasicClientDataSource40.getTraceFile(
                         augmentedProperties),
-                    ClientBaseDataSourceRoot.getTraceFileAppend(
+                    BasicClientDataSource40.getTraceFileAppend(
                         augmentedProperties),
                     traceLevel,
                     "_driver",
@@ -254,7 +254,7 @@ public class ClientDriver implements Dri
                 Attribute.USERNAME_ATTR,
                 properties.getProperty(
                     Attribute.USERNAME_ATTR,
-                    ClientBaseDataSourceRoot.propertyDefault_user));
+                    BasicClientDataSource40.propertyDefault_user));
 
         driverPropertyInfo[1] =
                 new DriverPropertyInfo(Attribute.PASSWORD_ATTR,
@@ -420,7 +420,7 @@ public class ClientDriver implements Dri
             attributeString = url.substring(attributeIndex);
         }
 
-        return ClientBaseDataSourceRoot.tokenizeAttributes(
+        return BasicClientDataSource40.tokenizeAttributes(
             attributeString, properties);
     }
     

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource.java Mon Jun 16 23:00:34 2014
@@ -57,10 +57,12 @@ public class ClientXADataSource
     public ClientXADataSource() {
     }
 
+    @Override
     public XAConnection getXAConnection() throws SQLException {
         return getXAConnectionMinion();
     }
 
+    @Override
     public XAConnection getXAConnection(String user, String password) throws SQLException {
         return getXAConnectionMinion(user, password);
     }    

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/BasicEmbeddedDataSource40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/BasicEmbeddedDataSource40.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/BasicEmbeddedDataSource40.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/BasicEmbeddedDataSource40.java Mon Jun 16 23:00:34 2014
@@ -21,13 +21,16 @@
 
 package org.apache.derby.jdbc;
 
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
 import java.util.logging.Logger;
 import org.apache.derby.impl.jdbc.Util;
 
 /**
  *
- * This datasource is suitable for an application using embedded Derby,
+ * This data source is suitable for an application using embedded Derby,
  * running on Java 8 Compact Profile 2 or higher.
  * <p/>
  * BasicEmbeddedDataSource40 is similar to EmbeddedDataSource40, but does
@@ -36,11 +39,148 @@ import org.apache.derby.impl.jdbc.Util;
  *
  * @see EmbeddedDataSource40
  */
- public class BasicEmbeddedDataSource40 extends EmbeddedBaseDataSource
+public class BasicEmbeddedDataSource40 extends EmbeddedBaseDataSource
     implements javax.sql.DataSource {
 
-   private static final long serialVersionUID = -4945135214995641182L;
+    private static final long serialVersionUID = -4945135214995641182L;
 
     public BasicEmbeddedDataSource40() {}
 
+    @Override
+    public void setLoginTimeout(int seconds) throws SQLException {
+        super.setLoginTimeout(seconds);
+    }
+
+    @Override
+    public int getLoginTimeout() throws SQLException {
+        return super.getLoginTimeout();
+    }
+
+    @Override
+    public void setLogWriter(PrintWriter logWriter)
+            throws SQLException {
+        super.setLogWriter(logWriter);
+    }
+
+    @Override
+    public PrintWriter getLogWriter() throws SQLException {
+        return super.getLogWriter();
+    }
+
+    @Override
+    public final void setPassword(String password) {
+        super.setPassword(password);
+    }
+
+    @Override
+    public final String getPassword() {
+        return super.getPassword();
+    }
+
+    @Override
+    public void setDatabaseName(String databaseName) {
+        super.setDatabaseName(databaseName);
+    }
+
+    @Override
+    public String getDatabaseName() {
+        return super.getDatabaseName();
+    }
+
+    @Override
+    public void setDataSourceName(String dataSourceName) {
+        super.setDataSourceName(dataSourceName);
+    }
+
+    @Override
+    public String getDataSourceName() {
+        return super.getDataSourceName();
+    }
+
+    @Override
+    public void setDescription(String description) {
+        super.setDescription(description);
+    }
+
+    @Override
+    public String getDescription() {
+        return super.getDescription();
+    }
+
+    @Override
+    public void setUser(String user) {
+        super.setUser(user);
+    }
+
+    @Override
+    public String getUser() {
+        return super.getUser();
+    }
+
+    @Override
+    public final void setCreateDatabase(String create) {
+        super.setCreateDatabase(create);
+    }
+
+    @Override
+    public final String getCreateDatabase() {
+        return super.getCreateDatabase();
+    }
+
+    @Override
+    public final void setShutdownDatabase(String shutdown) {
+        super.setShutdownDatabase(shutdown);
+    }
+
+    @Override
+    public final String getShutdownDatabase() {
+        return super.getShutdownDatabase();
+    }
+
+    @Override
+    public final void setConnectionAttributes(String prop) {
+        super.setConnectionAttributes(prop);
+    }
+
+    @Override
+    public final String getConnectionAttributes() {
+        return super.getConnectionAttributes();
+    }
+
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        return super.getConnection();
+    }
+
+    @Override
+    public Connection getConnection(String user, String password)
+            throws SQLException {
+        return super.getConnection(user, password);
+    }
+
+    @Override
+    public final Logger getParentLogger() throws SQLFeatureNotSupportedException {
+        return super.getParentLogger();
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return super.isWrapperFor(iface);
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return super.unwrap(iface);
+    }
+
+    @Override
+    public final void setAttributesAsPassword(boolean attributesAsPassword) {
+        super.setAttributesAsPassword(attributesAsPassword);
+    }
+
+    @Override
+    public final boolean getAttributesAsPassword() {
+        return super.getAttributesAsPassword();
+    }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/BasicEmbeddedXADataSource40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/BasicEmbeddedXADataSource40.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/BasicEmbeddedXADataSource40.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/BasicEmbeddedXADataSource40.java Mon Jun 16 23:00:34 2014
@@ -27,7 +27,7 @@ import org.apache.derby.iapi.jdbc.Resour
 
 /**
  *
- * This datasource is suitable for an application using embedded Derby,
+ * This data source is suitable for an application using embedded Derby,
  * running on Java 8 Compact Profile 2 or higher.
  * <p/>
  * BasicEmbeddedXADataSource40 is similar to

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedBaseDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedBaseDataSource.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedBaseDataSource.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedBaseDataSource.java Mon Jun 16 23:00:34 2014
@@ -115,7 +115,7 @@ public abstract class EmbeddedBaseDataSo
      *
      * @param databaseName the name of the database
      */
-    public final synchronized void setDatabaseName(String databaseName) {
+    public synchronized void setDatabaseName(String databaseName) {
         this.databaseName = databaseName;
 
         if( databaseName!= null && (databaseName.indexOf(";") >= 0)){
@@ -138,7 +138,7 @@ public abstract class EmbeddedBaseDataSo
     /**
      * @return database name with ant attributes stripped off.
      */
-    protected String getShortDatabaseName() {
+    private String getShortDatabaseName() {
         return shortDatabaseName;
     }
 
@@ -148,14 +148,14 @@ public abstract class EmbeddedBaseDataSo
      *
      *  @param dsn the name of the data source
      */
-    public final void setDataSourceName(String dsn) {
+    public void setDataSourceName(String dsn) {
         dataSourceName = dsn;
     }
 
     /**
      * @return data source name as set in {@link #setDataSourceName}.
      */
-    public final String getDataSourceName() {
+    public String getDataSourceName() {
         return dataSourceName;
     }
 
@@ -165,14 +165,14 @@ public abstract class EmbeddedBaseDataSo
      *
      * @param desc the description of the data source
      */
-    public final void setDescription(String desc) {
+    public void setDescription(String desc) {
         description = desc;
     }
 
     /**
      * @return the description as set in {@link #setDescription}.
      */
-    public final String getDescription() {
+    public String getDescription() {
         return description;
     }
 
@@ -182,14 +182,14 @@ public abstract class EmbeddedBaseDataSo
      * This is user name for any data source {@code getConnection()} call
      * that takes no arguments.
     */
-    public final void setUser(String user) {
+    public void setUser(String user) {
         this.user = user;
     }
 
     /**
      * @return the user name as set by {@link #setUser}.
      */
-    public final String getUser() {
+    public String getUser() {
         return user;
     }
 
@@ -199,14 +199,14 @@ public abstract class EmbeddedBaseDataSo
      * This is user's password for any data source {@code getConnection()} call
      * that takes no arguments.
      */
-    public final void setPassword(String password) {
+    public void setPassword(String password) {
         this.password = password;
     }
 
     /**
      * @return the password as set in {@link #setPassword}.
      */
-    public final String getPassword() {
+    public String getPassword() {
         return password;
     }
 
@@ -341,7 +341,7 @@ public abstract class EmbeddedBaseDataSo
      * source will try to create a new database of databaseName, or
      * boot the database if one by that name already exists.
      */
-    public final void setCreateDatabase(String create) {
+    public void setCreateDatabase(String create) {
         if (create != null &&
             create.toLowerCase(java.util.Locale.ENGLISH).equals("create")) {
             createDatabase = create;
@@ -354,7 +354,7 @@ public abstract class EmbeddedBaseDataSo
      * @return The string {@code "create"} if create is set, or {@code
      * null} if not
      */
-    public final String getCreateDatabase() {
+    public String getCreateDatabase() {
         return createDatabase;
     }
 
@@ -406,7 +406,7 @@ public abstract class EmbeddedBaseDataSo
      *
      * See the Derby documentation for complete list.
      */
-    public final void setConnectionAttributes(String prop) {
+    public void setConnectionAttributes(String prop) {
          connectionAttributes = prop;
          update();
     }
@@ -416,7 +416,7 @@ public abstract class EmbeddedBaseDataSo
      * @return the Derby specific connection URL attributes, see
      * {@link #setConnectionAttributes}.
      */
-    public final String getConnectionAttributes() {
+    public String getConnectionAttributes() {
         return connectionAttributes;
     }
 
@@ -427,7 +427,7 @@ public abstract class EmbeddedBaseDataSo
      * @param shutdown if set to the string {@code "shutdown"}, this
      * data source will shutdown the database if it is running.
      */
-    public final void setShutdownDatabase(String shutdown) {
+    public void setShutdownDatabase(String shutdown) {
         if (shutdown != null && shutdown.equalsIgnoreCase("shutdown")) {
             shutdownDatabase = shutdown;
         } else {
@@ -439,7 +439,7 @@ public abstract class EmbeddedBaseDataSo
      * @return the string {@code "shutdown"} if shutdown is set, or
      * null if not, cf.  {@link #setShutdownDatabase}.
      */
-    public final String getShutdownDatabase() {
+    public String getShutdownDatabase() {
         return shutdownDatabase;
     }
 
@@ -456,7 +456,7 @@ public abstract class EmbeddedBaseDataSo
      * @param attributesAsPassword Use {@code true} to encode password
      * argument as a set of connection attributes in a connection request.
      */
-    public final void setAttributesAsPassword(boolean attributesAsPassword) {
+    public void setAttributesAsPassword(boolean attributesAsPassword) {
         this.attributesAsPassword = attributesAsPassword;
         update();
     }
@@ -465,7 +465,7 @@ public abstract class EmbeddedBaseDataSo
      * Return the value of the {@code attributesAsPassword} property, cf.
      * {@link #setAttributesAsPassword}.
      */
-    public final boolean getAttributesAsPassword() {
+    public boolean getAttributesAsPassword() {
         return attributesAsPassword;
     }
 
@@ -631,16 +631,16 @@ public abstract class EmbeddedBaseDataSo
     // JDBC 4.0 java.sql.Wrapper interface methods
 
     /**
-     * Returns false unless {@code interfaces} is implemented.
+     * Returns false unless {@code interFace} is implemented.
      *
-     * @param iface a class defining an interface
+     * @param interFace a class defining an interface
      * @return {@code true} if this implements the interface or directly or
      *     indirectly wraps an object that does
      * @throws SQLException if an error occurs while determining
      *     whether this is a wrapper for an object with the given interface
      */
-    public boolean isWrapperFor(Class<?> iface) throws SQLException {
-        return iface.isInstance(this);
+    public boolean isWrapperFor(Class<?> interFace) throws SQLException {
+        return interFace.isInstance(this);
     }
 
     /**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedDataSource.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedDataSource.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedDataSource.java Mon Jun 16 23:00:34 2014
@@ -21,9 +21,14 @@
 
 package org.apache.derby.jdbc;
 
+import java.io.PrintWriter;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.logging.Logger;
 import javax.naming.NamingException;
 import javax.naming.Reference;
 import javax.naming.Referenceable;
@@ -31,7 +36,7 @@ import javax.naming.StringRefAddr;
 
 /**
    <P>
-    This datasource is suitable for an application using embedded Derby,
+    This data source is suitable for an application using embedded Derby,
     running on full Java SE 6 and higher, corresponding to 4.0 and higher.
     </P>
 
@@ -308,4 +313,151 @@ public class EmbeddedDataSource extends 
             }
         }
     }
+
+    @Override
+    public void setLoginTimeout(int seconds) throws SQLException {
+        super.setLoginTimeout(seconds);
+    }
+
+    @Override
+    public int getLoginTimeout() throws SQLException {
+        return super.getLoginTimeout();
+    }
+
+    @Override
+    public void setLogWriter(PrintWriter logWriter)
+            throws SQLException {
+        super.setLogWriter(logWriter);
+    }
+
+    @Override
+    public PrintWriter getLogWriter() throws SQLException {
+        return super.getLogWriter();
+    }
+
+    @Override
+    public final void setPassword(String password) {
+        super.setPassword(password);
+    }
+
+    @Override
+    public final String getPassword() {
+        return super.getPassword();
+    }
+
+    @Override
+    public void setDatabaseName(String databaseName) {
+        super.setDatabaseName(databaseName);
+    }
+
+    @Override
+    public String getDatabaseName() {
+        return super.getDatabaseName();
+    }
+
+    @Override
+    public void setDataSourceName(String dataSourceName) {
+        super.setDataSourceName(dataSourceName);
+    }
+
+    @Override
+    public String getDataSourceName() {
+        return super.getDataSourceName();
+    }
+
+    @Override
+    public void setDescription(String description) {
+        super.setDescription(description);
+    }
+
+    @Override
+    public String getDescription() {
+        return super.getDescription();
+    }
+
+    @Override
+    public void setUser(String user) {
+        super.setUser(user);
+    }
+
+    @Override
+    public String getUser() {
+        return super.getUser();
+    }
+
+    @Override
+    public final void setCreateDatabase(String create) {
+        super.setCreateDatabase(create);
+    }
+
+    @Override
+    public final String getCreateDatabase() {
+        return super.getCreateDatabase();
+    }
+
+    @Override
+    public final void setShutdownDatabase(String shutdown) {
+        super.setShutdownDatabase(shutdown);
+    }
+
+    @Override
+    public final String getShutdownDatabase() {
+        return super.getShutdownDatabase();
+    }
+
+    @Override
+    public final void setConnectionAttributes(String prop) {
+        super.setConnectionAttributes(prop);
+    }
+
+    @Override
+    public final String getConnectionAttributes() {
+        return super.getConnectionAttributes();
+    }
+
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        return super.getConnection();
+    }
+
+    @Override
+    public Connection getConnection(String user, String password)
+            throws SQLException {
+        return super.getConnection(user, password);
+    }
+
+    @Override
+    public final Logger getParentLogger() throws SQLFeatureNotSupportedException {
+        return super.getParentLogger();
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return super.isWrapperFor(iface);
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return super.unwrap(iface);
+    }
+
+    @Override
+    public final void setAttributesAsPassword(boolean attributesAsPassword) {
+        super.setAttributesAsPassword(attributesAsPassword);
+    }
+
+    @Override
+    public final boolean getAttributesAsPassword() {
+        return super.getAttributesAsPassword();
+    }
+
+    @Override
+    public Object getObjectInstance(Object refObj,
+                                    javax.naming.Name name,
+                                    javax.naming.Context nameContext,
+                                    java.util.Hashtable<?,?> environment)
+            throws java.lang.Exception {
+        return super.getObjectInstance(refObj, name, nameContext, environment);
+    }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/ReferenceableDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/ReferenceableDataSource.java?rev=1603019&r1=1603018&r2=1603019&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/ReferenceableDataSource.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/ReferenceableDataSource.java Mon Jun 16 23:00:34 2014
@@ -90,7 +90,7 @@ public class ReferenceableDataSource ext
     public Object getObjectInstance(Object refObj,
                                     javax.naming.Name name,
                                     javax.naming.Context nameContext,
-                                    java.util.Hashtable environment)
+                                    java.util.Hashtable<?,?> environment)
             throws java.lang.Exception {
 
         Object ds = null;

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/testData/serializedDataSources/BasicClientConnectionPoolDataSource40-10_11_1_0.ser
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/testData/serializedDataSources/BasicClientConnectionPoolDataSource40-10_11_1_0.ser?rev=1603019&view=auto
==============================================================================
Files db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/testData/serializedDataSources/BasicClientConnectionPoolDataSource40-10_11_1_0.ser (added) and db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/testData/serializedDataSources/BasicClientConnectionPoolDataSource40-10_11_1_0.ser Mon Jun 16 23:00:34 2014 differ

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/testData/serializedDataSources/BasicClientDataSource40-10_11_1_0.ser
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/testData/serializedDataSources/BasicClientDataSource40-10_11_1_0.ser?rev=1603019&view=auto
==============================================================================
Files db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/testData/serializedDataSources/BasicClientDataSource40-10_11_1_0.ser (added) and db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/testData/serializedDataSources/BasicClientDataSource40-10_11_1_0.ser Mon Jun 16 23:00:34 2014 differ