001package top.cenze.rule.utils;
002
003/**
004 * @desc: 规则文件工具
005 * @author: chengze
006 * @createByDate: 2023/8/7 15:17
007 */
008public class RuleFileUtil {
009//    private static final String DIR_NAME = "rules";             // 规则文件目录
010//    private static final String RELATIVE_PATH = "src/main/resources/rules";  // 规则文件相对目录
011//    private static final String EXT_NAME = ".drl";              // 规则文件扩展名
012//    private static final String PACKAGE_PREFIX = "package ";    // 规则包名前缀
013//    private static final String IMPORT_PREFIX = "import ";      // 规则引入前缀
014//    private static final String RULE_NAME_PREFIX = "rule ";      // 规则名称前缀
015//    private static final String RULE_WHEN = "when";      // 规则WHEN标识
016//    private static final String RULE_THEN = "then";      // 规则THEN标识
017//    private static final String RULE_END = "end";      // 规则END标识
018//
019//    private static final String EVAL_TRUE = "eval(true)";   // 默认条件
020//
021    // 文件内容写入器
022//    private static FileWriter fw;
023//
024//    // 文件内容叠加器
025//    private static StringBuilder sb;
026
027    /**
028     * 获取规则文件全路径
029     * @param ruleFileName
030     * @return
031     */
032//    public static String getRuleFileFullPath(String ruleFileName) {
033//        String dir = getRuleFileDir();
034//
035////        return dir + File.separator + ruleFileName + EXT_NAME;
036//        String filePath = dir + "\\" + ruleFileName + EXT_NAME;
037//
038//        return filePath;
039//    }
040//
041//    /**
042//     * 获取规则文件存储目录
043//     * @return
044//     */
045//    public static String getRuleFileDir() {
046//        // 获取项目资源文件根目录
047//        String dir = ResourceUtil.getResource("").getPath();
048//        // 去除每一个“/”字符(win系统)
049//        dir = StrUtil.sub(dir, 1, dir.length());
050//        // 获取最后一个字符
051//        String lastChar = StrUtil.sub(dir, dir.length() - 1, dir.length());
052//        // 拼接规则文件目录
053//        if (File.separator.equals(lastChar)) {
054//            dir = dir + DIR_NAME;
055//        } else if ("/".equals(lastChar)) {
056//            dir = dir + DIR_NAME;
057//        } else {
058//            dir = dir + File.separator + DIR_NAME;
059//        }
060//
061//        return "D:\\Projects\\cenze\\cenze-rule-engine\\src\\test\\resources\\rules";
062//    }
063//
064//    @SneakyThrows
065//    public static void writeRuleFile(String ruleFileFullPath, String ruleFileContent) {
066//        FileUtil.del(ruleFileFullPath);
067//        File file = FileUtil.touch(ruleFileFullPath);
068//
069//        // 新增文件写入器
070//        FileWriter fw = new FileWriter(file);
071//        fw.write(ruleFileContent);
072//        fw.close();
073//    }
074
075//    /**
076//     * 重载规则
077//     * @param rule
078//     */
079//    public static void reloadRuleContent(RuleDTO rule) {
080//        if (ObjectUtil.isNull(rule) || StrUtil.isEmpty(rule.getRuleName()) || StrUtil.isEmpty(rule.getRuleContent())) {
081//            new NullPointerException("规则对象、名称、内容不能为空");
082//        }
083//
084//        List<RuleDTO> lstRule = new ArrayList<>();
085//        lstRule.add(rule);
086//
087//        KieUtil.reloadRule(lstRule);
088//    }
089//
090//    /**
091//     * 重载规则文件
092//     * @param ruleFileFullPath
093//     * @return
094//     * @throws UnsupportedEncodingException
095//     */
096//    public static void reloadRuleFile(String ruleFileFullPath) {
097//        File file = new File(ruleFileFullPath);
098//
099//        reloadRuleFile(file);
100//    }
101//
102//    /**
103//     * 重载规则文件
104//     * @param file
105//     * @return
106//     */
107//    @SneakyThrows
108//    public static void reloadRuleFile(File file) {
109//        byte[] bytes = FileUtil.readBytes(file);
110//        String ruleContent = new String(bytes, "UTF-8");
111//
112//        RuleDTO rule = new RuleDTO();
113//        rule.setRuleName(file.getName());
114//        rule.setRuleContent(ruleContent);
115//
116//        System.out.println("rule: " + JSON.toJSONString(rule));
117//
118//        List<RuleDTO> lstRule = new ArrayList<>();
119//        lstRule.add(rule);
120//
121//        KieUtil.reloadRule(lstRule);
122//    }
123
124//    /**
125//     * 初始化规则文件对象(创建一个测试规则文件对象)
126//     * @return
127//     */
128//    public static RuleFile initRuleFile() {
129//        RuleFile ruleFile = new RuleFile();
130//        ruleFile.setFileName("rule");
131//        ruleFile.setPackageName("top.cenze.rule");
132//
133//        List<String> imports = new ArrayList<>();
134//        imports.add("top.cenze.rule.pojo.UserInfo");
135//        imports.add("top.cenze.rule.utils.TestUtil");
136//        ruleFile.setImports(imports);
137//
138//        List<String> lstRuleName = new ArrayList<>();
139//
140//        RuleHeader header = new RuleHeader();
141//        header.setRuleName("test_rule");
142//        header.setAttributes(null);
143//        lstRuleName.add(header.getRuleName());
144//
145//        RuleBodyWhenLhs lhs = new RuleBodyWhenLhs();
146//        lhs.setLhsObjBindName("userInfo");
147//        lhs.setLhsObjName("UserInfo");
148//        List<RuleBodyWhenSubLhs> lstSubLhs = new ArrayList<>();
149//        RuleBodyWhenSubLhs subLhs = new RuleBodyWhenSubLhs();
150//        subLhs.setLVal("age");
151//        subLhs.setCmpOps(RuleCompOperatorEnum.LT.getVal());
152//        subLhs.setRVal(50);
153//        lstSubLhs.add(subLhs);
154//        lhs.setLstSubLhs(lstSubLhs);
155//        List<RuleBodyWhenLhs> lstLhs = new ArrayList<>();
156//        lstLhs.add(lhs);
157//
158//        RuleBodyWhen rWhen = new RuleBodyWhen();
159//        rWhen.setLhs(lstLhs);
160//
161//        RuleBodyThenRhs rhs = new RuleBodyThenRhs();
162//        rhs.setRhs("$userInfo.setUserName(\"chengze\")");
163//        List<RuleBodyThenRhs> lstRhs = new ArrayList<>();
164//        lstRhs.add(rhs);
165//
166//        RuleBodyThen rThen = new RuleBodyThen();
167//        rThen.setRhs(lstRhs);
168//
169//        RuleBody body = new RuleBody();
170//        body.setRWhen(rWhen);
171//        body.setRThen(rThen);
172//
173//        Rule rule = new Rule();
174//        rule.setHeader(header);
175//        rule.setBody(body);
176//        List<Rule> lstRule = new ArrayList<>();
177//        lstRule.add(rule);
178//
179//        ruleFile.setRules(lstRule);
180//        ruleFile.setRuleNames(lstRuleName);
181//
182//        return ruleFile;
183//    }
184//
185//    /**
186//     * 创建规则文件
187//     * @param ruleFile
188//     */
189//    @SneakyThrows
190//    public static void createRuleFile(RuleFile ruleFile) {
191//        // 获取规则文件全路径
192//        String ruleFileFullPath = getRuleFileFullPath(ruleFile.getFileName());
193//
194//        // 规则引入
195//        List<String> imports = ruleFile.getImports();
196//        // 规则名称集合
197//        List<String> ruleNames = ruleFile.getRuleNames();
198//        // 规则集合
199//        List<Rule> rules = ruleFile.getRules();
200//
201//        // =======================> 创建规则文件
202//        FileUtil.touch(ruleFileFullPath);
203//    }
204//
205//    /**
206//     * 写入规则文件
207//     * @param ruleFile  规则文件对象
208//     * @param fwMode    写入方式(0叠加,1直接写入,默认为0)
209//     */
210//    @SneakyThrows
211//    private static void fwRuleFile(RuleFile ruleFile, Integer fwMode) {
212//        if (ObjectUtil.isNull(fwMode)) {
213//            fwMode = 0;
214//        }
215//
216//        // 获取规则文件全路径
217//        String ruleFileFullPath = getRuleFileFullPath(ruleFile.getFileName());
218//
219//        // 规则引入
220//        List<String> imports = ruleFile.getImports();
221//        // 规则名称集合
222//        List<String> ruleNames = ruleFile.getRuleNames();
223//        // 规则集合
224//        List<Rule> rules = ruleFile.getRules();
225//
226//        // =======================> 创建规则文件
227//        File file = FileUtil.touch(ruleFileFullPath);
228//
229//        // 新增文件写入器
230//        fw = new FileWriter(file);
231//
232//        // 写入规则package
233//        if (fwMode != 0) {
234//            fwNewLine(PACKAGE_PREFIX + ruleFile.getPackageName());
235//        } else {
236//            appendNewLine(PACKAGE_PREFIX + ruleFile.getPackageName());
237//        }
238//
239//        // 写入规则imports
240//        if (CollectionUtil.isNotEmpty(imports)) {
241//            for (String imp : imports) {
242//                if (StrUtil.isEmpty(imp)) {
243//                    continue;
244//                }
245//
246//                if (fwMode != 0) {
247//                    fwNewLine(IMPORT_PREFIX + imp);
248//                } else {
249//                    appendNewLine(IMPORT_PREFIX + imp);
250//                }
251//            }
252//        }
253//
254//        // -------------------------> 循环写入规则
255//        for (Rule rule: rules) {
256//            RuleHeader header = rule.getHeader();
257//            RuleBody body = rule.getBody();
258//            RuleBodyWhen rWhen = body.getRWhen();
259//            List<RuleBodyWhenLhs> lstLhs = rWhen.getLhs();
260//            RuleBodyThen rThen = body.getRThen();
261//            List<RuleBodyThenRhs> lstRhs = rThen.getRhs();
262//
263//            // 写入规则名称
264//            if (fwMode != 0) {
265//                fwNewLine(RULE_NAME_PREFIX + RuleSymbolEnum.DQUOTE.getVal() + header.getRuleName() + RuleSymbolEnum.DQUOTE.getVal());
266//            } else {
267//                appendNewLine(RULE_NAME_PREFIX + RuleSymbolEnum.DQUOTE.getVal() + header.getRuleName() + RuleSymbolEnum.DQUOTE.getVal());
268//            }
269//
270//            // 写入规则属性
271//            fwRuleAttrs(header.getAttributes(), fwMode);
272//
273//            // 写入WHEN
274//            fwRuleWhen(body.getRWhen(), fwMode);
275//
276//            // 写入THEN
277//            fwRuleThen(body.getRThen(), fwMode);
278//
279//            // 规则END标识
280//            if (fwMode != 0) {
281//                fwNewLine(RULE_END);
282//            } else {
283//                appendNewLine(RULE_END);
284//            }
285//        }
286//
287//        if (0 == fwMode) {
288//            fw.write(sb.toString());
289//        }
290//
291//        fw.close();
292//    }
293//
294//    /**
295//     * 删除规则文件
296//     * @param ruleFileName
297//     */
298//    public static void delRuleFile(String ruleFileName) {
299//        String ruleFileFullPath = getRuleFileFullPath(ruleFileName);
300//
301//        FileUtil.del(ruleFileFullPath);
302//    }
303//
304//    /**
305//     * 清除规则文件
306//     * @param ruleFileName
307//     */
308//    public static void cleanRuleFile(String ruleFileName) {
309//        String ruleFileFullPath = getRuleFileFullPath(ruleFileName);
310//
311//        FileUtil.clean(ruleFileFullPath);
312//    }
313//
314//    /**
315//     * 写入规则属性
316//     * @param attr
317//     */
318//    @SneakyThrows
319//    private static void fwRuleAttrs(RuleHeaderAttributes attr, Integer fwMode) {
320//        if (ObjectUtil.isNull(attr)) {
321//            return;
322//        }
323//
324//        // 写入当前规则是否启用属性
325//        if (ObjectUtil.isNotNull(attr.getEnabled())) {
326//            fwNewLine(RuleAttributesEnum.ENABLED.getVal() + " " + attr.getEnabled());
327//        }
328//
329//        // 写入规则使用的语言类型(取值为java和mvel,默认值为java)属性
330//        if (StrUtil.isNotEmpty(attr.getDialect())) {
331//            fwNewLine(RuleAttributesEnum.DIALECT.getVal() + " " + attr.getDialect());
332//        }
333//
334//        // 写入规则的执行优先级(数值越大越优先执行)属性
335//        if (ObjectUtil.isNotNull(attr.getSalience())) {
336//            fwNewLine(RuleAttributesEnum.SALIENCE.getVal() + " " + attr.getSalience());
337//        }
338//
339//        // 写入是否不允许多次循环执行(默认为false,为true则只允许被执行一次)属性
340//        if (ObjectUtil.isNotNull(attr.getLockOnActive())) {
341//            fwNewLine(RuleAttributesEnum.LOCK_ON_ACTIVE.getVal() + " " + attr.getLockOnActive());
342//        }
343//
344//        // 写入激活分组属性
345//        if (StrUtil.isNotEmpty(attr.getActivationGroup())) {
346//            fwNewLine(RuleAttributesEnum.ACTIVATION_GROUP.getVal() + " " + attr.getActivationGroup());
347//        }
348//
349//        // 写入议程分组属性
350//        if (StrUtil.isNotEmpty(attr.getAgendaGroup())) {
351//            fwNewLine(RuleAttributesEnum.AGENDA_GROUP.getVal() + " " + attr.getAgendaGroup());
352//        }
353//
354//        // 写入自动获取焦点(默认为false)属性
355//        if (ObjectUtil.isNotNull(attr.getAutoFocus())) {
356//            fwNewLine(RuleAttributesEnum.AUTO_FOCUS.getVal() + " " + attr.getAutoFocus());
357//        }
358//
359//        // 写入规则定时(单位:毫秒)属性
360//        if (ObjectUtil.isNotNull(attr.getDuration())) {
361//            fwNewLine(RuleAttributesEnum.DURATION.getVal() + " " + attr.getDuration());
362//        }
363//
364//        // 写入定时器的方式指定规则执行的时间属性
365//        if (StrUtil.isNotEmpty(attr.getTimer())) {
366//            fwNewLine(RuleAttributesEnum.TIMER.getVal() + " " + attr.getTimer());
367//        }
368//
369//        // 写入规则的生效时间属性
370//        if (StrUtil.isNotEmpty(attr.getDateEffective())) {
371//            fwNewLine(RuleAttributesEnum.DATE_EFFECTIVE.getVal() + " " + attr.getDateEffective());
372//        }
373//
374//        // 写入规则的失效时间属性
375//        if (StrUtil.isNotEmpty(attr.getDateExpires())) {
376//            fwNewLine(RuleAttributesEnum.DATE_EXPIRES.getVal() + " " + attr.getDateExpires());
377//        }
378//    }
379//
380//    /**
381//     * 写入规则条件
382//     * @param rWhen
383//     */
384//    @SneakyThrows
385//    private static void fwRuleWhen(RuleBodyWhen rWhen, Integer fwMode) {
386//        // 写入WHEN标识
387//        fwNewLine(RULE_WHEN);
388//
389//        // 如果条件集合为空,则写入默认条件
390//        if (CollectionUtil.isEmpty(rWhen.getLhs())) {
391//            fwNewLine(EVAL_TRUE);
392//
393//            return;
394//        }
395//
396//        // 循环写入规则条件
397//        for (RuleBodyWhenLhs lhs: rWhen.getLhs()) {
398//            if (ObjectUtil.isNull(lhs)) {
399//                continue;
400//            }
401//
402//            // 写入条件对象绑定变量名
403//            if (StrUtil.isNotEmpty(lhs.getLhsObjBindName())) {
404//                fw.write(RuleSymbolEnum.DOLLAR.getVal() + lhs.getLhsObjBindName() + RuleSymbolEnum.COLON.getVal());
405//            }
406//
407//            // 写入条件对象
408//            if (StrUtil.isNotEmpty(lhs.getLhsObjName())) {
409//                fw.write(lhs.getLhsObjName());
410//            }
411//
412//            // 写入对象左括号
413//            fw.write(RuleSymbolEnum.LPAREN.getVal());
414//
415//            // 如果自定义条件不为空,写入自定义条件
416//            if (StrUtil.isNotEmpty(lhs.getLhs())) {
417//                fw.write(lhs.getLhs());
418//            }
419//            // 否则,写入拼接条件
420//            else if (CollectionUtil.isNotEmpty(lhs.getLstSubLhs())) {
421//                for (RuleBodyWhenSubLhs subLhs : lhs.getLstSubLhs()) {
422//                    if (ObjectUtil.isNull(subLhs)) {
423//                        continue;
424//                    }
425//
426//                    // 写入左符号
427//                    if (StrUtil.isNotEmpty(subLhs.getOpenSymbol())) {
428//                        fw.write(subLhs.getOpenSymbol());
429//                    }
430//
431//                    fw.write(subLhs.getLVal() + RuleSymbolEnum.SPACE.getVal());
432//                    fw.write(subLhs.getCmpOps() + RuleSymbolEnum.SPACE.getVal());
433//                    if (subLhs.getRVal() instanceof String) {
434//                        fw.write(RuleSymbolEnum.DQUOTE.getVal() + (String)subLhs.getRVal() + RuleSymbolEnum.DQUOTE.getVal());
435//                    } else {
436//                        fw.write(Convert.toStr(subLhs.getRVal()));
437//                    }
438//
439//                    // 写入右符号
440//                    if (StrUtil.isNotEmpty(subLhs.getCloseSymbol())) {
441//                        fw.write(subLhs.getCloseSymbol());
442//                    }
443//
444//                    // 写入逻辑运算符
445//                    if (StrUtil.isNotEmpty(subLhs.getLogicalOperator())) {
446//                        fw.write(RuleSymbolEnum.SPACE.getVal() + subLhs.getLogicalOperator() + RuleSymbolEnum.SPACE.getVal());
447//                    }
448//                }
449//            }
450//
451//            // 写入对象右括号
452//            fw.write(RuleSymbolEnum.RPAREN.getVal());
453//
454//            // 写入换行
455//            fwNewLine(RuleSymbolEnum.NEWLINE.getVal());
456//        }
457//    }
458//
459//    /**
460//     * 写入THEN
461//     * @param rThen
462//     */
463//    @SneakyThrows
464//    private static void fwRuleThen(RuleBodyThen rThen, Integer fwMode) {
465//        // 写入THEN标识
466//        fwNewLine(RULE_THEN);
467//
468//        // 如果事务集合为空,则返回
469//        if (CollectionUtil.isEmpty(rThen.getRhs())) {
470//            return;
471//        }
472//
473//        // 循环写入规则事务
474//        for (RuleBodyThenRhs rhs : rThen.getRhs()) {
475//            if (ObjectUtil.isNull(rhs)) {
476//                continue;
477//            }
478//
479//            // 写入事务
480//            if (StrUtil.isNotEmpty(rhs.getRhs())) {
481//                fwNewLine(rhs.getRhs());
482//            }
483//        }
484//    }
485//
486//    /**
487//     * 写入新的一行
488//     * @param contant
489//     * @throws IOException
490//     */
491//    private static void fwNewLine(String contant) throws IOException {
492//        fw.write(contant + RuleSymbolEnum.NEWLINE.getVal());
493//    }
494//
495//    // 追加新的一行
496//    private static void appendNewLine(String contant) {
497//        sb.append(contant + RuleSymbolEnum.NEWLINE.getVal());
498//    }
499}