Source code: info/crossbar/filtersAndListeners/PersistenceFilter.java
1 /*
2 * @(#)PersistenceFilter.java $Revision: 1.3 $ $Date: 2003/06/04 04:55:33 $
3 *
4 * Copyright 2002 by Daniel Kehoe <kehoe@fortuity.com>
5 * All Rights Reserved
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28 package info.crossbar.filtersAndListeners;
29
30 import java.util.logging.*;
31 import java.util.*;
32
33 import java.io.IOException;
34
35 import javax.servlet.*;
36
37 import net.sf.hibernate.*;
38
39 import info.crossbar.state.App;
40 import info.crossbar.util.db.Pool;
41
42 /**
43 * PersistenceFilter class for use by <a href="http://www.crossbar.info/">Crossbar</a>.
44 *
45 * @author Daniel Kehoe, <a href="http://www.fortuity.com/">Fortuity Consulting</a>
46 * @version <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/crossbar/crossbar-sitemap/src/java/info/crossbar/filtersAndListeners/PersistenceFilter.java">View source, revision history</a>
47 * $Revision: 1.3 $ $Date: 2003/06/04 04:55:33 $
48 * <p>
49 * DESCRIPTION:
50 * Filter which manages a ThreadLocal hibernate session. Obtain the session
51 * by calling PersistenceFilter.getSession(). Based on an
52 * <a href="http://hibernate.bluemars.net/43.html">example</a> by Jeff Schnitzer.
53 */
54 public class PersistenceFilter implements javax.servlet.Filter {
55
56 /**
57 * Set up logging.
58 */
59 private static Logger log = Logger.getLogger(PersistenceFilter.class.getName());
60
61 /**
62 * Holds the current hibernate session, if one has been created.
63 */
64 protected static ThreadLocal hibernateHolder = new ThreadLocal();
65
66 /**
67 */
68 protected static SessionFactory factory;
69
70 /**
71 */
72 public void init(FilterConfig filterConfig) throws ServletException
73 {
74 // Hibernate is initialized by the ContextListener when the webapp is launched.
75 // Get the Hibernate SessionFactory from the application context:
76 factory = (SessionFactory) App.context.getAttribute("session_factory");
77 }
78
79 /**
80 */
81 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
82 throws IOException, ServletException
83 {
84 if (hibernateHolder.get() != null) {
85 String msg = "A Hibernate session is already associated with this thread! "
86 + "Someone must have called getSession() outside of the context "
87 + "of a servlet request.";
88 log.severe(msg);
89 throw new IllegalStateException(msg);
90 }
91 try {
92 chain.doFilter(request, response);
93 }
94 finally {
95 Session sess = (Session)hibernateHolder.get();
96 if (sess != null) {
97 hibernateHolder.set(null);
98 try {
99 sess.close();
100 log.fine("closing Hibernate session for this request");
101 }
102 catch (HibernateException ex) { throw new ServletException(ex); }
103 }
104 }
105 }
106
107 /**
108 * ONLY ever call this method from within the context of a servlet request
109 * (specifically, one that has been associated with this filter). If you
110 * want a Hibernate session at some other time, call getSessionFactory()
111 * and open/close the session yourself.
112 *
113 * @return an appropriate Session object
114 */
115 public static Session getSession() throws HibernateException
116 {
117 Session sess = (Session)hibernateHolder.get();
118
119 if (sess == null)
120 {
121 sess = factory.openSession();
122 hibernateHolder.set(sess);
123 log.fine("established Hibernate session for this request");
124 }
125 return sess;
126 }
127
128 /**
129 * @return the hibernate session factory
130 */
131 public static SessionFactory getSessionFactory()
132 {
133 return factory;
134 }
135
136 /**
137 */
138 public void destroy()
139 {
140 Session sess = (Session)hibernateHolder.get();
141 if (sess != null) {
142 hibernateHolder.set(null);
143 try {
144 sess.close();
145 log.fine("session destroyed, closing Hibernate session");
146 } catch (HibernateException ex) {
147 log.warning("session destroyed, problem closing Hibernate session: " + ex);
148 }
149 }
150 }
151 }