Skip to content

Commit 40a7cdb

Browse files
authored
Merge pull request #685 from fjtirado/refactor_expressions
Refactoring expression building
2 parents 4af2a6b + d778590 commit 40a7cdb

36 files changed

+567
-385
lines changed

experimental/agentic/src/main/java/io/serverlessworkflow/impl/expressions/agentic/AgenticModel.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ class AgenticModel extends JavaModel {
3232
this.cognisphere = cognisphere;
3333
}
3434

35+
@Override
36+
public void setObject(Object obj) {
37+
super.setObject(obj);
38+
}
39+
3540
@Override
3641
public Collection<WorkflowModel> asCollection() {
3742
return object instanceof Collection value

experimental/agentic/src/main/java/io/serverlessworkflow/impl/expressions/agentic/AgenticModelFactory.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,23 @@
2626
import java.util.Map;
2727

2828
class AgenticModelFactory implements WorkflowModelFactory {
29-
private final Cognisphere cognisphere = CognisphereRegistry.createEphemeralCognisphere();
29+
30+
private Cognisphere cognisphere = CognisphereRegistry.createEphemeralCognisphere();
3031

3132
private final AgenticModel TrueModel = new AgenticModel(Boolean.TRUE, cognisphere);
3233
private final AgenticModel FalseModel = new AgenticModel(Boolean.FALSE, cognisphere);
3334
private final AgenticModel NullModel = new AgenticModel(null, cognisphere);
3435

36+
public void setCognishere(Cognisphere cognisphere) {
37+
this.cognisphere = cognisphere;
38+
}
39+
40+
@Override
41+
public WorkflowModel fromAny(WorkflowModel prev, Object obj) {
42+
((AgenticModel) prev).setObject(obj);
43+
return prev;
44+
}
45+
3546
@Override
3647
public WorkflowModel combine(Map<String, WorkflowModel> workflowVariables) {
3748
return new AgenticModel(workflowVariables, cognisphere);

experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaForExecutorBuilder.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323
import io.serverlessworkflow.api.types.func.ForTaskFunction;
2424
import io.serverlessworkflow.api.types.func.TypedFunction;
2525
import io.serverlessworkflow.impl.WorkflowApplication;
26-
import io.serverlessworkflow.impl.WorkflowFilter;
2726
import io.serverlessworkflow.impl.WorkflowPosition;
28-
import io.serverlessworkflow.impl.WorkflowUtils;
27+
import io.serverlessworkflow.impl.WorkflowPredicate;
28+
import io.serverlessworkflow.impl.WorkflowValueResolver;
2929
import io.serverlessworkflow.impl.executors.ForExecutor.ForExecutorBuilder;
30+
import io.serverlessworkflow.impl.expressions.ExpressionDescriptor;
3031
import io.serverlessworkflow.impl.expressions.LoopPredicateIndex;
3132
import io.serverlessworkflow.impl.resources.ResourceLoader;
33+
import java.util.Collection;
3234
import java.util.Optional;
3335

3436
public class JavaForExecutorBuilder extends ForExecutorBuilder {
@@ -42,7 +44,8 @@ protected JavaForExecutorBuilder(
4244
super(position, task, workflow, application, resourceLoader);
4345
}
4446

45-
protected Optional<WorkflowFilter> buildWhileFilter() {
47+
@Override
48+
protected Optional<WorkflowPredicate> buildWhileFilter() {
4649
if (task instanceof ForTaskFunction taskFunctions) {
4750
final LoopPredicateIndex whilePred = taskFunctions.getWhilePredicate();
4851
Optional<Class<?>> whileClass = taskFunctions.getWhileClass();
@@ -52,23 +55,21 @@ protected Optional<WorkflowFilter> buildWhileFilter() {
5255
return Optional.of(
5356
(w, t, n) -> {
5457
Object item = safeObject(t.variables().get(varName));
55-
return application
56-
.modelFactory()
57-
.from(
58-
whilePred.test(
59-
JavaFuncUtils.convert(n, whileClass),
60-
item,
61-
(Integer) safeObject(t.variables().get(indexName))));
58+
return whilePred.test(
59+
JavaFuncUtils.convert(n, whileClass),
60+
item,
61+
(Integer) safeObject(t.variables().get(indexName)));
6262
});
6363
}
6464
}
6565
return super.buildWhileFilter();
6666
}
6767

68-
protected WorkflowFilter buildCollectionFilter() {
68+
protected WorkflowValueResolver<Collection<?>> buildCollectionFilter() {
6969
return task instanceof ForTaskFunction taskFunctions
70-
? WorkflowUtils.buildWorkflowFilter(
71-
application, null, collectionFilterObject(taskFunctions))
70+
? application
71+
.expressionFactory()
72+
.resolveCollection(ExpressionDescriptor.object(collectionFilterObject(taskFunctions)))
7273
: super.buildCollectionFilter();
7374
}
7475

experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaSwitchExecutorBuilder.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
import io.serverlessworkflow.api.types.func.SwitchCaseFunction;
2323
import io.serverlessworkflow.api.types.func.TypedPredicate;
2424
import io.serverlessworkflow.impl.WorkflowApplication;
25-
import io.serverlessworkflow.impl.WorkflowFilter;
2625
import io.serverlessworkflow.impl.WorkflowPosition;
27-
import io.serverlessworkflow.impl.WorkflowUtils;
26+
import io.serverlessworkflow.impl.WorkflowPredicate;
2827
import io.serverlessworkflow.impl.executors.SwitchExecutor.SwitchExecutorBuilder;
28+
import io.serverlessworkflow.impl.expressions.ExpressionDescriptor;
2929
import io.serverlessworkflow.impl.resources.ResourceLoader;
3030
import java.util.Optional;
3131
import java.util.function.Predicate;
@@ -42,11 +42,14 @@ protected JavaSwitchExecutorBuilder(
4242
}
4343

4444
@Override
45-
protected Optional<WorkflowFilter> buildFilter(SwitchCase switchCase) {
45+
protected Optional<WorkflowPredicate> buildFilter(SwitchCase switchCase) {
4646
return switchCase instanceof SwitchCaseFunction function
4747
? Optional.of(
48-
WorkflowUtils.buildWorkflowFilter(
49-
application, null, predObject(function.predicate(), function.predicateClass())))
48+
application
49+
.expressionFactory()
50+
.buildPredicate(
51+
ExpressionDescriptor.object(
52+
predObject(function.predicate(), function.predicateClass()))))
5053
: super.buildFilter(switchCase);
5154
}
5255

experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,75 +15,52 @@
1515
*/
1616
package io.serverlessworkflow.impl.expressions.func;
1717

18+
import io.cloudevents.CloudEventData;
1819
import io.serverlessworkflow.api.types.TaskBase;
1920
import io.serverlessworkflow.api.types.TaskMetadata;
2021
import io.serverlessworkflow.api.types.func.TypedFunction;
2122
import io.serverlessworkflow.api.types.func.TypedPredicate;
22-
import io.serverlessworkflow.impl.TaskContext;
23-
import io.serverlessworkflow.impl.WorkflowContext;
24-
import io.serverlessworkflow.impl.WorkflowFilter;
25-
import io.serverlessworkflow.impl.WorkflowModel;
2623
import io.serverlessworkflow.impl.WorkflowModelFactory;
27-
import io.serverlessworkflow.impl.expressions.Expression;
28-
import io.serverlessworkflow.impl.expressions.ExpressionFactory;
24+
import io.serverlessworkflow.impl.WorkflowPredicate;
25+
import io.serverlessworkflow.impl.expressions.AbstractExpressionFactory;
26+
import io.serverlessworkflow.impl.expressions.ExpressionDescriptor;
27+
import io.serverlessworkflow.impl.expressions.ObjectExpression;
2928
import io.serverlessworkflow.impl.expressions.TaskMetadataKeys;
29+
import java.time.OffsetDateTime;
30+
import java.util.Collection;
31+
import java.util.Map;
3032
import java.util.Optional;
31-
import java.util.function.BiFunction;
32-
import java.util.function.BiPredicate;
3333
import java.util.function.Function;
3434
import java.util.function.Predicate;
3535

36-
public class JavaExpressionFactory implements ExpressionFactory {
36+
public class JavaExpressionFactory extends AbstractExpressionFactory {
3737

3838
private final WorkflowModelFactory modelFactory = new JavaModelFactory();
39-
private final Expression dummyExpression =
40-
new Expression() {
41-
@Override
42-
public WorkflowModel eval(
43-
WorkflowContext workflowContext, TaskContext context, WorkflowModel model) {
44-
return model;
45-
}
46-
};
4739

4840
@Override
49-
public Expression buildExpression(String expression) {
50-
return dummyExpression;
51-
}
52-
53-
@Override
54-
public WorkflowFilter buildFilter(String expr, Object value) {
41+
public ObjectExpression buildExpression(ExpressionDescriptor descriptor) {
42+
Object value = descriptor.asObject();
5543
if (value instanceof Function func) {
56-
return (w, t, n) -> modelFactory.fromAny(func.apply(n.asJavaObject()));
44+
return (w, t, n) -> func.apply(n.asJavaObject());
5745
} else if (value instanceof TypedFunction func) {
58-
return (w, t, n) ->
59-
modelFactory.fromAny(func.function().apply(n.as(func.argClass()).orElseThrow()));
60-
} else if (value instanceof Predicate pred) {
61-
return fromPredicate(pred);
62-
} else if (value instanceof TypedPredicate pred) {
63-
return fromPredicate(pred);
64-
} else if (value instanceof BiPredicate pred) {
65-
return (w, t, n) -> modelFactory.from(pred.test(w, t));
66-
} else if (value instanceof BiFunction func) {
67-
return (w, t, n) -> modelFactory.fromAny(func.apply(w, t));
68-
} else if (value instanceof WorkflowFilter filter) {
69-
return filter;
46+
return (w, t, n) -> func.function().apply(n.as(func.argClass()).orElseThrow());
7047
} else {
7148
return (w, t, n) -> modelFactory.fromAny(value);
7249
}
7350
}
7451

7552
@SuppressWarnings({"rawtypes", "unchecked"})
76-
private WorkflowFilter fromPredicate(Predicate pred) {
77-
return (w, t, n) -> modelFactory.from(pred.test(n.asJavaObject()));
53+
private WorkflowPredicate fromPredicate(Predicate pred) {
54+
return (w, t, n) -> pred.test(n.asJavaObject());
7855
}
7956

8057
@SuppressWarnings({"rawtypes", "unchecked"})
81-
private WorkflowFilter fromPredicate(TypedPredicate pred) {
82-
return (w, t, n) -> modelFactory.from(pred.pred().test(n.as(pred.argClass()).orElseThrow()));
58+
private WorkflowPredicate fromPredicate(TypedPredicate pred) {
59+
return (w, t, n) -> pred.pred().test(n.as(pred.argClass()).orElseThrow());
8360
}
8461

8562
@Override
86-
public Optional<WorkflowFilter> buildIfFilter(TaskBase task) {
63+
public Optional<WorkflowPredicate> buildIfFilter(TaskBase task) {
8764
TaskMetadata metadata = task.getMetadata();
8865
if (metadata != null) {
8966
Object obj = metadata.getAdditionalProperties().get(TaskMetadataKeys.IF_PREDICATE);
@@ -93,11 +70,54 @@ public Optional<WorkflowFilter> buildIfFilter(TaskBase task) {
9370
return Optional.of(fromPredicate(pred));
9471
}
9572
}
96-
return ExpressionFactory.super.buildIfFilter(task);
73+
return super.buildIfFilter(task);
9774
}
9875

9976
@Override
10077
public WorkflowModelFactory modelFactory() {
10178
return modelFactory;
10279
}
80+
81+
@Override
82+
public WorkflowPredicate buildPredicate(ExpressionDescriptor desc) {
83+
Object value = desc.asObject();
84+
if (value instanceof Predicate pred) {
85+
return fromPredicate(pred);
86+
} else if (value instanceof TypedPredicate pred) {
87+
return fromPredicate(pred);
88+
} else if (value instanceof Boolean bool) {
89+
return (w, f, n) -> bool;
90+
} else {
91+
throw new IllegalArgumentException("value should be a predicate or a boolean");
92+
}
93+
}
94+
95+
@Override
96+
protected String toString(Object eval) {
97+
return asClass(eval, String.class);
98+
}
99+
100+
@Override
101+
protected CloudEventData toCloudEventData(Object eval) {
102+
return asClass(eval, CloudEventData.class);
103+
}
104+
105+
@Override
106+
protected OffsetDateTime toDate(Object eval) {
107+
return asClass(eval, OffsetDateTime.class);
108+
}
109+
110+
@Override
111+
protected Map<String, Object> toMap(Object eval) {
112+
return asClass(eval, Map.class);
113+
}
114+
115+
@Override
116+
protected Collection<?> toCollection(Object obj) {
117+
return asClass(obj, Collection.class);
118+
}
119+
120+
private <T> T asClass(Object obj, Class<T> clazz) {
121+
return clazz.cast(obj);
122+
}
103123
}

experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaModel.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package io.serverlessworkflow.impl.expressions.func;
1717

18-
import io.cloudevents.CloudEventData;
1918
import io.serverlessworkflow.impl.WorkflowModel;
2019
import java.time.OffsetDateTime;
2120
import java.util.Collection;
@@ -28,12 +27,16 @@
2827

2928
public class JavaModel implements WorkflowModel {
3029

31-
protected final Object object;
30+
protected Object object;
3231

3332
protected JavaModel(Object object) {
3433
this.object = asJavaObject(object);
3534
}
3635

36+
protected void setObject(Object object) {
37+
this.object = object;
38+
}
39+
3740
@Override
3841
public void forEach(BiConsumer<String, WorkflowModel> consumer) {
3942
asMap()
@@ -72,11 +75,6 @@ public Optional<Number> asNumber() {
7275
return object instanceof Number value ? Optional.of(value) : Optional.empty();
7376
}
7477

75-
@Override
76-
public Optional<CloudEventData> asCloudEventData() {
77-
return object instanceof CloudEventData value ? Optional.of(value) : Optional.empty();
78-
}
79-
8078
@Override
8179
public Optional<Map<String, Object>> asMap() {
8280
return object instanceof Map ? Optional.of((Map<String, Object>) object) : Optional.empty();

experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaModelFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public WorkflowModel fromNull() {
7979
}
8080

8181
@Override
82-
public WorkflowModel fromAny(Object obj) {
82+
public WorkflowModel fromOther(Object obj) {
8383
return new JavaModel(obj);
8484
}
8585
}

impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717

1818
@FunctionalInterface
1919
public interface WorkflowFilter {
20-
WorkflowModel apply(WorkflowContext workflow, TaskContext task, WorkflowModel node);
20+
WorkflowModel apply(WorkflowContext workflow, TaskContext task, WorkflowModel model);
2121
}

impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowModel.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package io.serverlessworkflow.impl;
1717

18-
import io.cloudevents.CloudEventData;
1918
import java.time.OffsetDateTime;
2019
import java.util.Collection;
2120
import java.util.Map;
@@ -36,8 +35,6 @@ public interface WorkflowModel {
3635

3736
Optional<Number> asNumber();
3837

39-
Optional<CloudEventData> asCloudEventData();
40-
4138
Optional<Map<String, Object>> asMap();
4239

4340
Object asJavaObject();

impl/core/src/main/java/io/serverlessworkflow/impl/WorkflowModelFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ default WorkflowModel fromOther(Object obj) {
4747
"Unsupported conversion for object " + obj + " of type" + obj.getClass());
4848
}
4949

50+
default WorkflowModel fromAny(WorkflowModel prev, Object obj) {
51+
return fromAny(obj);
52+
}
53+
5054
default WorkflowModel fromAny(Object obj) {
5155
if (obj == null) {
5256
return fromNull();
@@ -66,6 +70,10 @@ default WorkflowModel fromAny(Object obj) {
6670
return from((Map<String, Object>) obj);
6771
} else if (obj instanceof WorkflowModel model) {
6872
return model;
73+
} else if (obj instanceof CloudEventData ce) {
74+
return from(ce);
75+
} else if (obj instanceof CloudEvent ce) {
76+
return from(ce);
6977
} else {
7078
return fromOther(obj);
7179
}

0 commit comments

Comments
 (0)