diff --git a/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/JsonObjectProcessor.java b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/JsonObjectProcessor.java new file mode 100644 index 0000000000000..58568297170ea --- /dev/null +++ b/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/JsonObjectProcessor.java @@ -0,0 +1,18 @@ +package io.quarkus.qute.deployment; + +import io.quarkus.arc.deployment.AdditionalBeanBuildItem; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.qute.runtime.jsonobject.JsonObjectValueResolver; + +public class JsonObjectProcessor { + + @BuildStep + void init(Capabilities capabilities, BuildProducer beans) { + if (capabilities.isPresent(Capability.VERTX)) { + beans.produce(new AdditionalBeanBuildItem(JsonObjectValueResolver.class)); + } + } +} diff --git a/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/jsonobject/JsonObjectValueResolverTest.java b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/jsonobject/JsonObjectValueResolverTest.java new file mode 100644 index 0000000000000..692f7735d8458 --- /dev/null +++ b/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/jsonobject/JsonObjectValueResolverTest.java @@ -0,0 +1,37 @@ +package io.quarkus.qute.deployment.jsonobject; + +import java.util.HashMap; + +import jakarta.inject.Inject; + +import org.assertj.core.api.Assertions; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.qute.Template; +import io.quarkus.test.QuarkusUnitTest; +import io.vertx.core.json.JsonObject; + +public class JsonObjectValueResolverTest { + + @RegisterExtension + static final QuarkusUnitTest quarkusApp = new QuarkusUnitTest() + .withApplicationRoot( + app -> app.addAsResource(new StringAsset( + "{tool.name} {tool.fieldNames} {tool.fields} {tool.size} {tool.empty} {tool.isEmpty} {tool.get('name')} {tool.containsKey('name')}"), + "templates/foo.txt")); + + @Inject + Template foo; + + @Test + void testJsonObjectValueResolver() { + HashMap toolMap = new HashMap<>(); + toolMap.put("name", "Roq"); + JsonObject jsonObject = new JsonObject(toolMap); + String render = foo.data("tool", jsonObject).render(); + + Assertions.assertThat(render).isEqualTo("Roq [name] [name] 1 false false Roq true"); + } +} diff --git a/extensions/qute/runtime/pom.xml b/extensions/qute/runtime/pom.xml index 1a0b7d3243d8f..f6b3e3a03b3d3 100644 --- a/extensions/qute/runtime/pom.xml +++ b/extensions/qute/runtime/pom.xml @@ -31,6 +31,11 @@ quarkus-cache true + + io.quarkus + quarkus-vertx + true + diff --git a/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/jsonobject/JsonObjectValueResolver.java b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/jsonobject/JsonObjectValueResolver.java new file mode 100644 index 0000000000000..e5689ab3a55bb --- /dev/null +++ b/extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/jsonobject/JsonObjectValueResolver.java @@ -0,0 +1,54 @@ +package io.quarkus.qute.runtime.jsonobject; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +import io.quarkus.qute.EngineConfiguration; +import io.quarkus.qute.EvalContext; +import io.quarkus.qute.Results; +import io.quarkus.qute.ValueResolver; +import io.vertx.core.json.JsonObject; + +/** + * A value resolver for {@link JsonObject}. + */ +@EngineConfiguration +public class JsonObjectValueResolver implements ValueResolver { + + @Override + public boolean appliesTo(EvalContext context) { + return ValueResolver.matchClass(context, JsonObject.class); + } + + @Override + public CompletionStage resolve(EvalContext context) { + + JsonObject jsonObject = (JsonObject) context.getBase(); + switch (context.getName()) { + case "fieldNames": + case "fields": + return CompletableFuture.completedFuture(jsonObject.fieldNames()); + case "size": + return CompletableFuture.completedFuture(jsonObject.size()); + case "empty": + case "isEmpty": + return CompletableFuture.completedFuture(jsonObject.isEmpty()); + case "get": + if (context.getParams().size() == 1) { + return context.evaluate(context.getParams().get(0)).thenCompose(k -> { + return CompletableFuture.completedFuture(jsonObject.getValue((String) k)); + }); + } + case "containsKey": + if (context.getParams().size() == 1) { + return context.evaluate(context.getParams().get(0)).thenCompose(k -> { + return CompletableFuture.completedFuture(jsonObject.containsKey((String) k)); + }); + } + default: + return jsonObject.containsKey(context.getName()) + ? CompletableFuture.completedFuture(jsonObject.getValue(context.getName())) + : Results.notFound(context); + } + } +}