in juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java [7332:7424]
public <T> T getRemote(final Class<T> interfaceClass, Object rootUrl, final Serializer serializer, final Parser parser) {
if (rootUrl == null)
rootUrl = this.rootUrl;
final String restUrl2 = trimSlashes(emptyIfNull(rootUrl));
return (T)Proxy.newProxyInstance(
interfaceClass.getClassLoader(),
new Class[] { interfaceClass },
new InvocationHandler() {
final RemoteMeta rm = new RemoteMeta(interfaceClass);
@Override /* InvocationHandler */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
RemoteOperationMeta rom = rm.getOperationMeta(method);
String uri = rom.getFullPath();
if (uri.indexOf("://") == -1)
uri = restUrl2 + '/' + uri;
if (uri.indexOf("://") == -1)
throw new RemoteMetadataException(interfaceClass, "Root URI has not been specified. Cannot construct absolute path to remote resource.");
String httpMethod = rom.getHttpMethod();
RestRequest rc = request(httpMethod, uri, hasContent(httpMethod));
rc.serializer(serializer);
rc.parser(parser);
rm.getHeaders().forEach(x -> rc.header(x));
rom.forEachPathArg(a -> rc.pathArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer)));
rom.forEachQueryArg(a -> rc.queryArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer), a.isSkipIfEmpty()));
rom.forEachFormDataArg(a -> rc.formDataArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer), a.isSkipIfEmpty()));
rom.forEachHeaderArg(a -> rc.headerArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer), a.isSkipIfEmpty()));
RemoteOperationArg ba = rom.getContentArg();
if (ba != null)
rc.content(args[ba.getIndex()], ba.getSchema());
rom.forEachRequestArg(rmba -> {
RequestBeanMeta rbm = rmba.getMeta();
Object bean = args[rmba.getIndex()];
if (bean != null) {
for (RequestBeanPropertyMeta p : rbm.getProperties()) {
Object val = safeSupplier(()->p.getGetter().invoke(bean));
HttpPartType pt = p.getPartType();
String pn = p.getPartName();
HttpPartSchema schema = p.getSchema();
if (pt == PATH)
rc.pathArg(pn, val, schema, p.getSerializer().orElse(partSerializer));
else if (val != null) {
if (pt == QUERY)
rc.queryArg(pn, val, schema, p.getSerializer().orElse(partSerializer), schema.isSkipIfEmpty());
else if (pt == FORMDATA)
rc.formDataArg(pn, val, schema, p.getSerializer().orElse(partSerializer), schema.isSkipIfEmpty());
else if (pt == HEADER)
rc.headerArg(pn, val, schema, p.getSerializer().orElse(partSerializer), schema.isSkipIfEmpty());
else /* (pt == HttpPartType.BODY) */
rc.content(val, schema);
}
}
}
});
RemoteOperationReturn ror = rom.getReturns();
if (ror.isFuture()) {
return getExecutorService().submit(() -> {
try {
return executeRemote(interfaceClass, rc, method, rom);
} catch (Exception e) {
throw e;
} catch (Throwable e) {
throw asRuntimeException(e);
}
});
} else if (ror.isCompletableFuture()) {
CompletableFuture<Object> cf = new CompletableFuture<>();
getExecutorService().submit(() -> {
try {
cf.complete(executeRemote(interfaceClass, rc, method, rom));
} catch (Throwable e) {
cf.completeExceptionally(e);
}
return null;
});
return cf;
}
return executeRemote(interfaceClass, rc, method, rom);
}
});
}