package games.strategy.engine.message;
import java.io.Serializable;
import java.lang.reflect.Method;
import games.strategy.engine.message.unifiedmessenger.UnifiedMessenger;
import games.strategy.triplea.util.WrappedInvocationHandler;
/**
* Invocation handler for the UnifiedMessenger.
*
* <p>
* Handles the invocation for a channel
* </p>
*/
class UnifiedInvocationHandler extends WrappedInvocationHandler {
private final UnifiedMessenger m_messenger;
private final String m_endPointName;
private final boolean m_ignoreResults;
private final Class<?> m_remoteType;
public UnifiedInvocationHandler(final UnifiedMessenger messenger, final String endPointName,
final boolean ignoreResults, final Class<?> remoteType) {
// equality and hash code are bassed on end point name
super(endPointName);
m_messenger = messenger;
m_endPointName = endPointName;
m_ignoreResults = ignoreResults;
m_remoteType = remoteType;
}
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
if (super.shouldHandle(method, args)) {
return super.handle(method, args);
}
if (args != null) {
for (final Object o : args) {
if (o != null && !(o instanceof Serializable)) {
throw new IllegalArgumentException(
o + " is not serializable, all remote method args must be serializable. method:" + method);
}
}
}
final RemoteMethodCall remoteMethodMsg =
new RemoteMethodCall(m_endPointName, method.getName(), args, method.getParameterTypes(), m_remoteType);
if (m_ignoreResults) {
m_messenger.invoke(m_endPointName, remoteMethodMsg);
return null;
} else {
final RemoteMethodCallResults response = m_messenger.invokeAndWait(m_endPointName, remoteMethodMsg);
if (response.getException() != null) {
if (response.getException() instanceof MessengerException) {
final MessengerException cle = (MessengerException) response.getException();
cle.fillInInvokerStackTrace();
} else {
// do not chain the exception, we want to keep whatever the original exception's class was, so just add our
// bit to the stack
// trace.
final Throwable throwable = response.getException();
final StackTraceElement[] exceptionTrace = throwable.getStackTrace();
final Exception ourException =
new Exception(throwable.getMessage() + " exception in response from other system");
// Thread.currentThread().getStackTrace();
final StackTraceElement[] ourTrace = ourException.getStackTrace();
if (exceptionTrace != null && ourTrace != null) {
final StackTraceElement[] combinedTrace = new StackTraceElement[(exceptionTrace.length + ourTrace.length)];
int i = 0;
for (final StackTraceElement element : exceptionTrace) {
combinedTrace[i] = element;
i++;
}
for (final StackTraceElement element : ourTrace) {
combinedTrace[i] = element;
i++;
}
throwable.setStackTrace(combinedTrace);
}
}
throw response.getException();
}
return response.getRVal();
}
}
}