001/*
002 *    Copyright 2024-2025, Warm-Flow (290631660@qq.com).
003 *
004 *    Licensed under the Apache License, Version 2.0 (the "License");
005 *    you may not use this file except in compliance with the License.
006 *    You may obtain a copy of the License at
007 *
008 *       https://www.apache.org/licenses/LICENSE-2.0
009 *
010 *    Unless required by applicable law or agreed to in writing, software
011 *    distributed under the License is distributed on an "AS IS" BASIS,
012 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *    See the License for the specific language governing permissions and
014 *    limitations under the License.
015 */
016package org.dromara.warm.flow.core.utils;
017
018import org.dromara.warm.flow.core.constant.FlowCons;
019import org.dromara.warm.flow.core.entity.Definition;
020import org.dromara.warm.flow.core.entity.Node;
021import org.dromara.warm.flow.core.invoker.FrameInvoker;
022import org.dromara.warm.flow.core.listener.Listener;
023import org.dromara.warm.flow.core.listener.ListenerVariable;
024import org.dromara.warm.flow.core.listener.NodePermission;
025import org.dromara.warm.flow.core.listener.ValueHolder;
026
027import java.util.HashMap;
028import java.util.Map;
029import java.util.regex.Matcher;
030
031/**
032 * 监听器工具类
033 *
034 * @author warm
035 */
036public class ListenerUtil {
037
038    private ListenerUtil() {
039
040    }
041
042    /**
043     * 执行权限监听器,并赋值权限值集合
044     *
045     * @param listenerVariable
046     */
047    public static void executeGetNodePermission(ListenerVariable listenerVariable) {
048        for (Node node : listenerVariable.getNextNodes()) {
049            if (StringUtils.isNotEmpty(node.getListenerType()) && node.getListenerType().contains(Listener.LISTENER_PERMISSION)) {
050                //执行权限监听器
051                executeListener(listenerVariable, Listener.LISTENER_PERMISSION, node);
052
053                //拿到监听器内的权限标识 给NowNode.的PermissionFlag 赋值
054                if (CollUtil.isNotEmpty(listenerVariable.getNodePermissionList())) {
055                    NodePermission permissionByNode = listenerVariable.getPermissionByNode(node.getNodeCode());
056                    if (ObjectUtil.isNotNull(permissionByNode) && StringUtils.isNotEmpty(permissionByNode.getPermissionFlag())) {
057                        if (CollUtil.isNotEmpty(permissionByNode.getPermissionFlagList())) {
058                            node.setDynamicPermissionFlagList(permissionByNode.getPermissionFlagList());
059                        } else if (StringUtils.isNotEmpty(permissionByNode.getPermissionFlag())) {
060                            node.setDynamicPermissionFlagList(CollUtil.strToColl(permissionByNode.getPermissionFlag(), ","));
061                        }
062                    }
063                }
064            }
065        }
066    }
067
068    /**
069     * 执行结束监听器和下一节点的开始监听器
070     *
071     * @param listenerVariable
072     */
073    public static void endCreateListener(ListenerVariable listenerVariable) {
074        // 执行任务完成监听器
075        executeListener(listenerVariable, Listener.LISTENER_END);
076        // 执行任务创建监听器
077        listenerVariable.getNextNodes().forEach(node -> executeListener(listenerVariable, Listener.LISTENER_CREATE, node));
078    }
079
080    public static void executeListener(ListenerVariable listenerVariable, String lisType) {
081        executeListener(listenerVariable, lisType, listenerVariable.getNode());
082    }
083
084    public static void executeListener(ListenerVariable listenerVariable, String lisType, Node listenerNode) {
085        // 执行监听器
086        //listenerPath({"name": "John Doe", "age": 30})@@listenerPath@@listenerPath
087        String listenerType = listenerNode.getListenerType();
088        execute(listenerVariable, lisType, listenerNode.getListenerPath(), listenerType);
089        Definition definition = listenerVariable.getDefinition();
090        execute(listenerVariable, lisType, definition.getListenerPath(), definition.getListenerType());
091    }
092
093    private static void execute(ListenerVariable listenerVariable, String lisType, String listenerPathStr, String lisListType) {
094        if (StringUtils.isNotEmpty(lisListType)) {
095            String[] listenerTypeArr = lisListType.split(",");
096            for (int i = 0; i < listenerTypeArr.length; i++) {
097                String listenerTypeStr = listenerTypeArr[i].trim();
098                if (listenerTypeStr.equals(lisType)) {
099                    //"listenerPath1({\"name\": \"John Doe\", \"age\": 30})@@listenerPath2";
100                    if (StringUtils.isNotEmpty(listenerPathStr)) {
101                        //"listenerPath1({\"name\": \"John Doe\", \"age\": 30})";
102                        //listenerPath2
103                        String[] listenerPathArr = listenerPathStr.split(FlowCons.splitAt);
104                        String listenerPath = listenerPathArr[i].trim();
105                        ValueHolder valueHolder = new ValueHolder();
106                        //截取出path 和params
107                        getListenerPath(listenerPath, valueHolder);
108                        Class<?> clazz = ClassUtil.getClazz(valueHolder.getPath());
109                        // 增加传入类路径校验Listener接口, 防止强制类型转换失败
110                        if (ObjectUtil.isNotNull(clazz) && Listener.class.isAssignableFrom(clazz)) {
111                            Listener listener = (Listener) FrameInvoker.getBean(clazz);
112                            if (ObjectUtil.isNotNull(listener)) {
113                                Map<String, Object> variable = listenerVariable.getVariable();
114                                variable = MapUtil.isEmpty(variable) ? new HashMap<>() : variable;
115                                variable.put(FlowCons.WARM_LISTENER_PARAM, valueHolder.getParams());
116                                listener.notify(listenerVariable.setVariable(variable));
117                            }
118
119                        }
120                    }
121                }
122            }
123        }
124    }
125
126    /**
127     * 分别截取监听器path 和 监听器params
128     * String input = "listenerPath({\"name\": \"John Doe\", \"age\": 30})";
129     *
130     * @param listenerStr
131     * @param valueHolder
132     */
133    public static void getListenerPath(String listenerStr, ValueHolder valueHolder) {
134        String path;
135        String params;
136
137        Matcher matcher = FlowCons.listenerPattern.matcher(listenerStr);
138        if (matcher.find()) {
139            path = matcher.group(1).replaceAll("[\\(\\)]", "");
140            params = matcher.group(2).replaceAll("[\\(\\)]", "");
141            valueHolder.setPath(path);
142            valueHolder.setParams(params);
143        }
144    }
145}