2

In this question I asked about supporting an expression language and used the Javascript idea sucessfully Putting a simple expression language into java

But the Javascript expressions required have become quite verbose and Im trying to work out how I can use ScriptEngine to create javascript functions that I can refer to in my expressions so that the expressions can be shorter.

So far I've hacked a solution by using reexp on the user entered string which can include a pseudo function called ifempty which I then convert to the javascript before passing to script engine

public final String formatFromMask(String mask,Song exampleSong)
    {
        mask = convertPsuedoFunctions(mask);
        try
        {
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            for(SongFieldName next:SongFieldName.values())
            {
                engine.put(next.getScriptVar(),exampleSong.getFieldValueOrEmptyString(next.getSongFieldKey()));
            }
            Object result = engine.eval(mask);
            return (String)result;
        }
        catch(ScriptException se)
        {
            se.printStackTrace();
        }
        return "";
    }


    private String convertPsuedoFunctions(String mask)
    {
        //i.e ifnotempty(artist,' - ') -> (artist.length>0 ? artist + ' - ' : '')
        mask=mask.replaceAll("ifnotempty\\(([a-z]*)\\,('.*')\\)",
                             "($1.length>0 ? $1 + $2 : '')");

        return mask;
    }

which could parse an expression such as

ifnotempty(album,'/')
+ ifnotempty(artist,' - ')
+ ifnotempty(album,' - ')
+ ifnotempty(track,' - ')
+ ifnotempty(title,'')

but I was wondering about a proper solution, whereby I actually create a real javascript function.

1 Answer 1

2

Why not creating a real Javascript function that you add to the script?

function ifnotempty(value,sep){
    return value != undefined && value.length > 0 ? value + sep : '';
}

So your function becomes:

private String convertPsuedoFunctions(String mask)
{
    return 
         "function ifnotempty(value,sep){return value!=undefined&&value.length>0?value+sep:'';}"
         + mask;
}

Additionally you can create a file with some default functions you support and prepend that to the users script. Just like above. But instead of one hardcoded function, you read the file into a String.

private static final String defaultFunctions = 
     com.google.common.io.Files.toString(new File("functions.js"),Charsets.US_ASCII);

private String convertPsuedoFunctions(String mask)
{
    return defaultFunctions + mask;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Ah great, I knew there would be a way to do it, just couldn't see it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.