Как обрабатывать фильтр заданный пользователем?
Данные берутся из файла CSV, в нём находятся таблицы которые нужно вывести в соответствие с фильтром введённым пользователем в консоль, к примеру "column[1]>50 & column[4]=Значение20", то есть по сути пользователь вводит условие как для условного оператора, однако в консоль через сканер.
Фильтры могут быть — отношения равенства: равно (=), не равно (<>), больше (>), меньше (<). Фильтры могут соединяться отношением И (&) и ИЛИ (||). Также могут участвовать скобки для обозначения приоритета и группировки. Отношение И имеет более высокий приоритет нежели ИЛИ. Фильтр может быть не указан.
Ответы (1 шт):
Абсолютно согласен с комментариями. Хотел бы добавить ещё вариант - использование ScripEngine Api для выполнения скрипта (javasсipt, python, groovy, ...) из Java кода. Вот небольшой пример использования для groovy:
public static void main(String[] args) throws Exception {
// условие фильтрации - вводится пользователем в groovy синтаксисе
String condition = " column[1] > 50 & column[4] == 20 ";
// считываем данные csv
String[] yourCSV = {"1,2,3,4,5","1,51,3,4,20"};
// собственно сам движок. В случае c groovy необходимо подключать стороннюю
// библиотеку. Движок JavaScript этого не требует.
ScriptEngine engine = new ScriptEngineManager().getEngineByName("groovy");
for (String line : yourCSV) {
// преобразование линии из csv в тип integer
Integer[] columns = Arrays.stream(line.split(","))
.map(Integer::valueOf)
.toArray(Integer[]::new);
// передача параметров в скрипт (binding)
engine.put("column", columns);
// выполнение скрипта и получение результата
boolean result = (boolean) engine.eval(condition);
System.out.println(result); // false, true
}
}
Какие недостатки у данного подхода:
- Валидация того, что ввёл пользователь. Единственный способ это проверить - выполнить скрипт и отловить исключение. При этом не факт, что текст ошибки будет читабельным.
- Время выполнение. Пишут что долго, но это всё относительно.
- Инжекция вредоносного кода.