简体   繁体   中英

Java: Challenging Reflection - Dynamic Fields and Operators

I have data modeled in tables, which when queried could return a result set like:

+----------+-----------------+-----------+--------+-----------+----------+-------+
| subgroup | parent_subgroup | condition | field  | field_pos | operator | value |
+----------+-----------------+-----------+--------+-----------+----------+-------+
|        0 |            NULL | OR        | Field1 |         4 | equal    | A     |
|        1 |               0 | AND       | Field2 |         9 | equal    | B     |
|        1 |               0 | AND       | Field3 |        20 | equal    | C     |
+----------+-----------------+-----------+--------+-----------+----------+-------+

This would evaluate to the Boolean expression:

Field1 = A OR (Field2 = B AND Field3 = C)

Basically, I'd like to manufacture lines of code which execute during runtime. Which, having just said it, sounds insane. I'd much rather be doing this in a weakly typed language like PHP, but this has to happen in Java land.

The left two columns form an adjacency list, and the field_pos indicates the index in an array of strings where the value would be compared with.

So in Java this would need to turn into:

String[] fields = {"1", "2", "3", ... "n"};
if (fields[4].equals("A") || (fields[9].equals("B") && fields[20].equals("C"))) {
    return true;
}

I assume Java reflection would help, but don't know how this could be made elegant and not full of conditionals. Any ideas?

Ended up using GroovyShell. Here's my sandbox:

package com.jonas.groovy;

import groovy.lang.Binding;
import groovy.lang.GroovyShell;

public class GroovySandbox {

    public static void main(String[] args) {
        String toEvaluate = "'string' == 'string' && ('string' == 'String' || 'a' == 'N' || true)";
        System.out.println(evalFilter(toEvaluate));
        toEvaluate = "Calendar.getInstance().get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY";
        System.out.println(evalFilter(toEvaluate));
    }

    public static boolean evalFilter(String expression){
        GroovyShell shell=new GroovyShell(new Binding());
        Object value=shell.evaluate(expression);
        if (!(value instanceof Boolean)) {
            throw new RuntimeException("Boolean value expected out of expression: " + expression);
        }
        return (Boolean)value;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM