Skip to content

Commit 56f4099

Browse files
committed
Remove fragility of enrichOutput
Signed-off-by: Matheus Cruz <matheuscruz.dev@gmail.com>
1 parent acc5db6 commit 56f4099

2 files changed

Lines changed: 52 additions & 8 deletions

File tree

experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ public static <R> JavaContextFunction<Object, R> enrich(Function<WorkflowModel,
360360
*
361361
* <pre>{@code
362362
* function("processData", (Long input) -> input + 5, Long.class)
363-
* .outputAs(FuncDSL.enrichedOutput((taskOutput, rootInputModel) -> {
363+
* .outputAs(FuncDSL.enrichOutput((taskOutput, rootInputModel) -> {
364364
* Long rootInput = rootInputModel.as(Long.class).orElse(0L);
365365
* return taskOutput + rootInput;
366366
* }, Long.class))
@@ -372,16 +372,60 @@ public static <R> JavaContextFunction<Object, R> enrich(Function<WorkflowModel,
372372
* @param <R> the type of the enriched result
373373
* @return a JavaContextFunction that can be used with outputAs
374374
*/
375-
public static <T, R> JavaContextFunction<T, R> enrichedOutput(
375+
public static <T, R> JavaContextFunction<T, R> enrichOutput(
376376
EnrichWithModelBiFunction<T, R> fn, Class<T> taskOutputClass) {
377377
return (taskOutput, workflowContext) -> {
378378
Objects.requireNonNull(taskOutputClass, "taskOutputClass must not be null");
379379
final WorkflowModel rootInput = workflowContext.instanceData().input();
380-
final T typedTaskOutput = taskOutputClass.cast(taskOutput);
380+
final T typedTaskOutput = convertTaskOutput(taskOutput, taskOutputClass);
381381
return fn.apply(typedTaskOutput, rootInput);
382382
};
383383
}
384384

385+
private static <T> T convertTaskOutput(Object taskOutput, Class<T> taskOutputClass) {
386+
if (taskOutput == null) {
387+
return null;
388+
}
389+
if (taskOutputClass.isInstance(taskOutput)) {
390+
return taskOutputClass.cast(taskOutput);
391+
}
392+
if (Number.class.isAssignableFrom(taskOutputClass) && taskOutput instanceof Number) {
393+
Number number = (Number) taskOutput;
394+
if (taskOutputClass == Long.class) {
395+
@SuppressWarnings("unchecked")
396+
T converted = (T) Long.valueOf(number.longValue());
397+
return converted;
398+
}
399+
if (taskOutputClass == Integer.class) {
400+
@SuppressWarnings("unchecked")
401+
T converted = (T) Integer.valueOf(number.intValue());
402+
return converted;
403+
}
404+
if (taskOutputClass == Short.class) {
405+
@SuppressWarnings("unchecked")
406+
T converted = (T) Short.valueOf(number.shortValue());
407+
return converted;
408+
}
409+
if (taskOutputClass == Byte.class) {
410+
@SuppressWarnings("unchecked")
411+
T converted = (T) Byte.valueOf(number.byteValue());
412+
return converted;
413+
}
414+
if (taskOutputClass == Double.class) {
415+
@SuppressWarnings("unchecked")
416+
T converted = (T) Double.valueOf(number.doubleValue());
417+
return converted;
418+
}
419+
if (taskOutputClass == Float.class) {
420+
@SuppressWarnings("unchecked")
421+
T converted = (T) Float.valueOf(number.floatValue());
422+
return converted;
423+
}
424+
}
425+
// Fallback to the original behavior for incompatible types.
426+
return taskOutputClass.cast(taskOutput);
427+
}
428+
385429
/**
386430
* Create an output transformation that uses only the root workflow input as WorkflowModel.
387431
*
@@ -392,14 +436,14 @@ public static <T, R> JavaContextFunction<T, R> enrichedOutput(
392436
*
393437
* <pre>{@code
394438
* function("processData", (Long input) -> input * 2, Long.class)
395-
* .outputAs(FuncDSL.enrichedOutput(rootInput -> rootInput.asNumber().orElseThrow()))
439+
* .outputAs(FuncDSL.enrichOutput(rootInput -> rootInput.asNumber().orElseThrow()))
396440
* }</pre>
397441
*
398442
* @param fn the function that receives the root workflow input and returns the enriched result
399443
* @param <R> the type of the enriched result
400444
* @return a JavaContextFunction that can be used with outputAs
401445
*/
402-
public static <R> JavaContextFunction<Object, R> enrichedOutput(Function<WorkflowModel, R> fn) {
446+
public static <R> JavaContextFunction<Object, R> enrichOutput(Function<WorkflowModel, R> fn) {
403447
return (taskOutput, workflowContext) -> {
404448
final WorkflowModel rootInput = workflowContext.instanceData().input();
405449
return fn.apply(rootInput);

impl/test/src/test/java/io/serverlessworkflow/impl/test/FuncDSLEnrichWithTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
package io.serverlessworkflow.impl.test;
1717

1818
import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.enrich;
19-
import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.enrichedOutput;
19+
import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.enrichOutput;
2020
import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function;
2121

2222
import io.serverlessworkflow.api.types.Workflow;
@@ -120,7 +120,7 @@ void test_enrich_output_with_model_in_workflow() {
120120
},
121121
Long.class)
122122
.outputAs(
123-
enrichedOutput(
123+
enrichOutput(
124124
(taskOutput, rootInputModel) -> {
125125
// taskOutput is typed as Long (result from add5) = 15
126126
softly.assertThat(taskOutput).isEqualTo(15L);
@@ -160,7 +160,7 @@ void test_enrich_output_with_input_in_workflow() {
160160
},
161161
Long.class)
162162
.outputAs(
163-
enrichedOutput(
163+
enrichOutput(
164164
rootInput -> {
165165
Long value = rootInput.asNumber().orElseThrow().longValue();
166166
softly.assertThat(value).isEqualTo(10L);

0 commit comments

Comments
 (0)