package com.nominanuda.hyperapi; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.nominanuda.web.http.Http400Exception; import com.nominanuda.web.http.Http401Exception; import com.nominanuda.web.http.Http403Exception; import com.nominanuda.web.http.Http404Exception; import com.nominanuda.web.http.Http4xxException; import com.nominanuda.web.http.Http5xxException; import com.nominanuda.web.http.HttpAppException; import com.nominanuda.zen.common.Tuple2; import com.nominanuda.zen.obj.Obj; public class ExceptionCatcherFactory { protected IHttpAppExceptionRenderer exceptionRenderer = new IHttpAppExceptionRenderer() { @Override public Tuple2<Integer, Object> statusAndRender(HttpAppException e, Class<?> returnType) { Object result = returnType.isAssignableFrom(Obj.class) ? Obj.make() : new Object(); return new Tuple2<Integer, Object>(e.getStatusCode(), result); } @Override public void parseAndThrow(int status, Object response) throws HttpAppException { if(response == null) { response = "null"; } if (status >= 400) { if (status < 500) { switch (status) { case 400: throw new Http400Exception(response.toString()); case 401: throw new Http401Exception(response.toString()); case 403: throw new Http403Exception(response.toString()); case 404: throw new Http404Exception(response.toString()); default: throw new Http4xxException(response.toString(), status); } } throw new Http5xxException(response.toString(), status); } } }; public <T> T getInstance(final T apiImpl, Class<? extends T> apiInterface) { return apiInterface.cast(Proxy.newProxyInstance(apiInterface.getClassLoader(), new Class[] { apiInterface }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { return method.invoke(apiImpl, args); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); if (cause != null && cause instanceof HttpAppException) { return exceptionRenderer.statusAndRender((HttpAppException)cause, method.getReturnType()).get1(); } } return null; } })); } /* setters */ public void setExceptionRenderer(IHttpAppExceptionRenderer exceptionRenderer) { this.exceptionRenderer = exceptionRenderer; } }