drools dsl добавление выражения к последнему шаблону с '-' не работает - PullRequest
1 голос
/ 11 марта 2020

Я некоторое время работал с правилами drools и только недавно начал работать над dsl, чтобы упростить разработку правил для конечных пользователей. Хотя я смог получить простой dsl, определенный и правильно скомпилированный в drl, как и ожидалось, я не могу заставить работать функцию dsl «добавления ограничений к предыдущему выражению». Я даже пробую самые простые примеры из руководства drools dsl, и это не скомпилирует условия, которые я определил, начиная с '-', в предыдущее выражение. Я продолжаю получать «несоответствующую входную цену» в правиле «Rule1Sample_0», ошибка при его компиляции. как я сказал, у меня это работает для простых выражений условий и выражений следствий. но добавление ограничений после документов просто не работает вообще. Я использую drools версии 7.0.0. Наконец, это не поддерживается до более поздней версии?

В простом примере, который я тестирую, мой файл dsl просто содержит:

[condition][]There is a {ShoppingCart} that=${ShoppingCart!lc} : ${ShoppingCart!ucfirst}()
[condition][]- total price is greater than 1000 =totalPrice > 1000

[consequence]Update {ShoppingCart}=System.out.println("{ShoppingCart}" + " test")

Вот условие

"There is a ShoppingCart that total price is greater than 1000"

и действие, которое я указываю для части и когда мой шаблон:

"Action" "Update ShoppingCart"

Вот скомпилированный drl, прежде чем я передам его DrlParser:


    rule "Test1"
      dialect "mvel"
      when
         "There is a ShoppingCart that total price is greater than 1000"
      then
        "Update ShoppingCart"
    end

Это то, что содержит строка extendedDrl после выполнения приведенного выше фрагмента кода:

package com.sample.test

rule "Test1"
  dialect "mvel"
  when
     $shoppingcart : $Shoppingcart() total price is greater than 1000
  then
    System.out.println("ShoppingCart" + " test")
end

И вот сгенерированный drl для этого, когда я анализирую его с помощью DRLParser:

(фрагмент кода здесь, некоторые опущены)

DrlParser parser = new DrlParser();
        DefaultExpanderResolver resolver = new DefaultExpanderResolver(new StringReader(dsl));
        String expandedDrl = parser.getExpandedDRL(dslr, resolver);

Вот что содержит строка extendedDrl после запуска приведенного выше фрагмента кода:

package com.sample.test

rule "Test1"
  dialect "mvel"
  when
     $shoppingcart : $Shoppingcart() total price is greater than 1000
  then
    System.out.println("ShoppingCart" + " test")
end

И ошибка компилятора, которую я вижу в консоль:

[[13,43]: [ERR 102] Line 13:43 mismatched input 'price' in rule "Test1"  ....

1 Ответ

1 голос
/ 15 марта 2020

Не могли бы вы попробовать условие

There is a ShoppingCart that
- total price is greater than 1000

Не могли бы вы попробовать следовать dsl

... business definitions
[when]complex condition = (simple condition 
                           or another condition)
[when]simple condition = (total price is not 0)
[when]another condition = (total price greater than 10)

... field definitions
[when]total price = totalPrice

... consequences I advise to wrap in java util class each as a static method to write java code in java code
[consequence]Update {ShoppingCart}=System.out.println("{ShoppingCart}" + " test")

... tech dsl at the bottom

[when]There (is( an?)?|are) {entityType}s?( that)? = ${entityType}: {entityType}()
[when](is\s+)?not less than(\s+an?)? = >=
[when](is\s+)?less than(\s+an?)? = <
[when](is\s+)?not greater than(\s+an?)? = <=
[when](is\s+)?greater than(\s+an?)? = >
[when]((is|do(es)?)\s+)?not equals?(\s+to)? = !=
[when](is\s+)?equals?(\s+to)? = ==
[when]is not(\s+an?)? = !=
[when]is(\s+an?)? = ==
[when]like(\s+an?)? = matches
[when]{prefix}?\s*(?<![\w])and(?![\w])\s*{suffix}? = {prefix} && {suffix}
[when]{prefix}?\s*(?<![\w])or(?![\w])\s*{suffix}? = {prefix} || {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*\({suffix}? = {prefix} false == (true && {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*{suffix}? = {prefix} !{suffix}
[when](?<![^\(,])\s*- = 

, это должно быть в состоянии обрабатывать правила, такие как

There is a ShoppingCart that
- total price is greater than 1000
- not complex condition

Если вы хотите повторно использовать условия в других условиях, вы хотите, чтобы они были атомами c. Хорошее эмпирическое правило заключать RHS в скобки (), чтобы не нарушать атомизацию записи


test

@DroolsSession({ "classpath:/test.rdslr", "classpath:/business.dsl", "classpath:/keywords.dsl" })
public class PlaygroundTest {

    @Rule
    public DroolsAssert drools = new DroolsAssert();

    @Test
    public void testIt() {
        drools.insertAndFire(new ShoppingCart(BigDecimal.valueOf(1000.5)));
        drools.insertAndFire(new ShoppingCart(BigDecimal.valueOf(999)));
    }
}

domain

public class ShoppingCart {
    public BigDecimal totalPrice;

    public ShoppingCart(BigDecimal totalPrice) {
        this.totalPrice = totalPrice; 
    }
}

rdslr

rule Test1
    when
        There is a ShoppingCart that 
        - total price is greater than 1000
    then
        print eligible price
end

rule Test2
    when
        There is a ShoppingCart that 
        - worth a discount
    then
        print eligible price
end

business.dsl

[when]worth a discount = 
    (total price is not less than 500
    and not over limit
    or total price is greater than 5000)
// stupid condition just for demonstration
[when]over limit = ((total price + total price * 0.05) > total price + 50)
[when]total price = totalPrice

[then]print eligible price = System.out.println($ShoppingCart.totalPrice);

words.dsl

[when]There (is( an?)?|are) {entityType}s?( that)? = ${entityType}: {entityType}()
[when](is )?not within\s*\({tail}?= not in ({tail}
[when](is )?within\s*\({tail}?= in ({tail}
[when](is )?not one of\s*\({tail}?= not in ({tail}
[when](is )?one of\s*\({tail}?= in ({tail}
[when]ignore case '{tail}?= '(?i){tail}
[when]{param:[$\w\.!'\[\]]+} as {param2:[$\w\.!'\[\]]+}=(({param2}) {param})
[when](is\s+)?not less than(\s+an?)? = >=
[when](is\s+)?less than(\s+an?)? = <
[when](is\s+)?not greater than(\s+an?)? = <=
[when](is\s+)?greater than(\s+an?)? = >
[when]((is|do(es)?)\s+)?not equals?(\s+to)? = !=
[when](is\s+)?equals?(\s+to)? = ==
[when]is not(\s+an?)? = !=
[when]is(\s+an?)? = ==
[when]like(\s+an?)? = matches
[when]{prefix}?\s*(?<![\w])and(?![\w])\s*{suffix}? = {prefix} && {suffix}
[when]{prefix}?\s*(?<![\w])or(?![\w])\s*{suffix}? = {prefix} || {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*\({suffix}? = {prefix} false == (true && {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*{suffix}? = {prefix} !{suffix}
[when](?<![^\(,])\s*- = 

тестовый вывод

00:00:00 --> inserted: ShoppingCart[totalPrice=1000.5]
00:00:00 --> fireAllRules
00:00:00 <-- 'Test1' has been activated by the tuple [ShoppingCart]
1000.5
00:00:00 --> inserted: ShoppingCart[totalPrice=999]
00:00:00 --> fireAllRules
00:00:00 <-- 'Test2' has been activated by the tuple [ShoppingCart]
999
...