Search code examples
javascriptjavajava-8nashorn

Nashorn assign a Java function to a map


I have this engine which runs user-input (trusted) javascript function to filter some data for them using Nashorn. Don't want to go into the details of the requirements but let's say it's some sort of plugin system.

This javascript gets a Java map(which acts like a JS object) as a parameter to get some contextual data. So I want to add some convenience extension methods to this JS object for the users. So I did the following:

Map<String, String> inputMap = ....
inputMap.put("containsMagic", (Function<String, Boolean>) param -> some complex magic check and return boolean);

Works perfectly!

if(inputMap.containsMagic('Im Por Ylem'))
  do stuff;

However, I want it to accept no parameter as well, because null is a valid value and containsMagic() looks better than containsMagic(null).

if(inputMap.containsMagic())
  do stuff;

But I get this:

TypeError: Can not invoke method ......$$Lambda$15/1932831450@30c15d8b with the passed arguments; they do not match any of its method signatures.

I guess that's kind of normal given how Java works. If I pass null, it works of course but that's not very intuitive.

I can't add another function with 0 parameters and the same name because Java maps are single keyed. The complex magic check needs to be in java, so I can't assign a javascript function (JSObject?) either. Any ideas how I can accomplish this?


Solution

  • You can implement containsMagic as explicit method with a varargs parameter:

    public static class InputMap extends HashMap<String, Object> {
        public Boolean containsMagic(String... args) {
            String arg = args.length == 1 ? args[0] : null;
            // do magic 
        }
    }
    
    ...
    Map<String, Object> inputMap = new InputMap();