From 251dd0610278244d9947b413a8515cd10987039f Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Tue, 26 Nov 2024 19:55:22 +0100 Subject: [PATCH] Jq class clean up Signed-off-by: Francisco Javier Tirado Sarti --- .../serverlessworkflow/impl/ContextAware.java | 22 --- .../serverlessworkflow/impl/TaskContext.java | 2 +- .../impl/expressions/JQExpression.java | 177 +----------------- impl/pom.xml | 6 +- 4 files changed, 8 insertions(+), 199 deletions(-) delete mode 100644 impl/core/src/main/java/io/serverlessworkflow/impl/ContextAware.java diff --git a/impl/core/src/main/java/io/serverlessworkflow/impl/ContextAware.java b/impl/core/src/main/java/io/serverlessworkflow/impl/ContextAware.java deleted file mode 100644 index a58dc348..00000000 --- a/impl/core/src/main/java/io/serverlessworkflow/impl/ContextAware.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl; - -import java.util.Map; - -public interface ContextAware { - Map variables(); -} diff --git a/impl/core/src/main/java/io/serverlessworkflow/impl/TaskContext.java b/impl/core/src/main/java/io/serverlessworkflow/impl/TaskContext.java index c23de49f..138a4aed 100644 --- a/impl/core/src/main/java/io/serverlessworkflow/impl/TaskContext.java +++ b/impl/core/src/main/java/io/serverlessworkflow/impl/TaskContext.java @@ -22,7 +22,7 @@ import java.util.HashMap; import java.util.Map; -public class TaskContext implements ContextAware { +public class TaskContext { private final JsonNode rawInput; private final T task; diff --git a/impl/core/src/main/java/io/serverlessworkflow/impl/expressions/JQExpression.java b/impl/core/src/main/java/io/serverlessworkflow/impl/expressions/JQExpression.java index ae6c784f..9da21dbe 100644 --- a/impl/core/src/main/java/io/serverlessworkflow/impl/expressions/JQExpression.java +++ b/impl/core/src/main/java/io/serverlessworkflow/impl/expressions/JQExpression.java @@ -17,141 +17,38 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; -import io.serverlessworkflow.impl.ContextAware; import io.serverlessworkflow.impl.TaskContext; import io.serverlessworkflow.impl.WorkflowContext; import io.serverlessworkflow.impl.json.JsonUtils; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import net.thisptr.jackson.jq.Output; import net.thisptr.jackson.jq.Scope; import net.thisptr.jackson.jq.Version; import net.thisptr.jackson.jq.exception.JsonQueryException; import net.thisptr.jackson.jq.internal.javacc.ExpressionParser; -import net.thisptr.jackson.jq.internal.tree.FunctionCall; -import net.thisptr.jackson.jq.internal.tree.StringInterpolation; -import net.thisptr.jackson.jq.internal.tree.binaryop.BinaryOperatorExpression; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class JQExpression implements Expression { - private static final Logger logger = LoggerFactory.getLogger(JQExpression.class); - private final Map, Collection> - declaredFieldsMap = new ConcurrentHashMap<>(); - private final Map, Collection> - allFieldsMap = new ConcurrentHashMap<>(); - private final Supplier scope; private final String expr; private net.thisptr.jackson.jq.Expression internalExpr; - private static Field rhsField; - - static { - try { - rhsField = BinaryOperatorExpression.class.getDeclaredField("rhs"); - rhsField.setAccessible(true); - } catch (ReflectiveOperationException e) { - logger.warn("Unexpected exception while resolving rhs field", e); - } - } public JQExpression(Supplier scope, String expr, Version version) throws JsonQueryException { this.expr = expr; this.scope = scope; this.internalExpr = compile(version); - checkFunctionCall(internalExpr); } private net.thisptr.jackson.jq.Expression compile(Version version) throws JsonQueryException { - net.thisptr.jackson.jq.Expression expression; - try { - expression = ExpressionParser.compile(expr, version); - } catch (JsonQueryException ex) { - expression = handleStringInterpolation(version).orElseThrow(() -> ex); - } - checkFunctionCall(expression); - return expression; - } - - private Optional handleStringInterpolation(Version version) { - if (!expr.startsWith("\"")) { - try { - net.thisptr.jackson.jq.Expression expression = - ExpressionParser.compile("\"" + expr + "\"", version); - if (expression instanceof StringInterpolation) { - return Optional.of(expression); - } - } catch (JsonQueryException ex) { - // ignoring it - } - } - return Optional.empty(); + return ExpressionParser.compile(expr, version); } private interface TypedOutput extends Output { T getResult(); } - @SuppressWarnings("unchecked") - private TypedOutput output(Class returnClass) { - TypedOutput out; - if (String.class.isAssignableFrom(returnClass)) { - out = (TypedOutput) new StringOutput(); - } else if (Collection.class.isAssignableFrom(returnClass)) { - out = (TypedOutput) new CollectionOutput(); - } else { - out = (TypedOutput) new JsonNodeOutput(); - } - return out; - } - - private static class StringOutput implements TypedOutput { - StringBuilder sb = new StringBuilder(); - - @Override - public void emit(JsonNode out) throws JsonQueryException { - if (sb.length() > 0) { - sb.append(' '); - } - if (!out.isNull() && out.asText() != null) { - sb.append(out.asText()); - } - } - - @Override - public String getResult() { - return sb.toString(); - } - } - - private static class CollectionOutput implements TypedOutput> { - Collection result = new ArrayList<>(); - - @SuppressWarnings("unchecked") - @Override - public void emit(JsonNode out) throws JsonQueryException { - Object obj = JsonUtils.toJavaValue(out); - if (obj instanceof Collection) result.addAll((Collection) obj); - else { - result.add(obj); - } - } - - @Override - public Collection getResult() { - return result; - } - } - private static class JsonNodeOutput implements TypedOutput { private JsonNode result; @@ -179,7 +76,7 @@ public JsonNode getResult() { @Override public JsonNode eval(WorkflowContext workflow, TaskContext task, JsonNode node) { - TypedOutput output = output(JsonNode.class); + TypedOutput output = new JsonNodeOutput(); try { internalExpr.apply(createScope(workflow, task), node, output); return output.getResult(); @@ -190,74 +87,8 @@ public JsonNode eval(WorkflowContext workflow, TaskContext task, JsonNode nod } private Scope createScope(WorkflowContext workflow, TaskContext task) { - return createScope(scope.get(), task); - } - - private Scope createScope(Scope parentScope, ContextAware context) { - Scope childScope = Scope.newChildScope(parentScope); - context.variables().forEach((k, v) -> childScope.setValue(k, JsonUtils.fromValue(v))); + Scope childScope = Scope.newChildScope(scope.get()); + task.variables().forEach((k, v) -> childScope.setValue(k, JsonUtils.fromValue(v))); return childScope; } - - private void checkFunctionCall(net.thisptr.jackson.jq.Expression toCheck) - throws JsonQueryException { - if (toCheck instanceof FunctionCall) { - toCheck.apply(scope.get(), JsonUtils.mapper().createObjectNode(), out -> {}); - } else if (toCheck instanceof BinaryOperatorExpression) { - if (rhsField != null) { - try { - checkFunctionCall((net.thisptr.jackson.jq.Expression) rhsField.get(toCheck)); - } catch (ReflectiveOperationException e) { - logger.warn( - "Ignoring unexpected error {} while accesing field {} for class{} and expression {}", - e.getMessage(), - rhsField.getName(), - toCheck.getClass(), - expr); - } - } - } else if (toCheck != null) { - for (Field f : getAllExprFields(toCheck)) - try { - checkFunctionCall((net.thisptr.jackson.jq.Expression) f.get(toCheck)); - } catch (ReflectiveOperationException e) { - logger.warn( - "Ignoring unexpected error {} while accesing field {} for class{} and expression {}", - e.getMessage(), - f.getName(), - toCheck.getClass(), - expr); - } - } - } - - private Collection getAllExprFields(net.thisptr.jackson.jq.Expression toCheck) { - return allFieldsMap.computeIfAbsent(toCheck.getClass(), this::getAllExprFields); - } - - private Collection getAllExprFields( - Class clazz) { - Collection fields = new HashSet<>(); - Class currentClass = clazz; - do { - fields.addAll( - declaredFieldsMap.computeIfAbsent( - currentClass.asSubclass(net.thisptr.jackson.jq.Expression.class), - this::getDeclaredExprFields)); - currentClass = currentClass.getSuperclass(); - } while (net.thisptr.jackson.jq.Expression.class.isAssignableFrom(currentClass)); - return fields; - } - - private Collection getDeclaredExprFields( - Class clazz) { - Collection fields = new HashSet<>(); - for (Field f : clazz.getDeclaredFields()) { - if (net.thisptr.jackson.jq.Expression.class.isAssignableFrom(f.getType())) { - f.setAccessible(true); - fields.add(f); - } - } - return fields; - } } diff --git a/impl/pom.xml b/impl/pom.xml index 191dc39d..b49f8ab0 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -35,8 +35,8 @@ - http - core - bom + http + core + bom \ No newline at end of file