package org.jboss.web.tomcat.tc5.jca;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.resource.ResourceException;
import javax.servlet.ServletException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import org.apache.catalina.util.LifecycleSupport;
import org.jboss.logging.Logger;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.resource.connectionmanager.CachedConnectionManager;
public class CachedConnectionValve extends ValveBase implements Lifecycle
{
private static final Logger log = Logger.getLogger(CachedConnectionValve.class);
private static final String info = "CachedConnectionValve/1.0";
protected LifecycleSupport support = new LifecycleSupport(this);
protected String ccmName;
protected CachedConnectionManager ccm;
protected String tmName;
protected TransactionManager tm;
protected Set unsharableResources = new HashSet();
public CachedConnectionValve()
{
super();
}
public String getInfo()
{
return info;
}
public String getCachedConnectionManagerObjectName()
{
return ccmName;
}
public void setCachedConnectionManagerObjectName(String ccmName)
{
this.ccmName = ccmName;
}
public String getTransactionManagerObjectName()
{
return tmName;
}
public void setTransactionManagerObjectName(String tmName)
{
this.tmName = tmName;
}
public void invoke(Request request, Response response) throws IOException, ServletException
{
try
{
ccm.pushMetaAwareObject(this, unsharableResources);
try
{
getNext().invoke(request, response);
}
finally
{
ccm.popMetaAwareObject(unsharableResources);
checkTransactionComplete(request);
}
}
catch (ResourceException e)
{
throw new ServletException("Error invoking cached connection manager", e);
}
}
public void addLifecycleListener(LifecycleListener listener)
{
support.addLifecycleListener(listener);
}
public void removeLifecycleListener(LifecycleListener listener)
{
support.removeLifecycleListener(listener);
}
public LifecycleListener[] findLifecycleListeners()
{
return support.findLifecycleListeners();
}
public void start() throws LifecycleException
{
try
{
MBeanServer server = MBeanServerLocator.locateJBoss();
ccm = (CachedConnectionManager) server.getAttribute(new ObjectName(ccmName), "Instance");
tm = (TransactionManager) server.getAttribute(new ObjectName(tmName), "TransactionManager");
}
catch (Exception e)
{
throw new LifecycleException(e);
}
support.fireLifecycleEvent(START_EVENT, this);
}
public void stop() throws LifecycleException
{
support.fireLifecycleEvent(STOP_EVENT, this);
unsharableResources.clear();
}
protected void checkTransactionComplete(Request request)
{
int status = Status.STATUS_NO_TRANSACTION;
try
{
status = tm.getStatus();
}
catch (SystemException ex)
{
log.error("Failed to get status", ex);
}
switch (status)
{
case Status.STATUS_ACTIVE:
case Status.STATUS_COMMITTING:
case Status.STATUS_MARKED_ROLLBACK:
case Status.STATUS_PREPARING:
case Status.STATUS_ROLLING_BACK:
try
{
tm.rollback();
}
catch (Exception ex)
{
log.error("Failed to rollback", ex);
}
case Status.STATUS_PREPARED:
String servletName = "<Unknown>";
try
{
Wrapper servlet = request.getWrapper();
if (servlet != null)
{
servletName = servlet.getName();
if (servlet.getJspFile() != null)
servletName = servlet.getJspFile();
}
}
catch (Throwable ignored)
{
}
String msg = "Application error: " + servletName + " did not complete its transaction";
log.error(msg);
}
}
}