private T proxy()

in java/src/main/java/org/apache/brooklyn/rest/client/BrooklynApi.java [231:282]


    private <T> T proxy(Class<T> clazz) {
        AggregateClassLoader aggregateClassLoader =  AggregateClassLoader.newInstanceWithNoLoaders();
        aggregateClassLoader.addLast(clazz.getClassLoader());
        aggregateClassLoader.addLast(getClass().getClassLoader());

        final T result0 = ProxyBuilder.build(clazz, target)
                .executor(clientExecutor)
                .classloader(aggregateClassLoader)
                .providerFactory(ResteasyProviderFactory.getInstance())
                .extractorFactory(new DefaultEntityExtractorFactory())
                .requestAttributes(MutableMap.<String, Object>of())
                .now();

        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz }, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                try {
                    Object result1 = method.invoke(result0, args);
                    Class<?> type = String.class;
                    if (result1 instanceof Response) {
                        Response resp = (Response)result1;
                        if(isStatusCodeHealthy(resp.getStatus()) && method.isAnnotationPresent(ApiOperation.class)) {
                           type = getClassFromMethodAnnotationOrDefault(method, type);
                        }
                        // wrap the original response so it self-closes
                        result1 = BuiltResponsePreservingError.copyResponseAndClose(resp, type);
                    }
                    return result1;
                } catch (Throwable e) {
                    if (e instanceof InvocationTargetException) {
                        // throw the original exception
                        e = ((InvocationTargetException)e).getTargetException();
                    }
                    throw Exceptions.propagate(e);
                }
            }

            private boolean isStatusCodeHealthy(int code) { return (code>=200 && code<=299); }

            private Class<?> getClassFromMethodAnnotationOrDefault(Method method, Class<?> def){
                Class<?> type;
                try{
                    type = method.getAnnotation(ApiOperation.class).response();
                } catch (Exception e) {
                    type = def;
                    LOG.debug("Unable to get class from annotation: {}.  Defaulting to {}", e.getMessage(), def.getName());
                    Exceptions.propagateIfFatal(e);
                }
                return type;
            }
        });
    }