001: /*
002: * JBoss, Home of Professional Open Source
003: * Copyright 2005, JBoss Inc., and individual contributors as indicated
004: * by the @authors tag. See the copyright.txt in the distribution for a
005: * full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jbpm.db;
023:
024: import java.io.IOException;
025: import java.io.Serializable;
026: import java.sql.Connection;
027: import java.util.Collection;
028: import java.util.HashSet;
029: import java.util.Iterator;
030: import java.util.Properties;
031:
032: import javax.naming.InitialContext;
033: import javax.rmi.PortableRemoteObject;
034:
035: import org.apache.commons.logging.Log;
036: import org.apache.commons.logging.LogFactory;
037: import org.hibernate.HibernateException;
038: import org.hibernate.Session;
039: import org.hibernate.SessionFactory;
040: import org.hibernate.cfg.Configuration;
041: import org.hibernate.mapping.PersistentClass;
042: import org.hibernate.type.LongType;
043: import org.hibernate.type.StringType;
044: import org.jbpm.JbpmConfiguration;
045: import org.jbpm.JbpmException;
046: import org.jbpm.util.ClassLoaderUtil;
047:
048: /**
049: * creates JbpmSessions.
050: * Obtain a JbpmSessionFactory with
051: * <pre>
052: * static JbpmSessionFactory jbpmSessionFactory = JbpmSessionFactory.buildJbpmSessionFactory();
053: * </pre>
054: * and store it somewhere static. It takes quite some time to create a DbSessionFactory,
055: * but you only have to do it once. After that, creating DbSession's is really fast.
056: *
057: * @deprecated use {@link org.jbpm.tc.ContextBuilder} and {@link org.jbpm.tc.db.JbpmSessionContext} instead.
058: */
059: public class JbpmSessionFactory implements Serializable {
060:
061: private static final long serialVersionUID = 1L;
062:
063: static String jndiName = getJndiName();
064:
065: private static String getJndiName() {
066: String jndiName = null;
067: if (JbpmConfiguration.Configs
068: .hasObject("jbpm.session.factory.jndi.name")) {
069: jndiName = JbpmConfiguration.Configs
070: .getString("jbpm.session.factory.jndi.name");
071: }
072: return jndiName;
073: }
074:
075: Configuration configuration = null;
076: SessionFactory sessionFactory = null;
077: Collection hibernatableLongIdClasses = null;
078: Collection hibernatableStringIdClasses = null;
079: JbpmSchema jbpmSchema = null;
080:
081: static JbpmSessionFactory instance = null;
082:
083: /**
084: * a singleton is kept in JbpmSessionFactory as a convenient central location.
085: */
086: public static JbpmSessionFactory getInstance() {
087: if (instance == null) {
088:
089: // if there is a JNDI name configured
090: if (jndiName != null) {
091: try {
092: // fetch the JbpmSessionFactory from JNDI
093: log.debug("fetching JbpmSessionFactory from '"
094: + jndiName + "'");
095: InitialContext initialContext = new InitialContext();
096: Object o = initialContext.lookup(jndiName);
097: instance = (JbpmSessionFactory) PortableRemoteObject
098: .narrow(o, JbpmSessionFactory.class);
099: } catch (Exception e) {
100: throw new JbpmException(
101: "couldn't fetch JbpmSessionFactory from jndi '"
102: + jndiName + "'");
103: }
104:
105: } else { // else there is no JNDI name configured
106: // create a new default instance.
107: log.debug("building singleton JbpmSessionFactory");
108: instance = buildJbpmSessionFactory();
109: }
110: }
111: return instance;
112: }
113:
114: public JbpmSessionFactory(Configuration configuration) {
115: this (configuration, buildSessionFactory(configuration));
116: }
117:
118: public JbpmSessionFactory(Configuration configuration,
119: SessionFactory sessionFactory) {
120: this .configuration = configuration;
121: this .sessionFactory = sessionFactory;
122: }
123:
124: public static JbpmSessionFactory buildJbpmSessionFactory() {
125: return buildJbpmSessionFactory(getConfigResource());
126: }
127:
128: public static JbpmSessionFactory buildJbpmSessionFactory(
129: String configResource) {
130: return buildJbpmSessionFactory(createConfiguration(configResource));
131: }
132:
133: public static JbpmSessionFactory buildJbpmSessionFactory(
134: Configuration configuration) {
135: return new JbpmSessionFactory(configuration);
136: }
137:
138: private static String getConfigResource() {
139: return JbpmConfiguration.Configs
140: .getString("resource.hibernate.cfg.xml");
141: }
142:
143: public static Configuration createConfiguration() {
144: return createConfiguration(getConfigResource());
145: }
146:
147: public static Configuration createConfiguration(
148: String configResource) {
149: Configuration configuration = null;
150: // create the hibernate configuration
151: configuration = new Configuration();
152: if (configResource != null) {
153: log.debug("using '" + configResource
154: + "' as hibernate configuration for jbpm");
155: configuration.configure(configResource);
156: } else {
157: log
158: .debug("using the default hibernate configuration file: hibernate.cfg.xml");
159: configuration.configure();
160: }
161:
162: // check if the properties in the hibernate.cfg.xml need to be overwritten by a separate properties file.
163: if (JbpmConfiguration.Configs
164: .hasObject("resource.hibernate.properties")) {
165: String hibernatePropertiesResource = JbpmConfiguration.Configs
166: .getString("resource.hibernate.properties");
167: Properties hibernateProperties = new Properties();
168: try {
169: hibernateProperties.load(ClassLoaderUtil
170: .getStream(hibernatePropertiesResource));
171: } catch (IOException e) {
172: e.printStackTrace();
173: throw new JbpmException(
174: "couldn't load the hibernate properties from resource '"
175: + hibernatePropertiesResource + "'", e);
176: }
177: log.debug("overriding hibernate properties with "
178: + hibernateProperties);
179: configuration.setProperties(hibernateProperties);
180: }
181:
182: return configuration;
183: }
184:
185: public static SessionFactory buildSessionFactory(
186: Configuration configuration) {
187: SessionFactory sessionFactory = null;
188: // create the hibernate session factory
189: log.debug("building hibernate session factory");
190: sessionFactory = configuration.buildSessionFactory();
191: return sessionFactory;
192: }
193:
194: /**
195: * obtains a jdbc connection as specified in the hibernate configurations and
196: * creates a DbSession with it.
197: */
198: public JbpmSession openJbpmSession() {
199: return openJbpmSession((Connection) null);
200: }
201:
202: /**
203: * creates a DbSession around the given connection. Note that you are
204: * responsible for closing the connection so closing the DbSession will
205: * not close the jdbc connection.
206: */
207: public JbpmSession openJbpmSession(Connection jdbcConnection) {
208: JbpmSession dbSession = null;
209:
210: try {
211: Session session = null;
212:
213: if (jdbcConnection == null) {
214: // use the hibernate properties in the nwsp.properties file to
215: // create a jdbc connection for the created hibernate session.
216: session = getSessionFactory().openSession();
217: } else {
218: // use the client provided jdbc connection in
219: // the created hibernate session.
220: session = getSessionFactory().openSession(
221: jdbcConnection);
222: }
223:
224: dbSession = new JbpmSession(this , session);
225:
226: } catch (HibernateException e) {
227: log.error(e);
228: throw new JbpmException(
229: "couldn't create a hibernate persistence session",
230: e);
231: }
232: return dbSession;
233: }
234:
235: public JbpmSession openJbpmSession(Session session) {
236: return new JbpmSession(null, session);
237: }
238:
239: public JbpmSession openJbpmSessionAndBeginTransaction() {
240: JbpmSession dbSession = openJbpmSession((Connection) null);
241: dbSession.beginTransaction();
242: return dbSession;
243: }
244:
245: public SessionFactory getSessionFactory() {
246: return sessionFactory;
247: }
248:
249: public Configuration getConfiguration() {
250: return configuration;
251: }
252:
253: /**
254: * clears the process definitions from hibernate's second level cache.
255: public void evictCachedProcessDefinitions() {
256: sessionFactory.evict(ProcessDefinition.class);
257: }
258: */
259:
260: /**
261: * checks if the given class is persistable with hibernate and has an id of type long.
262: */
263: public boolean isHibernatableWithLongId(Class clazz) {
264: if (hibernatableLongIdClasses == null) {
265: initHibernatableClasses();
266: }
267: return hibernatableLongIdClasses.contains(clazz);
268: }
269:
270: /**
271: * checks if the given class is persistable with hibernate and has an id of type string.
272: */
273: public boolean isHibernatableWithStringId(Class clazz) {
274: if (hibernatableStringIdClasses == null) {
275: initHibernatableClasses();
276: }
277: return hibernatableStringIdClasses.contains(clazz);
278: }
279:
280: public JbpmSchema getJbpmSchema() {
281: if (jbpmSchema == null) {
282: jbpmSchema = new JbpmSchema(configuration);
283: }
284: return jbpmSchema;
285: }
286:
287: void initHibernatableClasses() {
288: hibernatableLongIdClasses = new HashSet();
289: hibernatableStringIdClasses = new HashSet();
290: Iterator iter = configuration.getClassMappings();
291: while (iter.hasNext()) {
292: PersistentClass persistentClass = (PersistentClass) iter
293: .next();
294: if (LongType.class == persistentClass.getIdentifier()
295: .getType().getClass()) {
296: hibernatableLongIdClasses.add(persistentClass
297: .getMappedClass());
298: } else if (StringType.class == persistentClass
299: .getIdentifier().getType().getClass()) {
300: hibernatableStringIdClasses.add(persistentClass
301: .getMappedClass());
302: }
303: }
304: }
305:
306: private static final Log log = LogFactory
307: .getLog(JbpmSessionFactory.class);
308: }
|