org.compass.gps.device.jpa.lifecycle.HibernateJpaEntityCollectionLifecycleInjector.java Source code

Java tutorial

Introduction

Here is the source code for org.compass.gps.device.jpa.lifecycle.HibernateJpaEntityCollectionLifecycleInjector.java

Source

/*
 * 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.lifecycle;

import java.io.Serializable;
import java.util.ArrayList;
import javax.persistence.EntityManagerFactory;

import org.compass.gps.device.jpa.JpaGpsDevice;
import org.compass.gps.device.jpa.JpaGpsDeviceException;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.engine.EntityEntry;
import org.hibernate.event.AbstractCollectionEvent;
import org.hibernate.event.EventListeners;
import org.hibernate.event.PostCollectionRecreateEvent;
import org.hibernate.event.PostCollectionRecreateEventListener;
import org.hibernate.event.PostCollectionRemoveEvent;
import org.hibernate.event.PostCollectionRemoveEventListener;
import org.hibernate.event.PostCollectionUpdateEvent;
import org.hibernate.event.PostCollectionUpdateEventListener;
import org.hibernate.impl.SessionFactoryImpl;

/**
 * @author kimchy
 */
public class HibernateJpaEntityCollectionLifecycleInjector extends HibernateJpaEntityLifecycleInjector {

    public static class HibernateCollectionEventListener extends HibernateEventListener
            implements PostCollectionRecreateEventListener, PostCollectionRemoveEventListener,
            PostCollectionUpdateEventListener {

        public HibernateCollectionEventListener(JpaGpsDevice device) {
            super(device);
        }

        public void onPostRecreateCollection(PostCollectionRecreateEvent postCollectionRecreateEvent) {
            processCollectionEvent(postCollectionRecreateEvent);
        }

        public void onPostRemoveCollection(PostCollectionRemoveEvent postCollectionRemoveEvent) {
            processCollectionEvent(postCollectionRemoveEvent);
        }

        public void onPostUpdateCollection(PostCollectionUpdateEvent postCollectionUpdateEvent) {
            processCollectionEvent(postCollectionUpdateEvent);
        }

        private void processCollectionEvent(AbstractCollectionEvent event) {
            final Object entity = event.getAffectedOwnerOrNull();
            if (entity == null) {
                //Hibernate cannot determine every single time the owner especially incase detached objects are involved
                // or property-ref is used
                //Should log really but we don't know if we're interested in this collection for indexing
                return;
            }
            Serializable id = getId(entity, event);
            if (id == null) {
                log.warn("Unable to reindex entity on collection change, id cannot be extracted: "
                        + event.getAffectedOwnerEntityName());
                return;
            }

            postUpdate(entity);
        }

        private Serializable getId(Object entity, AbstractCollectionEvent event) {
            Serializable id = event.getAffectedOwnerIdOrNull();
            if (id == null) {
                //most likely this recovery is unnecessary since Hibernate Core probably try that
                EntityEntry entityEntry = event.getSession().getPersistenceContext().getEntry(entity);
                id = entityEntry == null ? null : entityEntry.getId();
            }
            return id;
        }
    }

    private Object eventListener;

    public HibernateJpaEntityCollectionLifecycleInjector() {
        super();
    }

    public HibernateJpaEntityCollectionLifecycleInjector(boolean registerPostCommitListeneres) {
        super(registerPostCommitListeneres);
    }

    public void injectLifecycle(EntityManagerFactory entityManagerFactory, JpaGpsDevice device)
            throws JpaGpsDeviceException {
        super.injectLifecycle(entityManagerFactory, device);

        if (registerPostCommitListeneres) {
            return;
        }

        HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) entityManagerFactory;
        SessionFactoryImpl sessionFactory = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory();
        EventListeners eventListeners = sessionFactory.getEventListeners();

        if (eventListener instanceof PostCollectionRecreateEventListener) {
            PostCollectionRecreateEventListener[] listeners = eventListeners
                    .getPostCollectionRecreateEventListeners();
            PostCollectionRecreateEventListener[] tempListeners = new PostCollectionRecreateEventListener[listeners.length
                    + 1];
            System.arraycopy(listeners, 0, tempListeners, 0, listeners.length);
            tempListeners[listeners.length] = (PostCollectionRecreateEventListener) eventListener;
            eventListeners.setPostCollectionRecreateEventListeners(tempListeners);
        }

        if (eventListener instanceof PostCollectionRemoveEventListener) {
            PostCollectionRemoveEventListener[] listeners = eventListeners.getPostCollectionRemoveEventListeners();
            PostCollectionRemoveEventListener[] tempListeners = new PostCollectionRemoveEventListener[listeners.length
                    + 1];
            System.arraycopy(listeners, 0, tempListeners, 0, listeners.length);
            tempListeners[listeners.length] = (PostCollectionRemoveEventListener) eventListener;
            eventListeners.setPostCollectionRemoveEventListeners(tempListeners);
        }

        if (eventListener instanceof PostCollectionUpdateEventListener) {
            PostCollectionUpdateEventListener[] listeners = eventListeners.getPostCollectionUpdateEventListeners();
            PostCollectionUpdateEventListener[] tempListeners = new PostCollectionUpdateEventListener[listeners.length
                    + 1];
            System.arraycopy(listeners, 0, tempListeners, 0, listeners.length);
            tempListeners[listeners.length] = (PostCollectionUpdateEventListener) eventListener;
            eventListeners.setPostCollectionUpdateEventListeners(tempListeners);
        }
    }

    public void removeLifecycle(EntityManagerFactory entityManagerFactory, JpaGpsDevice device)
            throws JpaGpsDeviceException {
        super.removeLifecycle(entityManagerFactory, device);

        if (registerPostCommitListeneres) {
            return;
        }

        HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) entityManagerFactory;
        SessionFactoryImpl sessionFactory = (SessionFactoryImpl) hibernateEntityManagerFactory.getSessionFactory();
        EventListeners eventListeners = sessionFactory.getEventListeners();

        PostCollectionRecreateEventListener[] postCollectionRecreateEventListeners = eventListeners
                .getPostCollectionRecreateEventListeners();
        ArrayList<PostCollectionRecreateEventListener> tempPostCollectionRecreateEventListeners = new ArrayList<PostCollectionRecreateEventListener>();
        for (PostCollectionRecreateEventListener postCollectionRecreateEventListener : postCollectionRecreateEventListeners) {
            if (!(postCollectionRecreateEventListener instanceof HibernateCollectionEventListener)) {
                tempPostCollectionRecreateEventListeners.add(postCollectionRecreateEventListener);
            }
        }
        eventListeners.setPostCollectionRecreateEventListeners(tempPostCollectionRecreateEventListeners
                .toArray(new PostCollectionRecreateEventListener[tempPostCollectionRecreateEventListeners.size()]));

        PostCollectionUpdateEventListener[] postCollectionUpdateEventListeners = eventListeners
                .getPostCollectionUpdateEventListeners();
        ArrayList<PostCollectionUpdateEventListener> tempPostCollectionUpdateEventListeners = new ArrayList<PostCollectionUpdateEventListener>();
        for (PostCollectionUpdateEventListener postCollectionUpdateEventListener : postCollectionUpdateEventListeners) {
            if (!(postCollectionUpdateEventListener instanceof HibernateCollectionEventListener)) {
                tempPostCollectionUpdateEventListeners.add(postCollectionUpdateEventListener);
            }
        }
        eventListeners.setPostCollectionUpdateEventListeners(tempPostCollectionUpdateEventListeners
                .toArray(new PostCollectionUpdateEventListener[tempPostCollectionUpdateEventListeners.size()]));

        PostCollectionRemoveEventListener[] postCollectionRemoveEventListeners = eventListeners
                .getPostCollectionRemoveEventListeners();
        ArrayList<PostCollectionRemoveEventListener> tempPostCollectionRemoveEventListeners = new ArrayList<PostCollectionRemoveEventListener>();
        for (PostCollectionRemoveEventListener postCollectionRemoveEventListener : postCollectionRemoveEventListeners) {
            if (!(postCollectionRemoveEventListener instanceof HibernateCollectionEventListener)) {
                tempPostCollectionRemoveEventListeners.add(postCollectionRemoveEventListener);
            }
        }
        eventListeners.setPostCollectionRemoveEventListeners(tempPostCollectionRemoveEventListeners
                .toArray(new PostCollectionRemoveEventListener[tempPostCollectionRemoveEventListeners.size()]));

        eventListener = null;
    }

    protected Object doCreateListener(JpaGpsDevice device) {
        eventListener = new HibernateCollectionEventListener(device);
        return eventListener;
    }
}