package org.jboss.ejb.plugins;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.rmi.NoSuchObjectException;
import java.rmi.RemoteException;
import java.rmi.ServerError;
import java.rmi.ServerException;
import java.rmi.AccessException;
import java.security.GeneralSecurityException;
import javax.ejb.EJBException;
import javax.ejb.NoSuchEntityException;
import javax.ejb.NoSuchObjectLocalException;
import javax.ejb.TransactionRolledbackLocalException;
import javax.ejb.AccessLocalException;
import javax.transaction.TransactionRolledbackException;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.InvocationType;
import org.jboss.metadata.BeanMetaData;
import org.jboss.tm.JBossTransactionRolledbackException;
import org.jboss.tm.JBossTransactionRolledbackLocalException;
public class LogInterceptor extends AbstractInterceptor
{
protected String ejbName;
protected boolean callLogging;
public void create()
throws Exception
{
super.start();
BeanMetaData md = getContainer().getBeanMetaData();
ejbName = md.getEjbName();
callLogging = md.getContainerConfiguration().getCallLogging();
}
public Object invokeHome(Invocation invocation)
throws Exception
{
String methodName;
if (invocation.getMethod() != null)
{
methodName = invocation.getMethod().getName();
}
else
{
methodName = "<no method>";
}
boolean trace = log.isTraceEnabled();
if (trace)
{
log.trace("Start method=" + methodName);
}
if (callLogging)
{
StringBuffer str = new StringBuffer("InvokeHome: ");
str.append(methodName);
str.append("(");
Object[] args = invocation.getArguments();
if (args != null)
{
for (int i = 0; i < args.length; i++)
{
if (i > 0)
{
str.append(",");
}
str.append(args[i]);
}
}
str.append(")");
log.debug(str.toString());
}
try
{
return getNext().invokeHome(invocation);
}
catch(Throwable e)
{
throw handleException(e, invocation);
}
finally
{
if (trace)
{
log.trace("End method=" + methodName);
}
}
}
public Object invoke(Invocation invocation)
throws Exception
{
String methodName;
if (invocation.getMethod() != null)
{
methodName = invocation.getMethod().getName();
}
else
{
methodName = "<no method>";
}
boolean trace = log.isTraceEnabled();
if (trace)
{
log.trace("Start method=" + methodName);
}
if (callLogging)
{
StringBuffer str = new StringBuffer("Invoke: ");
if (invocation.getId() != null)
{
str.append("[" + invocation.getId().toString() + "] ");
}
str.append(methodName);
str.append("(");
Object[] args = invocation.getArguments();
if (args != null)
{
for (int i = 0; i < args.length; i++)
{
if (i > 0)
{
str.append(",");
}
str.append(args[i]);
}
}
str.append(")");
log.debug(str.toString());
}
try
{
return getNext().invoke(invocation);
}
catch(Throwable e)
{
throw handleException(e, invocation);
}
finally
{
if (trace)
{
log.trace("End method=" + methodName);
}
}
}
private Exception handleException(Throwable e, Invocation invocation)
{
InvocationType type = invocation.getType();
boolean isLocal =
type == InvocationType.LOCAL ||
type == InvocationType.LOCALHOME;
if (e instanceof TransactionRolledbackLocalException ||
e instanceof TransactionRolledbackException)
{
if (isLocal && e instanceof TransactionRolledbackException)
{
TransactionRolledbackException remoteTxRollback =
(TransactionRolledbackException)e;
Exception cause;
if (remoteTxRollback.detail instanceof Exception)
{
cause = (Exception)remoteTxRollback.detail;
}
else if (remoteTxRollback.detail instanceof Error)
{
String msg = formatException(
"Unexpected Error",
remoteTxRollback.detail);
cause = new EJBException(msg);
}
else
{
String msg = formatException(
"Unexpected Throwable",
remoteTxRollback.detail);
cause = new EJBException(msg);
}
e = new JBossTransactionRolledbackLocalException(
remoteTxRollback.getMessage(),
cause);
}
if (!isLocal && e instanceof TransactionRolledbackLocalException)
{
TransactionRolledbackLocalException localTxRollback =
(TransactionRolledbackLocalException)e;
e = new JBossTransactionRolledbackException(
localTxRollback.getMessage(), localTxRollback.getCausedByException());
}
Throwable cause = null;
String exceptionType = null;
if (e instanceof TransactionRolledbackException)
{
cause = ((TransactionRolledbackException)e).detail;
exceptionType = "TransactionRolledbackException";
}
else
{
cause =
((TransactionRolledbackLocalException)e).getCausedByException();
exceptionType = "TransactionRolledbackLocalException";
}
if (cause != null)
{
if ((cause instanceof EJBException) &&
(((EJBException) cause).getCausedByException() != null))
{
cause = ((EJBException) cause).getCausedByException();
}
log.error(exceptionType + " in method: " + invocation.getMethod()
+ ", causedBy:", cause);
}
else
{
log.error(exceptionType + " in method: " + invocation.getMethod(), e);
}
return (Exception)e;
}
if (e instanceof NoSuchEntityException)
{
NoSuchEntityException noSuchEntityException =
(NoSuchEntityException) e;
if (noSuchEntityException.getCausedByException() != null)
{
log.error("NoSuchEntityException in method: " + invocation.getMethod() + ", causedBy:",
noSuchEntityException.getCausedByException());
}
else
{
log.error("NoSuchEntityException in method: " + invocation.getMethod() + ":", noSuchEntityException);
}
if (isLocal)
{
return new NoSuchObjectLocalException(
noSuchEntityException.getMessage(),
noSuchEntityException.getCausedByException());
}
else
{
NoSuchObjectException noSuchObjectException =
new NoSuchObjectException(noSuchEntityException.getMessage());
noSuchObjectException.detail = noSuchEntityException;
return noSuchObjectException;
}
}
if (e instanceof EJBException)
{
EJBException ejbException = (EJBException) e;
if (ejbException.getCausedByException() != null)
{
log.error("EJBException in method: " + invocation.getMethod() + ", causedBy:",
ejbException.getCausedByException());
}
else
{
log.error("EJBException in method: " + invocation.getMethod() + ":", ejbException);
}
if (isLocal)
{
return ejbException;
}
else
{
return new ServerException("EJBException:", ejbException);
}
}
if (e instanceof SecurityException || e instanceof GeneralSecurityException)
{
Exception runtimeException = (Exception)e;
log.debug("SecurityException in method: " + invocation.getMethod() + ":", runtimeException);
if (isLocal)
{
return new AccessLocalException("SecurityException", runtimeException);
}
else
{
return new AccessException("SecurityException", runtimeException);
}
}
if (e instanceof RuntimeException)
{
RuntimeException runtimeException = (RuntimeException)e;
log.error("RuntimeException in method: " + invocation.getMethod() + ":", runtimeException);
if (isLocal)
{
return new EJBException("RuntimeException", runtimeException);
}
else
{
return new ServerException("RuntimeException", runtimeException);
}
}
if (e instanceof Error)
{
log.error("Unexpected Error in method: " + invocation.getMethod(), e);
if (isLocal)
{
String msg = formatException("Unexpected Error", e);
return new EJBException(msg);
}
else
{
return new ServerError("Unexpected Error", (Error)e);
}
}
if(isLocal && e instanceof RemoteException)
{
if (callLogging)
{
log.info("Remote Exception in method: " + invocation.getMethod(), e);
}
return new EJBException((RemoteException)e);
}
if (e instanceof Exception)
{
if (callLogging)
{
log.info("Application Exception in method: " + invocation.getMethod(), e);
}
return (Exception)e;
}
else
{
String msg = formatException("Unexpected Throwable", e);
log.warn("Unexpected Throwable in method: " + invocation.getMethod(), e);
if (isLocal)
{
return new EJBException(msg);
}
else
{
return new ServerException(msg);
}
}
}
private String formatException(String msg, Throwable t)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
if (msg != null)
pw.println(msg);
if (t != null)
{
t.printStackTrace(pw);
} return sw.toString();
}
}