Package io.dropwizard.hibernate

Source Code of io.dropwizard.hibernate.UnitOfWorkApplicationListener$UnitOfWorkEventListener

package io.dropwizard.hibernate;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.ext.Provider;

import org.glassfish.jersey.server.model.Resource;
import org.glassfish.jersey.server.model.ResourceMethod;
import org.glassfish.jersey.server.monitoring.ApplicationEvent;
import org.glassfish.jersey.server.monitoring.ApplicationEventListener;
import org.glassfish.jersey.server.monitoring.RequestEvent;
import org.glassfish.jersey.server.monitoring.RequestEventListener;

import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.context.internal.ManagedSessionContext;


/**
* An application event listener that listens for Jersey application initialization to
* be finished, then creates a map of resource method that have metrics annotations.
*
* Finally, it listens for method start events, and returns a {@link RequestEventListener}
* that updates the relevant metric for suitably annotated methods when it gets the
* request events indicating that the method is about to be invoked, or just got done
* being invoked.
*/
@Provider
public class UnitOfWorkApplicationListener implements ApplicationEventListener {

    private final SessionFactory sessionFactory;

    /**
     * Construct an application event listener using the given session factory.
     *
     * <p/>
     * When using this constructor, the {@link UnitOfWorkApplicationListener}
     * should be added to a Jersey {@code ResourceConfig} as a singleton.
     *
     * @param sessionFactory a {@link SessionFactory}
     */
    public UnitOfWorkApplicationListener (SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    private static class UnitOfWorkEventListener implements RequestEventListener {
        private final Map<Method,UnitOfWork> methodMap;
        private final SessionFactory sessionFactory;
        private UnitOfWork unitOfWork;
        private Session session;


        public UnitOfWorkEventListener (Map<Method,UnitOfWork> methodMap,
                                        SessionFactory sessionFactory) {
            this.methodMap = methodMap;
            this.sessionFactory = sessionFactory;
        }

        @Override
        public void onEvent(RequestEvent event) {
            if (event.getType() == RequestEvent.Type.RESOURCE_METHOD_START) {
                this.unitOfWork = this.methodMap.get(event.getUriInfo()
                        .getMatchedResourceMethod().getInvocable().getDefinitionMethod());
                if (unitOfWork != null) {
                    this.session = this.sessionFactory.openSession();
                    try {
                        configureSession();
                        ManagedSessionContext.bind(this.session);
                        beginTransaction();
                    } catch (Throwable th) {
                        this.session.close();
                        this.session = null;
                        ManagedSessionContext.unbind(this.sessionFactory);
                        throw th;
                    }
                }
            }
            else if (event.getType() == RequestEvent.Type.RESOURCE_METHOD_FINISHED) {
                if (this.session != null) {
                    try {
                        commitTransaction();
                    } catch (Exception e) {
                        rollbackTransaction();
                        this.<RuntimeException>rethrow(e);
                    }
                    finally {
                        this.session.close();
                        this.session = null;
                        ManagedSessionContext.unbind(this.sessionFactory);
                    }
                }
            }
            else if (event.getType() == RequestEvent.Type.ON_EXCEPTION) {
                if (this.session != null) {
                    try {
                        rollbackTransaction();
                    }
                    finally {
                        this.session.close();
                        this.session = null;
                        ManagedSessionContext.unbind(this.sessionFactory);
                    }
                }
            }
        }

        private void beginTransaction() {
            if (this.unitOfWork.transactional()) {
                this.session.beginTransaction();
            }
        }

        private void configureSession() {
            this.session.setDefaultReadOnly(this.unitOfWork.readOnly());
            this.session.setCacheMode(this.unitOfWork.cacheMode());
            this.session.setFlushMode(this.unitOfWork.flushMode());
        }

        private void rollbackTransaction() {
            if (this.unitOfWork.transactional()) {
                final Transaction txn = this.session.getTransaction();
                if (txn != null && txn.isActive()) {
                    txn.rollback();
                }
            }
        }

        private void commitTransaction() {
            if (this.unitOfWork.transactional()) {
                final Transaction txn = this.session.getTransaction();
                if (txn != null && txn.isActive()) {
                    txn.commit();
                }
            }
        }

        @SuppressWarnings("unchecked")
        private <E extends Exception> void rethrow(Exception e) throws E {
            throw (E) e;
        }
    }

    private Map<Method,UnitOfWork> methodMap = new HashMap<>();

    @Override
    public void onEvent(ApplicationEvent event) {
        if (event.getType() == ApplicationEvent.Type.INITIALIZATION_APP_FINISHED) {
            for (Resource resource : event.getResourceModel().getResources()) {
                for (ResourceMethod method : resource.getAllMethods()) {
                    registerUnitOfWorkAnnotations (method);
                }

                for (Resource childResource : resource.getChildResources()) {
                    for (ResourceMethod method : childResource.getAllMethods()) {
                        registerUnitOfWorkAnnotations (method);
                    }
                }
            }
        }
    }

    @Override
    public RequestEventListener onRequest(RequestEvent event) {
        RequestEventListener listener = new UnitOfWorkEventListener (methodMap, sessionFactory);

        return listener;
    }

    private void registerUnitOfWorkAnnotations (ResourceMethod method) {
        UnitOfWork annotation = method.getInvocable().getDefinitionMethod().getAnnotation(UnitOfWork.class);

        if (annotation != null) {
            this.methodMap.put(method.getInvocable().getDefinitionMethod(), annotation);
        }

    }
}
TOP

Related Classes of io.dropwizard.hibernate.UnitOfWorkApplicationListener$UnitOfWorkEventListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.