package org.testory.proxy.proxer;
import static org.testory.proxy.ProxyException.check;
import java.lang.reflect.Constructor;
import org.testory.proxy.Handler;
import org.testory.proxy.Invocation;
import org.testory.proxy.Proxer;
import org.testory.proxy.ProxyException;
import org.testory.proxy.Typing;
public class WrappingProxer implements Proxer {
private final Constructor<? extends RuntimeException> constructor;
private final Proxer proxer;
private WrappingProxer(Constructor<? extends RuntimeException> constructor, Proxer proxer) {
this.constructor = constructor;
this.proxer = proxer;
}
public static Proxer wrapping(Class<? extends RuntimeException> type, Proxer proxer) {
check(type != null);
check(proxer != null);
try {
return new WrappingProxer(type.getConstructor(Throwable.class), proxer);
} catch (NoSuchMethodException e) {
throw new ProxyException(e);
}
}
public Object proxy(Typing typing, Handler handler) {
try {
return proxer.proxy(typing, wrapping(handler));
} catch (ProxyException e) {
throw wrap(e);
}
}
private Handler wrapping(final Handler handler) {
return new Handler() {
public Object handle(Invocation invocation) throws Throwable {
try {
return handler.handle(invocation);
} catch (ProxyException e) {
throw wrap(e);
}
}
};
}
private RuntimeException wrap(ProxyException exception) {
try {
return constructor.newInstance(exception);
} catch (ReflectiveOperationException e) {
throw new ProxyException(e);
}
}
}