2012-10-02 39 views
1

比方說,我有下面的類:庫Java的評估邏輯表達式對象

class Person { 
    int age; 
    String city; 
    Collection<Person> friends; 
    Person spouse; 
} 

我需要一個庫,它可以讓我評價一個邏輯表達式是否爲給定Person對象上實現。該表達式將是這個樣子:

((age>25 OR spouse.age>27) AND city=="New-York" AND size(friends)>100) 

因此,要求是:

  1. 能夠使用給定對象的基本邏輯運算符
  2. 訪問屬性
  3. 內部的訪問屬性對象
  4. 使用簡單的數學\ sql-like函數,例如size,max,sum

對此提出建議?

+0

你能說你爲什麼不能用普通的Java來做到這一點嗎?表達式是否必須來自動態字符串? –

+0

你爲什麼不寫自己的功能? – Farnabaz

+0

爲什麼你需要任何庫? –

回答

2

OK,想我找到了我想要的東西,它是在assylias'答案的變化,但我喜歡它,因爲它是更規範(woudn't想在JavaScript表達式特別依賴,或運行JavaScript在所有爲物)。

顯然有一個Unified Expression Language評估表達式,它最初是爲JSP設計的,但也可以用於其他的東西。有幾個解析器的實現,我可能會去Spring ELJUEL

4

你可以使用一個ScriptEngine +反射:

  • 訪問都在你的對象fields和創建具有這些值
  • 計算表達式

這裏變量是一個人爲的例子輸出:

age = 35 
city = "London" 
age > 32 && city == "London" => true 
age > 32 && city == "Paris" => false 
age < 32 && city == "London" => false 

如果要處理非基元類型(如集合),可能會變得相當混亂。

public class Test1 { 

    public static void main(String[] args) throws Exception{ 
     Person p = new Person(); 
     p.age = 35; 
     p.city = "London"; 

     ScriptEngineManager factory = new ScriptEngineManager(); 
     ScriptEngine engine = factory.getEngineByName("JavaScript"); 

     Class<Person> c = Person.class; 
     for (Field f : c.getDeclaredFields()) { 
      Object o = f.get(p); 
      String assignement = null; 
      if (o instanceof String) { 
       assignement = f.getName() + " = \"" + String.valueOf(o) + "\""; 
      } else { 
       assignement = f.getName() + " = " + String.valueOf(o); 
      } 
      engine.eval(assignement); 
      System.out.println(assignement); 
     } 

     String condition = "age > 32 && city == \"London\""; 
     System.out.println(condition + " => " + engine.eval(condition)); 

     condition = "age > 32 && city == \"Paris\""; 
     System.out.println(condition + " => " + engine.eval(condition)); 

     condition = "age < 32 && city == \"London\""; 
     System.out.println(condition + " => " + engine.eval(condition)); 
    } 

    public static class Person { 

     int age; 
     String city; 
    } 
}