001: /*
002:
003: Derby - Class org.apache.derby.client.ClientDataSource
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.jdbc;
023:
024: import java.sql.Connection;
025: import java.sql.SQLException;
026: import javax.sql.DataSource;
027:
028: import org.apache.derby.client.am.LogWriter;
029: import org.apache.derby.client.am.SqlException;
030: import org.apache.derby.client.net.NetConnection;
031: import org.apache.derby.client.net.NetLogWriter;
032:
033: /**
034: * ClientDataSource is a simple data source implementation
035: * that can be used for establishing connections in a
036: * non-pooling, non-distributed environment.
037: * The class ClientConnectionPoolDataSource can be used in a connection pooling environment,
038: * and the class ClientXADataSource can be used in a distributed, and pooling
039: * environment. Use these DataSources if your application runs under
040: * JDBC3.0 or JDBC2.0, that is, on the following Java Virtual Machines:
041: * <p/>
042: * <UL>
043: * <LI> JDBC 3.0 - Java 2 - JDK 1.4, J2SE 5.0
044: * <LI> JDBC 2.0 - Java 2 - JDK 1.2,1.3
045: * </UL>
046: *
047: * <p>The example below registers a DNC data source object with a JNDI naming service.
048: * <pre>
049: * org.apache.derby.client.ClientDataSource dataSource = new org.apache.derby.client.ClientDataSource ();
050: * dataSource.setServerName ("my_derby_database_server");
051: * dataSource.setDatabaseName ("my_derby_database_name");
052: * javax.naming.Context context = new javax.naming.InitialContext();
053: * context.bind ("jdbc/my_datasource_name", dataSource);
054: * </pre>
055: * The first line of code in the example creates a data source object.
056: * The next two lines initialize the data source's
057: * properties. Then a Java object that references the initial JNDI naming
058: * context is created by calling the
059: * InitialContext() constructor, which is provided by JNDI.
060: * System properties (not shown) are used to tell JNDI the
061: * service provider to use. The JNDI name space is hierarchical,
062: * similar to the directory structure of many file
063: * systems. The data source object is bound to a logical JNDI name
064: * by calling Context.bind(). In this case the JNDI name
065: * identifies a subcontext, "jdbc", of the root naming context
066: * and a logical name, "my_datasource_name", within the jdbc
067: * subcontext. This is all of the code required to deploy
068: * a data source object within JNDI. This example is provided
069: * mainly for illustrative purposes. We expect that developers
070: * or system administrators will normally use a GUI tool to
071: * deploy a data source object.
072: * <p/>
073: * Once a data source has been registered with JNDI,
074: * it can then be used by a JDBC application, as is shown in the
075: * following example.
076: * <pre>
077: * javax.naming.Context context = new javax.naming.InitialContext ();
078: * javax.sql.DataSource dataSource = (javax.sql.DataSource) context.lookup ("jdbc/my_datasource_name");
079: * java.sql.Connection connection = dataSource.getConnection ("user", "password");
080: * </pre>
081: * The first line in the example creates a Java object
082: * that references the initial JNDI naming context. Next, the
083: * initial naming context is used to do a lookup operation
084: * using the logical name of the data source. The
085: * Context.lookup() method returns a reference to a Java Object,
086: * which is narrowed to a javax.sql.DataSource object. In
087: * the last line, the DataSource.getConnection() method
088: * is called to produce a database connection.
089: * <p/>
090: * This simple data source subclass of ClientBaseDataSource maintains
091: * it's own private <code>password</code> property.
092: * <p/>
093: * The specified password, along with the user, is validated by DERBY.
094: * This property can be overwritten by specifing
095: * the password parameter on the DataSource.getConnection() method call.
096: * <p/>
097: * This password property is not declared transient, and therefore
098: * may be serialized to a file in clear-text, or stored
099: * to a JNDI server in clear-text when the data source is saved.
100: * Care must taken by the user to prevent security
101: * breaches.
102: * <p/>
103: */
104: public class ClientDataSource extends ClientBaseDataSource implements
105: DataSource {
106: private final static long serialVersionUID = 1894299584216955553L;
107: public static final String className__ = "org.apache.derby.jdbc.ClientDataSource";
108:
109: // If a newer version of a serialized object has to be compatible with an older version, it is important that the newer version abides
110: // by the rules for compatible and incompatible changes.
111: //
112: // A compatible change is one that can be made to a new version of the class, which still keeps the stream compatible with older
113: // versions of the class. Examples of compatible changes are:
114: //
115: // Addition of new fields or classes does not affect serialization, as any new data in the stream is simply ignored by older
116: // versions. When the instance of an older version of the class is deserialized, the newly added field will be set to its default
117: // value.
118: // You can field change access modifiers like private, public, protected or package as they are not reflected to the serial
119: // stream.
120: // You can change a transient or static field to a non-transient or non-static field, as it is similar to adding a field.
121: // You can change the access modifiers for constructors and methods of the class. For instance a previously private method
122: // can now be made public, an instance method can be changed to static, etc. The only exception is that you cannot change
123: // the default signatures for readObject() and writeObject() if you are implementing custom serialization. The serialization
124: // process looks at only instance data, and not the methods of a class.
125: //
126: // Changes which would render the stream incompatible are:
127: //
128: // Once a class implements the Serializable interface, you cannot later make it implement the Externalizable interface, since
129: // this will result in the creation of an incompatible stream.
130: // Deleting fields can cause a problem. Now, when the object is serialized, an earlier version of the class would set the old
131: // field to its default value since nothing was available within the stream. Consequently, this default data may lead the newly
132: // created object to assume an invalid state.
133: // Changing a non-static into static or non-transient into transient is not permitted as it is equivalent to deleting fields.
134: // You also cannot change the field types within a class, as this would cause a failure when attempting to read in the original
135: // field into the new field.
136: // You cannot alter the position of the class in the class hierarchy. Since the fully-qualified class name is written as part of
137: // the bytestream, this change will result in the creation of an incompatible stream.
138: // You cannot change the name of the class or the package it belongs to, as that information is written to the stream during
139: // serialization.
140:
141: /**
142: * Creates a simple DERBY data source with default property values for a non-pooling, non-distributed environment.
143: * No particular DatabaseName or other properties are associated with the data source.
144: * <p/>
145: * Every Java Bean should provide a constructor with no arguments since many beanboxes attempt to instantiate a bean
146: * by invoking its no-argument constructor.
147: */
148: public ClientDataSource() {
149: super ();
150: }
151:
152: // ---------------------------interface methods-------------------------------
153:
154: /**
155: * Attempt to establish a database connection in a non-pooling, non-distributed environment.
156: *
157: * @return a Connection to the database
158: *
159: * @throws java.sql.SQLException if a database-access error occurs.
160: */
161: public Connection getConnection() throws SQLException {
162: return getConnection(getUser(), getPassword());
163: }
164:
165: /**
166: * Attempt to establish a database connection in a non-pooling, non-distributed environment.
167: *
168: * @param user the database user on whose behalf the Connection is being made
169: * @param password the user's password
170: *
171: * @return a Connection to the database
172: *
173: * @throws java.sql.SQLException if a database-access error occurs.
174: */
175: public Connection getConnection(String user, String password)
176: throws SQLException {
177: // Jdbc 2 connections will write driver trace info on a
178: // datasource-wide basis using the jdbc 2 data source log writer.
179: // This log writer may be narrowed to the connection-level
180: // This log writer will be passed to the agent constructor.
181:
182: try {
183: LogWriter dncLogWriter = super
184: .computeDncLogWriterForNewConnection("_sds");
185: updateDataSourceValues(tokenizeAttributes(
186: getConnectionAttributes(), null));
187: return ClientDriver.getFactory().newNetConnection(
188: (NetLogWriter) dncLogWriter, user, password, this ,
189: -1, false);
190: } catch (SqlException se) {
191: throw se.getSQLException();
192: }
193:
194: }
195:
196: }
|