1 | /* |
2 | |
3 | Derby - Class org.apache.derby.jdbc.EmbeddedXADataSource |
4 | |
5 | Copyright 2001, 2004 The Apache Software Foundation or its licensors, as 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 org.apache.derby.iapi.reference.MessageId; |
24 | import org.apache.derby.iapi.services.i18n.MessageService; |
25 | |
26 | import org.apache.derby.iapi.services.monitor.Monitor; |
27 | import org.apache.derby.iapi.jdbc.ResourceAdapter; |
28 | import org.apache.derby.iapi.db.Database; |
29 | |
30 | import org.apache.derby.iapi.reference.Property; |
31 | |
32 | import org.apache.derby.iapi.error.ExceptionSeverity; |
33 | |
34 | import java.sql.SQLException; |
35 | import java.sql.Connection; |
36 | import java.sql.Driver; |
37 | |
38 | |
39 | /** -- jdbc 2.0. extension -- */ |
40 | import javax.sql.XADataSource; |
41 | import javax.sql.XAConnection; |
42 | |
43 | |
44 | /** |
45 | |
46 | EmbeddedXADataSource is Derby's XADataSource implementation for JDBC3.0 and JDBC2.0. |
47 | |
48 | |
49 | <P>An XADataSource is a factory for XAConnection objects. It represents a |
50 | RM in a DTP environment. An object that implements the XADataSource |
51 | interface is typically registered with a JNDI service provider. |
52 | <P> |
53 | EmbeddedXADataSource automatically supports the correct JDBC specification version |
54 | for the Java Virtual Machine's environment. |
55 | <UL> |
56 | <LI> JDBC 3.0 - Java 2 - JDK 1.4, J2SE 5.0 |
57 | <LI> JDBC 2.0 - Java 2 - JDK 1.2,1.3 |
58 | </UL> |
59 | |
60 | <P>EmbeddedXADataSource object only works on a local database. There is no |
61 | client/server support. An EmbeddedXADataSource object must live in the same jvm as |
62 | the database. |
63 | |
64 | <P>EmbeddedXADataSource is serializable and referenceable. |
65 | |
66 | <P>See EmbeddedDataSource for DataSource properties. |
67 | |
68 | */ |
69 | public class EmbeddedXADataSource extends EmbeddedDataSource implements |
70 | javax.sql.XADataSource |
71 | { |
72 | |
73 | private static final long serialVersionUID = -5715798975598379738L; |
74 | |
75 | // link to the database |
76 | transient private ResourceAdapter ra; |
77 | |
78 | /** |
79 | no-arg constructor |
80 | */ |
81 | public EmbeddedXADataSource() |
82 | { |
83 | super(); |
84 | } |
85 | |
86 | |
87 | /* |
88 | * XADataSource methods |
89 | */ |
90 | |
91 | |
92 | /** |
93 | * Attempt to establish a database connection. |
94 | * |
95 | * @return a Connection to the database |
96 | * @exception SQLException if a database-access error occurs. |
97 | */ |
98 | public final XAConnection getXAConnection() throws SQLException |
99 | { |
100 | if (ra == null || !ra.isActive()) |
101 | setupResourceAdapter(null, null, false); |
102 | |
103 | return createXAConnection (ra, getUser(), getPassword(), false); |
104 | } |
105 | |
106 | /** |
107 | * Attempt to establish a database connection with the given user |
108 | * name and password. |
109 | * |
110 | * @param user the database user on whose behalf the Connection is being made |
111 | * @param password the user's password |
112 | * @return a Connection to the database |
113 | * @exception SQLException if a database-access error occurs. |
114 | */ |
115 | public final XAConnection getXAConnection(String user, String password) |
116 | throws SQLException |
117 | { |
118 | if (ra == null || !ra.isActive()) |
119 | setupResourceAdapter(user, password, true); |
120 | return createXAConnection (ra, user, password, true); |
121 | } |
122 | |
123 | /* |
124 | * private method |
125 | */ |
126 | |
127 | void update() { |
128 | ra = null; |
129 | super.update(); |
130 | } |
131 | |
132 | private void setupResourceAdapter(String user, String password, boolean requestPassword) throws SQLException |
133 | { |
134 | synchronized(this) |
135 | { |
136 | if (ra == null || !ra.isActive()) |
137 | { |
138 | // If it is inactive, it is useless. |
139 | ra = null; |
140 | |
141 | String dbName = getDatabaseName(); |
142 | if (dbName != null) { |
143 | |
144 | // see if database already booted, if it is, then don't make a |
145 | // connection. |
146 | Database database = null; |
147 | |
148 | // if monitor is never setup by any ModuleControl, getMonitor |
149 | // returns null and no cloudscape database has been booted. |
150 | if (Monitor.getMonitor() != null) |
151 | database = (Database) |
152 | Monitor.findService(Property.DATABASE_MODULE, dbName); |
153 | |
154 | if (database == null) |
155 | { |
156 | // If database is not found, try connecting to it. This |
157 | // boots and/or creates the database. If database cannot |
158 | // be found, this throws SQLException. |
159 | if (requestPassword) |
160 | getConnection(user, password).close(); |
161 | else |
162 | getConnection().close(); |
163 | |
164 | // now try to find it again |
165 | database = (Database) |
166 | Monitor.findService(Property.DATABASE_MODULE, dbName); |
167 | } |
168 | |
169 | if (database != null) |
170 | ra = (ResourceAdapter) database.getResourceAdapter(); |
171 | } |
172 | |
173 | if (ra == null) |
174 | throw new SQLException(MessageService.getTextMessage(MessageId.CORE_DATABASE_NOT_AVAILABLE), |
175 | "08006", |
176 | ExceptionSeverity.DATABASE_SEVERITY); |
177 | |
178 | |
179 | // If database is already up, we need to set up driver |
180 | // seperately. |
181 | findDriver(); |
182 | |
183 | if (driver == null) |
184 | throw new SQLException(MessageService.getTextMessage(MessageId.CORE_DRIVER_NOT_AVAILABLE), |
185 | "08006", |
186 | ExceptionSeverity.DATABASE_SEVERITY); |
187 | |
188 | } |
189 | } |
190 | } |
191 | |
192 | /** |
193 | * Intantiate and returns EmbedXAConnection. |
194 | * @param user |
195 | * @param password |
196 | * @return XAConnection |
197 | */ |
198 | protected XAConnection createXAConnection (ResourceAdapter ra, |
199 | String user, String password, |
200 | boolean requestPassword) throws SQLException { |
201 | return new EmbedXAConnection(this, ra, user, |
202 | password, requestPassword); |
203 | } |
204 | } |