001package co.codewizards.cloudstore.core.dto; 002 003import java.lang.reflect.Constructor; 004import java.lang.reflect.InvocationTargetException; 005 006public final class RemoteExceptionUtil { 007 008 private RemoteExceptionUtil() { } 009 010 public static void throwOriginalExceptionIfPossible(final Error error) { 011 Class<?> clazz; 012 try { 013 clazz = Class.forName(error.getClassName()); 014 } catch (final ClassNotFoundException e) { 015 return; 016 } 017 if (!Throwable.class.isAssignableFrom(clazz)) 018 return; 019 020 @SuppressWarnings("unchecked") 021 final Class<? extends Throwable> clasz = (Class<? extends Throwable>) clazz; 022 023 final RemoteException cause = new RemoteException(error); 024 025 Throwable throwable = null; 026 027 // trying XyzException(String message, Throwable cause) 028 if (throwable == null) 029 throwable = getObjectOrNull(clasz, new Class<?>[] { String.class, Throwable.class }, error.getMessage(), cause); 030 031 // trying XyzException(String message) 032 if (throwable == null) 033 throwable = getObjectOrNull(clasz, new Class<?>[] { String.class }, error.getMessage()); 034 035 // trying XyzException(Throwable cause) 036 if (throwable == null) 037 throwable = getObjectOrNull(clasz, new Class<?>[] { Throwable.class }, cause); 038 039 // trying XyzException() 040 if (throwable == null) 041 throwable = getObjectOrNull(clasz, null); 042 043 if (throwable != null) { 044 try { 045 throwable.initCause(cause); 046 } catch (final Exception x) { 047 // This happens, if either the cause was already set in an appropriate constructor (see above) 048 // or the concrete Throwable does not support it. If we were unable to set the cause we want, 049 // we better use a RemoteException and not the original one. 050 if (throwable.getCause() != cause) 051 return; 052 } 053 if (throwable instanceof RuntimeException) 054 throw (RuntimeException) throwable; 055 056 if (throwable instanceof java.lang.Error) 057 throw (java.lang.Error) throwable; 058 059 throw new RuntimeException(throwable); 060 } 061 } 062 063 private static <T> T getObjectOrNull(final Class<T> clazz, Class<?>[] argumentTypes, final Object ... arguments) { 064 T result = null; 065 if (argumentTypes == null) 066 argumentTypes = new Class<?> [0]; 067 068 if (argumentTypes.length == 0) { 069 try { 070 result = clazz.newInstance(); 071 } catch (final InstantiationException e) { 072 return null; 073 } catch (final IllegalAccessException e) { 074 return null; 075 } 076 } 077 078 if (result == null) { 079 Constructor<T> constructor; 080 try { 081 constructor = clazz.getConstructor(argumentTypes); 082 } catch (final NoSuchMethodException e) { 083 return null; 084 } catch (final SecurityException e) { 085 return null; 086 } 087 088 try { 089 result = constructor.newInstance(arguments); 090 } catch (final InstantiationException e) { 091 return null; 092 } catch (final IllegalAccessException e) { 093 return null; 094 } catch (final IllegalArgumentException e) { 095 return null; 096 } catch (final InvocationTargetException e) { 097 return null; 098 } 099 } 100 101 return result; 102 } 103}