001    package hirondelle.web4j.database;
002    
003    import java.sql.Connection;
004    import java.util.Map;
005    import java.util.Set;
006    
007    /**
008     Return a {@link Connection} to a database, using a policy defined by the application. 
009     
010     <P>See {@link hirondelle.web4j.BuildImpl} for important information on how this item is configured. 
011     {@link hirondelle.web4j.BuildImpl#forConnectionSource()} 
012     returns the configured implementation of this interface.
013     
014     <P>Here is an example 
015     <a href="http://www.javapractices.com/apps/fish/javadoc/src-html/hirondelle/web4j/config/ConnectionSrc.html">implementation</a>, 
016     taken from the WEB4J example application.
017     
018     <P>There are many alternatives for creating or accessing database connections.
019     The application programmer can use any technique whatsoever to implement this 
020     interface. For example, an implementation may :  
021     <ul>
022     <li>use a connection pool configured in the server environment (the style  
023     used in the example application)
024     <li>create a {@link Connection} directly, using the database driver. (Some modern 
025     drivers have connection pooling built directly into the driver.)
026     <li>use some other means
027     </ul>
028    
029     <P><span class="highlight">The design of this interface is slightly skewed towards applications 
030     that use more than one database.</span> 
031     If only one database is used in an application, then this interface is simply implemented
032     'as if' there were more than one. In practice, this should be only a minor nuisance. In addition, 
033     if a single-database application is extended to use more than one database, the changes will 
034     be absorbed naturally by the existing implementation. 
035     
036     <P>If no database is used at all, then {@link #getDatabaseNames()} returns an emtpy <tt>Set</tt>.
037    
038     <P>See {@link SqlId} for related information.
039    */
040    public interface ConnectionSource {
041      
042      /**
043       Read in any necessary configuration parameters.
044       
045       <P>This method is called by the framework early during startup processing.
046       If your implementation of this interface does not use any sort of config 
047       information, then it can simply ignore the given <tt>Map</tt> parameter.
048       
049       <P>In the context of a web application, the given <tt>Map</tt> is populated 
050       with the servlet's <tt>init-param</tt> settings in <tt>web.xml</tt>. 
051      */
052      void init(Map<String, String> aConfig);
053      
054      /**
055       Return the database names accepted by {@link #getConnection(String)}.
056       
057       <P>Return a <tt>Set</tt> with one or more entries. Each entry must have content.
058       If your application does not use a database at all, then you must return an empty <tt>Set</tt>.
059      */
060      Set<String> getDatabaseNames();  
061    
062      /**
063       Return a {@link Connection} to the <em>default</em> database.
064       
065       <P>The default database is selected by the application programmer as representing 
066       the principal or main database in the application, against which the majority of 
067       SQL statements are executed. (For most applications, this choice will be obvious.) 
068       In <tt>.sql</tt> files, SQL statements against the default database 
069       do not need an extra qualifier in their identifiers, while those against a non-default 
070       database do need an extra qualifier.
071       
072       <P>Implementations must translate any exceptions into a {@link DAOException}.
073       Examples of exceptions that may need translation are <tt>SQLException</tt> 
074       and <tt>javax.naming.NamingException</tt>.
075      */
076      Connection getConnection() throws DAOException;
077      
078      /**
079       Return a {@link Connection} for a specified database (default or non-default). 
080       
081       <P>The {@link #getConnection()} method is intended for the "default" or 
082       principal database used in the application, while this method is 
083       intended for all other databases (but may be used for the default as well).
084       
085       <P>See {@link SqlId} for related information.
086       
087       <span class="highlight">Here, <tt>aDatabaseName</tt> is a prefix used 
088       in <tt>.sql</tt> files as a qualifer to a SQL statement identifier.</span> 
089       For example, in an <tt>.sql</tt> file, the SQL statement identifier: 
090       <ul>
091       <li><tt>LIST_MEMBERS</tt> refers to the default database (no qualifier)
092       <li><tt>TRANSLATION.LOCALE_LIST</tt> refers to the '<tt>TRANSLATION</tt>' database. 
093       <em>It is this string </em>- '<tt>TRANSLATION</tt>' - <em>which is passed to this method</em>. 
094       </ul>  
095       
096       <P>The values taken by <tt>aDatabaseName</tt> are those returned by {@link #getDatabaseNames()}.
097       They may be chosen by the application programmer in any desired way, to clarify the SQL 
098       statement identifiers appearing in the <tt>.sql</tt> file(s).
099       Typically, an implementation of this interface will internally map these database 
100       identifiers into specific connection strings, such as 
101       '<tt>java:comp/env/jdbc/blah</tt>' (or whatever is required).
102        
103       <P>Implementations must translate any exceptions into a {@link DAOException}.
104       Examples of exceptions that may need translation are <tt>SQLException</tt> 
105       and <tt>javax.naming.NamingException</tt>.
106      */
107      Connection getConnection(String aDatabaseName) throws DAOException;
108    }