How to pass in multiple arguments in Java Lambda BiFunctions using Async? - java

I'm working with a PlayFramework example but I'm having trouble with the asynchronous calls. The function thenCombineAsync seems to only take in a BiFunction. I'd like to pass in multiple arguments to my render function (such as vendors) but I'm not sure how to add more.
return entryRepository.lookup(id).thenCombineAsync(vendorsFuture(entryOptional, vendors) -> {
// This is the HTTP rendering thread context
Entry c = entryOptional.get();
Form<Entry> entryForm = formFactory.form(Entry.class).fill(c);
return ok(views.html.editForm.render(id, entryForm, vendors));
}, httpExecutionContext.current());

Related

How to run a Google App Script using Google API Service Library (Java)

By following the Java Quickstart example, I am able to create a new Google App Script project and retrieve the scriptId. Also, by referring to the Restful API document, the script should be able to be executed using Method: scripts.run. However, I don't know how to retrieve the return value using com.google.api.services.script.Script in Java.
I've tried:
Script scriptService = getScriptService();
Script.Scripts scripts = scriptService.scripts();
Script.Scripts.Run run = scripts.run(scriptId, request);
and decompiled run function:
public Script.Scripts.Run run(String var1, ExecutionRequest var2) throws IOException {
Script.Scripts.Run var3 = new Script.Scripts.Run(var1, var2);
Script.this.initialize(var3);
return var3;
}
The function doesn't return an ExecutionResponse object which I am looking for.
Per the REST API documentation, calling script.run does not immediately return an ExecutionResponse object, but an Operation object that may contain an ExecutionResponse:
{
"done": boolean,
// Union field result can be only one of the following:
"error": {
object(Status)
},
"response": object(ExecutionResponse)
,
// End of list of possible types for union field result.
}
If we look at the Java API Client library, we see that method Script.Script.run takes arguments of the script ID, and an ExecutionRequest, and then returns a Script.Script.Run request that must be .execute()d:
Create a request for the method "scripts.run". This request holds the parameters needed by the script server. After setting any optional parameters, call the AbstractGoogleClientRequest.execute() method to invoke the remote operation.
The request referred to by the quoted documentation is Script.Script.Run, and has methods like .setAccessToken() for additional configuration, and several execution methods like .execute() and .executeMedia() to actually submit the execution request and return the Operation.

JAVA 8 pass return value back into same method x number of times

I have this code which I want to refactor using a functional style, using Java 8. I would like to remove the mutable object currentRequest and still return the filtered request.
HttpRequest currentRequest = httpRequest;
for (Filter filter : filters) {
currentRequest = filter.doFilter(currentRequest);
}
The aim is to pass a request to the filter.doFilter method, and take the output and pass it back into the filter.doFilter method, and continue to do this until all filters are applied.
For example in a more convoluted way to the for loop
HttpRequest filteredRequest1 = filters.get(0).doFilter(currentRequest);
HttpRequest filteredRequest2 = filters.get(1).doFilter(filteredRequest1);
HttpRequest filteredRequest3 = filters.get(2).doFilter(filteredRequest2);
...
I think this is a case for composing functions, and the doFilter method should be a function like below:
Function<HttpRequest, HttpRequest> applyFilter = request -> filters.get(0).doFilter(request);
But I know this is totally wrong, as I got stuck here.
The other way I was thinking was to use reduce, but I cannot see a way of using it in this case.
If you could help me out with a way of doing this, or point me to some resource that will be great.
It looks like you may want to do a reduce with your HttpRequest as its identity. Each step of the reduce will combine the intermediate result with the next filter, like so:
filters.stream().reduce(currentRequest,
(req, filter) -> filter.doFilter(req),
(req1, req2) -> throwAnExceptionAsWeShouldntBeHere());
Note: the last function is used to merge two HttpRequests together if a parallel stream is used. If that's the route you wish to go down, then proceed with caution.
Here's a way that streams the filters and maps each one of them to a UnaryOperator<HttpRequest>. Then, all the functions are reduced via the Function.andThen operator and finally, if the filters collections wasn't empty, the resulting composed function is executed with the currentRequest as an argument:
HttpRequest result = filters.stream()
.map(filter -> ((Function<HttpRequest, HttpRequest>) filter::doFilter))
.reduce(Function::andThen)
.map(function -> function.apply(currentRequest))
.orElse(currentRequest);

how to run multiple synchronous functions asynchronously?

I am writing in Java on the Vertx framework, and I have an architecture question regarding blocking code.
I have a JsonObject which consists of 10 objects, like so:
{
"system":"CD0",
"system":"CD1",
"system":"CD2",
"system":"CD3",
"system":"CD4",
"system":"CD5",
"system":"CD6",
"system":"CD7",
"system":"CD8",
"system":"CD9"
}
I also have a synchronous function which gets an object from the JsonObject, and consumes a SOAP web service, while sending the object to it.
the SOAP Web service gets the content (e.g. CD0), and after a few seconds returns an Enum.
I then want to take that enum value returned, and save it in some sort of data variable(like hash table).
What I ultimately want is a function that will iterate over all the JsonObject's objects, and for each one, run the blocking code, in parallel.
I want it to run in parallel so even if one of the calls to the function needs to wait 20 seconds, it won't stuck the other calls.
how can I do such a thing in vertx?
p.s: I will appreciate if you will correct mistakes I wrote.
Why not to use rxJava and "zip" separate calls? Vertx has great support for rxJava too. Assuming that you are calling 10 times same method with different String argument and returning another String you could do something like this:
private Single<String> callWs(String arg) {
return Single.fromCallable(() -> {
//DO CALL WS
return "yourResult";
});
}
and then just use it with some array of arguments:
String[] array = new String[10]; //get your arguments
List<Single<String>> wsCalls = new ArrayList<>();
for (String s : array) {
wsCalls.add(callWs(s));
}
Single.zip(wsCalls, r -> r).subscribe(allYourResults -> {
// do whatever you like with resutls
});
More about zip function and reactive programming in general: reactivex.io

JavaFX+WebView/Javascript : setTimeOut does not work call stack comes from Java

I have a JavaFX application that loads my own HTML/JS application in a WebView. Depending on the event, I need to call Javascript from Java, and Java from Javascript.
Every is good when going from JS to Java but I've got weird behaviors when going from Java to Javascript.
Here's, basically, how I setup the communication between the 2 languages:
_
var javaObjectInjected = typeof javaObject !== "undefined";
if(javaObjectInjected && !javaObjectInitialized) {
jThalesEventBusInitialized = true;
const jsAdapter = {
publishToJs: onPublishToJs
};
javaObject.setJsAdapter(jsAdapter);
}
My Java code will invoke the method publishToJs on the provided jsAdapter. This will result in the execution of onPublishToJs.
_
function onPublishToJs(topic, data) {
alert('Yeah! We are inside JS'); //output_1
setTimeout(
function() {
alert('inside setTimeOut'); //output_2
},
1000
);
}
I do get output_1 but not output_2. It's like the callback on setTimeOut was discarded.
Are there any known limitations when invoking JS from Java?
I refactored my code and instead of injecting jsAdapter to the Java world using javaObject.setJsAdapter(jsAdapter), I exposed jsAdapter to Java as a new member of window.
With this new code structure, I got exceptions when invoking jsAdapter from Java because I was doing it from the EDT instead of the JavaFX Application Thread.
Eventually, I wrapped the jsAdapter calls in Platform.runLater(() -> ...) and that was it.
When working with Javascript loaded from a JavaFX WebView, make sure to always perform Javascript calls from the JavaFX Application Thread.

Use ScriptEngine to bind global javascript functions from java code [duplicate]

The JSR223 Bindings class allows you to expose arbitrary Java objects to scripting languages. But they have to be objects. I would like to define a function quit() that can be called from the scripting environment that turns into quitObject.run() in Java. But JSR223 doesn't define the concept of a function object. Is there a language-independent way to do the following in Javascript, namely to take a Runnable() and create a function in the scripting environment?
static private Object asFunction(ScriptEngine engine, Runnable r)
throws ScriptException
{
final Bindings bindings = engine.createBindings();
bindings.put("r", r);
return engine.eval(
"(function (r) { var f = function() { r.run(); }; return f;})(r)",
bindings);
}
Runnable quitObject = /* get/create a Runnable here */
Bindings bindings = engine.createBindings();
bindings.put("quit", asFunction(engine, quitObject));
With the builtin Javascript support for JSR223 this creates a sun.org.mozilla.javascript.internal.InterpretedFunction which does what I want. But it obviously won't work in Jython or whatever, and I'd like to make this language-independent.
I don't want my script users to have to type quitObject.run() as that's clumsy, and I don't want to parse script input to find quit() as it could be buried within other code.
If you look at javascript engine source code you'll find how oracle/sun implemented 2 functions (print, and println) which are magically (or not so magically) present when you fire up your engine.
Those function are 'scripted' , which is more or less what you did.
What I would do is : load and evaluate a bootstrap.[language_extension] before evaluating any other input in the new context.
You could easily create such scripts for each language you intend to support.

Categories

Resources