Putting a simple expression language into java

后端 未结 4 1741
天涯浪人
天涯浪人 2020-12-06 19:29

Im my Java application, users can specify how to name their files from a series of metadata fields. i.e

%artist% - %album% - %disctotal%

相关标签:
4条回答
  • 2020-12-06 20:09

    How about using the JavaScript engine that is bundled with Java 1.6?

    You can see how you would pass in all the parameters:

    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("JavaScript");
    engine.put("artist", artist);
    ...
    

    You would read back the value using

    ScriptEngine.get(...)
    

    The final bit of glue would be to surround the user's expression with a function declaration, and write an expression that calls the function and assigns the result to a well known variable.

    So to start experimenting, lets have a function to test expressions out:

    private static void printResult(final ScriptEngine jsEngine, String name, String expr) throws ScriptException {
        Object result = jsEngine.eval(expr);
        System.out.println(name + " result: " + result + "; expr: " + expr);
    }
    

    Now let's call it:

    public static void main(String[] args) throws Exception {
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine jsEngine = sem.getEngineByName("JavaScript");
        printResult(jsEngine, "Hello World", "'Hello World'");
        printResult(jsEngine, "Simple Math", "123 + 456");
    }
    

    This produces:

    Hello World result: Hello World; expr: 'Hello World'
    Simple Math result: 579.0; expr: 123 + 456
    

    Now lets try with your usecase:

    public static void main(String[] args) throws Exception {
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine jsEngine = sem.getEngineByName("JavaScript");
    
        String expr = "artist + '-' + album + (disktotal > 1 ? ('-D' + diskno) : '')";
    
        jsEngine.put("artist", "U2");
        jsEngine.put("album", "The Joshua Tree");
        jsEngine.put("disktotal", 1);
        jsEngine.put("diskno", 1);
        printResult(jsEngine, "Single Disk", expr);
    
        jsEngine.put("artist", "Tori Amos");
        jsEngine.put("album", "To Venus and Back");
        jsEngine.put("disktotal", 2);
        jsEngine.put("diskno", 2);
        printResult(jsEngine, "Muti-Disk", expr);
    }
    

    Produces result:

    Single Disk result: U2-The Joshua Tree; expr: ...
    Muti-Disk result: Tori Amos-To Venus and Back-D2; expr: ...
    

    Notice how Tori's has 'D2' at the end.

    0 讨论(0)
  • 2020-12-06 20:10

    One option would be to use a parser generator.

    ANTLR is one such tool for Java. If you're a novice at creating grammars, you'll find the grammar IDE ANTLRWorks useful.

    0 讨论(0)
  • 2020-12-06 20:18

    I guess you are looking for a template engine

    0 讨论(0)
  • 2020-12-06 20:23

    I'd look into FreeMarker. It is a templating engine. You can pass your string with the el constructs to Freemarker and give it the objects you want to bind to your string and it will give you a string back.

    0 讨论(0)
提交回复
热议问题