package org.jboss.ejb.plugins;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import org.jboss.ejb.Container;
import org.jboss.ejb.StatefulSessionContainer;
import org.jboss.ejb.StatefulSessionEnterpriseContext;
import org.jboss.ejb.EnterpriseContext;
import org.jboss.invocation.Invocation;
public class StatefulHASessionSynchronisationInterceptor
extends AbstractInterceptor
{
protected StatefulSessionContainer container;
protected Method isModified = null;
public void start () throws Exception
{
try
{
isModified = this.container.getBeanClass().getMethod("isModified", new Class[0]);
if (!isModified.getReturnType().equals(Boolean.TYPE)) {
isModified = null; log.warn("Found isModified method, but return type is not boolean; ignoring");
}
else
{
log.debug("Using isModified method: " + isModified);
}
}
catch (NoSuchMethodException ignored) {}
}
public Object invokeHome (Invocation mi)
throws Exception
{
EnterpriseContext ctx = (EnterpriseContext)mi.getEnterpriseContext ();
try
{
return getNext ().invokeHome (mi);
}
finally
{
if ( (ctx != null) && (ctx.getId () != null) )
{
synchronizeState (ctx);
}
}
}
public Object invoke (Invocation mi)
throws Exception
{
EnterpriseContext ctx = (EnterpriseContext)mi.getEnterpriseContext ();
try
{
return getNext ().invoke (mi);
}
catch (RemoteException e)
{
ctx = null;
throw e;
}
catch (RuntimeException e)
{
ctx = null;
throw e;
}
catch (Error e)
{
ctx = null;
throw e;
}
finally
{
if ( (ctx != null) && (ctx.getId () != null) )
{
if(isModified == null)
{
synchronizeState (ctx);
}
else
{
Boolean modified = (Boolean) isModified.invoke (ctx.getInstance (), new Object[0]);
if (modified.booleanValue ())
synchronizeState (ctx);
}
}
}
}
protected void synchronizeState (EnterpriseContext ctx) throws Exception
{
((HAPersistentManager)container.getPersistenceManager ()).synchroSession ((StatefulSessionEnterpriseContext)ctx);
}
public void setContainer (Container container)
{
this.container = (StatefulSessionContainer)container;
}
public Container getContainer ()
{
return container;
}
}