View Javadoc

1   /*
2    * HibernatePersistenceFactory.java
3    *
4    * Created on June 15, 2005, 4:42 PM
5    *
6    * To change this template, choose Tools | Options and locate the template under
7    * the Source Creation and Management node. Right-click the template and choose
8    * Open. You can then make changes to the template in the Source Editor.
9    */
10  
11  package gov.bnl.gums.persistence;
12  
13  import gov.bnl.gums.configuration.Configuration;
14  import gov.bnl.gums.db.AccountPoolMapperDB;
15  import gov.bnl.gums.db.ConfigurationDB;
16  import gov.bnl.gums.db.HibernateAccountMapperDB;
17  import gov.bnl.gums.db.HibernateUserGroupDB;
18  import gov.bnl.gums.db.HibernateConfigurationDB;
19  import gov.bnl.gums.db.ManualAccountMapperDB;
20  import gov.bnl.gums.db.ManualUserGroupDB;
21  import gov.bnl.gums.db.UserGroupDB;
22  
23  import java.util.Date;
24  import java.util.Enumeration;
25  import java.util.HashMap;
26  import java.util.Iterator;
27  import java.util.Map;
28  import java.util.MissingResourceException;
29  import java.util.Properties;
30  import java.util.PropertyResourceBundle;
31  import java.util.ResourceBundle;
32  import java.util.Timer;
33  import java.util.TimerTask;
34  
35  import org.hibernate.*;
36  
37  import org.apache.log4j.Logger;
38  
39  /**
40   *
41   * @author Gabriele Carcassi, Jay Packard
42   */
43  public class HibernatePersistenceFactory extends PersistenceFactory {
44      static public String getTypeStatic() {
45  		return "hibernate";
46  	}
47      static final int expireTime = 300000;
48  	static Map propertyToPFSessionCreatorMap = new HashMap();
49  	static Configuration currentConfig = null;
50      static int numSessions = 0;
51      private Timer timer = new Timer();
52  	
53  	private Logger log = Logger.getLogger(HibernatePersistenceFactory.class);
54  	SessionFactory sessionFactory;
55      
56  	TimerTask closeExpiredSessions = new TimerTask() {
57  		public void run() {
58  			synchronized(propertyToPFSessionCreatorMap) {
59  				Iterator it = propertyToPFSessionCreatorMap.keySet().iterator();
60  				while (it.hasNext()) {
61  					Properties p = (Properties)it.next();
62  					HibernatePersistenceFactory pf = (HibernatePersistenceFactory)propertyToPFSessionCreatorMap.get(p);
63  					if (pf.getConfiguration() != currentConfig && new Date().after(new Date(pf.getConfiguration().getCreated().getTime()+expireTime))) {
64  						pf.sessionFactory.close();
65  						propertyToPFSessionCreatorMap.remove(p);it = propertyToPFSessionCreatorMap.keySet().iterator();
66  						numSessions--;
67  			            log.debug("Closed Hibernate session factory "+pf.sessionFactory+" with configuration "+pf.getConfiguration()+" and properties " + p + " - "+numSessions+" current instance(s)");
68  					}
69  				}
70  			}
71  		}
72  	};
73  	
74  	/**
75       * Create a new hibernate persistence factory.  This empty constructor is needed by the XML Digester.
76  	 */
77  	public HibernatePersistenceFactory() {
78      	log.trace("HibernatePersistenceFactory instanciated");
79      	timer.scheduleAtFixedRate(closeExpiredSessions, new Date(new Date().getTime()+expireTime), expireTime);
80      }
81      
82      /**
83       * Create a new hibernate persistence factory with a configuration.
84       * 
85       * @param configuration
86       */
87      public HibernatePersistenceFactory(Configuration configuration) {
88      	super(configuration);
89      	log.trace("HibernatePersistenceFactory instanciated");
90      	timer.scheduleAtFixedRate(closeExpiredSessions, new Date(new Date().getTime()+expireTime), expireTime);
91      }    
92  
93      /**
94       * Create a new ldap persistence factory with a configuration and a name.
95       * 
96       * @param configuration
97       * @param name
98       */
99      public HibernatePersistenceFactory(Configuration configuration, String name) {
100     	super(configuration, name);
101     	log.trace("HibernatePersistenceFactory instanciated");
102     	timer.scheduleAtFixedRate(closeExpiredSessions, new Date(new Date().getTime()+60000), 60000);
103     }
104     
105     public PersistenceFactory clone(Configuration configuration) {
106     	HibernatePersistenceFactory persistenceFactory = new HibernatePersistenceFactory(configuration, new String(getName()));
107     	persistenceFactory.setDescription(new String(getDescription()));
108     	persistenceFactory.setStoreConfig(getStoreConfig());
109     	persistenceFactory.setProperties((Properties)getProperties().clone());
110     	return persistenceFactory;
111     }
112     
113     public String getType() {
114 		return "hibernate";
115 	}
116     
117     public AccountPoolMapperDB retrieveAccountPoolMapperDB(String name) {
118         return new HibernateAccountMapperDB(this, name);
119     }
120 
121 	public ConfigurationDB retrieveConfigurationDB() {
122 		return new HibernateConfigurationDB(this);
123 	}	
124     
125     public ManualAccountMapperDB retrieveManualAccountMapperDB(String name) {
126         return new HibernateAccountMapperDB(this, name);
127     }
128 
129     public ManualUserGroupDB retrieveManualUserGroupDB(String name) {
130         return new HibernateUserGroupDB(this, name);
131     }
132     
133     public UserGroupDB retrieveUserGroupDB(String name) {
134         return new HibernateUserGroupDB(this, name);
135     }
136     
137     public void setConnectionFromHibernateProperties() {
138         try {
139             setProperties(readHibernateProperties());
140         } catch (MissingResourceException e) {
141             throw new RuntimeException("Couldn't find database configuration file (hibernate.properties)", e);
142         }
143     }
144     
145 	public String toXML() {
146     	String retStr = "\t\t<hibernatePersistenceFactory\n"+
147     		"\t\t\tname='"+getName()+"'\n"+
148     		"\t\t\tdescription='"+getDescription()+"'\n"+
149 			"\t\t\tstoreConfig='"+(getStoreConfig()?"true":"false")+"'\n";
150     	
151     	Iterator keyIt = getProperties().keySet().iterator();
152     	while(keyIt.hasNext()) {
153     		String key = (String)keyIt.next();
154     		retStr += "\t\t\t"+key+"='"+getProperties().getProperty(key)+"'\n";
155     	}
156 
157     	if (retStr.charAt(retStr.length()-1)=='\n')
158     		retStr = retStr.substring(0, retStr.length()-1);    	
159     	
160     	retStr += "/>\n\n";
161     	
162     	return retStr;
163 	}
164 
165 	public SessionFactory retrieveSessionFactory() throws Exception {
166 		if (sessionFactory == null) {
167 			synchronized(propertyToPFSessionCreatorMap) {
168 				// If there's a hibernate persistence factory with the same properties, use it, 
169 				// otherwise create a new one and register in propertyToPFSessionCreatorMap list
170 				HibernatePersistenceFactory pf = ((HibernatePersistenceFactory)propertyToPFSessionCreatorMap.get(getProperties()));
171 				if (pf!=null && !pf.sessionFactory.isClosed()) {
172 					sessionFactory = pf.sessionFactory;
173 					log.debug("Obtained previous hibernate session factory "+sessionFactory+" with configuration "+getConfiguration()+" and properties " + pf.getProperties() + " - "+numSessions+" current instance(s)");
174 				}
175 				else {
176 					sessionFactory = buildSessionFactory();
177 					numSessions++;
178 		            log.debug("Created new Hibernate session factory "+sessionFactory+" with configuration "+getConfiguration()+" and properties " + getProperties() + " - "+numSessions+" current instance(s)");
179 				}
180 				propertyToPFSessionCreatorMap.put(getProperties(), this);
181 				currentConfig = getConfiguration();
182 			}
183 		}
184 		
185 		return sessionFactory;
186 	}
187 	
188     private SessionFactory buildSessionFactory() {
189         try {
190             log.trace("Creating Hibernate Session Factory with the following properties: " + getProperties());
191             // Properties for the hibernate session are taken from the properties specified either in the
192             // gums.config file, or set programmatically to the class (when unit testing)
193             org.hibernate.cfg.Configuration cfg = new org.hibernate.cfg.Configuration()
194                 .setProperties(getProperties())
195                 .addClass(gov.bnl.gums.db.HibernateMapping.class)
196                 .addClass(gov.bnl.gums.db.HibernateUser.class)
197                 .addClass(gov.bnl.gums.db.HibernateConfig.class);
198             return cfg.buildSessionFactory();
199         } catch (Exception e) {
200             log.error("Couldn't initialize Hibernate", e);
201             throw new RuntimeException("An error occurred while initializing the database environment (hibernate): "+ e.getMessage(), e);
202         }
203     }
204     
205     private Properties readHibernateProperties() {
206         log.trace("Retrieving hibernate properties from hibernate.properties in the classpath");
207         PropertyResourceBundle prop = (PropertyResourceBundle) ResourceBundle.getBundle("hibernate");
208         Properties prop2 = new Properties();
209         Enumeration keys = prop.getKeys();
210         while (keys.hasMoreElements()) {
211             String key = (String) keys.nextElement();
212             prop2.setProperty(key, prop.getString(key));
213         }
214         return prop2;
215     }
216     
217 }