@@ -59,6 +59,7 @@ public class ParseUtils {
59
59
// Matches ${{ foo.bar }} (whitespace optional) with capturing groups 1=foo, 2=bar
60
60
// private static final Pattern SUBSTITUTION_PATTERN = Pattern.compile("\\$\\{\\{\\s*(.+)\\.(.+?)\\s*\\}\\}");
61
61
private static final Pattern SUBSTITUTION_PATTERN = Pattern .compile ("\\ $\\ {\\ {\\ s*([\\ w_]+)\\ .([\\ w_]+)\\ s*\\ }\\ }" );
62
+ private static final Pattern JSON_ARRAY_DOUBLE_QUOTES_PATTERN = Pattern .compile ("\" \\ [(.*?)]\" " );
62
63
63
64
private ParseUtils () {}
64
65
@@ -70,7 +71,7 @@ private ParseUtils() {}
70
71
* @param json the json string
71
72
* @return The XContent parser for the json string
72
73
* @throws IOException on failure to create the parser
73
- */
74
+ */
74
75
public static XContentParser jsonToParser (String json ) throws IOException {
75
76
XContentParser parser = JsonXContent .jsonXContent .createParser (
76
77
NamedXContentRegistry .EMPTY ,
@@ -104,7 +105,7 @@ public static String resourceToString(String path) throws IOException {
104
105
* Builds an XContent object representing a map of String keys to String values.
105
106
*
106
107
* @param xContentBuilder An XContent builder whose position is at the start of the map object to build
107
- * @param map A map as key-value String pairs.
108
+ * @param map A map as key-value String pairs.
108
109
* @throws IOException on a build failure
109
110
*/
110
111
public static void buildStringToStringMap (XContentBuilder xContentBuilder , Map <?, ?> map ) throws IOException {
@@ -119,7 +120,7 @@ public static void buildStringToStringMap(XContentBuilder xContentBuilder, Map<?
119
120
* Builds an XContent object representing a map of String keys to Object values.
120
121
*
121
122
* @param xContentBuilder An XContent builder whose position is at the start of the map object to build
122
- * @param map A map as key-value String to Object.
123
+ * @param map A map as key-value String to Object.
123
124
* @throws IOException on a build failure
124
125
*/
125
126
public static void buildStringToObjectMap (XContentBuilder xContentBuilder , Map <?, ?> map ) throws IOException {
@@ -138,7 +139,7 @@ public static void buildStringToObjectMap(XContentBuilder xContentBuilder, Map<?
138
139
* Builds an XContent object representing a LLMSpec.
139
140
*
140
141
* @param xContentBuilder An XContent builder whose position is at the start of the map object to build
141
- * @param llm LLMSpec
142
+ * @param llm LLMSpec
142
143
* @throws IOException on a build failure
143
144
*/
144
145
public static void buildLLMMap (XContentBuilder xContentBuilder , LLMSpec llm ) throws IOException {
@@ -171,6 +172,7 @@ public static Map<String, String> parseStringToStringMap(XContentParser parser)
171
172
* Parses an XContent object representing a map of String keys to Object values.
172
173
* The Object value here can either be a string or a map
173
174
* If an array is found in the given parser we conver the array to a string representation of the array
175
+ *
174
176
* @param parser An XContent parser whose position is at the start of the map object to parse
175
177
* @return A map as identified by the key-value pairs in the XContent
176
178
* @throws IOException on a parse failure
@@ -189,10 +191,13 @@ public static Map<String, Object> parseStringToObjectMap(XContentParser parser)
189
191
// Handle array: convert it to a string representation
190
192
List <String > elements = new ArrayList <>();
191
193
while (parser .nextToken () != XContentParser .Token .END_ARRAY ) {
192
- elements .add ("\" " + parser .text () + "\" " ); // Adding escaped quotes around each element
194
+ if (parser .currentToken ().equals (XContentParser .Token .VALUE_NUMBER )) {
195
+ elements .add (String .valueOf (parser .numberValue ())); // If number value don't add escaping quotes
196
+ } else {
197
+ elements .add ("\" " + parser .text () + "\" " ); // Adding escaped quotes around each element
198
+ }
193
199
}
194
- String arrayString = "[" + String .join (", " , elements ) + "]" ;
195
- map .put (fieldName , arrayString );
200
+ map .put (fieldName , elements .toString ());
196
201
} else {
197
202
// Otherwise, parse it as a string
198
203
map .put (fieldName , parser .text ());
@@ -220,6 +225,7 @@ public static Instant parseInstant(XContentParser parser) throws IOException {
220
225
* (e.g., john||own_index,testrole|__user__, no backend role so you see two verticle line after john.).
221
226
* This is the user string format used internally in the OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT and may be
222
227
* parsed using User.parse(string).
228
+ *
223
229
* @param client Client containing user info. A public API request will fill in the user info in the thread context.
224
230
* @return parsed user object
225
231
*/
@@ -233,7 +239,7 @@ public static User getUserContext(Client client) {
233
239
* Creates a XContentParser from a given Registry
234
240
*
235
241
* @param xContentRegistry main registry for serializable content
236
- * @param bytesReference given bytes to be parsed
242
+ * @param bytesReference given bytes to be parsed
237
243
* @return bytesReference of {@link java.time.Instant}
238
244
* @throws IOException IOException if content can't be parsed correctly
239
245
*/
@@ -244,7 +250,8 @@ public static XContentParser createXContentParserFromRegistry(NamedXContentRegis
244
250
245
251
/**
246
252
* Generates a string to string Map
247
- * @param map content map
253
+ *
254
+ * @param map content map
248
255
* @param fieldName fieldName
249
256
* @return instance of the map
250
257
*/
@@ -260,15 +267,15 @@ public static Map<String, String> getStringToStringMap(Object map, String fieldN
260
267
* Creates a map containing the specified input keys, with values derived from template data or previous node
261
268
* output.
262
269
*
263
- * @param requiredInputKeys A set of keys that must be present, or will cause an exception to be thrown
264
- * @param optionalInputKeys A set of keys that may be present, or will be absent in the returned map
265
- * @param currentNodeInputs Input params and content for this node, from workflow parsing
266
- * @param outputs WorkflowData content of previous steps
270
+ * @param requiredInputKeys A set of keys that must be present, or will cause an exception to be thrown
271
+ * @param optionalInputKeys A set of keys that may be present, or will be absent in the returned map
272
+ * @param currentNodeInputs Input params and content for this node, from workflow parsing
273
+ * @param outputs WorkflowData content of previous steps
267
274
* @param previousNodeInputs Input params for this node that come from previous steps
268
- * @param params Params that came from REST path
275
+ * @param params Params that came from REST path
269
276
* @return A map containing the requiredInputKeys with their corresponding values,
270
- * and optionalInputKeys with their corresponding values if present.
271
- * Throws a {@link FlowFrameworkException} if a required key is not present.
277
+ * and optionalInputKeys with their corresponding values if present.
278
+ * Throws a {@link FlowFrameworkException} if a required key is not present.
272
279
*/
273
280
public static Map <String , Object > getInputsFromPreviousSteps (
274
281
Set <String > requiredInputKeys ,
@@ -357,9 +364,10 @@ public static Map<String, Object> getInputsFromPreviousSteps(
357
364
358
365
/**
359
366
* Executes substitution on the given value by looking at any matching values in either the ouputs or params map
360
- * @param value the Object that will have the substitution done on
367
+ *
368
+ * @param value the Object that will have the substitution done on
361
369
* @param outputs potential location of values to be substituted in
362
- * @param params potential location of values to be subsituted in
370
+ * @param params potential location of values to be subsituted in
363
371
* @return the substituted object back
364
372
*/
365
373
public static Object conditionallySubstitute (Object value , Map <String , WorkflowData > outputs , Map <String , String > params ) {
@@ -403,6 +411,7 @@ public static Object conditionallySubstitute(Object value, Map<String, WorkflowD
403
411
404
412
/**
405
413
* Generates a string based on an arbitrary String to object map using Jackson
414
+ *
406
415
* @param map content map
407
416
* @return instance of the string
408
417
* @throws JsonProcessingException JsonProcessingException from Jackson for issues processing map
@@ -415,6 +424,7 @@ public static String parseArbitraryStringToObjectMapToString(Map<String, Object>
415
424
416
425
/**
417
426
* Generates a String to String map based on a Json File
427
+ *
418
428
* @param path file path
419
429
* @return instance of the string
420
430
* @throws JsonProcessingException JsonProcessingException from Jackson for issues processing map
@@ -430,15 +440,21 @@ public static Map<String, String> parseJsonFileToStringToStringMap(String path)
430
440
* (e.g. "[\"text\", \"hello\"]" to "["text", "hello"]"), this is needed for processors that take in string arrays,
431
441
* This also removes the quotations around the array making the array valid to consume
432
442
* (e.g. "weights": "[0.7, 0.3]" to "weights": [0.7, 0.3])
443
+ *
433
444
* @param input The inputString given to be transformed
434
445
* @return the transformed string
435
446
*/
436
447
public static String removingBackslashesAndQuotesInArrayInJsonString (String input ) {
437
- return Pattern .compile ("\" \\ [(.*?)]\" " ).matcher (input ).replaceAll (matchResult -> {
448
+ Matcher matcher = JSON_ARRAY_DOUBLE_QUOTES_PATTERN .matcher (input );
449
+ StringBuffer result = new StringBuffer ();
450
+ while (matcher .find ()) {
438
451
// Extract matched content and remove backslashes before quotes
439
- String withoutEscapes = matchResult .group (1 ).replaceAll ("\\ \\ \" " , "\" " );
452
+ String withoutEscapes = matcher .group (1 ).replaceAll ("\\ \\ \" " , "\" " );
440
453
// Return the transformed string with the brackets but without the outer quotes
441
- return "[" + withoutEscapes + "]" ;
442
- });
454
+ matcher .appendReplacement (result , "[" + withoutEscapes + "]" );
455
+ }
456
+ // Append remaining input after the last match
457
+ matcher .appendTail (result );
458
+ return result .toString ();
443
459
}
444
460
}
0 commit comments