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.node; 017 018import dev.tinyflow.core.chain.*; 019import dev.tinyflow.core.util.StringUtil; 020import dev.tinyflow.core.util.TextTemplate; 021 022import java.util.HashMap; 023import java.util.Map; 024 025public class EndNode extends BaseNode { 026 private boolean normal = true; 027 private String message; 028 029 public String getMessage() { 030 return message; 031 } 032 033 public void setMessage(String message) { 034 this.message = message; 035 } 036 037 public boolean isNormal() { 038 return normal; 039 } 040 041 public void setNormal(boolean normal) { 042 this.normal = normal; 043 } 044 045 public EndNode() { 046 this.name = "end"; 047 } 048 049 @Override 050 public Map<String, Object> execute(Chain chain) { 051 052 Map<String, Object> output = new HashMap<>(); 053 if (normal) { 054 output.put(ChainConsts.CHAIN_STATE_STATUS_KEY, ChainStatus.SUCCEEDED); 055 } else { 056 output.put(ChainConsts.CHAIN_STATE_STATUS_KEY, ChainStatus.FAILED); 057 } 058 059 if (StringUtil.hasText(message)) { 060 output.put(ChainConsts.CHAIN_STATE_MESSAGE_KEY, message); 061 } 062 063 Map<String, Object> formatParameters = getFormatParameters(chain); 064 065 066 if (this.outputDefs != null) { 067 for (Parameter outputDef : this.outputDefs) { 068 Object refObject = chain.getState().resolveValue(outputDef.getRef()); 069 if (outputDef.getRefType() == RefType.REF) { 070 output.put(outputDef.getName(), refObject); 071 } else if (outputDef.getRefType() == RefType.INPUT) { 072 output.put(outputDef.getName(), outputDef.getRef()); 073 } else if (outputDef.getRefType() == RefType.FIXED) { 074 String value = TextTemplate.of(outputDef.getValue()).formatToString(formatParameters); 075 output.put(outputDef.getName(), StringUtil.getFirstWithText(value, outputDef.getDefaultValue())); 076 } 077 // default is ref type 078 else if (StringUtil.hasText(outputDef.getRef())) { 079 output.put(outputDef.getName(), refObject); 080 } 081 } 082 } 083 084 return output; 085 } 086 087 088 @Override 089 public String toString() { 090 return "EndNode{" + 091 "normal=" + normal + 092 ", message='" + message + '\'' + 093 ", parameters=" + parameters + 094 ", outputDefs=" + outputDefs + 095 ", id='" + id + '\'' + 096 ", name='" + name + '\'' + 097 ", description='" + description + '\'' + 098 ", condition=" + condition + 099 ", validator=" + validator + 100 ", loopEnable=" + loopEnable + 101 ", loopIntervalMs=" + loopIntervalMs + 102 ", loopBreakCondition=" + loopBreakCondition + 103 ", maxLoopCount=" + maxLoopCount + 104 ", retryEnable=" + retryEnable + 105 ", resetRetryCountAfterNormal=" + resetRetryCountAfterNormal + 106 ", maxRetryCount=" + maxRetryCount + 107 ", retryIntervalMs=" + retryIntervalMs + 108 ", computeCostExpr='" + computeCostExpr + '\'' + 109 '}'; 110 } 111}