1 | /* |
2 | |
3 | Derby - Class org.apache.derby.client.ClientDataSource |
4 | |
5 | Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.jdbc; |
22 | |
23 | import java.sql.Connection; |
24 | import java.sql.SQLException; |
25 | import javax.sql.DataSource; |
26 | |
27 | import org.apache.derby.client.am.LogWriter; |
28 | import org.apache.derby.client.am.SqlException; |
29 | import org.apache.derby.client.net.NetConnection; |
30 | import org.apache.derby.client.net.NetLogWriter; |
31 | |
32 | /** |
33 | * ClientDataSource is a simple data source implementation |
34 | * that can be used for establishing connections in a |
35 | * non-pooling, non-distributed environment. |
36 | * The class ClientConnectionPoolDataSource can be used in a connection pooling environment, |
37 | * and the class ClientXADataSource can be used in a distributed, and pooling |
38 | * environment. Use these DataSources if your application runs under |
39 | * JDBC3.0 or JDBC2.0, that is, on the following Java Virtual Machines: |
40 | * <p/> |
41 | * <UL> |
42 | * <LI> JDBC 3.0 - Java 2 - JDK 1.4, J2SE 5.0 |
43 | * <LI> JDBC 2.0 - Java 2 - JDK 1.2,1.3 |
44 | * </UL> |
45 | * |
46 | * <p>The example below registers a DNC data source object with a JNDI naming service. |
47 | * <pre> |
48 | * org.apache.derby.client.ClientDataSource dataSource = new org.apache.derby.client.ClientDataSource (); |
49 | * dataSource.setServerName ("my_derby_database_server"); |
50 | * dataSource.setDatabaseName ("my_derby_database_name"); |
51 | * javax.naming.Context context = new javax.naming.InitialContext(); |
52 | * context.bind ("jdbc/my_datasource_name", dataSource); |
53 | * </pre> |
54 | * The first line of code in the example creates a data source object. |
55 | * The next two lines initialize the data source's |
56 | * properties. Then a Java object that references the initial JNDI naming |
57 | * context is created by calling the |
58 | * InitialContext() constructor, which is provided by JNDI. |
59 | * System properties (not shown) are used to tell JNDI the |
60 | * service provider to use. The JNDI name space is hierarchical, |
61 | * similar to the directory structure of many file |
62 | * systems. The data source object is bound to a logical JNDI name |
63 | * by calling Context.bind(). In this case the JNDI name |
64 | * identifies a subcontext, "jdbc", of the root naming context |
65 | * and a logical name, "my_datasource_name", within the jdbc |
66 | * subcontext. This is all of the code required to deploy |
67 | * a data source object within JNDI. This example is provided |
68 | * mainly for illustrative purposes. We expect that developers |
69 | * or system administrators will normally use a GUI tool to |
70 | * deploy a data source object. |
71 | * <p/> |
72 | * Once a data source has been registered with JNDI, |
73 | * it can then be used by a JDBC application, as is shown in the |
74 | * following example. |
75 | * <pre> |
76 | * javax.naming.Context context = new javax.naming.InitialContext (); |
77 | * javax.sql.DataSource dataSource = (javax.sql.DataSource) context.lookup ("jdbc/my_datasource_name"); |
78 | * java.sql.Connection connection = dataSource.getConnection ("user", "password"); |
79 | * </pre> |
80 | * The first line in the example creates a Java object |
81 | * that references the initial JNDI naming context. Next, the |
82 | * initial naming context is used to do a lookup operation |
83 | * using the logical name of the data source. The |
84 | * Context.lookup() method returns a reference to a Java Object, |
85 | * which is narrowed to a javax.sql.DataSource object. In |
86 | * the last line, the DataSource.getConnection() method |
87 | * is called to produce a database connection. |
88 | * <p/> |
89 | * This simple data source subclass of ClientBaseDataSource maintains |
90 | * it's own private <code>password</code> property. |
91 | * <p/> |
92 | * The specified password, along with the user, is validated by DERBY. |
93 | * This property can be overwritten by specifing |
94 | * the password parameter on the DataSource.getConnection() method call. |
95 | * <p/> |
96 | * This password property is not declared transient, and therefore |
97 | * may be serialized to a file in clear-text, or stored |
98 | * to a JNDI server in clear-text when the data source is saved. |
99 | * Care must taken by the user to prevent security |
100 | * breaches. |
101 | * <p/> |
102 | */ |
103 | public class ClientDataSource extends ClientBaseDataSource implements DataSource { |
104 | private final static long serialVersionUID = 1894299584216955553L; |
105 | public static final String className__ = "org.apache.derby.jdbc.ClientDataSource"; |
106 | |
107 | // If a newer version of a serialized object has to be compatible with an older version, it is important that the newer version abides |
108 | // by the rules for compatible and incompatible changes. |
109 | // |
110 | // A compatible change is one that can be made to a new version of the class, which still keeps the stream compatible with older |
111 | // versions of the class. Examples of compatible changes are: |
112 | // |
113 | // Addition of new fields or classes does not affect serialization, as any new data in the stream is simply ignored by older |
114 | // versions. When the instance of an older version of the class is deserialized, the newly added field will be set to its default |
115 | // value. |
116 | // You can field change access modifiers like private, public, protected or package as they are not reflected to the serial |
117 | // stream. |
118 | // You can change a transient or static field to a non-transient or non-static field, as it is similar to adding a field. |
119 | // You can change the access modifiers for constructors and methods of the class. For instance a previously private method |
120 | // can now be made public, an instance method can be changed to static, etc. The only exception is that you cannot change |
121 | // the default signatures for readObject() and writeObject() if you are implementing custom serialization. The serialization |
122 | // process looks at only instance data, and not the methods of a class. |
123 | // |
124 | // Changes which would render the stream incompatible are: |
125 | // |
126 | // Once a class implements the Serializable interface, you cannot later make it implement the Externalizable interface, since |
127 | // this will result in the creation of an incompatible stream. |
128 | // Deleting fields can cause a problem. Now, when the object is serialized, an earlier version of the class would set the old |
129 | // field to its default value since nothing was available within the stream. Consequently, this default data may lead the newly |
130 | // created object to assume an invalid state. |
131 | // Changing a non-static into static or non-transient into transient is not permitted as it is equivalent to deleting fields. |
132 | // You also cannot change the field types within a class, as this would cause a failure when attempting to read in the original |
133 | // field into the new field. |
134 | // You cannot alter the position of the class in the class hierarchy. Since the fully-qualified class name is written as part of |
135 | // the bytestream, this change will result in the creation of an incompatible stream. |
136 | // You cannot change the name of the class or the package it belongs to, as that information is written to the stream during |
137 | // serialization. |
138 | |
139 | |
140 | /** |
141 | * Creates a simple DERBY data source with default property values for a non-pooling, non-distributed environment. |
142 | * No particular DatabaseName or other properties are associated with the data source. |
143 | * <p/> |
144 | * Every Java Bean should provide a constructor with no arguments since many beanboxes attempt to instantiate a bean |
145 | * by invoking its no-argument constructor. |
146 | */ |
147 | public ClientDataSource() { |
148 | super(); |
149 | } |
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) throws SQLException { |
176 | // Jdbc 2 connections will write driver trace info on a |
177 | // datasource-wide basis using the jdbc 2 data source log writer. |
178 | // This log writer may be narrowed to the connection-level |
179 | // This log writer will be passed to the agent constructor. |
180 | |
181 | try |
182 | { |
183 | LogWriter dncLogWriter = super.computeDncLogWriterForNewConnection("_sds"); |
184 | updateDataSourceValues(tokenizeAttributes(getConnectionAttributes(), null)); |
185 | return ClientDriver.getFactory().newNetConnection |
186 | ((NetLogWriter) dncLogWriter, user, |
187 | password, this, -1, false); |
188 | } |
189 | catch(SqlException se) |
190 | { |
191 | throw se.getSQLException(); |
192 | } |
193 | |
194 | } |
195 | |
196 | } |
197 | |