diff --git a/pom.xml b/pom.xml
index dffcb646c..970c69c94 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,11 @@
jackson-dataformat-yaml
2.14.0
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jdk8
+ 2.14.0
+
@@ -150,6 +155,10 @@
com.fasterxml.jackson.dataformat
jackson-dataformat-yaml
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jdk8
+
ch.obermuhlner
big-math
diff --git a/src/main/java/com/hubspot/jinjava/JinjavaConfig.java b/src/main/java/com/hubspot/jinjava/JinjavaConfig.java
index 9cdee6f85..3cff4787c 100644
--- a/src/main/java/com/hubspot/jinjava/JinjavaConfig.java
+++ b/src/main/java/com/hubspot/jinjava/JinjavaConfig.java
@@ -19,6 +19,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.google.common.collect.ImmutableSet;
import com.hubspot.jinjava.el.JinjavaInterpreterResolver;
import com.hubspot.jinjava.el.JinjavaObjectUnwrapper;
@@ -158,7 +159,7 @@ private JinjavaConfig(Builder builder) {
private ObjectMapper setupObjectMapper(@Nullable ObjectMapper objectMapper) {
if (objectMapper == null) {
- objectMapper = new ObjectMapper();
+ objectMapper = new ObjectMapper().registerModule(new Jdk8Module());
if (legacyOverrides.isUseSnakeCasePropertyNaming()) {
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
}
diff --git a/src/main/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapper.java b/src/main/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapper.java
index a8bcbeec5..5fe91e808 100644
--- a/src/main/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapper.java
+++ b/src/main/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapper.java
@@ -9,6 +9,7 @@
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.google.common.annotations.Beta;
import com.hubspot.jinjava.interpret.DeferredValueException;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
@@ -45,6 +46,7 @@ private static ObjectMapper getPyishObjectMapper() {
ObjectMapper mapper = new ObjectMapper(
new JsonFactoryBuilder().quoteChar('\'').build()
)
+ .registerModule(new Jdk8Module())
.registerModule(
new SimpleModule()
.setSerializerModifier(PyishBeanSerializerModifier.INSTANCE)
diff --git a/src/main/java/com/hubspot/jinjava/objects/serialization/PyishSerializable.java b/src/main/java/com/hubspot/jinjava/objects/serialization/PyishSerializable.java
index b967cb828..da9dd29c5 100644
--- a/src/main/java/com/hubspot/jinjava/objects/serialization/PyishSerializable.java
+++ b/src/main/java/com/hubspot/jinjava/objects/serialization/PyishSerializable.java
@@ -6,6 +6,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.google.common.annotations.Beta;
import com.hubspot.jinjava.interpret.DeferredValueException;
import com.hubspot.jinjava.objects.PyWrapper;
@@ -19,6 +20,7 @@ public interface PyishSerializable extends PyWrapper {
ObjectWriter SELF_WRITER = new ObjectMapper(
new JsonFactoryBuilder().quoteChar('\'').build()
)
+ .registerModule(new Jdk8Module())
.writer(PyishPrettyPrinter.INSTANCE)
.with(PyishCharacterEscapes.INSTANCE);
diff --git a/src/test/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapperTest.java b/src/test/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapperTest.java
index dd5db54ff..1f68b62c3 100644
--- a/src/test/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapperTest.java
+++ b/src/test/java/com/hubspot/jinjava/objects/serialization/PyishObjectMapperTest.java
@@ -16,6 +16,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Test;
@@ -168,6 +169,11 @@ public void itSerializesToSnakeCaseWhenLegacyOverrideIsSet() {
}
}
+ @Test
+ public void itSerializesOptional() {
+ assertThat(PyishObjectMapper.getAsPyishString(Optional.of("foo"))).isEqualTo("'foo'");
+ }
+
static class Foo {
private final String bar;
diff --git a/src/test/java/com/hubspot/jinjava/util/EagerExpressionResolverTest.java b/src/test/java/com/hubspot/jinjava/util/EagerExpressionResolverTest.java
index e634ae0fc..70c7cc58f 100644
--- a/src/test/java/com/hubspot/jinjava/util/EagerExpressionResolverTest.java
+++ b/src/test/java/com/hubspot/jinjava/util/EagerExpressionResolverTest.java
@@ -35,6 +35,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.After;
@@ -93,6 +94,15 @@ private JinjavaInterpreter getInterpreter(boolean evaluateMapKeys) throws Except
this.getClass().getDeclaredMethod("sleeper")
)
);
+ jinjava
+ .getGlobalContext()
+ .registerFunction(
+ new ELFunctionDefinition(
+ "",
+ "optionally",
+ this.getClass().getDeclaredMethod("optionally", boolean.class)
+ )
+ );
interpreter = new JinjavaInterpreter(jinjava.newInterpreter());
context = interpreter.getContext();
context.put("deferred", DeferredValue.instance());
@@ -124,6 +134,14 @@ public void itResolvesDeferredBoolean() {
assertThat(interpreter.resolveELExpression(partiallyResolved, 1)).isEqualTo(true);
}
+ @Test
+ public void itSerializesNestedOptional() {
+ assertThat(eagerResolveExpression("[optionally(true)]").toString())
+ .isEqualTo("['1']");
+ assertThat(eagerResolveExpression("[optionally(false)]").toString())
+ .isEqualTo("[null]");
+ }
+
@Test
public void itResolvesDeferredList() {
context.put("foo", "foo_val");
@@ -877,6 +895,10 @@ public static long sleeper() throws InterruptedException {
return sleepTime;
}
+ public static Optional optionally(boolean hasValue) {
+ return Optional.of(hasValue).filter(Boolean::booleanValue).map(ignored -> "1");
+ }
+
private static class Foo {
private final String bar;