001: /*
002:
003: Derby - Class org.apache.derby.jdbc.Driver20
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 org.apache.derby.iapi.reference.Attribute;
025: import org.apache.derby.iapi.reference.MessageId;
026: import org.apache.derby.iapi.reference.Property;
027: import org.apache.derby.iapi.reference.SQLState;
028:
029: import org.apache.derby.impl.jdbc.EmbedConnection;
030:
031: import org.apache.derby.iapi.services.sanity.SanityManager;
032: import org.apache.derby.iapi.error.StandardException;
033: import org.apache.derby.iapi.sql.ResultSet;
034: import org.apache.derby.iapi.jdbc.BrokeredConnection;
035: import org.apache.derby.iapi.jdbc.BrokeredConnectionControl;
036: import org.apache.derby.iapi.services.i18n.MessageService;
037: import org.apache.derby.iapi.services.monitor.Monitor;
038: import org.apache.derby.iapi.services.io.FormatableProperties;
039:
040: import org.apache.derby.impl.jdbc.*;
041:
042: import java.sql.Connection;
043: import java.sql.SQLException;
044: import java.sql.Driver;
045: import java.sql.DriverManager;
046: import java.sql.DriverPropertyInfo;
047:
048: import java.util.Properties;
049:
050: /**
051: This class extends the local JDBC driver in order to determine at JBMS
052: boot-up if the JVM that runs us does support JDBC 2.0. If it is the case
053: then we will load the appropriate class(es) that have JDBC 2.0 new public
054: methods and sql types.
055: */
056:
057: public class Driver20 extends InternalDriver implements Driver {
058:
059: private static final String[] BOOLEAN_CHOICES = { "false", "true" };
060:
061: private Class antiGCDriverManager;
062:
063: /*
064: ** Methods from ModuleControl
065: */
066:
067: public void boot(boolean create, Properties properties)
068: throws StandardException {
069:
070: super .boot(create, properties);
071:
072: // Register with the driver manager
073: AutoloadedDriver.registerDriverModule(this );
074:
075: // hold onto the driver manager to avoid its being garbage collected.
076: // make sure the class is loaded by using .class
077: antiGCDriverManager = java.sql.DriverManager.class;
078: }
079:
080: public void stop() {
081:
082: super .stop();
083:
084: AutoloadedDriver.unregisterDriverModule();
085: }
086:
087: /**
088: * Get a new nested connection.
089: *
090: * @param conn The EmbedConnection.
091: *
092: * @return A nested connection object.
093: *
094: */
095: public Connection getNewNestedConnection(EmbedConnection conn) {
096: return new EmbedConnection(conn);
097: }
098:
099: /*
100: Methods to be overloaded in sub-implementations such as
101: a tracing driver.
102: */
103: public EmbedConnection getNewEmbedConnection(String url,
104: Properties info) throws SQLException {
105: // make a new local connection with a new transaction resource
106: return new EmbedConnection(this , url, info);
107: }
108:
109: /**
110: @exception SQLException if fails to create statement
111: */
112: public java.sql.PreparedStatement newEmbedPreparedStatement(
113: EmbedConnection conn, String stmt, boolean forMetaData,
114: int resultSetType, int resultSetConcurrency,
115: int resultSetHoldability, int autoGeneratedKeys,
116: int[] columnIndexes, String[] columnNames)
117: throws SQLException {
118: return new EmbedPreparedStatement20(conn, stmt, forMetaData,
119: resultSetType, resultSetConcurrency,
120: resultSetHoldability, autoGeneratedKeys, columnIndexes,
121: columnNames);
122: }
123:
124: /**
125: @exception SQLException if fails to create statement
126: */
127: public java.sql.CallableStatement newEmbedCallableStatement(
128: EmbedConnection conn, String stmt, int resultSetType,
129: int resultSetConcurrency, int resultSetHoldability)
130: throws SQLException {
131: return new EmbedCallableStatement20(conn, stmt, resultSetType,
132: resultSetConcurrency, resultSetHoldability);
133: }
134:
135: public org.apache.derby.impl.jdbc.EmbedResultSet newEmbedResultSet(
136: EmbedConnection conn, ResultSet results,
137: boolean forMetaData,
138: org.apache.derby.impl.jdbc.EmbedStatement statement,
139: boolean isAtomic) throws SQLException {
140: return new EmbedResultSet20(conn, results, forMetaData,
141: statement, isAtomic);
142: }
143:
144: public BrokeredConnection newBrokeredConnection(
145: BrokeredConnectionControl control) {
146:
147: return new BrokeredConnection(control);
148: }
149:
150: /**
151: * <p>The getPropertyInfo method is intended to allow a generic GUI tool to
152: * discover what properties it should prompt a human for in order to get
153: * enough information to connect to a database. Note that depending on
154: * the values the human has supplied so far, additional values may become
155: * necessary, so it may be necessary to iterate though several calls
156: * to getPropertyInfo.
157: *
158: * @param url The URL of the database to connect to.
159: * @param info A proposed list of tag/value pairs that will be sent on
160: * connect open.
161: * @return An array of DriverPropertyInfo objects describing possible
162: * properties. This array may be an empty array if no properties
163: * are required.
164: * @exception SQLException if a database-access error occurs.
165: */
166: public DriverPropertyInfo[] getPropertyInfo(String url,
167: Properties info) throws SQLException {
168:
169: // RESOLVE other properties should be added into this method in the future ...
170:
171: if (info != null) {
172: if (Boolean.valueOf(
173: info.getProperty(Attribute.SHUTDOWN_ATTR))
174: .booleanValue()) {
175:
176: // no other options possible when shutdown is set to be true
177: return new DriverPropertyInfo[0];
178: }
179: }
180:
181: // at this point we have databaseName,
182:
183: String dbname = InternalDriver.getDatabaseName(url, info);
184:
185: // convert the ;name=value attributes in the URL into
186: // properties.
187: FormatableProperties finfo = getAttributes(url, info);
188: info = null; // ensure we don't use this reference directly again.
189: boolean encryptDB = Boolean.valueOf(
190: finfo.getProperty(Attribute.DATA_ENCRYPTION))
191: .booleanValue();
192: String encryptpassword = finfo
193: .getProperty(Attribute.BOOT_PASSWORD);
194:
195: if (dbname.length() == 0
196: || (encryptDB = true && encryptpassword == null)) {
197:
198: // with no database name we can have shutdown or a database name
199:
200: // In future, if any new attribute info needs to be included in this
201: // method, it just has to be added to either string or boolean or secret array
202: // depending on whether it accepts string or boolean or secret(ie passwords) value.
203:
204: String[][] connStringAttributes = {
205: { Attribute.DBNAME_ATTR,
206: MessageId.CONN_DATABASE_IDENTITY },
207: { Attribute.CRYPTO_PROVIDER,
208: MessageId.CONN_CRYPTO_PROVIDER },
209: { Attribute.CRYPTO_ALGORITHM,
210: MessageId.CONN_CRYPTO_ALGORITHM },
211: { Attribute.CRYPTO_KEY_LENGTH,
212: MessageId.CONN_CRYPTO_KEY_LENGTH },
213: { Attribute.CRYPTO_EXTERNAL_KEY,
214: MessageId.CONN_CRYPTO_EXTERNAL_KEY },
215: { Attribute.TERRITORY, MessageId.CONN_LOCALE },
216: { Attribute.USERNAME_ATTR,
217: MessageId.CONN_USERNAME_ATTR },
218: { Attribute.LOG_DEVICE, MessageId.CONN_LOG_DEVICE },
219: { Attribute.ROLL_FORWARD_RECOVERY_FROM,
220: MessageId.CONN_ROLL_FORWARD_RECOVERY_FROM },
221: { Attribute.CREATE_FROM, MessageId.CONN_CREATE_FROM },
222: { Attribute.RESTORE_FROM,
223: MessageId.CONN_RESTORE_FROM }, };
224:
225: String[][] connBooleanAttributes = {
226: { Attribute.SHUTDOWN_ATTR,
227: MessageId.CONN_SHUT_DOWN_CLOUDSCAPE },
228: { Attribute.CREATE_ATTR,
229: MessageId.CONN_CREATE_DATABASE },
230: { Attribute.DATA_ENCRYPTION,
231: MessageId.CONN_DATA_ENCRYPTION },
232: { Attribute.UPGRADE_ATTR,
233: MessageId.CONN_UPGRADE_DATABASE }, };
234:
235: String[][] connStringSecretAttributes = {
236: { Attribute.BOOT_PASSWORD,
237: MessageId.CONN_BOOT_PASSWORD },
238: { Attribute.PASSWORD_ATTR,
239: MessageId.CONN_PASSWORD_ATTR }, };
240:
241: DriverPropertyInfo[] optionsNoDB = new DriverPropertyInfo[connStringAttributes.length
242: + connBooleanAttributes.length
243: + connStringSecretAttributes.length];
244:
245: int attrIndex = 0;
246: for (int i = 0; i < connStringAttributes.length; i++, attrIndex++) {
247: optionsNoDB[attrIndex] = new DriverPropertyInfo(
248: connStringAttributes[i][0],
249: finfo.getProperty(connStringAttributes[i][0]));
250: optionsNoDB[attrIndex].description = MessageService
251: .getTextMessage(connStringAttributes[i][1]);
252: }
253:
254: optionsNoDB[0].choices = Monitor.getMonitor()
255: .getServiceList(Property.DATABASE_MODULE);
256: // since database name is not stored in FormatableProperties, we
257: // assign here explicitly
258: optionsNoDB[0].value = dbname;
259:
260: for (int i = 0; i < connStringSecretAttributes.length; i++, attrIndex++) {
261: optionsNoDB[attrIndex] = new DriverPropertyInfo(
262: connStringSecretAttributes[i][0],
263: (finfo
264: .getProperty(connStringSecretAttributes[i][0]) == null ? ""
265: : "****"));
266: optionsNoDB[attrIndex].description = MessageService
267: .getTextMessage(connStringSecretAttributes[i][1]);
268: }
269:
270: for (int i = 0; i < connBooleanAttributes.length; i++, attrIndex++) {
271: optionsNoDB[attrIndex] = new DriverPropertyInfo(
272: connBooleanAttributes[i][0],
273: Boolean
274: .valueOf(
275: finfo == null ? ""
276: : finfo
277: .getProperty(connBooleanAttributes[i][0]))
278: .toString());
279: optionsNoDB[attrIndex].description = MessageService
280: .getTextMessage(connBooleanAttributes[i][1]);
281: optionsNoDB[attrIndex].choices = BOOLEAN_CHOICES;
282: }
283:
284: return optionsNoDB;
285: }
286:
287: return new DriverPropertyInfo[0];
288: }
289: }
|