EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [EmbeddedDataSource.java]

nameclass, %method, %block, %line, %
EmbeddedDataSource.java100% (1/1)73%  (11/15)64%  (244/379)61%  (63.4/104)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class EmbeddedDataSource100% (1/1)73%  (11/15)64%  (244/379)61%  (63.4/104)
EmbeddedDataSource (): void 100% (1/1)100% (3/3)100% (2/2)
equals (Object): boolean 0%   (0/1)0%   (0/121)0%   (0/37)
findDriver (): InternalDriver 100% (1/1)88%  (38/43)92%  (7.4/8)
getAttributesAsPassword (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
getConnection (): Connection 100% (1/1)100% (8/8)100% (1/1)
getConnection (String, String): Connection 100% (1/1)100% (6/6)100% (1/1)
getConnection (String, String, boolean): Connection 100% (1/1)100% (91/91)100% (21/21)
getConnectionAttributes (): String 100% (1/1)100% (3/3)100% (1/1)
getCreateDatabase (): String 0%   (0/1)0%   (0/3)0%   (0/1)
getShutdownDatabase (): String 0%   (0/1)0%   (0/3)0%   (0/1)
setAttributesAsPassword (boolean): void 100% (1/1)100% (6/6)100% (3/3)
setConnectionAttributes (String): void 100% (1/1)100% (6/6)100% (3/3)
setCreateDatabase (String): void 100% (1/1)100% (16/16)100% (4/4)
setShutdownDatabase (String): void 100% (1/1)100% (14/14)100% (4/4)
update (): void 100% (1/1)100% (53/53)100% (16/16)

1/*
2 
3   Derby - Class org.apache.derby.jdbc.EmbeddedDataSource
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 
21package org.apache.derby.jdbc;
22 
23import org.apache.derby.iapi.reference.Attribute;
24 
25import java.sql.Connection;
26import java.sql.DriverManager;
27import java.sql.SQLException;
28 
29import java.io.PrintWriter;
30import java.util.Properties;
31 
32/* -- New jdbc 20 extension types --- */
33import javax.sql.DataSource;
34 
35 
36import org.apache.derby.iapi.reference.Attribute;
37import org.apache.derby.iapi.reference.MessageId;
38import org.apache.derby.iapi.reference.SQLState;
39import org.apache.derby.iapi.error.ExceptionSeverity;
40import org.apache.derby.iapi.services.i18n.MessageService;
41import org.apache.derby.impl.jdbc.Util;
42 
43/** 
44        
45 
46        EmbeddedDataSource is Derby's DataSource implementation for JDBC3.0 and JDBC2.0.
47        
48 
49        <P>A DataSource  is a factory for Connection objects. An object that
50        implements the DataSource interface will typically be registered with a
51        JNDI service provider.
52        <P>
53        EmbeddedDataSource 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>The following is a list of properties that can be set on a Derby
61        DataSource object:
62        <P><B>Standard DataSource properties</B> (from JDBC 3.0 specification).
63 
64        <UL><LI><B><code>databaseName</code></B> (String): <I>Mandatory</I>
65        <BR>This property must be set and it
66        identifies which database to access.  If a database named wombat located at
67        g:/db/wombat is to be accessed, then one should call
68        <code>setDatabaseName("g:/db/wombat")</code> on the data source object.</LI>
69 
70        <LI><B><code>dataSourceName</code></B> (String): <I>Optional</I>
71        <BR> Name for DataSource.  Not used by the data source object.  Used for
72        informational purpose only.</LI>
73 
74        <LI><B><code>description</code></B> (String): <I>Optional</I>
75        <BR>Description of the data source.  Not
76        used by the data source object.  Used for informational purpose only.</LI> 
77 
78        <LI><B><code>password</code></B> (String): <I>Optional</I>
79        <BR>Database password for the no argument <code>DataSource.getConnection()</code>,
80        <code>ConnectionPoolDataSource.getPooledConnection()</code>
81        and <code>XADataSource.getXAConnection()</code> methods.
82 
83        <LI><B><code>user</code></B> (String): <I>Optional</I>
84        <BR>Database user for the no argument <code>DataSource.getConnection()</code>,
85        <code>ConnectionPoolDataSource.getPooledConnection()</code>
86        and <code>XADataSource.getXAConnection()</code> methods.
87        </UL>
88 
89        <BR><B>Derby specific DataSource properties.</B>
90 
91  <UL>
92 
93  <LI><B><code>attributesAsPassword</code></B> (Boolean): <I>Optional</I>
94        <BR>If true, treat the password value in a
95        <code>DataSource.getConnection(String user, String password)</code>,
96        <code>ConnectionPoolDataSource.getPooledConnection(String user, String password)</code>
97        or <code>XADataSource.getXAConnection(String user, String password)</code> as a set
98        of connection attributes. The format of the attributes is the same as the format
99        of the attributes in the property connectionAttributes. If false the password value
100        is treated normally as the password for the given user.
101        Setting this property to true allows a connection request from an application to
102        provide more authentication information that just a password, for example the request
103        can include the user's password and an encrypted database's boot password.</LI>
104 
105  <LI><B><code>connectionAttributes</code></B> (String): <I>Optional</I>
106  <BR>Defines a set of Derby connection attributes for use in all connection requests.
107  The format of the String matches the format of the connection attributes in a Derby JDBC URL.
108  That is a list of attributes in the form <code><I>attribute</I>=<I>value</I></code>, each separated by semi-colon (';').
109  E.g. <code>setConnectionAttributes("bootPassword=erd3234dggd3kazkj3000");</code>.
110  <BR>The database name must be set by the DataSource property <code>databaseName</code> and not by setting the <code>databaseName</code>
111  connection attribute in the <code>connectionAttributes</code> property.
112        <BR>
113   Any attributes that can be set using a property of this DataSource implementation
114   (e.g user, password) should not be set in connectionAttributes. Conflicting
115   settings in connectionAttributes and properties of the DataSource will lead to
116   unexpected behaviour. 
117  <BR>Please see the Derby documentation for a complete list of connection attributes. </LI>
118 
119  <LI><B><code>createDatabase</code></B> (String): <I>Optional</I>
120        <BR>If set to the string "create", this will
121        cause a new database of <code>databaseName</code> if that database does not already
122        exist.  The database is created when a connection object is obtained from
123        the data source. </LI> 
124 
125        <LI><B><code>shutdownDatabase</code></B> (String): <I>Optional</I>
126        <BR>If set to the string "shutdown",
127        this will cause the database to shutdown when a java.sql.Connection object
128        is obtained from the data source.  E.g., If the data source is an
129        XADataSource, a getXAConnection().getConnection() is necessary to cause the
130        database to shutdown.
131 
132        </UL>
133 
134        <P><B>Examples.</B>
135 
136        <P>This is an example of setting a property directly using Derby's
137        EmbeddedDataSource object.  This code is typically written by a system integrator :
138        <PRE> 
139        *
140        * import org.apache.derby.jdbc.*;
141        *
142        * // dbname is the database name
143        * // if create is true, create the database if necessary
144        * javax.sql.DataSource makeDataSource (String dbname, boolean create)
145        *        throws Throwable 
146        * { 
147        *        EmbeddedDataSource ds = new EmbeddedDataSource(); 
148        *        ds.setDatabaseName(dbname);
149        *
150        *        if (create)
151        *                ds.setCreateDatabase("create");
152    *   
153        *        return ds;
154        * }
155        </PRE>
156 
157        <P>Example of setting properties thru reflection.  This code is typically
158        generated by tools or written by a system integrator: <PRE>
159        *        
160        * javax.sql.DataSource makeDataSource(String dbname) 
161        *        throws Throwable 
162        * {
163        *        Class[] parameter = new Class[1];
164        *        parameter[0] = dbname.getClass();
165        *        DataSource ds =  new EmbeddedDataSource();
166        *        Class cl = ds.getClass();
167        *
168        *        Method setName = cl.getMethod("setDatabaseName", parameter);
169        *        Object[] arg = new Object[1];
170        *        arg[0] = dbname;
171        *        setName.invoke(ds, arg);
172        *
173        *        return ds;
174        * }
175        </PRE>
176 
177        <P>Example on how to register a data source object with a JNDI naming
178        service.
179        <PRE>
180        * DataSource ds = makeDataSource("mydb");
181        * Context ctx = new InitialContext();
182        * ctx.bind("jdbc/MyDB", ds);
183        </PRE>
184 
185        <P>Example on how to retrieve a data source object from a JNDI naming
186        service. 
187        <PRE>
188        * Context ctx = new InitialContext();
189        * DataSource ds = (DataSource)ctx.lookup("jdbc/MyDB");
190        </PRE>
191 
192*/
193public class EmbeddedDataSource extends ReferenceableDataSource implements
194                                javax.sql.DataSource
195{
196 
197        private static final long serialVersionUID = -4945135214995641181L;
198 
199        /** instance variables that will be serialized */
200 
201        /**
202         * The database name.
203         * @serial
204         */
205        private String databaseName;
206 
207        /**
208         * The data source name.
209         * @serial
210         */
211        private String dataSourceName;
212 
213        /**
214         * Description of the database.
215         * @serial
216         */
217        private String description;
218 
219        /**
220         * Set to "create" if the database should be created.
221         * @serial
222         */
223        private String createDatabase;
224 
225        /**
226         * Set to "shutdown" if the database should be shutdown.
227         * @serial
228         */
229        private String shutdownDatabase;
230 
231        /**
232         * Derby specific connection attributes.
233         * @serial
234         */
235        private String connectionAttributes;
236 
237        /**
238                Set password to be a set of connection attributes.
239        */
240        private boolean attributesAsPassword;
241 
242        /** instance variables that will not be serialized */
243        transient private PrintWriter printer;
244        transient private int loginTimeout;
245 
246        // Unlike a DataSource, LocalDriver is shared by all
247        // Derby databases in the same jvm.
248        transient InternalDriver driver;
249 
250        transient private String jdbcurl;
251 
252        /**
253                No-arg constructor.
254         */
255        public EmbeddedDataSource() {
256                // needed by Object Factory
257 
258                // don't put anything in here or in any of the set method because this
259                // object may be materialized in a remote machine and then sent thru
260                // the net to the machine where it will be used.
261        }
262 
263 
264  //Most of our customers would be using jndi to get the data
265  //sources. Since we don't have a jndi to test this, we are
266  //adding this method to fake it. This is getting used in
267  //xaJNDI test so we can compare the 2 data sources.
268        public boolean equals(Object p0) {
269    if (p0 instanceof EmbeddedDataSource) {
270      EmbeddedDataSource ds = (EmbeddedDataSource)p0;
271 
272      boolean match = true;
273      
274                        if (databaseName != null) {
275        if  (!(databaseName.equals(ds.databaseName)))
276                                        match = false;
277                        } else if (ds.databaseName != null)
278        match = false;
279 
280                        if (dataSourceName != null) {
281        if  (!(dataSourceName.equals(ds.dataSourceName)))
282                                        match = false;
283                        } else if (ds.dataSourceName != null)
284        match = false;
285 
286                        if (description != null) {
287        if  (!(description.equals(ds.description)))
288                                        match = false;
289                        } else if (ds.description != null)
290        match = false;
291 
292                        if (createDatabase != null) {
293        if  (!(createDatabase.equals(ds.createDatabase)))
294                                        match = false;
295                        } else if (ds.createDatabase != null)
296        match = false;
297 
298                        if (shutdownDatabase != null) {
299        if  (!(shutdownDatabase.equals(ds.shutdownDatabase)))
300                                        match = false;
301                        } else if (ds.shutdownDatabase != null)
302        match = false;
303 
304                        if (connectionAttributes != null) {
305        if  (!(connectionAttributes.equals(ds.connectionAttributes)))
306                                        match = false;
307                        } else if (ds.connectionAttributes != null)
308        match = false;
309 
310      if (loginTimeout != ds.loginTimeout)
311        match = false;
312 
313      return match;
314 
315    }
316 
317    return false;
318        }
319 
320        /*
321         * Properties to be seen by Bean - access thru reflection.
322         */
323 
324        /**
325                Set this property to create a new database.  If this
326                property is not set, the database (identified by databaseName) is
327                assumed to be already existing.
328 
329                @param create if set to the string "create", this data source will try
330                to create a new database of databaseName, or boot the database if one
331                by that name already exists.
332         */
333        public final void setCreateDatabase(String create) {
334                if (create != null && create.toLowerCase(java.util.Locale.ENGLISH).equals("create"))
335                        createDatabase = create;
336                else
337                        createDatabase = null;
338        }
339        /** @return "create" if create is set, or null if not */
340        public final String getCreateDatabase() {
341                return createDatabase;
342        }
343 
344 
345        /**
346                 Set this property if one wishes to shutdown the database identified by
347                databaseName. 
348 
349                @param shutdown if set to the string "shutdown", this data source will 
350                shutdown the database if it is running.
351         */
352        public final void setShutdownDatabase(String shutdown) {
353                if (shutdown != null && shutdown.equalsIgnoreCase("shutdown"))
354                        shutdownDatabase = shutdown;
355                else
356                        shutdownDatabase = null;
357        }
358        /** @return "shutdown" if shutdown is set, or null if not */
359        public final String getShutdownDatabase() {
360                return shutdownDatabase;
361        }
362 
363        /**
364                 Set this property to pass in more Derby specific
365                connection URL attributes.
366                <BR>
367       Any attributes that can be set using a property of this DataSource implementation
368       (e.g user, password) should not be set in connectionAttributes. Conflicting
369       settings in connectionAttributes and properties of the DataSource will lead to
370       unexpected behaviour. 
371 
372                @param prop set to the list of Derby connection
373                attributes separated by semi-colons.   E.g., to specify an encryption
374                bootPassword of "x8hhk2adf", and set upgrade to true, do the following: 
375                <PRE>
376                        ds.setConnectionAttributes("bootPassword=x8hhk2adf;upgrade=true");
377                </PRE>
378                See the Derby documentation for complete list.
379         */
380        public final void setConnectionAttributes(String prop) {
381                 connectionAttributes = prop;
382                 update();
383        }
384        /** @return Derby specific connection URL attributes */
385        public final String getConnectionAttributes() {
386                return connectionAttributes;
387        }
388 
389 
390        /**
391                Set attributeAsPassword property to enable passing connection request attributes in the password argument of getConnection.
392                If the property is set to true then the password argument of the DataSource.getConnection(String user, String password)
393                method call is taken to be a list of connection attributes with the same format as the connectionAttributes property.
394 
395                @param attributesAsPassword true to encode password argument as a set of connection attributes in a connection request.
396        */
397        public final void setAttributesAsPassword(boolean attributesAsPassword) {
398                this.attributesAsPassword = attributesAsPassword;
399                 update();
400        }
401 
402        /**
403                Return the value of the attributesAsPassword property.
404        */
405        public final boolean getAttributesAsPassword() {
406                return attributesAsPassword;
407        }
408 
409        /*
410         * DataSource methods 
411         */
412 
413 
414        /**
415         * Attempt to establish a database connection.
416         *
417         * @return  a Connection to the database
418         * @exception SQLException if a database-access error occurs.
419         */
420        public final Connection getConnection() throws SQLException
421        {
422                return this.getConnection(getUser(), getPassword(), false);
423        }
424 
425        /**
426         * Attempt to establish a database connection with the given username and password.
427           If the attributeAsPassword property is set to true then the password argument is taken to be a list of
428           connection attributes with the same format as the connectionAttributes property.
429 
430         *
431         * @param username the database user on whose behalf the Connection is 
432         *  being made
433         * @param password the user's password
434         * @return  a Connection to the database
435         * @exception SQLException if a database-access error occurs.
436         */
437        public final Connection getConnection(String username, String password) 
438                 throws SQLException
439        {
440                return this.getConnection(username, password, true);
441        }
442 
443        /**
444                @param        requestPassword true if the password came from the getConnection() call.
445        */
446        final Connection getConnection(String username, String password, boolean requestPassword)
447                throws SQLException {
448 
449                Properties info = new Properties();
450                if (username != null)
451                        info.put(Attribute.USERNAME_ATTR, username);
452 
453                if (!requestPassword || !attributesAsPassword)
454                {
455                        if (password != null)
456                                info.put(Attribute.PASSWORD_ATTR, password);
457                }
458 
459                if (createDatabase != null)
460                        info.put(Attribute.CREATE_ATTR, "true");
461                if (shutdownDatabase != null)
462                        info.put(Attribute.SHUTDOWN_ATTR, "true");
463 
464                String url = jdbcurl;
465 
466                if (attributesAsPassword && requestPassword && password != null) {
467 
468 
469                        StringBuffer sb = new StringBuffer(url.length() + password.length() + 1);
470 
471                        sb.append(url);
472                        sb.append(';');
473                        sb.append(password); // these are now request attributes on the URL
474 
475                        url = sb.toString();
476 
477                }
478                Connection conn =  findDriver().connect(url, info);
479 
480        // JDBC driver's getConnection method returns null if
481        // the driver does not handle the request's URL.
482        if (conn == null)
483           throw Util.generateCsSQLException(SQLState.PROPERTY_INVALID_VALUE,Attribute.DBNAME_ATTR,getDatabaseName());
484 
485        return conn;
486        }
487   
488        InternalDriver findDriver() throws SQLException
489        {
490                String url = jdbcurl;
491 
492                if (driver == null || !driver.acceptsURL(url))
493                {
494                        synchronized(this)
495                        {
496                                // The driver has either never been booted, or it has been
497                                // shutdown by a 'jdbc:derby:;shutdown=true'
498                                if (driver == null || !driver.acceptsURL(url))
499                                {
500 
501                                        new org.apache.derby.jdbc.EmbeddedDriver();
502 
503                                        // If we know the driver, we loaded it.   Otherwise only
504                                        // work if DriverManager has already loaded it.
505 
506                                        driver = (InternalDriver) DriverManager.getDriver(url);
507                                        // DriverManager will throw an exception if it cannot find the driver
508                                }
509                        }
510                }
511                return driver;
512                // else driver != null and driver can accept url
513        }
514 
515        void update()
516        {
517                StringBuffer sb = new StringBuffer(64);
518 
519                sb.append(Attribute.PROTOCOL);
520 
521 
522                // Set the database name from the databaseName property
523                String dbName = getDatabaseName();
524 
525                if (dbName != null) {
526                        dbName = dbName.trim();
527                }
528 
529                if (dbName == null || dbName.length() == 0) {
530                        // need to put something in so that we do not allow the
531                        // database name to be set from the request or from the
532                        // connection attributes.
533 
534                        // this space will selected as the database name (and trimmed to an empty string)
535                        // See the getDatabaseName() code in InternalDriver. Since this is a non-null
536                        // value, it will be selected over any databaseName connection attribute.
537                        dbName = " ";
538                }
539 
540                sb.append(dbName);
541 
542 
543                String connAttrs = getConnectionAttributes();
544                if (connAttrs != null) {
545                        connAttrs = connAttrs.trim();
546                        if (connAttrs.length() != 0) {
547                                sb.append(';');
548                                sb.append(connectionAttributes);
549                        }
550                }
551 
552                jdbcurl = sb.toString();
553        }
554}

[all classes][org.apache.derby.jdbc]
EMMA 2.0.5312 (C) Vladimir Roubtsov