1

I have a UI where the user can build a query to then apply those conditions to search in a text file. Let's assume the string is as follows: A and (B or C) I also have access to each value (A, B, C), logical operators (and, or) and grouping brackets.

So what I need to have is: line.contains(A) && (line.contains(B) || line.contains(C))

boolean found = false;

BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line = null;
while ((line = reader.readLine()) != null && !contains) {
    if (line.contains(A) && (line.contains(B) || line.contains(C))) {
        found = true;
    }
}

return found;

The above specific conditions might also not work since I'm searching for that in each line and the conditions might be in different lines. But this is another issue I have to deal with :)

Any idea on how to do this?

Somebody
  • 2,667
  • 14
  • 60
  • 100
  • can there be more values than A,B,C? – sidgate Jul 02 '19 at 16:13
  • @sidgate could be up to 5 conditions: A,B,C,D,E :) – Somebody Jul 02 '19 at 16:15
  • Parse the input string to build a tree of (And) and (Or) nodes, Then calculate the result easily. – Ammar Jul 02 '19 at 16:33
  • https://stackoverflow.com/questions/40165157/evaluating-a-string-holding-a-logic-operation-as-a-boolean-in-java take a look – Oleks Jul 02 '19 at 16:34
  • I like your problem. You need an Expression Tree data structure, from it you can get value of an expression easily. I have implemented it in C++ (https://github.com/TaQuangTu/ExpressionTreeC-). of course Im not a good coder so my code is not clean, but i think it is enough for you to solve some small problems. – TaQuangTu Jul 02 '19 at 16:36
  • You can either [implement your own rule-engine](https://stackoverflow.com/questions/20763189/creating-a-simple-rule-engine-in-java) or make use of one of the already existing ones. Most of them allow you to define certain triggers what should happen if a rule applies – Roman Vottner Jul 02 '19 at 16:51
  • Besides an Expression Tree also look at implementing a parser. Parsers build expression trees, so you need to do that first. https://en.wikipedia.org/wiki/Parsing#Computer_languages – markspace Jul 02 '19 at 17:20

1 Answers1

0

Based on your comments I was able to resolve my question by using ScriptEngineManager. I'm building the condition I want to evaluate using JavaScript language and doing engine.eval(query).

private boolean containsSearchQuery(InputStream input, String searchQuery) {
    boolean match = false;

    // create a script engine manager
    ScriptEngineManager factory = new ScriptEngineManager();
    // create a JavaScript engine
    ScriptEngine engine = factory.getEngineByName("JavaScript");

    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
    String lines = reader.lines().collect(Collectors.joining());

    engine.put("lines", lines);

    try {
        match = (boolean) engine.eval(searchQuery);
    } catch (ScriptException e) {
        System.out.println("Error: " + e.getMessage());
    }

    return match;
}
Somebody
  • 2,667
  • 14
  • 60
  • 100