View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.core.setup;
16  
17  import org.figure8.join.util.LogUtil;
18  import org.figure8.join.core.ContainerContextHandler;
19  
20  import org.apache.commons.logging.Log;
21  import net.sf.hibernate.MappingException;
22  import net.sf.hibernate.cfg.Configuration;
23  import net.sf.hibernate.tool.hbm2ddl.SchemaUpdate;
24  
25  import java.util.List;
26  import java.util.Properties;
27  import java.util.Enumeration;
28  /**
29   * Helper object for configuring Hibernate and its SessionFactory
30   * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
31   * @version $Revision: 1.2 $
32   */
33  public class HibernateConfigurator{
34     
35     // Static -------------------------------------------------------------------
36     
37     /** Get a commons logger. */
38     protected static Log log = LogUtil.getLog(HibernateConfigurator.class);
39     
40     /** Prefix of application properties related to hibernate. */
41     protected final static String HBN_PROPERTIES_PREFIX = "hibernate.";
42     /** Name of application property telling if Hibernate has been setup */
43     public final static String HBN_SETUP_PROPERTY = HBN_PROPERTIES_PREFIX + "setup";
44  
45  
46     // Attributes ---------------------------------------------------------------
47     
48     /** Hibernate mapping files resources. */
49     private List mappingResources = null;
50     /** Hibernate configuration wrapper. */
51     private Configuration hbnConfig = null;
52     /** Application configuration wrapper. */
53     private ApplicationConfig appConfig = null;
54     
55     
56     // Constructors -------------------------------------------------------------
57     
58     /** Creates a new instance of HibernateConfigurator */
59     public HibernateConfigurator(){
60     }
61     
62     
63     // Public -------------------------------------------------------------------
64  
65     /** @param config <code>ApplicationConfig</code> instance */
66     public void setApplicationConfig(ApplicationConfig config){
67        this.appConfig = config;
68     }
69     /** @return The <code>ApplicationConfig</code> instance used. */
70     public ApplicationConfig getApplicationConfig(){
71        return appConfig;
72     }
73  
74     /**
75      * Extract hibernate related properties from ApplicationConfig.
76      * @return A set of hibernate properties already present into ApplicationConfig
77      */
78     public Properties getHibernateProperties(){
79        log.debug("Extracting Hibernate properties from application config...");
80        Properties properties = new Properties();
81        // Browse application config properties.
82        Enumeration keys = appConfig.getProperties().keys();
83        while (keys != null && keys.hasMoreElements()){
84           String key = (String)keys.nextElement();
85           if (key.startsWith(HBN_PROPERTIES_PREFIX))
86              properties.setProperty(key, appConfig.getProperty(key));
87        }
88        log.debug("Found " + properties.size() + " Hibernate related properties.");
89        // Return props.
90        return properties;
91     }
92  
93     /**
94      * Configure Hibernate according to the given database details
95      * @param details Wrapper object for database connection details
96      * @param embedded Boolean telling if database to use is embedded (HSQLDB)
97      * @throws BootstrapException if application config cannot be updated
98      */
99     public synchronized void configureDatabase(DatabaseDetails details, boolean embedded) throws BootstrapException{
100       if (embedded){
101          // Assign the database a file Url.
102          String databasePath = BootstrapUtil.getBootstrapManager().getJoinHome() + "/database/joindb";
103          details.setDatabaseUrl("jdbc:hsqldb:" + databasePath);
104          log.debug("Database is embedded. Setting its Url to: " + details.getDatabaseUrl());
105       }
106       // Creating a set of specific Hibernate properties.
107       Properties properties = new Properties();
108       properties.setProperty("hibernate.connection.driver_class", details.getDriverClassname());
109       properties.setProperty("hibernate.connection.url", details.getDatabaseUrl());
110       properties.setProperty("hibernate.connection.username", details.getUsername());
111       properties.setProperty("hibernate.connection.password", details.getPassword());
112       properties.setProperty("hibernate.dialect", details.getDialect());
113       properties.setProperty("hibernate.c3p0.max_size", "" + details.getPoolSize());
114       properties.setProperty("hibernate.c3p0.min_size", "0");
115       properties.setProperty("hibernate.c3p0.timeout", "30");
116       properties.setProperty("hibernate.c3p0.max_statements", "0");
117       
118       // Now call the generic configureHibernate().
119       configureHibernate(properties);
120    }
121    
122    /**
123     * Configure Hibernate according to the given datasource JNDI name.
124     * @param datasourceName JNDI name of the datasource to use for connections
125     * @param dialect SQL dialect implementation of the database behind datasource
126     * @throws BootstrapException if application config cannot be updated
127     */
128    public synchronized void configureDatasource(String datasourceName, String dialect) throws BootstrapException{
129       // Creating a set of specific Hibernate properties.
130       Properties properties = new Properties();
131       properties.setProperty("hibernate.connection.datasource", datasourceName);
132       properties.setProperty("hibernate.dialect", dialect);
133       
134       // Now call the generic configureHibernate().
135       configureHibernate(properties);
136    }
137    
138    
139    // Protected ----------------------------------------------------------------
140    
141    /**
142     * Do the real job by filling application with Hibernate properties
143     * and creating the database schema if needed.
144     * @param properties Hibernate specific properties (starting with "hibernate.")
145     * @throws BootstrapException if configuration backup or schema update fails
146     */
147    protected void configureHibernate(Properties properties) throws BootstrapException{
148       if (log.isInfoEnabled())
149          log.info("Configuring Hibernate & Application with properties: " + properties);
150       
151       // Add Hibernate properties to application ones.
152       Enumeration keys = properties.keys();
153       while (keys != null && keys.hasMoreElements()){
154          String key = (String)keys.nextElement();
155          appConfig.setProperty(key, properties.getProperty(key));
156       }
157       try{
158          // Save application configuration & refresh.
159          log.info("Now saving configuration before updating database schema...");
160          appConfig.save();
161          ContainerContextHandler.getInstance().refresh();
162          // Execute a schema update on database.
163          log.info("Configuration backup is ok. Updating database schema...");
164          SchemaUpdate update = new SchemaUpdate(getHibernateConfiguration());
165          update.execute(true, true);
166          // Say that hibernate has been setup.
167          appConfig.setProperty(HBN_SETUP_PROPERTY, "true");
168       }
169       catch (Exception e){
170          log.error("Execution of configuration backup & database schema update fails...");
171          log.error("Here's the error message: " + e.getMessage());
172          throw new BootstrapException("Configuration of Hibernate fails !", e);
173       }
174    }
175 
176 
177    // Private -----------------------------------------------------------------
178 
179    /**
180     * Get an Hibernate configuration object with correct properties
181     * and resource mappings.
182     * @throws MappingException if resource mappings are wrong
183     * @return An Hibernate configuration wrapper
184     */
185    private Configuration getHibernateConfiguration() throws MappingException{
186       if (hbnConfig == null){
187          try{
188             // First try retrieving mapping resources.
189             mappingResources = (List)ContainerContextHandler.getInstance().getComponent("mappingResources");
190          }
191          catch (Exception e){
192             log.error("mappingResources component cannot be found: " + e.getMessage());
193             throw new MappingException("mappingResources component cannot be found !", e);
194          }
195 
196          hbnConfig = new Configuration().setProperties(getHibernateProperties());
197          // Add mapping resources to config if any.
198          if (mappingResources != null && mappingResources.size() > 0){
199             for (int i=0; i<mappingResources.size(); i++)
200                hbnConfig.addResource((String)mappingResources.get(i), Thread.currentThread().getContextClassLoader());
201          }
202       }
203       return hbnConfig;
204    }
205 }