Skip to content

Commit 788fc3a

Browse files
sunyuhan1998markpollack
authored andcommitted
Rename the option skipBuiltInFunctionsValidation of StTemplateRenderer to supportStFunctions.
- Add javadocs Signed-off-by: Sun Yuhan <1085481446@qq.com>
1 parent af29a79 commit 788fc3a

File tree

2 files changed

+64
-15
lines changed

2 files changed

+64
-15
lines changed

spring-ai-template-st/src/main/java/org/springframework/ai/template/st/StTemplateRenderer.java

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,15 @@
3232
import java.util.Set;
3333

3434
/**
35-
* Renders a template using the StringTemplate (ST) library.
35+
* Renders a template using the StringTemplate (ST) v4 library.
36+
*
37+
* <p>
38+
* This renderer allows customization of delimiters, validation behavior when template
39+
* variables are missing, and how StringTemplate's built-in functions are handled during
40+
* validation.
41+
*
42+
* <p>
43+
* Use the {@link #builder()} to create and configure instances.
3644
*
3745
* @author Thomas Vitale
3846
* @since 1.0.0
@@ -49,22 +57,23 @@ public class StTemplateRenderer implements TemplateRenderer {
4957

5058
private static final ValidationMode DEFAULT_VALIDATION_MODE = ValidationMode.THROW;
5159

52-
private static final boolean DEFAULT_SKIP_BUILT_IN_FUNCTIONS_VALIDATION = false;
60+
private static final boolean DEFAULT_SUPPORT_ST_FUNCTIONS = false;
5361

5462
private final char startDelimiterToken;
5563

5664
private final char endDelimiterToken;
5765

5866
private final ValidationMode validationMode;
5967

60-
private final boolean skipBuiltInFunctionsValidation;
68+
private final boolean supportStFunctions;
6169

62-
StTemplateRenderer(char startDelimiterToken, char endDelimiterToken, ValidationMode validationMode, boolean skipBuiltInFunctionsValidation) {
70+
StTemplateRenderer(char startDelimiterToken, char endDelimiterToken, ValidationMode validationMode,
71+
boolean supportStFunctions) {
6372
Assert.notNull(validationMode, "validationMode cannot be null");
6473
this.startDelimiterToken = startDelimiterToken;
6574
this.endDelimiterToken = endDelimiterToken;
6675
this.validationMode = validationMode;
67-
this.skipBuiltInFunctionsValidation = skipBuiltInFunctionsValidation;
76+
this.supportStFunctions = supportStFunctions;
6877
}
6978

7079
@Override
@@ -120,7 +129,7 @@ private Set<String> getInputVariables(ST st) {
120129
&& tokens.get(i + 1).getType() == STLexer.ID) {
121130
if (i + 2 < tokens.size() && tokens.get(i + 2).getType() == STLexer.COLON) {
122131
String text = tokens.get(i + 1).getText();
123-
if (!Compiler.funcs.containsKey(text) || !skipBuiltInFunctionsValidation) {
132+
if (!Compiler.funcs.containsKey(text) || !supportStFunctions) {
124133
inputVariables.add(text);
125134
isInsideList = true;
126135
}
@@ -130,7 +139,7 @@ else if (token.getType() == STLexer.RDELIM) {
130139
isInsideList = false;
131140
}
132141
else if (!isInsideList && token.getType() == STLexer.ID) {
133-
if (!Compiler.funcs.containsKey(token.getText()) || !skipBuiltInFunctionsValidation) {
142+
if (!Compiler.funcs.containsKey(token.getText()) || !supportStFunctions) {
134143
inputVariables.add(token.getText());
135144
}
136145
}
@@ -143,6 +152,9 @@ public static Builder builder() {
143152
return new Builder();
144153
}
145154

155+
/**
156+
* Builder for configuring and creating {@link StTemplateRenderer} instances.
157+
*/
146158
public static class Builder {
147159

148160
private char startDelimiterToken = DEFAULT_START_DELIMITER_TOKEN;
@@ -151,33 +163,70 @@ public static class Builder {
151163

152164
private ValidationMode validationMode = DEFAULT_VALIDATION_MODE;
153165

154-
private boolean skipBuiltInFunctionsValidation = DEFAULT_SKIP_BUILT_IN_FUNCTIONS_VALIDATION;
166+
private boolean supportStFunctions = DEFAULT_SUPPORT_ST_FUNCTIONS;
155167

156168
private Builder() {
157169
}
158170

171+
/**
172+
* Sets the character used as the start delimiter for template expressions.
173+
* Default is '{'.
174+
* @param startDelimiterToken The start delimiter character.
175+
* @return This builder instance for chaining.
176+
*/
159177
public Builder startDelimiterToken(char startDelimiterToken) {
160178
this.startDelimiterToken = startDelimiterToken;
161179
return this;
162180
}
163181

182+
/**
183+
* Sets the character used as the end delimiter for template expressions. Default
184+
* is '}'.
185+
* @param endDelimiterToken The end delimiter character.
186+
* @return This builder instance for chaining.
187+
*/
164188
public Builder endDelimiterToken(char endDelimiterToken) {
165189
this.endDelimiterToken = endDelimiterToken;
166190
return this;
167191
}
168192

193+
/**
194+
* Sets the validation mode to control behavior when the provided variables do not
195+
* match the variables required by the template. Default is
196+
* {@link ValidationMode#THROW}.
197+
* @param validationMode The desired validation mode.
198+
* @return This builder instance for chaining.
199+
*/
169200
public Builder validationMode(ValidationMode validationMode) {
170201
this.validationMode = validationMode;
171202
return this;
172203
}
173204

174-
public Builder skipBuiltInFunctionsValidation() {
175-
this.skipBuiltInFunctionsValidation = true;
205+
/**
206+
* Configures the renderer to support StringTemplate's built-in functions during
207+
* validation.
208+
* <p>
209+
* When enabled (set to true), identifiers in the template that match known ST
210+
* function names (e.g., "first", "rest", "length") will not be treated as
211+
* required input variables during validation.
212+
* <p>
213+
* When disabled (default, false), these identifiers are treated like regular
214+
* variables and must be provided in the input map if validation is enabled
215+
* ({@link ValidationMode#WARN} or {@link ValidationMode#THROW}).
216+
* @return This builder instance for chaining.
217+
*/
218+
public Builder supportStFunctions() {
219+
this.supportStFunctions = true;
176220
return this;
177221
}
178222

223+
/**
224+
* Builds and returns a new {@link StTemplateRenderer} instance with the
225+
* configured settings.
226+
* @return A configured {@link StTemplateRenderer}.
227+
*/
179228
public StTemplateRenderer build() {
180-
return new StTemplateRenderer(startDelimiterToken, endDelimiterToken, validationMode, skipBuiltInFunctionsValidation);
229+
return new StTemplateRenderer(startDelimiterToken, endDelimiterToken, validationMode, supportStFunctions);
181230
}
182231

183232
}

spring-ai-template-st/src/test/java/org/springframework/ai/template/st/StTemplateRendererTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,12 @@ void shouldHandleObjectVariables() {
281281
}
282282

283283
/**
284-
* Test whether StringTemplate can correctly render a template containing built-in functions
285-
* when {@code skipBuiltInFunctionsValidation()} is enabled. It should render properly.
284+
* Test whether StringTemplate can correctly render a template containing built-in
285+
* functions when {@code supportStFunctions()} is enabled. It should render properly.
286286
*/
287287
@Test
288-
void shouldRenderTemplateWithSkipBuiltInFunctionsValidation() {
289-
StTemplateRenderer renderer = StTemplateRenderer.builder().skipBuiltInFunctionsValidation().build();
288+
void shouldRenderTemplateWithSupportStFunctions() {
289+
StTemplateRenderer renderer = StTemplateRenderer.builder().supportStFunctions().build();
290290
Map<String, Object> variables = new HashMap<>();
291291
variables.put("memory", "you are a helpful assistant");
292292
String template = "{if(strlen(memory))}Hello!{endif}";

0 commit comments

Comments
 (0)