package uk.ac.cam.cl.dtg.teaching.hibernate;

import java.io.IOException;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.hibernate.HibernateException;
import org.hibernate.Transaction;

public class HibernateSessionRequestFilter implements Filter {

	private HibernateUtil hibernateUtil;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		hibernateUtil = HibernateUtil.getInstance();
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {

		if (hibernateUtil.isReady()) {
			hibernateUtil.getSF().getCurrentSession().beginTransaction();
		}

		chain.doFilter(request, response);

		if (hibernateUtil.isReady()) {
			Transaction t = hibernateUtil.getSF().getCurrentSession()
					.getTransaction();
			try {
				t.commit();
			} catch (HibernateException e) {
				try {
					t.rollback();
					throw new HibernateException("Caught exception trying to commit transaction",e);
				}
				catch (HibernateException e2) {
					HibernateException e3 = new HibernateException("Got exception trying to rollback transaction after failure",e2);
					e3.addSuppressed(e);
					throw e3;
				}
			}
		}
	}

	@Override
	public void destroy() {
		hibernateUtil.getSession().close();
		hibernateUtil.close();

		Enumeration<Driver> drivers = DriverManager.getDrivers();
		while (drivers.hasMoreElements()) {
			Driver driver = drivers.nextElement();
			try {
				DriverManager.deregisterDriver(driver);
			} catch (SQLException e) {

			}

		}
	}
}
@@ -394,16 +394,63 @@
 esponse;
+%0Aimport javax.servlet.http.HttpServletResponse;
 %0A%0Aimport
@@ -517,16 +517,73 @@
 saction;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Apublic
@@ -679,16 +679,109 @@
 eUtil;%0A%0A
+%09private static Logger log = LoggerFactory.getLogger(HibernateSessionRequestFilter.class);%0A%09%0A
 %09@Overri
@@ -1083,16 +1083,26 @@
 dy()) %7B%0A
+%09%09%09try %7B%0A%09
 %09%09%09hiber
@@ -1158,16 +1158,367 @@
 tion();%0A
+%09%09%09%7D catch (HibernateException e) %7B%0A%09%09%09%09// failed to get a new transaction - one reason for this might%0A%09%09%09%09// be that the connection pool is empty%0A%09%09%09%09log.error(%22Unable to open a database connection%22);%0A%09%09%09%09((HttpServletResponse)response).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,%22Unable to open a database connection%22);%0A%09%09%09%09return;%0A%09%09%09%7D%0A
 %09%09%7D%0A%0A%09%09c
@@ -1750,19 +1750,202 @@
 %09%09%09%09
-t.rollback(
+log.warn(%22Caught exception when trying to commit transaction. Rolling back.%22,e);%0A%09%09%09%09%09t.rollback();%0A%09%09%09%09%09((HttpServletResponse)response).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,%22%22
 );%0A%09
@@ -1977,16 +1977,24 @@
 ception(
+%0A%09%09%09%09%09%09%09
 %22Caught 
@@ -2033,16 +2033,17 @@
 action%22,
+ 
 e);%0A%09%09%09%09
@@ -2043,21 +2043,17 @@
 );%0A%09%09%09%09%7D
-%0A%09%09%09%09
+ 
 catch (H
@@ -2072,24 +2072,101 @@
 ption e2) %7B%0A
+%09%09%09%09%09log.error(%22Failed to rollback transaction after failing to commit%22,e2);%0A
 %09%09%09%09%09Hiberna
@@ -2205,16 +2205,24 @@
 ception(
+%0A%09%09%09%09%09%09%09
 %22Got exc
@@ -2274,16 +2274,24 @@
 ailure%22,
+%0A%09%09%09%09%09%09%09
 e2);%0A%09%09%09

Send a sensible error message if you cannot get a connection from the connection pool (e.g. if its been drained). Added warning messages if we fail to commit the transaction and have to rollback