Coverage report

  %line %branch
org.apache.torque.pool.TorqueClassicDataSource
0% 
0% 

 1  
 package org.apache.torque.pool;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2004 The Apache Software Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License")
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import java.io.PrintWriter;
 20  
 import java.io.Serializable;
 21  
 import java.sql.Connection;
 22  
 import java.sql.SQLException;
 23  
 import java.util.HashMap;
 24  
 import java.util.Hashtable;
 25  
 import java.util.Map;
 26  
 import java.util.Properties;
 27  
 import javax.naming.BinaryRefAddr;
 28  
 import javax.naming.Context;
 29  
 import javax.naming.InitialContext;
 30  
 import javax.naming.Name;
 31  
 import javax.naming.NamingException;
 32  
 import javax.naming.RefAddr;
 33  
 import javax.naming.Reference;
 34  
 import javax.naming.Referenceable;
 35  
 import javax.naming.StringRefAddr;
 36  
 import javax.naming.spi.ObjectFactory;
 37  
 import javax.sql.ConnectionPoolDataSource;
 38  
 import javax.sql.DataSource;
 39  
 import org.apache.commons.lang.SerializationUtils;
 40  
 
 41  
 /**
 42  
  * Torque's default connection pool DataSource
 43  
  *
 44  
  * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
 45  
  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 46  
  * @version $Id: TorqueClassicDataSource.java,v 1.11.2.2 2004/05/20 04:36:05 seade Exp $
 47  
  * @deprecated as of version 3.1
 48  
  */
 49  
 public class TorqueClassicDataSource
 50  
     implements DataSource, Referenceable, Serializable, ObjectFactory
 51  
 {
 52  
     /** Pools keyed by username. */
 53  0
     private static Map pools = new HashMap();
 54  
 
 55  
     /** Counter used to create an internal unique name od the Data Source */
 56  
     private static int cpdsCounter;
 57  
 
 58  
     /** DataSource Name used to find the ConnectionPoolDataSource */
 59  
     private String dataSourceName;
 60  
 
 61  
     /** Description */
 62  
     private String description;
 63  
 
 64  
     /** Login TimeOut in seconds */
 65  
     private int loginTimeout;
 66  
 
 67  
     /** Pool Data Source that is used to fetch connections */
 68  
     private ConnectionPoolDataSource cpds;
 69  
 
 70  
     /** Log stream */
 71  
     private PrintWriter logWriter;
 72  
 
 73  
     /** Environment that may be used to set up a jndi initial context. */
 74  
     private Properties jndiEnvironment;
 75  
 
 76  
     /** Maximum Number of Connections cached in this Data Source */
 77  
     private int defaultMaxConnections;
 78  
 
 79  
     /**
 80  
      * Maximum Number of Connections for a specified User in this Data
 81  
      * Source
 82  
      */
 83  
     private Properties perUserMaxConnections;
 84  
 
 85  
     /** Maximum lifetime of a database connection */
 86  
     private int maxExpiryTime;
 87  
 
 88  
     /**
 89  
      * time to wait when initiating a connection
 90  
      * for the database to respond
 91  
      */
 92  
     private int connectionWaitTimeout;
 93  
 
 94  
     /** Interval (in seconds) that the monitor thread reports the pool state */
 95  
     private int logInterval;
 96  
 
 97  
     /** Do connections from this pool are auto-committing? */
 98  
     private boolean defaultAutoCommit;
 99  
 
 100  
     /** Are connections from this pool read-only? */
 101  
     private boolean defaultReadOnly;
 102  
 
 103  
     /**
 104  
      * Default no-arg constructor for Serialization
 105  
      */
 106  
     public TorqueClassicDataSource()
 107  0
     {
 108  0
         defaultAutoCommit = true;
 109  0
     }
 110  
 
 111  
     // Properties
 112  
 
 113  
     /**
 114  
      * Get the number of database connections to cache per user.
 115  
      * This value is used for any username which is not specified
 116  
      * in perUserMaxConnections.  The default is 1.
 117  
      *
 118  
      * @return value of maxConnections.
 119  
      */
 120  
     public int getDefaultMaxConnections()
 121  
     {
 122  0
         return defaultMaxConnections;
 123  
     }
 124  
 
 125  
     /**
 126  
      * Set the number of database connections to cache per user.
 127  
      * This value is used for any username which is not specified
 128  
      * in perUserMaxConnections.  The default is 1.
 129  
      *
 130  
      * @param v  Value to assign to maxConnections.
 131  
      */
 132  
     public void setDefaultMaxConnections(int  v)
 133  
     {
 134  0
         this.defaultMaxConnections = v;
 135  0
     }
 136  
 
 137  
     /**
 138  
      * Get the number of database connections to cache per user.  The keys
 139  
      * are usernames and the value is the maximum connections.  Any username
 140  
      * specified here will override the value of defaultMaxConnections.
 141  
      *
 142  
      * @return value of perUserMaxConnections.
 143  
      */
 144  
     public Properties getPerUserMaxConnections()
 145  
     {
 146  0
         return perUserMaxConnections;
 147  
     }
 148  
 
 149  
     /**
 150  
      * Set the number of database connections to cache per user.  The keys
 151  
      * are usernames and the value is the maximum connections.  Any username
 152  
      * specified here will override the value of defaultMaxConnections.
 153  
      *
 154  
      * @param v  Value to assign to perUserMaxConnections.
 155  
      */
 156  
     public void setPerUserMaxConnections(Properties  v)
 157  
     {
 158  0
         this.perUserMaxConnections = v;
 159  0
     }
 160  
 
 161  
     /**
 162  
      * Get the amount of time (in seconds) that database connections
 163  
      * will be cached.  The default is 3600 (1 hour).
 164  
      *
 165  
      * @return value of expiryTime.
 166  
      */
 167  
     public int getMaxExpiryTime()
 168  
     {
 169  0
         return maxExpiryTime;
 170  
     }
 171  
 
 172  
     /**
 173  
      * Set the amount of time (in seconds) that database connections
 174  
      * will be cached.  The default is 3600 (1 hour).
 175  
      *
 176  
      * @param v  Value to assign to expiryTime.
 177  
      */
 178  
     public void setMaxExpiryTime(int v)
 179  
     {
 180  0
         this.maxExpiryTime = v;
 181  0
     }
 182  
 
 183  
     /**
 184  
      * Get the amount of time (in seconds) a connection request will
 185  
      * have to wait before a time out occurs and an error is thrown.
 186  
      * The default is 10 seconds.
 187  
      *
 188  
      * @return value of connectionWaitTimeout.
 189  
      */
 190  
     public int getConnectionWaitTimeout()
 191  
     {
 192  0
         return connectionWaitTimeout;
 193  
     }
 194  
 
 195  
     /**
 196  
      * Eet the amount of time (in seconds) a connection request will
 197  
      * have to wait before a time out occurs and an error is thrown.
 198  
      * The default is 10 seconds.
 199  
      *
 200  
      * @param v  Value to assign to connectionWaitTimeout.
 201  
      */
 202  
     public void setConnectionWaitTimeout(int v)
 203  
     {
 204  0
         this.connectionWaitTimeout = v;
 205  0
     }
 206  
 
 207  
     /**
 208  
      * Get the interval (in seconds) between which the ConnectionPool logs
 209  
      * the status of it's Connections. Default is 0 which indicates no
 210  
      * logging.
 211  
      *
 212  
      * @return value of logInterval.
 213  
      */
 214  
     public int getLogInterval()
 215  
     {
 216  0
         return logInterval;
 217  
     }
 218  
 
 219  
     /**
 220  
      * Set the interval (in seconds) between which the ConnectionPool logs
 221  
      * the status of it's Connections. Default is 0 which indicates no
 222  
      * logging.
 223  
      *
 224  
      * @param v  Value to assign to logInterval.
 225  
      */
 226  
     public void setLogInterval(int v)
 227  
     {
 228  0
         this.logInterval = v;
 229  0
     }
 230  
 
 231  
     /**
 232  
      * Get the value of defaultAutoCommit, which defines the state of
 233  
      * connections handed out from this pool.  The value can be changed
 234  
      * on the Connection using Connection.setAutoCommit(boolean).
 235  
      * The default is true.
 236  
      *
 237  
      * @return value of defaultAutoCommit.
 238  
      */
 239  
     public boolean isDefaultAutoCommit()
 240  
     {
 241  0
         return defaultAutoCommit;
 242  
     }
 243  
 
 244  
     /**
 245  
      * Set the value of defaultAutoCommit, which defines the state of
 246  
      * connections handed out from this pool.  The value can be changed
 247  
      * on the Connection using Connection.setAutoCommit(boolean).
 248  
      * The default is true.
 249  
      *
 250  
      * @param v  Value to assign to defaultAutoCommit.
 251  
      */
 252  
     public void setDefaultAutoCommit(boolean v)
 253  
     {
 254  0
         this.defaultAutoCommit = v;
 255  0
     }
 256  
 
 257  
     /**
 258  
      * Get the value of defaultReadOnly, which defines the state of
 259  
      * connections handed out from this pool.  The value can be changed
 260  
      * on the Connection using Connection.setReadOnly(boolean).
 261  
      * The default is false.
 262  
      *
 263  
      * @return value of defaultReadOnly.
 264  
      */
 265  
     public boolean isDefaultReadOnly()
 266  
     {
 267  0
         return defaultReadOnly;
 268  
     }
 269  
 
 270  
     /**
 271  
      * Set the value of defaultReadOnly, which defines the state of
 272  
      * connections handed out from this pool.  The value can be changed
 273  
      * on the Connection using Connection.setReadOnly(boolean).
 274  
      * The default is false.
 275  
      *
 276  
      * @param v  Value to assign to defaultReadOnly.
 277  
      */
 278  
     public void setDefaultReadOnly(boolean v)
 279  
     {
 280  0
         this.defaultReadOnly = v;
 281  0
     }
 282  
 
 283  
     /**
 284  
      * Get the name of the ConnectionPoolDataSource which backs this pool.
 285  
      * This name is used to look up the datasource from a jndi service
 286  
      * provider.
 287  
      *
 288  
      * @return value of dataSourceName.
 289  
      */
 290  
     public String getDataSourceName()
 291  
     {
 292  0
         return dataSourceName;
 293  
     }
 294  
 
 295  
     /**
 296  
      * Set the name of the ConnectionPoolDataSource which backs this pool.
 297  
      * This name is used to look up the datasource from a jndi service
 298  
      * provider.
 299  
      *
 300  
      * @param v  Value to assign to dataSourceName.
 301  
      */
 302  
     public void setDataSourceName(String v)
 303  
     {
 304  0
         if (getConnectionPoolDataSource() != null)
 305  
         {
 306  0
             throw new IllegalStateException("connectionPoolDataSource property"
 307  
                 + " already has a value.  Both dataSourceName and "
 308  
                 + "connectionPoolDataSource properties cannot be set.");
 309  
         }
 310  
 
 311  0
         this.dataSourceName = v;
 312  0
     }
 313  
 
 314  
 
 315  
     /**
 316  
      * Get the description.  This property is defined by jdbc as for use with
 317  
      * GUI (or other) tools that might deploy the datasource.  It serves no
 318  
      * internal purpose.
 319  
      *
 320  
      * @return value of description.
 321  
      */
 322  
     public String getDescription()
 323  
     {
 324  0
         return description;
 325  
     }
 326  
 
 327  
     /**
 328  
      * Set the description.  This property is defined by jdbc as for use with
 329  
      * GUI (or other) tools that might deploy the datasource.  It serves no
 330  
      * internal purpose.
 331  
      *
 332  
      * @param v  Value to assign to description.
 333  
      */
 334  
     public void setDescription(String v)
 335  
     {
 336  0
         this.description = v;
 337  0
     }
 338  
 
 339  
 
 340  
     /**
 341  
      * Get the value of jndiEnvironment which is used when instantiating
 342  
      * a jndi InitialContext.  This InitialContext is used to locate the
 343  
      * backend ConnectionPoolDataSource.
 344  
      *
 345  
      * @param key environment key
 346  
      * @return value of jndiEnvironment.
 347  
      */
 348  
     public String getJndiEnvironment(String key)
 349  
     {
 350  0
         String value = null;
 351  0
         if (jndiEnvironment != null)
 352  
         {
 353  0
             value = jndiEnvironment.getProperty(key);
 354  
         }
 355  0
         return value;
 356  
     }
 357  
 
 358  
     /**
 359  
      * Set the value of jndiEnvironment which is used when instantiating
 360  
      * a jndi InitialContext.  This InitialContext is used to locate the
 361  
      * backend ConnectionPoolDataSource.
 362  
      *
 363  
      * @param key environment key
 364  
      * @param value  Value to assign to jndiEnvironment.
 365  
      */
 366  
     public void setJndiEnvironment(String key, String value)
 367  
     {
 368  0
         if (jndiEnvironment == null)
 369  
         {
 370  0
             jndiEnvironment = new Properties();
 371  
         }
 372  0
         jndiEnvironment.setProperty(key, value);
 373  0
     }
 374  
 
 375  
 
 376  
     /**
 377  
      * Get the value of connectionPoolDataSource.  This method will return
 378  
      * null, if the backing datasource is being accessed via jndi.
 379  
      *
 380  
      * @return value of connectionPoolDataSource.
 381  
      */
 382  
     public ConnectionPoolDataSource getConnectionPoolDataSource()
 383  
     {
 384  0
         return cpds;
 385  
     }
 386  
 
 387  
     /**
 388  
      * Set the backend ConnectionPoolDataSource.  This property should not be
 389  
      * set if using jndi to access the datasource.
 390  
      *
 391  
      * @param v  Value to assign to connectionPoolDataSource.
 392  
      */
 393  
     public void setConnectionPoolDataSource(ConnectionPoolDataSource  v)
 394  
     {
 395  0
         if (v == null)
 396  
         {
 397  0
             throw new IllegalArgumentException(
 398  
                 "Null argument value is not allowed.");
 399  
         }
 400  0
         if (getDataSourceName() != null)
 401  
         {
 402  0
             throw new IllegalStateException("dataSourceName property"
 403  
                 + " already has a value.  Both dataSourceName and "
 404  
                 + "connectionPoolDataSource properties cannot be set.");
 405  
         }
 406  0
         this.cpds = v;
 407  
 
 408  
         // set the dataSourceName to a unique value
 409  0
         dataSourceName = v.hashCode() + " internal cpds name " + cpdsCounter++;
 410  0
     }
 411  
 
 412  
     /**
 413  
      * Attempt to establish a database connection.
 414  
      *
 415  
      * @return A database connection.
 416  
      * @throws SQLException
 417  
      */
 418  
     public Connection getConnection() throws SQLException
 419  
     {
 420  0
         return getConnection(null, class="keyword">null);
 421  
     }
 422  
 
 423  
     /**
 424  
      * Attempt to establish a database connection.
 425  
      *
 426  
      * @param username The name of the database user.
 427  
      * @param password The password of the database user.
 428  
      * @return         A database connection.
 429  
      * @throws SQLException
 430  
      */
 431  
     public synchronized Connection getConnection(String username,
 432  
                                                  String password)
 433  
         throws SQLException
 434  
     {
 435  0
         String key = getKey(username);
 436  0
         ConnectionPool pool = (ConnectionPool) pools.get(key);
 437  0
         if (pool == null)
 438  
         {
 439  
             try
 440  
             {
 441  0
                 registerPool(username, password);
 442  0
                 pool = (ConnectionPool) pools.get(key);
 443  
             }
 444  0
             catch (Exception e)
 445  
             {
 446  0
                 throw new SQLException(e.getMessage());
 447  0
             }
 448  
         }
 449  
 
 450  0
         Connection con = pool.getConnection(username, password).getConnection();
 451  0
         con.setAutoCommit(defaultAutoCommit);
 452  0
         con.setReadOnly(defaultReadOnly);
 453  0
         return con;
 454  
     }
 455  
 
 456  
     /**
 457  
      *
 458  
      * @param suffix
 459  
      * @return
 460  
      */
 461  
     private String getKey(String suffix)
 462  
     {
 463  0
         String key = getDataSourceName();
 464  0
         if (key == null)
 465  
         {
 466  0
             throw new IllegalStateException("Attempted to use DataSource "
 467  
                 + "without a backend ConnectionPoolDataSource defined.");
 468  
         }
 469  
 
 470  0
         if (suffix != null)
 471  
         {
 472  0
             key += suffix;
 473  
         }
 474  0
         return key;
 475  
     }
 476  
 
 477  
     /**
 478  
      *
 479  
      * @param username The name of the database user.
 480  
      * @param password The password of the database user.
 481  
      * @throws javax.naming.NamingException
 482  
      */
 483  
     synchronized private void registerPool(String username, String password)
 484  
          throws javax.naming.NamingException
 485  
     {
 486  0
         String key = getKey(username);
 487  0
         if (!pools.containsKey(key))
 488  
         {
 489  0
             ConnectionPoolDataSource cpds = this.cpds;
 490  0
             if (cpds == null)
 491  
             {
 492  0
                 Context ctx = null;
 493  0
                 if (jndiEnvironment == null)
 494  
                 {
 495  0
                     ctx = new InitialContext();
 496  
                 }
 497  
                 else
 498  
                 {
 499  0
                     ctx = new InitialContext(jndiEnvironment);
 500  
                 }
 501  0
                 cpds = (ConnectionPoolDataSource) ctx.lookup(dataSourceName);
 502  
             }
 503  
 
 504  0
             int maxConnections = getDefaultMaxConnections();
 505  0
             if (username != null)
 506  
             {
 507  0
                 String userMaxCon =
 508  
                     (String) getPerUserMaxConnections().get(username);
 509  0
                 if (userMaxCon != null)
 510  
                 {
 511  0
                     maxConnections = Integer.parseInt(userMaxCon);
 512  
                 }
 513  
             }
 514  
 
 515  0
             ConnectionPool pool = new ConnectionPool(cpds, username, password,
 516  
                 maxConnections,
 517  
                 getMaxExpiryTime(),
 518  
                 getConnectionWaitTimeout(),
 519  
                 getLogInterval());
 520  
 
 521  
             // avoid ConcurrentModificationException
 522  0
             Map newPools = new HashMap(pools);
 523  0
             newPools.put(key, pool);
 524  0
             pools = newPools;
 525  
         }
 526  0
     }
 527  
 
 528  
     /**
 529  
      * Gets the maximum time in seconds that this data source can wait
 530  
      * while attempting to connect to a database.
 531  
      *
 532  
      * @return the login timeout
 533  
      */
 534  
     public int getLoginTimeout()
 535  
     {
 536  0
         return loginTimeout;
 537  
     }
 538  
 
 539  
     /**
 540  
      * Get the log writer for this data source.
 541  
      *
 542  
      * @return the log writer
 543  
      * @deprecated Use correct debugging and logging code from Log4j
 544  
      */
 545  
     public PrintWriter getLogWriter()
 546  
     {
 547  0
         if (logWriter == null)
 548  
         {
 549  0
             logWriter = new PrintWriter(System.out);
 550  
         }
 551  0
         return logWriter;
 552  
     }
 553  
 
 554  
     /**
 555  
      * Sets the maximum time in seconds that this data source will wait
 556  
      * while attempting to connect to a database. NOT USED.
 557  
      *
 558  
      * @param seconds the login timeout
 559  
      */
 560  
     public void setLoginTimeout(int seconds)
 561  
     {
 562  0
         loginTimeout = seconds;
 563  0
     }
 564  
 
 565  
     /**
 566  
      * Set the log writer for this data source.
 567  
      *
 568  
      * @param out the log writer to use
 569  
      * @deprecated Use correct debugging and logging code from Log4j
 570  
      */
 571  
     public void setLogWriter(java.io.PrintWriter out)
 572  
     {
 573  0
         logWriter = out;
 574  0
     }
 575  
 
 576  
     /**
 577  
      * <CODE>Referenceable</CODE> implementation.
 578  
      *
 579  
      * @return a reference
 580  
      * @throws NamingException
 581  
      */
 582  
     public Reference getReference() throws NamingException
 583  
     {
 584  0
         String factory = getClass().getName();
 585  
 
 586  0
         Reference ref = new Reference(getClass().getName(), factory, null);
 587  
 
 588  0
         ref.add(new StringRefAddr("defaultMaxConnections",
 589  
                                   String.valueOf(getDefaultMaxConnections())));
 590  0
         ref.add(new StringRefAddr("maxExpiryTime",
 591  
                                   String.valueOf(getMaxExpiryTime())));
 592  0
         ref.add(new StringRefAddr("connectionWaitTimeout",
 593  
                                   String.valueOf(getConnectionWaitTimeout())));
 594  0
         ref.add(new StringRefAddr("logInterval",
 595  
                                   String.valueOf(getLogInterval())));
 596  0
         ref.add(new StringRefAddr("dataSourceName", getDataSourceName()));
 597  0
         ref.add(new StringRefAddr("description", getDescription()));
 598  
 
 599  0
         byte[] serJndiEnv = null;
 600  
         // BinaryRefAddr does not allow null byte[].
 601  0
         if (jndiEnvironment != null)
 602  
         {
 603  0
             serJndiEnv = SerializationUtils.serialize(jndiEnvironment);
 604  0
             ref.add(new BinaryRefAddr("jndiEnvironment", serJndiEnv));
 605  
         }
 606  
 
 607  0
         byte[] serPUMC = null;
 608  
         // BinaryRefAddr does not allow null byte[].
 609  0
         if (getPerUserMaxConnections() != null)
 610  
         {
 611  0
             serPUMC = SerializationUtils.serialize(getPerUserMaxConnections());
 612  0
             ref.add(new BinaryRefAddr("perUserMaxConnections", serPUMC));
 613  
         }
 614  
 
 615  0
         return ref;
 616  
     }
 617  
 
 618  
     /**
 619  
      * implements ObjectFactory to create an instance of this class
 620  
      *
 621  
      * @param refObj
 622  
      * @param name
 623  
      * @param context
 624  
      * @param env
 625  
      * @return an instance of this class
 626  
      * @throws Exception
 627  
      */
 628  
     public Object getObjectInstance(Object refObj, Name name,
 629  
                                     Context context, Hashtable env)
 630  
         throws Exception
 631  
     {
 632  0
         Reference ref = (Reference) refObj;
 633  
 
 634  0
         if (ref.getClassName().equals(getClass().getName()))
 635  
         {
 636  0
             setDefaultMaxConnections(Integer.parseInt(
 637  
                 (String) ref.get("defaultMaxConnections").getContent()));
 638  0
             setMaxExpiryTime(Integer.parseInt(
 639  
                 (String) ref.get("maxExpiryTime").getContent()));
 640  0
             setConnectionWaitTimeout(Integer.parseInt(
 641  
                 (String) ref.get("connectionWaitTimeout").getContent()));
 642  0
             setLogInterval(Integer.parseInt(
 643  
                 (String) ref.get("logInterval").getContent()));
 644  0
             setDataSourceName((String) ref.get("dataSourceName").getContent());
 645  0
             setDescription((String) ref.get("description").getContent());
 646  
 
 647  0
             RefAddr refAddr = ref.get("jndiEnvironment");
 648  0
             if (refAddr != null)
 649  
             {
 650  0
                 byte[] serialized = (byte[]) refAddr.getContent();
 651  0
                 jndiEnvironment = (Properties)
 652  
                         SerializationUtils.deserialize(serialized);
 653  
             }
 654  
 
 655  0
             refAddr = ref.get("perUserMaxConnections");
 656  0
             if (refAddr != null)
 657  
             {
 658  0
                 byte[] serialized = (byte[]) refAddr.getContent();
 659  0
                 setPerUserMaxConnections(
 660  
                     (Properties) SerializationUtils.deserialize(serialized));
 661  
             }
 662  
 
 663  0
             return this;
 664  
         }
 665  
         else
 666  
         {
 667  
             // We can't create an instance of the reference
 668  0
             return null;
 669  
         }
 670  
     }
 671  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.