001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.gps.device.hibernate;
018:
019: import java.util.Hashtable;
020: import java.util.Map;
021:
022: import org.compass.core.CompassException;
023: import org.compass.core.CompassSession;
024: import org.compass.core.CompassTransaction;
025: import org.compass.core.CompassTransaction.TransactionIsolation;
026: import org.compass.core.config.CompassSettings;
027: import org.compass.core.spi.InternalCompassSession;
028: import org.compass.core.transaction.AbstractTransactionFactory;
029: import org.compass.core.transaction.InternalCompassTransaction;
030: import org.hibernate.Session;
031: import org.hibernate.SessionFactory;
032: import org.hibernate.Transaction;
033: import org.hibernate.engine.SessionImplementor;
034:
035: /**
036: * <p>Integrates with Hibernate transaction managemnet abstraction and Compass transactions. Uses Hibernate
037: * support for "context session" including its support for registration of synchronizations with the current
038: * transaction.
039: *
040: * <p>Will start a Hibernate transaction of none exists, and will join an existing one if one is already
041: * in progress. If the Hibernate transcation is started by this transaction factory, it will also be committed
042: * by it.
043: *
044: * <p>In order to use the transaction factory, it must be configured with Compass, as well as calling
045: * {@link #setSessionFactory(org.hibernate.SessionFactory)} before the Compass instance is created.
046: *
047: * @author kimchy
048: */
049: public class HibernateSyncTransactionFactory extends
050: AbstractTransactionFactory {
051:
052: private static ThreadLocal sessionFactoryHolder = new ThreadLocal();
053:
054: private static String sessionFactoryKey = HibernateSyncTransactionFactory.class
055: .getName();
056:
057: private SessionFactory sessionFactory;
058:
059: private transient Map currentSessionMap = new Hashtable();
060:
061: public static void setSessionFactory(SessionFactory sessionFactory) {
062: sessionFactoryHolder.set(sessionFactory);
063: }
064:
065: protected void doConfigure(CompassSettings settings) {
066: this .sessionFactory = (SessionFactory) sessionFactoryHolder
067: .get();
068: if (sessionFactory == null) {
069: sessionFactory = (SessionFactory) settings
070: .getRegistry(sessionFactoryKey);
071: }
072: if (sessionFactory != null) {
073: settings.setRegistry(sessionFactoryKey, sessionFactory);
074: }
075: sessionFactoryHolder.set(null);
076: }
077:
078: protected boolean isWithinExistingTransaction(
079: InternalCompassSession session) throws CompassException {
080: return ((SessionImplementor) sessionFactory.getCurrentSession())
081: .isTransactionInProgress();
082: }
083:
084: protected InternalCompassTransaction doBeginTransaction(
085: InternalCompassSession session,
086: TransactionIsolation transactionIsolation)
087: throws CompassException {
088: HibernateSyncTransaction tr = new HibernateSyncTransaction(
089: sessionFactory, commitBeforeCompletion, this );
090: tr.begin(session, transactionIsolation);
091: return tr;
092: }
093:
094: protected InternalCompassTransaction doContinueTransaction(
095: InternalCompassSession session) throws CompassException {
096: HibernateSyncTransaction tr = new HibernateSyncTransaction(
097: sessionFactory, commitBeforeCompletion, this );
098: tr.join(session);
099: return tr;
100: }
101:
102: public CompassSession getTransactionBoundSession()
103: throws CompassException {
104: Session session = sessionFactory.getCurrentSession();
105: if (!((SessionImplementor) session).isTransactionInProgress()) {
106: return null;
107: }
108: return (CompassSession) currentSessionMap.get(session
109: .getTransaction());
110: }
111:
112: protected void doBindSessionToTransaction(CompassTransaction tr,
113: CompassSession session) throws CompassException {
114: currentSessionMap.put(sessionFactory.getCurrentSession()
115: .getTransaction(), session);
116: }
117:
118: public void unbindSessionFromTransaction(Transaction transaction) {
119: currentSessionMap.remove(transaction);
120: }
121:
122: public SessionFactory getSessionFactory() {
123: return this.sessionFactory;
124: }
125: }
|