package com.opensymphony.xwork.interceptor;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import net.sf.hibernate.FlushMode;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate.SessionFactoryUtils;
import org.springframework.orm.hibernate.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.opensymphony.webwork.ServletActionContext;
import com.opensymphony.webwork.portlet.context.PortletContext;
import com.opensymphony.xwork.ActionInvocation;
public class OpenSessionInXWorkInterceptor extends AroundInterceptor {
public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory";
private String sessionFactoryBeanName = "sessionFactory";
private boolean singleSession = true;
String alreadyInterceptedName = "OpenSessionInXWorkIntercetpor.AlreadyIntercepted";
protected final Log logger = LogFactory.getLog(getClass());
protected void before(ActionInvocation invocation) throws Exception {
}
protected void after(ActionInvocation invocation, String result) throws Exception {
}
public String intercept(ActionInvocation invocation) throws Exception {
before(invocation);
String result = "";
if (alreadyInterceptedName.equals(OpenSessionContext.getContext().getOpenSessionAlreadyIntercepted())) {
result = invocation.invoke();
} else {
OpenSessionContext.getContext().setOpenSessionAlreadyIntercepted(alreadyInterceptedName);
result = doInterceptInternal(invocation);
}
after(invocation, result);
return result;
}
protected String doInterceptInternal(ActionInvocation invocation) throws Exception {
String result = "";
SessionFactory sessionFactory = lookupSessionFactory();
Session session = null;
boolean participate = false;
if (isSingleSession()) {
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
participate = true;
} else {
if (logger.isDebugEnabled())
logger.debug("Opening single Hibernate session in OpenSessionInViewFilter");
session = getSession(sessionFactory);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
} else if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory))
participate = true;
else
SessionFactoryUtils.initDeferredClose(sessionFactory);
try {
result = invocation.invoke();
} finally {
if (!participate)
if (isSingleSession()) {
TransactionSynchronizationManager.unbindResource(sessionFactory);
if (logger.isDebugEnabled())
logger.debug("Closing single Hibernate session in OpenSessionInViewFilter");
closeSession(session, sessionFactory);
} else {
SessionFactoryUtils.processDeferredClose(sessionFactory);
}
}
return result;
}
protected SessionFactory lookupSessionFactory() {
if (logger.isDebugEnabled())
logger.debug("Using session factory '" + getSessionFactoryBeanName() + "' for OpenSessionInViewFilter");
ServletConfig sc = PortletContext.getContext().getServletConfig();
ServletContext servletContext = null;
if (sc != null) {
ServletActionContext.setServletConfig(sc);
servletContext = ServletActionContext.getServletContext();
}else {
//////////////////////Fix for Jetspeed/Tomcat ////////////////
//////////////////////Get ServletContext from PortletContext context directly //////////////
servletContext = PortletContext.getContext().getServletContext();
}
if (logger.isDebugEnabled())
logger.debug("OpenSessionInXWorkInterceptor: " + servletContext);
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
return (SessionFactory) wac.getBean(getSessionFactoryBeanName());
}
protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.NEVER);
return session;
}
protected void closeSession(Session session, SessionFactory sessionFactory) {
SessionFactoryUtils.closeSessionIfNecessary(session, sessionFactory);
}
protected boolean isSingleSession() {
return singleSession;
}
protected String getSessionFactoryBeanName() {
return sessionFactoryBeanName;
}
}