package co.codewizards.cloudstore.core.dto;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public final class RemoteExceptionUtil {
private RemoteExceptionUtil() { }
public static void throwOriginalExceptionIfPossible(final Error error) {
Class<?> clazz;
try {
clazz = Class.forName(error.getClassName());
} catch (final ClassNotFoundException e) {
return;
}
if (!Throwable.class.isAssignableFrom(clazz))
return;
@SuppressWarnings("unchecked")
final Class<? extends Throwable> clasz = (Class<? extends Throwable>) clazz;
final RemoteException cause = new RemoteException(error);
Throwable throwable = null;
// trying XyzException(String message, Throwable cause)
if (throwable == null)
throwable = getObjectOrNull(clasz, new Class<?>[] { String.class, Throwable.class }, error.getMessage(), cause);
// trying XyzException(String message)
if (throwable == null)
throwable = getObjectOrNull(clasz, new Class<?>[] { String.class }, error.getMessage());
// trying XyzException(Throwable cause)
if (throwable == null)
throwable = getObjectOrNull(clasz, new Class<?>[] { Throwable.class }, cause);
// trying XyzException()
if (throwable == null)
throwable = getObjectOrNull(clasz, null);
if (throwable != null) {
try {
throwable.initCause(cause);
} catch (final Exception x) {
// This happens, if either the cause was already set in an appropriate constructor (see above)
// or the concrete Throwable does not support it. If we were unable to set the cause we want,
// we better use a RemoteException and not the original one.
if (throwable.getCause() != cause)
return;
}
if (throwable instanceof RuntimeException)
throw (RuntimeException) throwable;
if (throwable instanceof java.lang.Error)
throw (java.lang.Error) throwable;
throw new RuntimeException(throwable);
}
}
private static <T> T getObjectOrNull(final Class<T> clazz, Class<?>[] argumentTypes, final Object ... arguments) {
T result = null;
if (argumentTypes == null)
argumentTypes = new Class<?> [0];
if (argumentTypes.length == 0) {
try {
result = clazz.newInstance();
} catch (final InstantiationException e) {
return null;
} catch (final IllegalAccessException e) {
return null;
}
}
if (result == null) {
Constructor<T> constructor;
try {
constructor = clazz.getConstructor(argumentTypes);
} catch (final NoSuchMethodException e) {
return null;
} catch (final SecurityException e) {
return null;
}
try {
result = constructor.newInstance(arguments);
} catch (final InstantiationException e) {
return null;
} catch (final IllegalAccessException e) {
return null;
} catch (final IllegalArgumentException e) {
return null;
} catch (final InvocationTargetException e) {
return null;
}
}
return result;
}
}