001/** 002 * Copyright (c) 2025-2026, Michael Yang 杨福海 (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.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 * <p> 008 * http://www.gnu.org/licenses/lgpl-3.0.txt 009 * <p> 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 dev.tinyflow.core.parser; 017 018 019import com.alibaba.fastjson.JSONArray; 020import com.alibaba.fastjson.JSONObject; 021import dev.tinyflow.core.chain.DataType; 022import dev.tinyflow.core.chain.JsCodeCondition; 023import dev.tinyflow.core.chain.Parameter; 024import dev.tinyflow.core.chain.RefType; 025import dev.tinyflow.core.node.BaseNode; 026import dev.tinyflow.core.util.StringUtil; 027 028import java.util.ArrayList; 029import java.util.Collections; 030import java.util.List; 031 032 033public abstract class BaseNodeParser<T extends BaseNode> implements NodeParser<T> { 034 035 private static final JSONObject EMPTY_JSON_OBJECT = new JSONObject(Collections.emptyMap()); 036 037 private ChainParser chainParser; 038 039 @Override 040 public ChainParser getChainParser() { 041 return chainParser; 042 } 043 044 public JSONObject getData(JSONObject nodeObject) { 045 JSONObject jsonObject = nodeObject.getJSONObject("data"); 046 return jsonObject != null ? jsonObject : EMPTY_JSON_OBJECT; 047 } 048 049 public void addParameters(BaseNode node, JSONObject data) { 050 List<Parameter> inputParameters = getParameters(data, "parameters"); 051 node.setParameters(inputParameters); 052 } 053 054 public List<Parameter> getParameters(JSONObject data, String key) { 055 return getParameters(data.getJSONArray(key)); 056 } 057 058 public List<Parameter> getParameters(JSONArray parametersJsonArray) { 059 if (parametersJsonArray == null || parametersJsonArray.isEmpty()) { 060 return Collections.emptyList(); 061 } 062 List<Parameter> parameters = new ArrayList<>(parametersJsonArray.size()); 063 for (int i = 0; i < parametersJsonArray.size(); i++) { 064 JSONObject parameterJsonObject = parametersJsonArray.getJSONObject(i); 065 Parameter parameter = new Parameter(); 066 parameter.setId(parameterJsonObject.getString("id")); 067 parameter.setName(parameterJsonObject.getString("name")); 068 parameter.setDescription(parameterJsonObject.getString("description")); 069 parameter.setDataType(DataType.ofValue(parameterJsonObject.getString("dataType"))); 070 parameter.setRef(parameterJsonObject.getString("ref")); 071 parameter.setValue(parameterJsonObject.getString("value")); 072 parameter.setDefaultValue(parameterJsonObject.getString("defaultValue")); 073 parameter.setRefType(RefType.ofValue(parameterJsonObject.getString("refType"))); 074 parameter.setDataType(DataType.ofValue(parameterJsonObject.getString("dataType"))); 075 parameter.setRequired(parameterJsonObject.getBooleanValue("required")); 076 parameter.setDefaultValue(parameterJsonObject.getString("defaultValue")); 077 078 //新增 079 parameter.setContentType(parameterJsonObject.getString("contentType")); 080 parameter.setEnums(parameterJsonObject.getJSONArray("enums")); 081 parameter.setFormType(parameterJsonObject.getString("formType")); 082 parameter.setFormLabel(parameterJsonObject.getString("formLabel")); 083 parameter.setFormPlaceholder(parameterJsonObject.getString("formPlaceholder")); 084 parameter.setFormAttrs(parameterJsonObject.getString("formAttrs")); 085 parameter.setFormDescription(parameterJsonObject.getString("formDescription")); 086 087 JSONArray children = parameterJsonObject.getJSONArray("children"); 088 if (children != null && !children.isEmpty()) { 089 parameter.addChildren(getParameters(children)); 090 } 091 092 parameters.add(parameter); 093 } 094 095 return parameters; 096 } 097 098 099 public void addOutputDefs(BaseNode node, JSONObject data) { 100 List<Parameter> outputDefs = getParameters(data, "outputDefs"); 101 if (outputDefs == null || outputDefs.isEmpty()) { 102 return; 103 } 104 node.setOutputDefs(outputDefs); 105 } 106 107 108 @Override 109 public T parse(JSONObject nodeJSONObject, JSONObject chainJSONObject, ChainParser chainParser) { 110 this.chainParser = chainParser; 111 JSONObject data = getData(nodeJSONObject); 112 T node = doParse(nodeJSONObject, data, chainJSONObject); 113 if (node != null) { 114 115 node.setId(nodeJSONObject.getString("id")); 116 node.setParentId(nodeJSONObject.getString("parentId")); 117 node.setName(nodeJSONObject.getString("label")); 118 node.setDescription(nodeJSONObject.getString("description")); 119 120 if (!data.isEmpty()) { 121 122 addParameters(node, data); 123 addOutputDefs(node, data); 124 125 String conditionString = data.getString("condition"); 126 127 if (StringUtil.hasText(conditionString)) { 128 node.setCondition(new JsCodeCondition(conditionString.trim())); 129 } 130 131// Boolean async = data.getBoolean("async"); 132// if (async != null) { 133// node.setAsync(async); 134// } 135 136 String name = data.getString("title"); 137 if (StringUtil.hasText(name)) { 138 node.setName(name); 139 } 140 141 String description = data.getString("description"); 142 if (StringUtil.hasText(description)) { 143 node.setDescription(description); 144 } 145 146 // 循环执行 start ======= 147 Boolean loopEnable = data.getBoolean("loopEnable"); 148 if (loopEnable != null) { 149 node.setLoopEnable(loopEnable); 150 } 151 152 if (loopEnable != null && loopEnable) { 153 Long loopIntervalMs = data.getLong("loopIntervalMs"); 154 if (loopIntervalMs == null) { 155 loopIntervalMs = 3000L; 156 } 157 node.setLoopIntervalMs(loopIntervalMs); 158 159 Integer maxLoopCount = data.getInteger("maxLoopCount"); 160 if (maxLoopCount != null) { 161 node.setMaxLoopCount(maxLoopCount); 162 } 163 164 String loopBreakCondition = data.getString("loopBreakCondition"); 165 if (StringUtil.hasText(loopBreakCondition)) { 166 node.setLoopBreakCondition(new JsCodeCondition(loopBreakCondition.trim())); 167 } 168 } 169 // 循环执行 end ======= 170 171 172 // 错误重试 start ======= 173 Boolean retryEnable = data.getBoolean("retryEnable"); 174 if (retryEnable != null) { 175 node.setRetryEnable(retryEnable); 176 } 177 178 if (retryEnable != null && retryEnable) { 179 Boolean resetRetryCountAfterNormal = data.getBoolean("resetRetryCountAfterNormal"); 180 if (resetRetryCountAfterNormal == null) { 181 resetRetryCountAfterNormal = true; 182 } 183 node.setResetRetryCountAfterNormal(resetRetryCountAfterNormal); 184 185 Long retryIntervalMs = data.getLong("retryIntervalMs"); 186 if (retryIntervalMs == null) { 187 retryIntervalMs = 1000L; 188 } 189 node.setRetryIntervalMs(retryIntervalMs); 190 191 Integer maxRetryCount = data.getInteger("maxRetryCount"); 192 if (maxRetryCount == null) { 193 maxRetryCount = 3; 194 } 195 node.setMaxRetryCount(maxRetryCount); 196 } 197 // 错误重试 end ======= 198 } 199 } 200 201 return node; 202 } 203 204 protected abstract T doParse(JSONObject nodeJSONObject, JSONObject data, JSONObject chainJSONObject); 205}