我是一个新手,学习很快。我正在尝试创建基于规则的假日日历。实施了一套规则,根据假日或工作日的日期确定
我创建了规则文件和类,似乎正在运行
规则文件
//created on: Dec 30, 2017
//list any import classes here.
import com.intlsys.holidaycalendar.model.CheckDay;
import java.util.*;
//declare any global variables here
rule "Weekend1_saturday"
when
//conditions
$checkday : CheckDay($dayofWeek : dayofWeek == 7)
then
//actions
System.out.println("Weekend1_saturday");
modify($checkday) {
setWeekend1(true)
};
modify($checkday) {
setHoliday(true)
};
end
rule "Weekend2_sunday"
when
//conditions
$checkday : CheckDay($dayofWeek : dayofWeek == 1)
then
//actions
System.out.println("Weekend1_sunday");
modify($checkday) {
setWeekend2(true)
};
end
rule "Holiday_newyear_day"
when
//conditions
$checkday : CheckDay($month : month == 1, $dayofMonth : dayofMonth == 1)
then
System.out.println("Holiday_newyear_day");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_MartinLutherKingBirthday."
when
//conditions
$checkday : CheckDay(month == 1, dayofWeek == 2, dayofWeekinMonth == 3)
then
System.out.println("Holiday_MartinLutherKingBirthday.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_WashingtonBirthday_PresidentsDay."
when
//conditions
$checkday : CheckDay(month == 2, dayofWeek == 2, dayofWeekinMonth == 3)
then
System.out.println("Holiday_WashingtonBirthday_PresidentsDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_MemorialDay."
when
//conditions
$checkday : CheckDay(month == 5, dayofWeek == 2, dayofMonth > (31 - 7))
then
System.out.println("Holiday_MemorialDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_IndependenceDay."
when
//conditions
$checkday : CheckDay(month == 7, dayofMonth == 4)
then
System.out.println("Holiday_IndependenceDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_LaborDay."
when
//conditions
$checkday : CheckDay(month == 9, dayofWeek == 2, dayofWeekinMonth == 1)
then
System.out.println("Holiday_LaborDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_ColumbusDay."
when
//conditions
$checkday : CheckDay(month == 10, dayofWeek == 2, dayofWeekinMonth == 2)
then
System.out.println("Holiday_ColumbusDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_VeteransDay."
when
//conditions
$checkday : CheckDay(month == 11, dayofMonth == 11)
then
System.out.println("Holiday_VeteransDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_ThanksGivingDay."
when
//conditions
$checkday : CheckDay(month == 11, dayofWeek == 5, dayofWeekinMonth == 4)
then
System.out.println("Holiday_ThanksGivingDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_ChristmasDay."
when
//conditions
$checkday : CheckDay(month == 12, dayofMonth == 25)
then
System.out.println("Holiday_ChristmasDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
java类文件
package com.intlsys.holidaycalendar.model;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import lombok.Data;
public @Data class CheckDay {
private int dayofWeek;
private int month;
private int dayofMonth;
private int dayofWeekinMonth;
private int year;
public boolean isWeekend1; // Weekend 1 = Saturday
public boolean isWeekend2; // Weekend 1 = Sunday
public boolean isHoliday;
private Date currentday;
private Date nextday;
private Date previousday;
private Calendar cal;
public CheckDay(int year, int month, int dayOfMonth) {
cal = new GregorianCalendar(year, month - 1, dayOfMonth);
this.year = cal.get(Calendar.YEAR);
this.month = cal.get(Calendar.MONTH) + 1;
this.dayofMonth = cal.get(Calendar.DAY_OF_MONTH);
this.dayofWeek = cal.get(Calendar.DAY_OF_WEEK);
this.dayofWeekinMonth = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
this.currentday = cal.getTime();
this.setNextday();
this.setPreviousday();
}
public void setPreviousday() {
Calendar c = Calendar.getInstance();
c.setTime(this.currentday);
c.add(Calendar.DATE, -1);
this.previousday = c.getTime();
}
public void setNextday() {
Calendar c = Calendar.getInstance();
c.setTime(this.currentday);
c.add(Calendar.DATE, 1);
this.nextday = c.getTime();
}
}
但现在我想实施两条规则
如果nextdate是假日,nextdate是周末1,则isholdate=true
如果previousdate是假日,而previousdate是周末2,那么isholday=true
我在CheckDay类中添加了nextday和previousday属性,但我无法找到实现这两个规则的方法
我需要drool专家就如何实现这些规则或如何使用drool解决此问题提供建议。
注意:我已经知道如何在不使用口水的情况下解决这个问题,所以我不想寻找答案。我的目的不是解决假期日历问题,但我想了解,这种问题可以用drool解决吗?
其他类
package com.intlsys.holidaycalendar;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.intlsys.holidaycalendar.model.CheckDay;
import com.intlsys.holidaycalendar.service.HolidayCalculator;
import com.intlsys.holidaycalendar.service.HolidayCalculatorImpl;
@SpringBootApplication
public class HolidaycalendarApplication {
public static void main(String[] args) {
SpringApplication.run(HolidaycalendarApplication.class, args);
ApplicationContext context =
new AnnotationConfigApplicationContext(HolidayCalendarCalculation.class);
HolidayCalculator holidayCalculatorService =
(HolidayCalculator) context.getBean(HolidayCalculatorImpl.class);
CheckDay day = new CheckDay(2018, 12, 25);
boolean isbusinessday = holidayCalculatorService.isbusinessday(day);
System.out.println("isbusinessday: " + isbusinessday);
}
}
和
package com.intlsys.holidaycalendar;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.intlsys.holidaycalendar.service")
public class HolidayCalendarCalculation {
public static final String drlFile = "HOLIDAY_RULES.drl";
@Bean
public KieContainer kieContainer() {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource(drlFile));
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
KieModule kieModule = kieBuilder.getKieModule();
return kieServices.newKieContainer(kieModule.getReleaseId());
}
}
服务级别
package com.intlsys.holidaycalendar.service;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.intlsys.holidaycalendar.model.CheckDay;
@Service
public class HolidayCalculatorImpl implements HolidayCalculator {
@Autowired
private KieContainer kContainer;
@Override
public boolean isbusinessday(CheckDay day) {
KieSession kieSession = kContainer.newKieSession();
kieSession.insert(day);
kieSession.fireAllRules();
kieSession.dispose();
return day.isHoliday()? false: true;
}
}
我能解决问题,但应该有更好的办法
我在holidaycalculation服务中解决的方法是填充setNextdayweekend1Holiday和setPreviousdayWeekend2Holiday,然后添加了两条规则Weekend1\u saturday和Weekend2\u sunday
规则文件
//created on: Dec 30, 2017
//list any import classes here.
import com.intlsys.holidaycalendar.model.CheckDay;
import java.util.*;
//declare any global variables here
rule "Weekend1_saturday"
when
//conditions
$checkday : CheckDay($dayofWeek : dayofWeek == 7)
then
//actions
System.out.println("Weekend1_saturday");
modify($checkday) {
setWeekend1(true)
};
modify($checkday) {
setHoliday(true)
};
end
rule "Weekend2_sunday"
when
//conditions
$checkday : CheckDay($dayofWeek : dayofWeek == 1)
then
//actions
System.out.println("Weekend1_sunday");
modify($checkday) {
setWeekend2(true)
};
end
rule "Holiday_newyear_day"
when
//conditions
$checkday : CheckDay($month : month == 1, $dayofMonth : dayofMonth == 1)
then
System.out.println("Holiday_newyear_day");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_MartinLutherKingBirthday."
when
//conditions
$checkday : CheckDay(month == 1, dayofWeek == 2, dayofWeekinMonth == 3)
then
System.out.println("Holiday_MartinLutherKingBirthday.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_WashingtonBirthday_PresidentsDay."
when
//conditions
$checkday : CheckDay(month == 2, dayofWeek == 2, dayofWeekinMonth == 3)
then
System.out.println("Holiday_WashingtonBirthday_PresidentsDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_MemorialDay."
when
//conditions
$checkday : CheckDay(month == 5, dayofWeek == 2, dayofMonth > (31 - 7))
then
System.out.println("Holiday_MemorialDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_IndependenceDay."
when
//conditions
$checkday : CheckDay(month == 7, dayofMonth == 4)
then
System.out.println("Holiday_IndependenceDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_LaborDay."
when
//conditions
$checkday : CheckDay(month == 9, dayofWeek == 2, dayofWeekinMonth == 1)
then
System.out.println("Holiday_LaborDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_ColumbusDay."
when
//conditions
$checkday : CheckDay(month == 10, dayofWeek == 2, dayofWeekinMonth == 2)
then
System.out.println("Holiday_ColumbusDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_VeteransDay."
when
//conditions
$checkday : CheckDay(month == 11, dayofMonth == 11)
then
System.out.println("Holiday_VeteransDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_ThanksGivingDay."
when
//conditions
$checkday : CheckDay(month == 11, dayofWeek == 5, dayofWeekinMonth == 4)
then
System.out.println("Holiday_ThanksGivingDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_ChristmasDay."
when
//conditions
$checkday : CheckDay(month == 12, dayofMonth == 25)
then
System.out.println("Holiday_ChristmasDay.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_Nextdayweekend1Holiday."
when
//conditions
$checkday : CheckDay(nextdayweekend1Holiday == true)
then
System.out.println("Holiday_Nextdayweekend1Holiday.");
//actions
modify($checkday) {
setHoliday(true)
};
end
rule "Holiday_Previousdayweekend2Holiday."
when
//conditions
$checkday : CheckDay(previousdayWeekend2Holiday == true)
then
System.out.println("Holiday_Previousdayweekend2Holiday.");
//actions
modify($checkday) {
setHoliday(true)
};
end
类文件
package com.intlsys.holidaycalendar.service;
import java.util.Calendar;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.intlsys.holidaycalendar.model.CheckDay;
@Service
public class HolidayCalculatorImpl implements HolidayCalculator {
@Autowired private KieContainer kContainer;
@Override
public boolean isbusinessday(CheckDay day) {
KieSession kieSession = kContainer.newKieSession();
Calendar cal1 = Calendar.getInstance();
//check if next day is holiday and saturday
cal1.setTime(day.getNextday());
CheckDay nextday =
new CheckDay(
cal1.get(Calendar.YEAR), cal1.get(Calendar.MONTH) + 1, cal1.get(Calendar.DAY_OF_MONTH));
kieSession.insert(nextday);
kieSession.fireAllRules();
if (nextday.isHoliday == true && nextday.isWeekend1 == true)
day.setNextdayweekend1Holiday(true);
// check if previous day is holiday and sunday
cal1.setTime(day.getPreviousday());
CheckDay previousday =
new CheckDay(
cal1.get(Calendar.YEAR), cal1.get(Calendar.MONTH) + 1, cal1.get(Calendar.DAY_OF_MONTH));
kieSession.insert(previousday);
kieSession.fireAllRules();
if (previousday.isHoliday == true && previousday.isWeekend2 == true)
day.setPreviousdayWeekend2Holiday(true);
kieSession.insert(day);
kieSession.fireAllRules();
kieSession.dispose();
return day.isHoliday() ? false : true;
}
}
服务等级
package com.intlsys.holidaycalendar.service;
import java.util.Calendar;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.intlsys.holidaycalendar.model.CheckDay;
@Service
public class HolidayCalculatorImpl implements HolidayCalculator {
@Autowired private KieContainer kContainer;
@Override
public boolean isbusinessday(CheckDay day) {
KieSession kieSession = kContainer.newKieSession();
Calendar cal1 = Calendar.getInstance();
//check if next day is holiday and saturday
cal1.setTime(day.getNextday());
CheckDay nextday =
new CheckDay(
cal1.get(Calendar.YEAR), cal1.get(Calendar.MONTH) + 1, cal1.get(Calendar.DAY_OF_MONTH));
kieSession.insert(nextday);
kieSession.fireAllRules();
if (nextday.isHoliday == true && nextday.isWeekend1 == true)
day.setNextdayweekend1Holiday(true);
// check if previous day is holiday and sunday
cal1.setTime(day.getPreviousday());
CheckDay previousday =
new CheckDay(
cal1.get(Calendar.YEAR), cal1.get(Calendar.MONTH) + 1, cal1.get(Calendar.DAY_OF_MONTH));
kieSession.insert(previousday);
kieSession.fireAllRules();
if (previousday.isHoliday == true && previousday.isWeekend2 == true)
day.setPreviousdayWeekend2Holiday(true);
kieSession.insert(day);
kieSession.fireAllRules();
kieSession.dispose();
return day.isHoliday() ? false : true;
}
}
这篇文章建议添加一些事实类作为嵌套规则的一种方式。http://drools.46999.n3.nabble.com/How-can-I-nested-rules-td4020488.html#a4020681 我想知道的是——有没有保证“年龄和性别女性”在“怀孕”之前执行,“怀孕”在“怀孕2”之前执行?据我所知,我的申请中总是这样。但是,它是记录在口水留档的某个地方,还是只是等待倒塌的纸牌屋?
我是规则引擎新手,我的应用程序需要从文件系统动态加载xml文件中的规则,因为管理员可以在运行时创建规则。(Java) 我的问题是:有没有可能流口水?如果是,那么请分享知识,如果不是,那么还有其他选择吗?
我们正在使用JBoss Drools来外部化我们正在构建的某些服务中一些特别容易更改的业务逻辑。 在我们的开发人员可以创建和维护这些规则的地方,这些规则运行得很好,我们有很好的集成水平和集成工作流。 我们希望将其应用扩展到一种需要非常高级别定制的新服务。本质上,“专家用户”需要能够设置两种不同类型的规则: > “标准”规则-这些几乎是隐含的规则,我们知道这些规则是常见的需求,我们可以构建UI来设置
我的问题是: 在Drools规则中,有没有一种方法可以拦截“成功”事件?为了更好地解释。。。有一种方法可以在规则的所有条件都为真时调用侦听器? 注意:我不想设置一个全局对象(在会话上)来管理规则的“然后”子句中的这个条件。 我正在寻找一个已经在Drools上实现的解决方案 规则示例
谢谢
我正在向drools规则引擎插入数据,但我无法理解它是如何处理插入的数据的。插入数据的代码是: