All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.compass.gps.device.jpa.embedded.eclipselink.CompassSessionEventListener Maven / Gradle / Ivy

/*
 * Copyright 2004-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.compass.gps.device.jpa.embedded.eclipselink;

import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.compass.core.Compass;
import org.compass.core.CompassSession;
import org.compass.core.CompassTransaction;
import org.compass.gps.device.jpa.embedded.JpaCompassGps;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;
import org.eclipse.persistence.sessions.UnitOfWork;

/**
 * An EclipseLink SessionEventListener that uses the transaction callback methods
 * to sync between them and Compass transaction mechanism.
 *
 * @author kimchy
 */
public class CompassSessionEventListener extends SessionEventAdapter {

    private static final Log log = LogFactory.getLog(CompassSessionEventListener.class);

    private Compass compass;

    private JpaCompassGps jpaCompassGps;

    private Properties indexSettings;

    private boolean commitBeforeCompletion;

    private boolean eclipselinkControlledTransaction;

    private ConcurrentHashMap sessionsHolders = new ConcurrentHashMap();

    public CompassSessionEventListener(Compass compass, JpaCompassGps jpaCompassGps,
                                       boolean commitBeforeCompletion, boolean eclipselinkControlledTransaction,
                                       Properties indexSettings) {
        this.compass = compass;
        this.jpaCompassGps = jpaCompassGps;
        this.commitBeforeCompletion = commitBeforeCompletion;
        this.eclipselinkControlledTransaction = eclipselinkControlledTransaction;
        this.indexSettings = indexSettings;
    }

    public Compass getCompass() {
        return compass;
    }

    public JpaCompassGps getJpaCompassGps() {
        return jpaCompassGps;
    }

    public Properties getIndexSettings() {
        return indexSettings;
    }

    public CompassSession getCurrentCompassSession(Session session) {
        if (session.isUnitOfWork()) {
            Session parentSession = ((UnitOfWork) session).getParent();
            CompassSessionHolder sessionHolder = sessionsHolders.get(parentSession);
            if (sessionHolder != null) {
                return sessionHolder.session;
            } else {
                return beginCompassSessionAndTx(parentSession).session;
            }
        } else {
            CompassSessionHolder sessionHolder = sessionsHolders.get(session);
            if (sessionHolder != null) {
                return sessionHolder.session;
            } else {
                return beginCompassSessionAndTx(session).session;
            }
        }
    }

    public void postBeginTransaction(SessionEvent event) {
        Session session = findSession(event);
        beginCompassSessionAndTx(session);
    }

    public void preCommitTransaction(SessionEvent event) {
        if (commitBeforeCompletion) {
            commit(findSession(event));
        }
    }

    public void postCommitTransaction(SessionEvent event) {
        if (!commitBeforeCompletion) {
            commit(findSession(event));
        }
    }

    public void postRollbackTransaction(SessionEvent event) {
        rollback(findSession(event));
    }

    private CompassSessionHolder beginCompassSessionAndTx(Session session) {
        CompassSession compassSession = compass.openSession();
        CompassTransaction tr = compassSession.beginTransaction();
        CompassSessionHolder sessionHolder = new CompassSessionHolder(compassSession, tr);
        sessionsHolders.put(session, sessionHolder);
        return sessionHolder;
    }

    private void commit(Session session) {
        CompassSessionHolder holder = sessionsHolders.remove(session);
        if (eclipselinkControlledTransaction) {
            try {
                holder.tr.commit();
            } finally {
                holder.session.close();
            }
        }
    }

    private void rollback(Session session) {
        CompassSessionHolder holder = sessionsHolders.remove(session);
        if (holder == null) {
            return;
        }
        if (eclipselinkControlledTransaction) {
            try {
                holder.tr.rollback();
            } finally {
                holder.session.close();
            }
        }
    }

    private Session findSession(SessionEvent event) {
        return event.getSession();
    }

    protected void finalize() throws Throwable {
        super.finalize();
        //TODO: is there a better place to close this?
        if (log.isInfoEnabled()) {
            log.info("Compass embedded EcliseLink shutting down");
        }
        if (jpaCompassGps.isRunning()) {
            jpaCompassGps.stop();
        }
        compass.close();
    }

    private class CompassSessionHolder {

        CompassSession session;

        CompassTransaction tr;

        public CompassSessionHolder(CompassSession session, CompassTransaction tr) {
            this.session = session;
            this.tr = tr;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy