--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.jdbc.EmbeddedSimpleDataSource\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.jdbc;\r
+\r
+import org.apache.derby.iapi.jdbc.JDBCBoot;\r
+import org.apache.derby.iapi.reference.Attribute;\r
+import org.apache.derby.iapi.reference.MessageId;\r
+\r
+import java.sql.Connection;\r
+import java.sql.SQLException;\r
+import java.sql.SQLFeatureNotSupportedException;\r
+import java.io.PrintWriter;\r
+import java.util.Properties;\r
+\r
+import java.util.logging.Logger;\r
+\r
+/* -- New jdbc 20 extension types --- */\r
+import javax.sql.DataSource;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.i18n.MessageService;\r
+import org.apache.derby.impl.jdbc.Util;\r
+\r
+/**\r
+ * \r
+ * \r
+ * EmbeddedSimpleDataSource is Derby's DataSource implementation\r
+ * for J2ME/CDC/Foundation. It is also supports J2SE platforms.\r
+ * \r
+ * \r
+ * Supports the same properties as EmbeddedDataSource, see that class for details.\r
+ * <P>\r
+ EmbeddedSimpleDataSource automatically supports the correct JDBC specification version\r
+ for the Java Virtual Machine's environment.\r
+ <UL>\r
+ <LI> JDBC Optional Package for CDC/Foundation Profile(JSR-169) - J2ME - CDC/Foundation\r
+ <LI> JDBC 3.0 - Java 2 - JDK 1.4, J2SE 5.0\r
+ </UL> \r
+ * @see EmbeddedDataSource\r
+ *\r
+ */\r
+public final class EmbeddedSimpleDataSource implements DataSource {\r
+\r
+ private String password;\r
+\r
+ private String user;\r
+\r
+ /**\r
+ * The database name.\r
+ * \r
+ * @serial\r
+ */\r
+ private String databaseName;\r
+\r
+ /**\r
+ * The data source name.\r
+ * \r
+ * @serial\r
+ */\r
+ private String dataSourceName;\r
+\r
+ /**\r
+ * Description of the database.\r
+ * \r
+ * @serial\r
+ */\r
+ private String description;\r
+\r
+ /**\r
+ * Set to "create" if the database should be created.\r
+ * \r
+ * @serial\r
+ */\r
+ private String createDatabase;\r
+\r
+ /**\r
+ * Set to "shutdown" if the database should be shutdown.\r
+ * \r
+ * @serial\r
+ */\r
+ private String shutdownDatabase;\r
+\r
+ /**\r
+ * Derby specific connection attributes.\r
+ * \r
+ * @serial\r
+ */\r
+ private String connectionAttributes;\r
+\r
+ /** instance variables that will not be serialized */\r
+ transient private PrintWriter printer;\r
+\r
+ transient private int loginTimeout;\r
+\r
+ // Unlike a DataSource, LocalDriver is shared by all\r
+ // Derby databases in the same jvm.\r
+ transient private InternalDriver driver;\r
+\r
+ transient private String jdbcurl;\r
+\r
+ /**\r
+ * No-arg constructor.\r
+ */\r
+ public EmbeddedSimpleDataSource() {\r
+ }\r
+\r
+ /*\r
+ * DataSource methods\r
+ */\r
+\r
+ /**\r
+ * Gets the maximum time in seconds that this data source can wait while\r
+ * attempting to connect to a database. A value of zero means that the\r
+ * timeout is the default system timeout if there is one; otherwise it means\r
+ * that there is no timeout. When a data source object is created, the login\r
+ * timeout is initially zero.\r
+ * \r
+ * @return the data source login time limit\r
+ * @exception SQLException\r
+ * if a database access error occurs.\r
+ */\r
+ public int getLoginTimeout() throws SQLException {\r
+ return loginTimeout;\r
+ }\r
+\r
+ /**\r
+ * Sets the maximum time in seconds that this data source will wait while\r
+ * attempting to connect to a database. A value of zero specifies that the\r
+ * timeout is the default system timeout if there is one; otherwise it\r
+ * specifies that there is no timeout. When a data source object is created,\r
+ * the login timeout is initially zero.\r
+ * <P>\r
+ * Derby ignores this property.\r
+ * \r
+ * @param seconds\r
+ * the data source login time limit\r
+ * @exception SQLException\r
+ * if a database access error occurs.\r
+ */\r
+ public void setLoginTimeout(int seconds) throws SQLException {\r
+ loginTimeout = seconds;\r
+ }\r
+\r
+ /**\r
+ * Get the log writer for this data source.\r
+ * \r
+ * <p>\r
+ * The log writer is a character output stream to which all logging and\r
+ * tracing messages for this data source object instance will be printed.\r
+ * This includes messages printed by the methods of this object, messages\r
+ * printed by methods of other objects manufactured by this object, and so\r
+ * on. Messages printed to a data source specific log writer are not printed\r
+ * to the log writer associated with the java.sql.Drivermanager class. When\r
+ * a data source object is created the log writer is initially null, in\r
+ * other words, logging is disabled.\r
+ * \r
+ * @return the log writer for this data source, null if disabled\r
+ * @exception SQLException\r
+ * if a database-access error occurs.\r
+ */\r
+ public PrintWriter getLogWriter() throws SQLException {\r
+ return printer;\r
+ }\r
+\r
+ /**\r
+ * Set the log writer for this data source.\r
+ * \r
+ * <p>\r
+ * The log writer is a character output stream to which all logging and\r
+ * tracing messages for this data source object instance will be printed.\r
+ * This includes messages printed by the methods of this object, messages\r
+ * printed by methods of other objects manufactured by this object, and so\r
+ * on. Messages printed to a data source specific log writer are not printed\r
+ * to the log writer associated with the java.sql.Drivermanager class. When\r
+ * a data source object is created the log writer is initially null, in\r
+ * other words, logging is disabled.\r
+ * \r
+ * @param out\r
+ * the new log writer; to disable, set to null\r
+ * @exception SQLException\r
+ * if a database-access error occurs.\r
+ */\r
+ public void setLogWriter(PrintWriter out) throws SQLException {\r
+ printer = out;\r
+ }\r
+\r
+ /*\r
+ * Properties to be seen by Bean - access thru reflection.\r
+ */\r
+ /**\r
+ * Set the database name. Setting this property is mandatory. If a database\r
+ * named wombat at g:/db needs to be accessed, database name should be set\r
+ * to "g:/db/wombat". The database will be booted if it is not already\r
+ * running in the system.\r
+ * \r
+ * @param databaseName\r
+ * the name of the database\r
+ */\r
+ public final synchronized void setDatabaseName(String databaseName) {\r
+ this.databaseName = databaseName;\r
+ update();\r
+ }\r
+\r
+ public String getDatabaseName() {\r
+ return databaseName;\r
+ }\r
+\r
+ /**\r
+ * Set the data source name. The property is not mandatory. It is used for\r
+ * informational purposes only.\r
+ * \r
+ * @param dsn\r
+ * the name of the data source\r
+ */\r
+ public final void setDataSourceName(String dsn) {\r
+ dataSourceName = dsn;\r
+ }\r
+\r
+ /** @return data source name */\r
+ public final String getDataSourceName() {\r
+ return dataSourceName;\r
+ }\r
+\r
+ /**\r
+ * Set the data source descripton. This property is not mandatory. It is\r
+ * used for informational purposes only.\r
+ * \r
+ * @param desc\r
+ * the description of the data source\r
+ */\r
+ public final void setDescription(String desc) {\r
+ description = desc;\r
+ }\r
+\r
+ /** @return description */\r
+ public final String getDescription() {\r
+ return description;\r
+ }\r
+\r
+ /**\r
+ * Set the <code>user</code> property for the data source. This is user\r
+ * name for any data source getConnection() call that takes no arguments.\r
+ */\r
+ public final void setUser(String user) {\r
+ this.user = user;\r
+ }\r
+\r
+ /** @return user */\r
+ public final String getUser() {\r
+ return user;\r
+ }\r
+\r
+ /**\r
+ * Set the <code>password</code> property for the data source. This is\r
+ * user's password for any data source getConnection() call that takes no\r
+ * arguments.\r
+ */\r
+ public final void setPassword(String password) {\r
+ this.password = password;\r
+ }\r
+\r
+ /** @return password */\r
+ public final String getPassword() {\r
+ return password;\r
+ }\r
+\r
+ /**\r
+ * Set this property to create a new database. If this property is not set,\r
+ * the database (identified by databaseName) is assumed to be already\r
+ * existing.\r
+ * \r
+ * @param create\r
+ * if set to the string "create", this data source will try to\r
+ * create a new database of databaseName, or boot the database if\r
+ * one by that name already exists.\r
+ */\r
+ public final void setCreateDatabase(String create) {\r
+ if (create != null\r
+ && create.toLowerCase(java.util.Locale.ENGLISH)\r
+ .equals("create"))\r
+ createDatabase = create;\r
+ else\r
+ createDatabase = null;\r
+ }\r
+\r
+ /** @return "create" if create is set, or null if not */\r
+ public final String getCreateDatabase() {\r
+ return createDatabase;\r
+ }\r
+\r
+ /**\r
+ * Set this property if one wishes to shutdown the database identified by\r
+ * databaseName.\r
+ * \r
+ * @param shutdown\r
+ * if set to the string "shutdown", this data source will\r
+ * shutdown the database if it is running.\r
+ */\r
+ public final void setShutdownDatabase(String shutdown) {\r
+ if (shutdown != null && shutdown.equalsIgnoreCase("shutdown"))\r
+ shutdownDatabase = shutdown;\r
+ else\r
+ shutdownDatabase = null;\r
+ }\r
+\r
+ /** @return "shutdown" if shutdown is set, or null if not */\r
+ public final String getShutdownDatabase() {\r
+ return shutdownDatabase;\r
+ }\r
+\r
+ /**\r
+ * Set this property to pass in more Derby specific connection URL\r
+ * attributes.\r
+ <BR>\r
+ Any attributes that can be set using a property of this DataSource implementation\r
+ (e.g user, password) should not be set in connectionAttributes. Conflicting\r
+ settings in connectionAttributes and properties of the DataSource will lead to\r
+ unexpected behaviour. \r
+ * \r
+ * @param prop\r
+ * set to the list of Derby connection attributes separated\r
+ * by semi-colons. E.g., to specify an encryption bootPassword of\r
+ * "x8hhk2adf", and set upgrade to true, do the following:\r
+ * \r
+ * <PRE>\r
+ * \r
+ * ds.setConnectionAttributes("bootPassword=x8hhk2adf;upgrade=true");\r
+ * \r
+ * </PRE>\r
+ * \r
+ * See Derby's documentation for complete list.\r
+ */\r
+ public final void setConnectionAttributes(String prop) {\r
+ connectionAttributes = prop;\r
+ update();\r
+ }\r
+\r
+ /** @return Derby specific connection URL attributes */\r
+ public final String getConnectionAttributes() {\r
+ return connectionAttributes;\r
+ }\r
+\r
+ /*\r
+ * DataSource methods\r
+ */\r
+\r
+ /**\r
+ * Attempt to establish a database connection.\r
+ * \r
+ * @return a Connection to the database\r
+ * @exception SQLException\r
+ * if a database-access error occurs.\r
+ */\r
+ public final Connection getConnection() throws SQLException {\r
+ return this.getConnection(getUser(), getPassword());\r
+ }\r
+\r
+ /**\r
+ * Attempt to establish a database connection with the given username and\r
+ * password. If the attributeAsPassword property is set to true then the\r
+ * password argument is taken to be a list of connection attributes with the\r
+ * same format as the connectionAttributes property.\r
+ * \r
+ * \r
+ * @param username\r
+ * the database user on whose behalf the Connection is being made\r
+ * @param password\r
+ * the user's password\r
+ * @return a Connection to the database\r
+ * @exception SQLException\r
+ * if a database-access error occurs.\r
+ */\r
+ public final Connection getConnection(String username, String password)\r
+ throws SQLException {\r
+\r
+ Properties info = new Properties();\r
+ if (username != null)\r
+ info.put(Attribute.USERNAME_ATTR, username);\r
+\r
+ if (password != null)\r
+ info.put(Attribute.PASSWORD_ATTR, password);\r
+\r
+ if (createDatabase != null)\r
+ info.put(Attribute.CREATE_ATTR, "true");\r
+ if (shutdownDatabase != null)\r
+ info.put(Attribute.SHUTDOWN_ATTR, "true");\r
+\r
+ Connection conn = findDriver().connect(jdbcurl, info);\r
+\r
+ // JDBC driver's getConnection method returns null if\r
+ // the driver does not handle the request's URL.\r
+ if (conn == null)\r
+ throw Util.generateCsSQLException(SQLState.PROPERTY_INVALID_VALUE,\r
+ Attribute.DBNAME_ATTR, getDatabaseName());\r
+\r
+ return conn;\r
+ }\r
+\r
+ private InternalDriver findDriver() throws SQLException {\r
+ String url = jdbcurl;\r
+\r
+ if (driver == null || !driver.acceptsURL(url)) {\r
+ synchronized (this) {\r
+ // The driver has either never been booted, or it has been\r
+ // shutdown by a 'jdbc:derby:;shutdown=true'\r
+ if (driver == null || !driver.acceptsURL(url)) {\r
+ \r
+ \r
+ new JDBCBoot().boot(Attribute.PROTOCOL, System.err);\r
+ \r
+ // If we know the driver, we loaded it. Otherwise only\r
+ // work if DriverManager has already loaded it.\r
+\r
+ driver = InternalDriver.activeDriver();\r
+ \r
+ if (driver == null)\r
+ throw new SQLException(MessageService.getTextMessage(MessageId.CORE_JDBC_DRIVER_UNREGISTERED));\r
+ }\r
+ }\r
+ }\r
+ return driver;\r
+ // else driver != null and driver can accept url\r
+ }\r
+\r
+ private void update() {\r
+ StringBuffer sb = new StringBuffer(64);\r
+\r
+ sb.append(Attribute.PROTOCOL);\r
+\r
+ // Set the database name from the databaseName property\r
+ String dbName = getDatabaseName();\r
+\r
+ if (dbName != null) {\r
+ dbName = dbName.trim();\r
+ }\r
+\r
+ if (dbName == null || dbName.length() == 0) {\r
+ // need to put something in so that we do not allow the\r
+ // database name to be set from the request or from the\r
+ // connection attributes.\r
+\r
+ // this space will selected as the database name (and trimmed to an\r
+ // empty string)\r
+ // See the getDatabaseName() code in InternalDriver. Since this is a\r
+ // non-null\r
+ // value, it will be selected over any databaseName connection\r
+ // attribute.\r
+ dbName = " ";\r
+ }\r
+\r
+ sb.append(dbName);\r
+\r
+ String connAttrs = getConnectionAttributes();\r
+ if (connAttrs != null) {\r
+ connAttrs = connAttrs.trim();\r
+ if (connAttrs.length() != 0) {\r
+ sb.append(';');\r
+ sb.append(connectionAttributes);\r
+ }\r
+ }\r
+\r
+ jdbcurl = sb.toString();\r
+ }\r
+\r
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {\r
+ // TODO Auto-generated method stub\r
+ return false;\r
+ }\r
+\r
+ public <T> T unwrap(Class<T> iface) throws SQLException {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+}\r
+\r