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 dj...@apache.org on 2005/02/08 22:57:59 UTC

svn commit: r152944 - in incubator/derby/code/trunk/java/engine/org/apache/derby: iapi/jdbc/JDBCBoot.java impl/jdbc/ConnectionChild.java impl/jdbc/EmbedConnection.java impl/jdbc/EmbedConnection30.java impl/jdbc/TransactionResourceImpl.java jdbc/Driver169.java jdbc/Driver20.java jdbc/EmbeddedDataSource.java jdbc/InternalDriver.java

Author: djd
Date: Tue Feb  8 13:57:55 2005
New Revision: 152944

URL: http://svn.apache.org/viewcvs?view=rev&rev=152944
Log:
Create InternalDriver as base of JDBC driver hierarchy, contains
 the logic that was in Driver169. Driver169 will become the driver
or JDBC object factory for J2ME.

Added:
    incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/InternalDriver.java
Modified:
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/JDBCBoot.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ConnectionChild.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection30.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/TransactionResourceImpl.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver169.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver20.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedDataSource.java

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/JDBCBoot.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/JDBCBoot.java?view=diff&r1=152943&r2=152944
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/JDBCBoot.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/JDBCBoot.java Tue Feb  8 13:57:55 2005
@@ -60,13 +60,13 @@
 	*/
 	public void boot(String protocol, PrintStream logging) {
 
-		if (org.apache.derby.jdbc.Driver169.activeDriver() == null)
+		if (org.apache.derby.jdbc.InternalDriver.activeDriver() == null)
 		{
 
-			// request that the java.sql.Driver (JDBC) service and the
+			// request that the InternalDriver (JDBC) service and the
 			// authentication service be started.
 			//
-			addProperty("derby.service.jdbc", "org.apache.derby.jdbc.Driver169");
+			addProperty("derby.service.jdbc", "org.apache.derby.jdbc.InternalDriver");
 			addProperty("derby.service.authentication", AuthenticationService.MODULE);
 
 			Monitor.startMonitor(bootProperties, logging);

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ConnectionChild.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ConnectionChild.java?view=diff&r1=152943&r2=152944
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ConnectionChild.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ConnectionChild.java Tue Feb  8 13:57:55 2005
@@ -20,7 +20,7 @@
 
 package org.apache.derby.impl.jdbc;
 
-import org.apache.derby.jdbc.Driver169;
+import org.apache.derby.jdbc.InternalDriver;
 
 import org.apache.derby.iapi.services.context.ContextManager;
 
@@ -48,7 +48,7 @@
 	/**	
 		Factory for JDBC objects to be created.
 	*/
-	protected final Driver169 factory;
+	protected final InternalDriver factory;
 
 	/**
 		Calendar for data operations.

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java?view=diff&r1=152943&r2=152944
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java Tue Feb  8 13:57:55 2005
@@ -20,7 +20,7 @@
 
 package org.apache.derby.impl.jdbc;
 
-import org.apache.derby.jdbc.Driver169;
+import org.apache.derby.jdbc.InternalDriver;
 
 import org.apache.derby.iapi.reference.Attribute;
 import org.apache.derby.iapi.reference.JDBC20Translation;
@@ -126,7 +126,7 @@
 	/**	
 		Factory for JDBC objects to be created.
 	*/
-	public Driver169 factory;
+	public InternalDriver factory;
 
 	/**
 		The Connection object the application is using when accessing the
@@ -151,7 +151,7 @@
 
 	// create a new Local Connection, using a new context manager
 	//
-	public EmbedConnection(Driver169 driver, String url, Properties info)
+	public EmbedConnection(InternalDriver driver, String url, Properties info)
 		 throws SQLException
 	{
 		// Create a root connection.
@@ -1621,7 +1621,7 @@
 		}
 	}
 
-	public final Driver169 getLocalDriver()
+	public final InternalDriver getLocalDriver()
 	{
 		if (SanityManager.DEBUG)
 			SanityManager.ASSERT(!isClosed(), "connection is closed");

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection30.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection30.java?view=diff&r1=152943&r2=152944
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection30.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection30.java Tue Feb  8 13:57:55 2005
@@ -25,7 +25,7 @@
 
 import org.apache.derby.impl.jdbc.EmbedConnection;
 import org.apache.derby.impl.jdbc.Util;
-import org.apache.derby.jdbc.Driver169;
+import org.apache.derby.jdbc.InternalDriver;
 
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.reference.DB2Limit;
@@ -64,7 +64,7 @@
 	//////////////////////////////////////////////////////////
 
 	public EmbedConnection30(
-			Driver169 driver,
+			InternalDriver driver,
 			String url,
 			Properties info)
 		throws SQLException

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/TransactionResourceImpl.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/TransactionResourceImpl.java?view=diff&r1=152943&r2=152944
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/TransactionResourceImpl.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/TransactionResourceImpl.java Tue Feb  8 13:57:55 2005
@@ -20,7 +20,7 @@
 
 package org.apache.derby.impl.jdbc;
 
-import org.apache.derby.jdbc.Driver169;
+import org.apache.derby.jdbc.InternalDriver;
 
 import org.apache.derby.iapi.services.context.Context;
 import org.apache.derby.iapi.services.context.ContextService;
@@ -117,7 +117,7 @@
 	protected String username;
 
 	private String dbname;
-	private Driver169 driver;
+	private InternalDriver driver;
 	private String url;
 	private String drdaID;
 
@@ -129,13 +129,13 @@
 	 * create a brand new connection for a brand new transaction
 	 */
 	TransactionResourceImpl(
-							Driver169 driver, 
+							InternalDriver driver, 
 							String url,
 							Properties info) throws SQLException 
 	{
 		this.driver = driver;
 		csf = driver.getContextServiceFactory();
-		dbname = Driver169.getDatabaseName(url, info);
+		dbname = InternalDriver.getDatabaseName(url, info);
 		this.url = url;
 
 		// the driver manager will push a user name
@@ -193,7 +193,7 @@
 	 * should perhaps stop giving out reference to these things but instead use
 	 * the transaction resource itself.
 	 */
-	Driver169 getDriver() {
+	InternalDriver getDriver() {
 		return driver;
 	}
 	ContextService getCsf() {

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver169.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver169.java?view=diff&r1=152943&r2=152944
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver169.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver169.java Tue Feb  8 13:57:55 2005
@@ -2,7 +2,7 @@
 
    Derby - Class org.apache.derby.jdbc.Driver169
 
-   Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -20,372 +20,30 @@
 
 package org.apache.derby.jdbc;
 
-import org.apache.derby.iapi.reference.Attribute;
-import org.apache.derby.iapi.reference.SQLState;
-import org.apache.derby.iapi.reference.MessageId;
-import org.apache.derby.iapi.reference.Property;
-import org.apache.derby.iapi.services.info.ProductVersionHolder;
-import org.apache.derby.iapi.services.io.FormatableProperties;
-
-import org.apache.derby.iapi.jdbc.ConnectionContext;
-
-import org.apache.derby.iapi.services.monitor.ModuleControl;
-import org.apache.derby.iapi.services.monitor.Monitor;
-import org.apache.derby.iapi.services.context.ContextService;
-import org.apache.derby.iapi.services.context.ContextManager;
-import org.apache.derby.iapi.services.io.FormatIdUtil;
-import org.apache.derby.iapi.services.sanity.SanityManager;
-import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.services.i18n.MessageService;
 
 import org.apache.derby.iapi.sql.ResultSet;
 
-import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
-
-import org.apache.derby.iapi.jdbc.AuthenticationService;
-
 import org.apache.derby.impl.jdbc.*;
 
 import java.sql.Connection;
-import java.sql.DatabaseMetaData;
 import java.sql.SQLException;
 
 import java.util.Properties;
-import java.util.StringTokenizer;
 
 
 /**
-	A Local JDBC Driver. Note that this is an implementation of a 
-	protocol that is not defined by Cloudscape, i.e. we are viewing
-	java.sql as a protocol. But this module should not be accessed
-	through findModule(), the correct way to get obtain JDBC drivers
-	is through java.sql.DriverManager.
+    Driver169 - JDBC "driver" for J2ME/CDC/Foundation/JSR169, really
+    the JDBC object factory for the JSR169 environment.
+    
+    WORK IN PROGRESS
+
 
 	@author djd
 */
 
-public abstract class Driver169 implements ModuleControl {
-
-	private static final Object syncMe = new Object();
-	private static Driver169 activeDriver;
-
-	protected boolean active;
-	private ContextService contextServiceFactory;
-	private AuthenticationService	authenticationService;
-
-	public static final Driver169 activeDriver()
-	{
-		return activeDriver;
-	}
+public abstract class Driver169 extends InternalDriver {
 
 	public Driver169() {
-		contextServiceFactory = ContextService.getFactory();
-	}
-
-	/*
-	**	Methods from ModuleControl
-	*/
-
-	public void boot(boolean create, Properties properties) throws StandardException {
-
-		synchronized (Driver169.syncMe)
-		{
-			Driver169.activeDriver = this;
-		}
-
-		active = true;
-	}
-
-	public void stop() {
-
-		synchronized (Driver169.syncMe)
-		{
-			Driver169.activeDriver = null;
-		}
-
-		active = false;
-
-		contextServiceFactory = null;
-	}
-
-	/*
-	** Methods from java.sql.Driver
-	*/
-	public boolean acceptsURL(String url) {
-		return active && (url.startsWith(Attribute.PROTOCOL) || url.equals(Attribute.SQLJ_NESTED));
-	}
-
-	public Connection connect(String url, Properties info)
-		 throws SQLException 
-	{
-		if (!acceptsURL(url)) { return null; }
-
-			
-		/*
-		** A url "jdbc:default:connection" means get the current
-		** connection.  From within a method called from JSQL, the
-		** "current" connection is the one that is running the
-		** JSQL statement containing the method call.
-		*/
-		boolean current = url.equals(Attribute.SQLJ_NESTED);
-		
-		/* If jdbc:default:connection, see if user already has a
-		 * connection. All connection attributes are ignored.
-		 */
-		if (current) {
-
-			ConnectionContext connContext = getConnectionContext();
-
-			if (connContext != null) {
-						
-				return connContext.getNestedConnection(false);
-				
-			}
-			// there is no cloudscape connection, so
-			// return null, as we are not the driver to handle this
-			return null;
-		}
-
-		// convert the ;name=value attributes in the URL into
-		// properties.
-		FormatableProperties finfo = getAttributes(url, info);
-		info = null; // ensure we don't use this reference directly again.
-		try {
-
-			/*
-			** A property "shutdown=true" means shut the system or database down
-			*/
-			boolean shutdown = Boolean.valueOf(finfo.getProperty(Attribute.SHUTDOWN_ATTR)).booleanValue();
-			
-			if (shutdown) {
-				
-				// If we are shutting down the system don't attempt to create
-				// a connection; but we validate users credentials if we have to.
-				// In case of datbase shutdown, we ask the database authentication
-				// service to authenticate the user. If it is a system shutdown,
-				// then we ask the Driver to do the authentication.
-				//
-				if (Driver169.getDatabaseName(url, finfo).length() == 0) {
-					//
-					// We need to authenticate the user if authentication is
-					// ON. Note that this is a system shutdown.
-					// check that we do have a authentication service
-					// it is _always_ expected.
-					if (this.getAuthenticationService() == null)
-						throw Util.generateCsSQLException(
-                        SQLState.LOGIN_FAILED, 
-						MessageService.getTextMessage(MessageId.AUTH_NO_SERVICE_FOR_SYSTEM));
-					
-						
-					if (!this.getAuthenticationService().authenticate((String) null, finfo)) {
-
-						// not a valid user
-						throw Util.generateCsSQLException(
-                                  SQLState.LOGIN_FAILED, MessageService.getTextMessage(MessageId.AUTH_INVALID));
-					}
-
-					Monitor.getMonitor().shutdown();
-					throw Util.generateCsSQLException(
-                                         SQLState.CLOUDSCAPE_SYSTEM_SHUTDOWN);
-				}
-			}
-			
-			EmbedConnection conn = getNewEmbedConnection(url, finfo);
-
-			// if this is not the correct driver a EmbedConnection
-			// object is returned in the closed state.
-			if (conn.isClosed()) {
-				return null;
-			}
-
-			return conn;
-		}
-		finally {
-			// break any link with the user's Properties set.
-			finfo.clearDefaults();
-		}
-	}
-
-	public int getMajorVersion() {
-		return Monitor.getMonitor().getEngineVersion().getMajorVersion();
-	}
-	
-	public int getMinorVersion() {
-		return Monitor.getMonitor().getEngineVersion().getMinorVersion();
-	}
-
-	public boolean jdbcCompliant() {
-		return false;
-	}
-
-	/*
-	** URL manipulation
-	*/
-
-	/**
-		Convert all the attributes in the url into properties and
-		combine them with the set provided. 
-		<BR>
-		If the caller passed in a set of attributes (info != null)
-		then we set that up as the default of the returned property
-		set as the user's set. This means we can easily break the link
-		with the user's set, ensuring that we don't hang onto the users object.
-		It also means that we don't add our attributes into the user's
-		own property object.
-
-		@exception SQLException thrown if URL form bad
-	*/
-	protected FormatableProperties getAttributes(String url, Properties info) 
-		throws SQLException {
-
-		// We use FormatableProperties here to take advantage
-		// of the clearDefaults, method.
-		FormatableProperties finfo = new FormatableProperties(info);
-		info = null; // ensure we don't use this reference directly again.
-
-
-		StringTokenizer st = new StringTokenizer(url, ";");
-		st.nextToken(); // skip the first part of the url
-
-		while (st.hasMoreTokens()) {
-
-			String v = st.nextToken();
-
-			int eqPos = v.indexOf('=');
-			if (eqPos == -1)
-				throw Util.generateCsSQLException(
-                                            SQLState.MALFORMED_URL, url);
-
-			//if (eqPos != v.lastIndexOf('='))
-			//	throw Util.malformedURL(url);
-
-			finfo.put((v.substring(0, eqPos)).trim(),
-					 (v.substring(eqPos + 1)).trim()
-					);
-		}
-
-		// now validate any attributes we can
-		//
-		// Boolean attributes -
-		//  dataEncryption,create,createSource,convertToSource,shutdown,upgrade,current
-
-
-		checkBoolean(finfo, Attribute.DATA_ENCRYPTION);
-		checkBoolean(finfo, Attribute.CREATE_ATTR);
-		checkBoolean(finfo, Attribute.SHUTDOWN_ATTR);
-		checkBoolean(finfo, Attribute.UPGRADE_ATTR);
-
-		return finfo;
-	}
-
-	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(java.util.Locale.ENGLISH).equals( choices[i].toUpperCase(java.util.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 Util.generateCsSQLException(
-                SQLState.INVALID_ATTRIBUTE, attribute, value, choicesStr + "}");
-	}
-
-
-	/**
-		Get the database name from the url.
-		Copes with three forms
-
-		jdbc:derby:dbname
-		jdbc:derby:dbname;...
-		jdbc:derby:;subname=dbname
-
-		@param url The url being used for the connection
-		@param info The properties set being used for the connection, must include
-		the properties derived from the attributes in the url
-
-		@return a String containing the database name or an empty string ("") if
-		no database name is present in the URL.
-	*/
-	public static String getDatabaseName(String url, Properties info) {
-
-		if (url.equals(Attribute.SQLJ_NESTED))
-		{
-			return "";
-		}	
-		
-		// skip the jdbc:derby:
-		int attributeStart = url.indexOf(';');
-		String dbname;
-		if (attributeStart == -1)
-			dbname = url.substring(Attribute.PROTOCOL.length());
-		else
-			dbname = url.substring(Attribute.PROTOCOL.length(), attributeStart);
-
-		// For security reasons we rely on here an non-null string being
-		// taken as the database name, before the databaseName connection
-		// attribute. Specifically, even if dbname is blank we still we
-		// to use it rather than the connection attribute, even though
-		// it will end up, after the trim, as a zero-length string.
-		// See EmbeddedDataSource.update()
-
-		if (dbname.length() == 0) {
-		    if (info != null)
-				dbname = info.getProperty(Attribute.DBNAME_ATTR, dbname);
-		}
-		// Beetle 4653 - trim database name to remove blanks that might make a difference on finding the database
-		// on unix platforms
-		dbname = dbname.trim();
-
-		return dbname;
-	}
-
-	public final ContextService getContextServiceFactory() {
-		return contextServiceFactory;
-	}
-
-	// returns the authenticationService handle
-	public AuthenticationService getAuthenticationService() {
-		//
-		// If authenticationService handle not cached in yet, then
-		// ask the monitor to find it for us and set it here in its
-		// attribute.
-		//
-		if (this.authenticationService == null) {
-			this.authenticationService = (AuthenticationService)
-				Monitor.findService(AuthenticationService.MODULE,
-									"authentication"
-								   );
-		}
-
-		// We should have a Authentication Service (always)
-		//
-		if (SanityManager.DEBUG)
-		{
-			SanityManager.ASSERT(this.authenticationService != null, 
-				"Unexpected - There is no valid authentication service!");
-		}
-		return this.authenticationService;
 	}
 
 	/*
@@ -399,39 +57,6 @@
 //		return new EmbedConnection(this, url, info);
 //	}
 
-	private ConnectionContext getConnectionContext() {
-
-		/*
-		** The current connection is the one in the current
-		** connection context, so get the context.
-		*/
-		ContextManager	cm = getCurrentContextManager();
-
-		ConnectionContext localCC = null;
-
-		/*
-			cm is null the very first time, and whenever
-			we aren't actually nested.
-		 */
-		if (cm != null) {
-			localCC = (ConnectionContext)
-				(cm.getContext(ConnectionContext.CONTEXT_ID));
-		}
-
-		return localCC;
-	}
-
-	private ContextManager getCurrentContextManager() {
-		return getContextServiceFactory().getCurrentContextManager();
-	}
-
-
-	/**
-		Return true if this driver is active. Package private method.
-	*/
-	public boolean isActive() {
-		return active;
-	}
 
 	/**
  	 * Get a new nested connection.
@@ -491,14 +116,7 @@
 //		return new EmbedCallableStatement(conn,stmt, resultSetType,
 //		resultSetConcurrency, resultSetHoldability);
 //	}
-	/**
-	 	@exception StandardException if fails to create metadata
-	 	@exception SQLException on SPS property error
-	 */
-	public DatabaseMetaData newEmbedDatabaseMetaData(EmbedConnection conn,
-		String dbname) throws SQLException {
-		return new EmbedDatabaseMetaData(conn,dbname);
-	}
+
 
 	public abstract EmbedResultSet
 		newEmbedResultSet(EmbedConnection conn, ResultSet results, boolean forMetaData, EmbedStatement statement, boolean isAtomic) throws SQLException;

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver20.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver20.java?view=diff&r1=152943&r2=152944
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver20.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver20.java Tue Feb  8 13:57:55 2005
@@ -53,7 +53,7 @@
 	methods and sql types.
 */
 
-public class Driver20 extends Driver169 implements Driver {
+public class Driver20 extends InternalDriver implements Driver {
 
 	private static final String[] BOOLEAN_CHOICES = {"false", "true"};
 
@@ -191,7 +191,7 @@
 
 		// at this point we have databaseName, 
 
-		String dbname = Driver169.getDatabaseName(url, info);
+		String dbname = InternalDriver.getDatabaseName(url, info);
 
 		// convert the ;name=value attributes in the URL into
 		// properties.

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedDataSource.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedDataSource.java?view=diff&r1=152943&r2=152944
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedDataSource.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedDataSource.java Tue Feb  8 13:57:55 2005
@@ -240,7 +240,7 @@
 
 	// Unlike a DataSource, LocalDriver is shared by all
 	// Cloudscape databases in the same jvm.
-	transient protected Driver169 driver;
+	transient protected InternalDriver driver;
 
 	transient private String jdbcurl;
 
@@ -475,7 +475,7 @@
         return conn;
 	}
    
-	Driver169 findDriver() throws SQLException
+	InternalDriver findDriver() throws SQLException
 	{
 		String url = jdbcurl;
 
@@ -493,7 +493,7 @@
 					// If we know the driver, we loaded it.   Otherwise only
 					// work if DriverManager has already loaded it.
 
-					driver = (Driver169) DriverManager.getDriver(url);
+					driver = (InternalDriver) DriverManager.getDriver(url);
 					// DriverManager will throw an exception if it cannot find the driver
 				}
 			}
@@ -522,7 +522,7 @@
 			// connection attributes.
 
 			// this space will selected as the database name (and trimmed to an empty string)
-			// See the getDatabaseName() code in Driver169. Since this is a non-null
+			// See the getDatabaseName() code in InternalDriver. Since this is a non-null
 			// value, it will be selected over any databaseName connection attribute.
 			dbName = " ";
 		}

Added: incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/InternalDriver.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/InternalDriver.java?view=auto&rev=152944
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/InternalDriver.java (added)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/jdbc/InternalDriver.java Tue Feb  8 13:57:55 2005
@@ -0,0 +1,498 @@
+/*
+
+   Derby - Class org.apache.derby.jdbc.InternalDriver
+
+   Copyright 1997, 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.jdbc;
+
+import org.apache.derby.iapi.reference.Attribute;
+import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.reference.MessageId;
+import org.apache.derby.iapi.services.io.FormatableProperties;
+
+import org.apache.derby.iapi.jdbc.ConnectionContext;
+
+import org.apache.derby.iapi.services.monitor.ModuleControl;
+import org.apache.derby.iapi.services.monitor.Monitor;
+import org.apache.derby.iapi.services.context.ContextService;
+import org.apache.derby.iapi.services.context.ContextManager;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.i18n.MessageService;
+
+import org.apache.derby.iapi.sql.ResultSet;
+
+import org.apache.derby.iapi.jdbc.AuthenticationService;
+
+import org.apache.derby.impl.jdbc.*;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+
+/**
+	Abstract factory class and api for JDBC objects.
+	@author djd
+*/
+
+public abstract class InternalDriver implements ModuleControl {
+
+	private static final Object syncMe = new Object();
+	private static InternalDriver activeDriver;
+
+	protected boolean active;
+	private ContextService contextServiceFactory;
+	private AuthenticationService	authenticationService;
+
+	public static final InternalDriver activeDriver()
+	{
+		return activeDriver;
+	}
+
+	public InternalDriver() {
+		contextServiceFactory = ContextService.getFactory();
+	}
+
+	/*
+	**	Methods from ModuleControl
+	*/
+
+	public void boot(boolean create, Properties properties) throws StandardException {
+
+		synchronized (InternalDriver.syncMe)
+		{
+			InternalDriver.activeDriver = this;
+		}
+
+		active = true;
+	}
+
+	public void stop() {
+
+		synchronized (InternalDriver.syncMe)
+		{
+			InternalDriver.activeDriver = null;
+		}
+
+		active = false;
+
+		contextServiceFactory = null;
+	}
+
+	/*
+	** Methods from java.sql.Driver
+	*/
+	public boolean acceptsURL(String url) {
+		return active && (url.startsWith(Attribute.PROTOCOL) || url.equals(Attribute.SQLJ_NESTED));
+	}
+
+	public Connection connect(String url, Properties info)
+		 throws SQLException 
+	{
+		if (!acceptsURL(url)) { return null; }
+
+			
+		/*
+		** A url "jdbc:default:connection" means get the current
+		** connection.  From within a method called from JSQL, the
+		** "current" connection is the one that is running the
+		** JSQL statement containing the method call.
+		*/
+		boolean current = url.equals(Attribute.SQLJ_NESTED);
+		
+		/* If jdbc:default:connection, see if user already has a
+		 * connection. All connection attributes are ignored.
+		 */
+		if (current) {
+
+			ConnectionContext connContext = getConnectionContext();
+
+			if (connContext != null) {
+						
+				return connContext.getNestedConnection(false);
+				
+			}
+			// there is no cloudscape connection, so
+			// return null, as we are not the driver to handle this
+			return null;
+		}
+
+		// convert the ;name=value attributes in the URL into
+		// properties.
+		FormatableProperties finfo = getAttributes(url, info);
+		info = null; // ensure we don't use this reference directly again.
+		try {
+
+			/*
+			** A property "shutdown=true" means shut the system or database down
+			*/
+			boolean shutdown = Boolean.valueOf(finfo.getProperty(Attribute.SHUTDOWN_ATTR)).booleanValue();
+			
+			if (shutdown) {
+				
+				// If we are shutting down the system don't attempt to create
+				// a connection; but we validate users credentials if we have to.
+				// In case of datbase shutdown, we ask the database authentication
+				// service to authenticate the user. If it is a system shutdown,
+				// then we ask the Driver to do the authentication.
+				//
+				if (InternalDriver.getDatabaseName(url, finfo).length() == 0) {
+					//
+					// We need to authenticate the user if authentication is
+					// ON. Note that this is a system shutdown.
+					// check that we do have a authentication service
+					// it is _always_ expected.
+					if (this.getAuthenticationService() == null)
+						throw Util.generateCsSQLException(
+                        SQLState.LOGIN_FAILED, 
+						MessageService.getTextMessage(MessageId.AUTH_NO_SERVICE_FOR_SYSTEM));
+					
+						
+					if (!this.getAuthenticationService().authenticate((String) null, finfo)) {
+
+						// not a valid user
+						throw Util.generateCsSQLException(
+                                  SQLState.LOGIN_FAILED, MessageService.getTextMessage(MessageId.AUTH_INVALID));
+					}
+
+					Monitor.getMonitor().shutdown();
+					throw Util.generateCsSQLException(
+                                         SQLState.CLOUDSCAPE_SYSTEM_SHUTDOWN);
+				}
+			}
+			
+			EmbedConnection conn = getNewEmbedConnection(url, finfo);
+
+			// if this is not the correct driver a EmbedConnection
+			// object is returned in the closed state.
+			if (conn.isClosed()) {
+				return null;
+			}
+
+			return conn;
+		}
+		finally {
+			// break any link with the user's Properties set.
+			finfo.clearDefaults();
+		}
+	}
+
+	public int getMajorVersion() {
+		return Monitor.getMonitor().getEngineVersion().getMajorVersion();
+	}
+	
+	public int getMinorVersion() {
+		return Monitor.getMonitor().getEngineVersion().getMinorVersion();
+	}
+
+	public boolean jdbcCompliant() {
+		return false;
+	}
+
+	/*
+	** URL manipulation
+	*/
+
+	/**
+		Convert all the attributes in the url into properties and
+		combine them with the set provided. 
+		<BR>
+		If the caller passed in a set of attributes (info != null)
+		then we set that up as the default of the returned property
+		set as the user's set. This means we can easily break the link
+		with the user's set, ensuring that we don't hang onto the users object.
+		It also means that we don't add our attributes into the user's
+		own property object.
+
+		@exception SQLException thrown if URL form bad
+	*/
+	protected FormatableProperties getAttributes(String url, Properties info) 
+		throws SQLException {
+
+		// We use FormatableProperties here to take advantage
+		// of the clearDefaults, method.
+		FormatableProperties finfo = new FormatableProperties(info);
+		info = null; // ensure we don't use this reference directly again.
+
+
+		StringTokenizer st = new StringTokenizer(url, ";");
+		st.nextToken(); // skip the first part of the url
+
+		while (st.hasMoreTokens()) {
+
+			String v = st.nextToken();
+
+			int eqPos = v.indexOf('=');
+			if (eqPos == -1)
+				throw Util.generateCsSQLException(
+                                            SQLState.MALFORMED_URL, url);
+
+			//if (eqPos != v.lastIndexOf('='))
+			//	throw Util.malformedURL(url);
+
+			finfo.put((v.substring(0, eqPos)).trim(),
+					 (v.substring(eqPos + 1)).trim()
+					);
+		}
+
+		// now validate any attributes we can
+		//
+		// Boolean attributes -
+		//  dataEncryption,create,createSource,convertToSource,shutdown,upgrade,current
+
+
+		checkBoolean(finfo, Attribute.DATA_ENCRYPTION);
+		checkBoolean(finfo, Attribute.CREATE_ATTR);
+		checkBoolean(finfo, Attribute.SHUTDOWN_ATTR);
+		checkBoolean(finfo, Attribute.UPGRADE_ATTR);
+
+		return finfo;
+	}
+
+	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(java.util.Locale.ENGLISH).equals( choices[i].toUpperCase(java.util.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 Util.generateCsSQLException(
+                SQLState.INVALID_ATTRIBUTE, attribute, value, choicesStr + "}");
+	}
+
+
+	/**
+		Get the database name from the url.
+		Copes with three forms
+
+		jdbc:derby:dbname
+		jdbc:derby:dbname;...
+		jdbc:derby:;subname=dbname
+
+		@param url The url being used for the connection
+		@param info The properties set being used for the connection, must include
+		the properties derived from the attributes in the url
+
+		@return a String containing the database name or an empty string ("") if
+		no database name is present in the URL.
+	*/
+	public static String getDatabaseName(String url, Properties info) {
+
+		if (url.equals(Attribute.SQLJ_NESTED))
+		{
+			return "";
+		}	
+		
+		// skip the jdbc:derby:
+		int attributeStart = url.indexOf(';');
+		String dbname;
+		if (attributeStart == -1)
+			dbname = url.substring(Attribute.PROTOCOL.length());
+		else
+			dbname = url.substring(Attribute.PROTOCOL.length(), attributeStart);
+
+		// For security reasons we rely on here an non-null string being
+		// taken as the database name, before the databaseName connection
+		// attribute. Specifically, even if dbname is blank we still we
+		// to use it rather than the connection attribute, even though
+		// it will end up, after the trim, as a zero-length string.
+		// See EmbeddedDataSource.update()
+
+		if (dbname.length() == 0) {
+		    if (info != null)
+				dbname = info.getProperty(Attribute.DBNAME_ATTR, dbname);
+		}
+		// Beetle 4653 - trim database name to remove blanks that might make a difference on finding the database
+		// on unix platforms
+		dbname = dbname.trim();
+
+		return dbname;
+	}
+
+	public final ContextService getContextServiceFactory() {
+		return contextServiceFactory;
+	}
+
+	// returns the authenticationService handle
+	public AuthenticationService getAuthenticationService() {
+		//
+		// If authenticationService handle not cached in yet, then
+		// ask the monitor to find it for us and set it here in its
+		// attribute.
+		//
+		if (this.authenticationService == null) {
+			this.authenticationService = (AuthenticationService)
+				Monitor.findService(AuthenticationService.MODULE,
+									"authentication"
+								   );
+		}
+
+		// We should have a Authentication Service (always)
+		//
+		if (SanityManager.DEBUG)
+		{
+			SanityManager.ASSERT(this.authenticationService != null, 
+				"Unexpected - There is no valid authentication service!");
+		}
+		return this.authenticationService;
+	}
+
+	/*
+		Methods to be overloaded in sub-implementations such as
+		a tracing driver.
+	 */
+	protected abstract EmbedConnection getNewEmbedConnection(String url, Properties info) 
+		 throws SQLException ;
+
+
+	private ConnectionContext getConnectionContext() {
+
+		/*
+		** The current connection is the one in the current
+		** connection context, so get the context.
+		*/
+		ContextManager	cm = getCurrentContextManager();
+
+		ConnectionContext localCC = null;
+
+		/*
+			cm is null the very first time, and whenever
+			we aren't actually nested.
+		 */
+		if (cm != null) {
+			localCC = (ConnectionContext)
+				(cm.getContext(ConnectionContext.CONTEXT_ID));
+		}
+
+		return localCC;
+	}
+
+	private ContextManager getCurrentContextManager() {
+		return getContextServiceFactory().getCurrentContextManager();
+	}
+
+
+	/**
+		Return true if this driver is active. Package private method.
+	*/
+	public boolean isActive() {
+		return active;
+	}
+
+	/**
+ 	 * Get a new nested connection.
+	 *
+	 * @param conn	The EmbedConnection.
+	 *
+	 * @return A nested connection object.
+	 *
+	 */
+	public abstract Connection getNewNestedConnection(EmbedConnection conn);
+
+	/*
+	** methods to be overridden by subimplementations wishing to insert
+	** their classes into the mix.
+	*/
+
+	public java.sql.Statement newEmbedStatement(
+				EmbedConnection conn,
+				boolean forMetaData,
+				int resultSetType,
+				int resultSetConcurrency,
+				int resultSetHoldability)
+	{
+		return new EmbedStatement(conn, forMetaData, resultSetType, resultSetConcurrency,
+		resultSetHoldability);
+	}
+	/**
+	 	@exception SQLException if fails to create statement
+	 */
+	public abstract java.sql.PreparedStatement newEmbedPreparedStatement(
+				EmbedConnection conn,
+				String stmt, 
+				boolean forMetaData, 
+				int resultSetType,
+				int resultSetConcurrency,
+				int resultSetHoldability,
+				int autoGeneratedKeys,
+				int[] columnIndexes,
+				String[] columnNames)
+		throws SQLException;
+
+	/**
+	 	@exception SQLException if fails to create statement
+	 */
+	public abstract java.sql.CallableStatement newEmbedCallableStatement(
+				EmbedConnection conn,
+				String stmt, 
+				int resultSetType,
+				int resultSetConcurrency,
+				int resultSetHoldability)
+		throws SQLException;
+
+	/**
+	 * Return a new java.sql.DatabaseMetaData instance for this implementation.
+	 	@exception SQLException on failure to create.
+	 */
+	public DatabaseMetaData newEmbedDatabaseMetaData(EmbedConnection conn,
+		String dbname) throws SQLException {
+		return new EmbedDatabaseMetaData(conn,dbname);
+	}
+
+	/**
+	 * Return a new java.sql.ResultSet instance for this implementation.
+	 * @param conn Owning connection
+	 * @param results Top level of language result set tree
+	 * @param forMetaData Is this for meta-data
+	 * @param statement The statement that is creating the SQL ResultSet
+	 * @param isAtomic 
+	 * @return a new java.sql.ResultSet
+	 * @throws SQLException
+	 */
+	public abstract EmbedResultSet
+		newEmbedResultSet(EmbedConnection conn, ResultSet results, boolean forMetaData, EmbedStatement statement, boolean isAtomic) throws SQLException;
+}
+
+
+