001 /* Copyright 2006-2009 the original author or authors. 002 * 003 * Licensed under the Apache License, Version 2.0 (the "License"); 004 * you may not use this file except in compliance with the License. 005 * You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software 010 * distributed under the License is distributed on an "AS IS" BASIS, 011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 * See the License for the specific language governing permissions and 013 * limitations under the License. 014 */ 015 package org.codehaus.groovy.grails.plugins.springsecurity; 016 017 import org.apache.log4j.Logger; 018 import org.hibernate.Session; 019 import org.hibernate.SessionFactory; 020 import org.springframework.orm.hibernate3.SessionFactoryUtils; 021 import org.springframework.orm.hibernate3.SessionHolder; 022 import org.springframework.transaction.support.TransactionSynchronizationManager; 023 import org.springframework.web.context.support.WebApplicationObjectSupport; 024 025 /** 026 * Grails Web Application Object Support. 027 * 028 * @author T.Yamamoto 029 * @author <a href='mailto:beckwithb@studentsonly.com'>Burt Beckwith</a> 030 */ 031 public abstract class GrailsWebApplicationObjectSupport extends WebApplicationObjectSupport { 032 033 private final Logger _log = Logger.getLogger(getClass()); 034 035 private SessionFactory _sessionFactory; 036 037 /** 038 * Dependency injection for Hibernate session factory. 039 * @param sessionFactory the factory 040 */ 041 public void setSessionFactory(final SessionFactory sessionFactory) { 042 _sessionFactory = sessionFactory; 043 } 044 045 /** 046 * Holds the session created or existing session and a flag indicating whether it was 047 * existing (so we know whether to close it or not). 048 */ 049 public static class SessionContainer { 050 private final Session _session; 051 private final boolean _existingSession; 052 053 private SessionContainer(final Session session, final boolean existingSession) { 054 _session = session; 055 _existingSession = existingSession; 056 } 057 058 /** 059 * Get the session. 060 * @return the session 061 */ 062 public Session getSession() { 063 return _session; 064 } 065 } 066 067 /** 068 * Set up hibernate session. 069 * @return the session container, which holds the session and a boolean indicating if the session was pre-existing 070 */ 071 protected SessionContainer setUpSession() { 072 SessionFactory sessionFactory = getSessionFactory(); 073 074 Session session; 075 boolean existing; 076 if (TransactionSynchronizationManager.hasResource(sessionFactory)) { 077 _log.debug("Session already has transaction attached"); 078 existing = true; 079 session = ((SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory)).getSession(); 080 } 081 else { 082 _log.debug("Session does not have transaction attached... Creating new one"); 083 existing = false; 084 session = SessionFactoryUtils.getSession(sessionFactory, true); 085 SessionHolder sessionHolder = new SessionHolder(session); 086 TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder); 087 } 088 089 return new SessionContainer(session, existing); 090 } 091 092 /** 093 * Release Session. 094 */ 095 protected void releaseSession(final SessionContainer session) { 096 if (session._existingSession) { 097 return; 098 } 099 100 SessionFactory sessionFactory = getSessionFactory(); 101 SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.unbindResource(sessionFactory); 102 SessionFactoryUtils.releaseSession(sessionHolder.getSession(), sessionFactory); 103 _log.debug("Session released"); 104 } 105 106 private SessionFactory getSessionFactory() { 107 if (_sessionFactory == null) { 108 // should be set via DI, but for backwards compatibility lookup the standard bean 109 _sessionFactory = (SessionFactory)getWebApplicationContext().getBean("sessionFactory"); 110 } 111 return _sessionFactory; 112 } 113 }