diff --git a/pom.xml b/pom.xml index 9518a2a85..1f44875e6 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,8 @@ 0.8.3 3.0.1 + 1.9 + --add-opens=java.base/java.lang=ALL-UNNAMED @@ -89,6 +91,16 @@ jackson-datatype-jdk8 2.14.0 + + com.hubspot.immutables + hubspot-style + ${dep.hubspot-immutables.version} + + + com.hubspot.immutables + immutables-exceptions + ${dep.hubspot-immutables.version} + @@ -187,6 +199,20 @@ mockito-core test + + org.immutables + value + provided + + + com.hubspot.immutables + hubspot-style + provided + + + com.hubspot.immutables + immutables-exceptions + diff --git a/src/main/java/com/hubspot/jinjava/interpret/Context.java b/src/main/java/com/hubspot/jinjava/interpret/Context.java index b619a6238..1ea7aaf71 100644 --- a/src/main/java/com/hubspot/jinjava/interpret/Context.java +++ b/src/main/java/com/hubspot/jinjava/interpret/Context.java @@ -22,7 +22,6 @@ import com.google.common.collect.SetMultimap; import com.google.common.collect.Sets; import com.hubspot.jinjava.lib.Importable; -import com.hubspot.jinjava.lib.expression.DefaultExpressionStrategy; import com.hubspot.jinjava.lib.expression.ExpressionStrategy; import com.hubspot.jinjava.lib.exptest.ExpTest; import com.hubspot.jinjava.lib.exptest.ExpTestLibrary; @@ -65,11 +64,11 @@ public class Context extends ScopeMap { private Map> disabled; public boolean isValidationMode() { - return validationMode; + return contextConfiguration.isValidationMode(); } public Context setValidationMode(boolean validationMode) { - this.validationMode = validationMode; + contextConfiguration = contextConfiguration.withValidationMode(validationMode); return this; } @@ -101,8 +100,6 @@ public enum Library { private final FunctionLibrary functionLibrary; private final TagLibrary tagLibrary; - private ExpressionStrategy expressionStrategy = new DefaultExpressionStrategy(); - private final Context parent; private int renderDepth = -1; @@ -110,14 +107,7 @@ public enum Library { private List superBlock; private final Stack renderStack = new Stack<>(); - - private boolean validationMode = false; - private boolean deferredExecutionMode = false; - private boolean deferLargeObjects = false; - private boolean throwInterpreterErrors = false; - private boolean partialMacroEvaluation = false; - private boolean unwrapRawOverride = false; - private DynamicVariableResolver dynamicVariableResolver = null; + private ContextConfiguration contextConfiguration = ContextConfiguration.of(); private final Set metaContextVariables; // These variable names aren't tracked in eager execution private final Set overriddenNonMetaContextVariables; private Node currentNode; @@ -215,13 +205,7 @@ public Context( this.overriddenNonMetaContextVariables = parent == null ? new HashSet<>() : parent.overriddenNonMetaContextVariables; if (parent != null) { - this.expressionStrategy = parent.expressionStrategy; - this.partialMacroEvaluation = parent.partialMacroEvaluation; - this.unwrapRawOverride = parent.unwrapRawOverride; - this.dynamicVariableResolver = parent.dynamicVariableResolver; - this.deferredExecutionMode = parent.deferredExecutionMode; - this.deferLargeObjects = parent.deferLargeObjects; - this.throwInterpreterErrors = parent.throwInterpreterErrors; + this.contextConfiguration = parent.contextConfiguration; } } @@ -654,21 +638,23 @@ public void registerTag(Tag t) { } public DynamicVariableResolver getDynamicVariableResolver() { - return dynamicVariableResolver; + return contextConfiguration.getDynamicVariableResolver(); } public void setDynamicVariableResolver( final DynamicVariableResolver dynamicVariableResolver ) { - this.dynamicVariableResolver = dynamicVariableResolver; + contextConfiguration = + contextConfiguration.withDynamicVariableResolver(dynamicVariableResolver); } public ExpressionStrategy getExpressionStrategy() { - return expressionStrategy; + return contextConfiguration.getExpressionStrategy(); } public void setExpressionStrategy(ExpressionStrategy expressionStrategy) { - this.expressionStrategy = expressionStrategy; + contextConfiguration = + contextConfiguration.withExpressionStrategy(expressionStrategy); } public Optional getImportResourceAlias() { @@ -754,20 +740,21 @@ public SetMultimap getDependencies() { } public boolean isDeferredExecutionMode() { - return deferredExecutionMode; + return contextConfiguration.isDeferredExecutionMode(); } public Context setDeferredExecutionMode(boolean deferredExecutionMode) { - this.deferredExecutionMode = deferredExecutionMode; + contextConfiguration = + contextConfiguration.withDeferredExecutionMode(deferredExecutionMode); return this; } public boolean isDeferLargeObjects() { - return deferLargeObjects; + return contextConfiguration.isDeferLargeObjects(); } public Context setDeferLargeObjects(boolean deferLargeObjects) { - this.deferLargeObjects = deferLargeObjects; + contextConfiguration = contextConfiguration.withDeferLargeObjects(deferLargeObjects); return this; } @@ -775,27 +762,29 @@ public TemporaryValueClosable withDeferLargeObjects( boolean deferLargeObjects ) { TemporaryValueClosable temporaryValueClosable = new TemporaryValueClosable<>( - this.deferLargeObjects, + isDeferLargeObjects(), this::setDeferLargeObjects ); - this.deferLargeObjects = deferLargeObjects; + setDeferLargeObjects(deferLargeObjects); return temporaryValueClosable; } public boolean getThrowInterpreterErrors() { - return throwInterpreterErrors; + return contextConfiguration.isThrowInterpreterErrors(); } public void setThrowInterpreterErrors(boolean throwInterpreterErrors) { - this.throwInterpreterErrors = throwInterpreterErrors; + contextConfiguration = + contextConfiguration.withThrowInterpreterErrors(throwInterpreterErrors); } public boolean isPartialMacroEvaluation() { - return partialMacroEvaluation; + return contextConfiguration.isPartialMacroEvaluation(); } public void setPartialMacroEvaluation(boolean partialMacroEvaluation) { - this.partialMacroEvaluation = partialMacroEvaluation; + contextConfiguration = + contextConfiguration.withPartialMacroEvaluation(partialMacroEvaluation); } public TemporaryValueClosable withPartialMacroEvaluation() { @@ -806,27 +795,27 @@ public TemporaryValueClosable withPartialMacroEvaluation( boolean partialMacroEvaluation ) { TemporaryValueClosable temporaryValueClosable = new TemporaryValueClosable<>( - this.partialMacroEvaluation, + isPartialMacroEvaluation(), this::setPartialMacroEvaluation ); - this.partialMacroEvaluation = partialMacroEvaluation; + setPartialMacroEvaluation(partialMacroEvaluation); return temporaryValueClosable; } public boolean isUnwrapRawOverride() { - return unwrapRawOverride; + return contextConfiguration.isUnwrapRawOverride(); } public void setUnwrapRawOverride(boolean unwrapRawOverride) { - this.unwrapRawOverride = unwrapRawOverride; + contextConfiguration = contextConfiguration.withUnwrapRawOverride(unwrapRawOverride); } public TemporaryValueClosable withUnwrapRawOverride() { TemporaryValueClosable temporaryValueClosable = new TemporaryValueClosable<>( - this.unwrapRawOverride, + isUnwrapRawOverride(), this::setUnwrapRawOverride ); - this.unwrapRawOverride = true; + setUnwrapRawOverride(true); return temporaryValueClosable; } diff --git a/src/main/java/com/hubspot/jinjava/interpret/ContextConfigurationIF.java b/src/main/java/com/hubspot/jinjava/interpret/ContextConfigurationIF.java new file mode 100644 index 000000000..5aac82fa8 --- /dev/null +++ b/src/main/java/com/hubspot/jinjava/interpret/ContextConfigurationIF.java @@ -0,0 +1,50 @@ +package com.hubspot.jinjava.interpret; + +import com.hubspot.immutables.style.HubSpotImmutableStyle; +import com.hubspot.jinjava.lib.expression.DefaultExpressionStrategy; +import com.hubspot.jinjava.lib.expression.ExpressionStrategy; +import javax.annotation.Nullable; +import org.immutables.value.Value.Default; +import org.immutables.value.Value.Immutable; + +@Immutable(singleton = true) +@HubSpotImmutableStyle +public interface ContextConfigurationIF { + @Default + default ExpressionStrategy getExpressionStrategy() { + return new DefaultExpressionStrategy(); + } + + @Nullable + DynamicVariableResolver getDynamicVariableResolver(); + + @Default + default boolean isValidationMode() { + return false; + } + + @Default + default boolean isDeferredExecutionMode() { + return false; + } + + @Default + default boolean isDeferLargeObjects() { + return false; + } + + @Default + default boolean isThrowInterpreterErrors() { + return false; + } + + @Default + default boolean isPartialMacroEvaluation() { + return false; + } + + @Default + default boolean isUnwrapRawOverride() { + return false; + } +}