2015-10-14 3 views
0

У меня есть данные моделируются в виде таблиц, которые при запросе может возвращать результат, установленные как:Java: Интересное Отражение - Динамические поля и операторы

+----------+-----------------+-----------+--------+-----------+----------+-------+ 
| 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  | 
+----------+-----------------+-----------+--------+-----------+----------+-------+ 

Это будет оценивать в логическое выражение:

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

В принципе, я бы хотел создать строки кода, которые выполняются во время выполнения. Который, только что сказал, звучит безумно. Я бы скорее сделал это на слабо типизированном языке, таком как PHP, но это должно произойти на Java-землях.

Левые два столбца образуют список смежности, а field_pos указывает индекс в массиве строк, где значение сравнивалось бы.

Таким образом, в Java это потребуется, чтобы превратиться в:

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

Я предполагаю, Java отражение бы помочь, но не знаю, как это можно было бы сделать элегантный и не полный условными. Есть идеи?

+0

Поскольку вы знаете, массив, единственное, что вам необходимо сопоставить оператор и условие, и я хотел бы использовать переключатель случай/HashMap или что-то подобное для этого, то оценивать каждое выражение снизу вверх, или я что-то упускаю? –

+0

Я бы хотел избежать переключения/условных обозначений. Я на самом деле нахожу несколько библиотек, которые делают такие вещи - в основном конвертирование строк в код. Java Expression Parser, похоже, в значительной степени соответствует тому, что я имею в виду. [Здесь] (https://github.com/uklimaschewski/EvalEx), я думаю, может быть полезно. – JonasJSchreiber

+0

Да, Java Expression Parser - это реализация [Интерпретатора] (https://en.wikipedia.org/wiki/Interpreter_pattern). Это то, что я бы рекомендовал, если вы хотите что-то гибкое, которое меняется на лету. Обратите внимание, что это именно то, что делают другие библиотеки. Драйвер JDBC - это шаблон интерпретатора/моста. – markspace

ответ

0

Закончено с использованием GroovyShell. Вот моя песочница:

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; 
    } 
} 
Смежные вопросы