Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/enableit/db/daf/castor/JdoFactory.java


1   package org.enableit.db.daf.castor;
2   
3   import java.io.PrintWriter;
4   import java.sql.*;
5   import java.util.*;
6   
7   import javax.naming.InitialContext;
8   import javax.sql.DataSource;
9   
10  import org.exolab.castor.jdo.JDO;
11  import org.exolab.castor.jdo.Database;
12  import org.exolab.castor.jdo.OQLQuery;
13  import org.exolab.castor.jdo.QueryResults;
14  import org.exolab.castor.mapping.Mapping;
15  import org.exolab.castor.mapping.MappingResolver;
16  import org.exolab.castor.mapping.FieldDescriptor;
17  import org.exolab.castor.util.Logger;
18  
19  // Log4J imports
20  import org.apache.log4j.Category;
21  
22  /** 
23   * Factory pattern for creating connections to a JDO managed datasource.
24   * <br>
25   * This class is final to prevent a breach of security by subclassing. 
26   * <br>
27   * The JDO implementation is Castor from 
28   * <a href="http://castor.exolab.org/">exolab.org</a>.
29   */
30  public final class JdoFactory
31  {
32     private static Mapping mapping;
33     private static JDO jdo;
34     
35     private static String databaseName = "dev";
36     public static final String DATABASE_FILE = "database.xml";
37     public static final String DATABASE_WITHOUT_CONTAINER_FILE = "database-without-container.xml";
38     public static final String MAPPING_FILE = "mapping.xml";
39  
40      /** 
41       * Define a static Category instance for logging
42       * Use one per package 
43       */
44      private static Category logger = Category.getInstance(JdoFactory.class);
45  
46  
47      /** 
48       * Sets the database name to be used and resets the internal JDO reference.
49       * This is useful if either the mapping or database configuration files 
50       * has been changed. 
51       */
52      public static void setDatabaseName(String newDatabaseName) 
53      { 
54          logger.info("METHOD_ENTRY: setDatabaseName" ) ; 
55  
56          databaseName = newDatabaseName ; 
57  
58          // reset mapping and jdo in case the config file was actually changed
59          mapping = null ;
60          jdo = null ; 
61  
62          logger.info("METHOD_EXIT: setDatabaseName" ) ; 
63      } 
64  
65      /** 
66       * Get a JDO object. 
67       * This is analogous to a JDBC 2 DataSource. 
68       */
69      public static final JDO getJdo() 
70      {
71          logger.info("METHOD_ENTRY: getJdo" ) ; 
72  
73          try {
74              // Load the mapping file
75              if (mapping==null) {
76                  logger.debug("configuring new mapping") ; 
77                  mapping = new Mapping( JdoFactory.class.getClassLoader() );
78                  logger.debug("... instantiated ok") ; 
79                  // uncomment the following line to debug JDO 
80                  mapping.setLogWriter( Logger.getSystemLogger() );
81                  mapping.loadMapping( JdoFactory.class.getResource( MAPPING_FILE ) );
82                  logger.debug("... mapping config file loaded ok") ; 
83              }
84         
85              if (jdo==null) {
86                  logger.debug("configuring new JDO") ; 
87                  jdo = new JDO();        
88                  // uncomment the following line to debug JDO 
89                  jdo.setLogWriter(Logger.getSystemLogger());
90                  jdo.setConfiguration( JdoFactory.class.getResource( DATABASE_FILE ).toString() );
91                  logger.debug("... database config file loaded ok") ; 
92                  jdo.setDatabaseName( databaseName );
93                  logger.debug("... database set to '" + databaseName + "'") ; 
94              }
95            
96          } catch (java.io.IOException e) {
97              logger.fatal(e.getMessage()) ; 
98              logger.fatal(e) ; 
99              throw new RuntimeException(e.getMessage()) ; 
100         } catch (org.exolab.castor.mapping.MappingException e) {
101             logger.fatal(e.getMessage()) ; 
102             logger.fatal(e) ; 
103             throw new RuntimeException(e.getMessage()) ; 
104         }
105    
106         logger.info("METHOD_ENTRY: getJdo" ) ; 
107         return jdo ; 
108    }
109 
110     /** 
111      * Get a JDO Database object. 
112      * This is analogous to a JDBC Connection. 
113      */
114    public static final Database getDatabase() 
115     {
116         logger.info("METHOD_ENTRY: getDatabase" ) ; 
117         
118         Database database = null  ;
119         try {
120           database = getJdo().getDatabase() ;
121         } catch (org.exolab.castor.jdo.DatabaseNotFoundException e) {
122             if (e.getMessage().startsWith("Nested error: javax.naming")) {
123                 // Assume running outside container and attempt config appropriately
124                 try {
125                     logger.debug("configuring new JDO outside a J2EE container") ; 
126                     jdo = new JDO();        
127                     // uncomment the following line to debug JDO 
128                     //jdo.setLogWriter(Logger.getSystemLogger());
129                     jdo.setConfiguration( JdoFactory.class.getResource( DATABASE_WITHOUT_CONTAINER_FILE ).toString() );
130                     logger.debug("... database config file loaded ok") ; 
131                     jdo.setDatabaseName( databaseName );
132                     logger.warn("... database set to '" + databaseName + "'") ; 
133                   database = jdo.getDatabase() ;                  
134                 } catch (Exception e2) {
135                     // We are probably dealing with a development time error now
136                     System.err.println("ERROR: " + e2.getClass().getName()) ; 
137                     System.err.println("ERROR: " + e2.getMessage()) ; 
138                     logger.fatal(e.getMessage()) ; 
139                     logger.fatal(e) ; 
140                     throw new RuntimeException(e2.getMessage()) ; 
141                 }
142             } else { 
143                 logger.fatal(e.getMessage()) ; 
144                 logger.fatal(e) ; 
145                 throw new RuntimeException(e.getMessage()) ; 
146             } 
147         } catch (org.exolab.castor.jdo.PersistenceException e) {
148             logger.fatal(e.getMessage()) ; 
149             logger.fatal(e) ; 
150             throw new RuntimeException(e.getMessage()) ; 
151         }           
152 
153         logger.info("METHOD_EXIT: getDatabase" ) ; 
154         return database ; 
155     } 
156 
157     /**  
158      * Get the property name that holds the database key.
159      */
160     public static String getIdentity(Class clazz) 
161     { 
162         logger.info("METHOD_ENTRY: getIdentity");
163         
164         String keyField = null ; 
165         try {
166             MappingResolver resolver = mapping.getResolver(Mapping.JDO) ; 
167             FieldDescriptor identityDescriptor = resolver.getDescriptor(clazz).getIdentity() ; 
168         
169             if (identityDescriptor!=null) {
170                 keyField = identityDescriptor.getFieldName() ; 
171             }
172         } catch (org.exolab.castor.mapping.MappingException e) {
173             logger.error(e.getClass().getName() + ":" + e.getMessage()) ;   
174             // continue and hope for the best, probably a development time prob
175         }
176 
177         logger.info("METHOD_EXIT: getIdentity");
178         logger.info("... with params keyField=" + keyField) ; 
179         return keyField ; 
180     } 
181 
182     /**  
183      * Return a standard JDBC connection, nothing to do with JDO.
184      */
185     public static final Connection getConnection()
186     { 
187         logger.info("METHOD_ENTRY: getConnection" ) ; 
188         
189         Connection conn = null ; 
190         try {
191             InitialContext ic = new InitialContext() ; 
192             javax.naming.Context envContext = (javax.naming.Context)ic.lookup("java:comp/env");
193             DataSource ds = (DataSource)envContext.lookup("jdbc/DefaultDS") ; 
194 
195             conn = ds.getConnection() ; 
196             if (conn==null) {
197                throw new SQLException("DataSource returned null connection.") ; 
198             }
199         } catch (javax.naming.NamingException e) {
200             /* 
201              * Assume this is because we are not running in a J2EE container 
202              * Try to get a Connection another way 
203              */
204 
205             // TODO , implement a connection factory 
206             if (conn==null) {
207                 throw new RuntimeException("have null connection: " + 
208                         e.getMessage()) ; 
209             }
210         } catch (java.sql.SQLException e) {
211             logger.fatal(e.getMessage()) ; 
212             logger.fatal(e) ; 
213             throw new RuntimeException(e.getMessage()) ; 
214         }
215 
216         logger.info("METHOD_EXIT: getConnection" ) ; 
217         return conn ; 
218     } 
219 }
220