Skip to content

Commit f9b6855

Browse files
committed
Add new class to consider temp variables for the purpose of preserving
state to be meta context variables. Update var names to be consistent and update usages
1 parent c0706d0 commit f9b6855

27 files changed

Lines changed: 278 additions & 231 deletions

File tree

src/main/java/com/hubspot/jinjava/el/ext/eager/EvalResultHolder.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.hubspot.jinjava.el.ext.IdentifierPreservationStrategy;
66
import com.hubspot.jinjava.interpret.DeferredValueException;
77
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
8+
import com.hubspot.jinjava.interpret.MetaContextVariables;
89
import com.hubspot.jinjava.interpret.PartiallyDeferredValue;
910
import com.hubspot.jinjava.util.EagerExpressionResolver;
1011
import de.odysseus.el.tree.Bindings;
@@ -125,11 +126,12 @@ static String reconstructNode(
125126
if (astNode instanceof AstIdentifier) {
126127
String name = ((AstIdentifier) astNode).getName();
127128
if (
128-
((JinjavaInterpreter) context
129-
.getELResolver()
130-
.getValue(context, null, ExtendedParser.INTERPRETER)).getContext()
131-
.getComputedMetaContextVariables()
132-
.contains(name)
129+
MetaContextVariables.isMetaContextVariable(
130+
name,
131+
((JinjavaInterpreter) context
132+
.getELResolver()
133+
.getValue(context, null, ExtendedParser.INTERPRETER)).getContext()
134+
)
133135
) {
134136
return name;
135137
}

src/main/java/com/hubspot/jinjava/interpret/Context.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,14 +337,17 @@ public void addResolvedFunction(String function) {
337337
}
338338
}
339339

340+
/**
341+
* @deprecated Use {@link MetaContextVariables#isMetaContextVariable(String, Context)}
342+
*/
340343
@Deprecated
341344
@Beta
342345
public Set<String> getMetaContextVariables() {
343346
return metaContextVariables;
344347
}
345348

346349
@Beta
347-
public Set<String> getComputedMetaContextVariables() {
350+
Set<String> getComputedMetaContextVariables() {
348351
return Sets.difference(metaContextVariables, overriddenNonMetaContextVariables);
349352
}
350353

@@ -353,6 +356,10 @@ public void addMetaContextVariables(Collection<String> variables) {
353356
metaContextVariables.addAll(variables);
354357
}
355358

359+
Set<String> getNonMetaContextVariables() {
360+
return overriddenNonMetaContextVariables;
361+
}
362+
356363
@Beta
357364
public void addNonMetaContextVariables(Collection<String> variables) {
358365
overriddenNonMetaContextVariables.addAll(
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.hubspot.jinjava.interpret;
2+
3+
import com.google.common.annotations.Beta;
4+
import java.util.Objects;
5+
6+
@Beta
7+
public class MetaContextVariables {
8+
9+
public static final String TEMPORARY_META_CONTEXT_PREFIX = "__temp_meta_";
10+
private static final String TEMPORARY_IMPORT_ALIAS_PREFIX =
11+
TEMPORARY_META_CONTEXT_PREFIX + "import_alias_";
12+
13+
private static final String TEMPORARY_IMPORT_ALIAS_FORMAT =
14+
TEMPORARY_IMPORT_ALIAS_PREFIX + "%d__";
15+
private static final String TEMP_CURRENT_PATH_PREFIX =
16+
TEMPORARY_META_CONTEXT_PREFIX + "current_path_";
17+
private static final String TEMP_CURRENT_PATH_FORMAT =
18+
TEMP_CURRENT_PATH_PREFIX + "%d__";
19+
20+
public static boolean isMetaContextVariable(String varName, Context context) {
21+
if (isTemporaryMetaContextVariable(varName)) {
22+
return true;
23+
}
24+
return (
25+
context.getMetaContextVariables().contains(varName) &&
26+
!context.getNonMetaContextVariables().contains(varName)
27+
);
28+
}
29+
30+
private static boolean isTemporaryMetaContextVariable(String varName) {
31+
return varName.startsWith(TEMPORARY_META_CONTEXT_PREFIX);
32+
}
33+
34+
public static boolean isTemporaryImportAlias(String varName) {
35+
// This is just faster than checking a regex
36+
return varName.startsWith(TEMPORARY_IMPORT_ALIAS_PREFIX);
37+
}
38+
39+
public static String getTemporaryImportAlias(String fullAlias) {
40+
return String.format(
41+
TEMPORARY_IMPORT_ALIAS_FORMAT,
42+
Math.abs(Objects.hashCode(fullAlias))
43+
);
44+
}
45+
46+
public static String getTemporaryCurrentPathVarName(String newPath) {
47+
return String.format(
48+
TEMP_CURRENT_PATH_FORMAT,
49+
Math.abs(Objects.hash(newPath, TEMPORARY_META_CONTEXT_PREFIX) >> 1)
50+
);
51+
}
52+
}

src/main/java/com/hubspot/jinjava/lib/tag/eager/DeferredToken.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.hubspot.jinjava.interpret.DeferredValue;
1111
import com.hubspot.jinjava.interpret.DeferredValueShadow;
1212
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
13+
import com.hubspot.jinjava.interpret.MetaContextVariables;
1314
import com.hubspot.jinjava.tree.parse.Token;
1415
import com.hubspot.jinjava.tree.parse.TokenScannerSymbols;
1516
import com.hubspot.jinjava.util.EagerExpressionResolver;
@@ -376,7 +377,7 @@ private static Collection<String> markDeferredWordsAndFindSources(
376377
}
377378
return !(val instanceof DeferredValue);
378379
})
379-
.filter(prop -> !context.getComputedMetaContextVariables().contains(prop))
380+
.filter(prop -> !MetaContextVariables.isMetaContextVariable(prop, context))
380381
.filter(prop -> {
381382
DeferredValue deferredValue = convertToDeferredValue(context, prop);
382383
context.put(prop, deferredValue);

src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerSetTagStrategy.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import com.google.common.annotations.Beta;
44
import com.hubspot.jinjava.interpret.DeferredValueException;
55
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
6+
import com.hubspot.jinjava.interpret.MetaContextVariables;
67
import com.hubspot.jinjava.lib.tag.SetTag;
7-
import com.hubspot.jinjava.lib.tag.eager.importing.AliasedEagerImportingStrategy;
88
import com.hubspot.jinjava.tree.TagNode;
99
import com.hubspot.jinjava.util.EagerReconstructionUtils;
1010
import com.hubspot.jinjava.util.PrefixToPreserveState;
@@ -180,16 +180,17 @@ private static String getSuffixToPreserveState(
180180
JinjavaInterpreter interpreter
181181
) {
182182
StringBuilder suffixToPreserveState = new StringBuilder();
183-
Optional<String> maybeTemporaryImportAlias =
184-
AliasedEagerImportingStrategy.getTemporaryImportAlias(interpreter.getContext());
183+
Optional<String> maybeTemporaryImportAlias = interpreter
184+
.getContext()
185+
.getImportResourceAlias()
186+
.map(MetaContextVariables::getTemporaryImportAlias);
185187
if (maybeTemporaryImportAlias.isPresent()) {
186188
boolean stillInsideImportTag = interpreter
187189
.getContext()
188190
.containsKey(maybeTemporaryImportAlias.get());
189191
List<String> filteredVars = varStream
190-
.filter(var -> !AliasedEagerImportingStrategy.isTemporaryImportAlias(var))
191192
.filter(var ->
192-
!interpreter.getContext().getComputedMetaContextVariables().contains(var)
193+
!MetaContextVariables.isMetaContextVariable(var, interpreter.getContext())
193194
)
194195
.peek(var -> {
195196
if (!stillInsideImportTag) {

src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/AliasedEagerImportingStrategy.java

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.hubspot.jinjava.interpret.DeferredValueException;
88
import com.hubspot.jinjava.interpret.InterpretException;
99
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
10+
import com.hubspot.jinjava.interpret.MetaContextVariables;
1011
import com.hubspot.jinjava.lib.fn.MacroFunction;
1112
import com.hubspot.jinjava.lib.tag.eager.DeferredToken;
1213
import com.hubspot.jinjava.objects.collections.PyMap;
@@ -16,35 +17,12 @@
1617
import java.util.Collections;
1718
import java.util.HashMap;
1819
import java.util.Map;
19-
import java.util.Objects;
2020
import java.util.Optional;
2121
import java.util.StringJoiner;
2222
import java.util.stream.Stream;
2323

2424
public class AliasedEagerImportingStrategy implements EagerImportingStrategy {
2525

26-
private static final String TEMPORARY_IMPORT_ALIAS_PREFIX = "__temp_import_alias_";
27-
private static final String TEMPORARY_IMPORT_ALIAS_FORMAT =
28-
TEMPORARY_IMPORT_ALIAS_PREFIX + "%d__";
29-
30-
public static Optional<String> getTemporaryImportAlias(Context context) {
31-
return context
32-
.getImportResourceAlias()
33-
.map(AliasedEagerImportingStrategy::getTemporaryImportAlias);
34-
}
35-
36-
public static boolean isTemporaryImportAlias(String varName) {
37-
// This is just faster than checking a regex
38-
return varName.startsWith(TEMPORARY_IMPORT_ALIAS_PREFIX);
39-
}
40-
41-
private static String getTemporaryImportAlias(String fullAlias) {
42-
return String.format(
43-
TEMPORARY_IMPORT_ALIAS_FORMAT,
44-
Math.abs(Objects.hashCode(fullAlias))
45-
);
46-
}
47-
4826
private final ImportingData importingData;
4927
private final String currentImportAlias;
5028
private final String fullImportAlias;
@@ -95,7 +73,10 @@ public void setup(JinjavaInterpreter child) {
9573
importingData
9674
.getOriginalInterpreter()
9775
.getContext()
98-
.put(getTemporaryImportAlias(fullImportAlias), DeferredValue.instance());
76+
.put(
77+
MetaContextVariables.getTemporaryImportAlias(fullImportAlias),
78+
DeferredValue.instance()
79+
);
9980
}
10081

10182
@Override
@@ -108,7 +89,9 @@ public void integrateChild(JinjavaInterpreter child) {
10889
}
10990
Map<String, Object> childBindings = child.getContext().getSessionBindings();
11091
childBindings.putAll(child.getContext().getGlobalMacros());
111-
String temporaryImportAlias = getTemporaryImportAlias(fullImportAlias);
92+
String temporaryImportAlias = MetaContextVariables.getTemporaryImportAlias(
93+
fullImportAlias
94+
);
11295
Map<String, Object> mapForCurrentContextAlias = getMapForCurrentContextAlias(
11396
currentImportAlias,
11497
child
@@ -128,7 +111,9 @@ public void integrateChild(JinjavaInterpreter child) {
128111

129112
@Override
130113
public String getFinalOutput(String output, JinjavaInterpreter child) {
131-
String temporaryImportAlias = getTemporaryImportAlias(fullImportAlias);
114+
String temporaryImportAlias = MetaContextVariables.getTemporaryImportAlias(
115+
fullImportAlias
116+
);
132117
return (
133118
EagerReconstructionUtils.buildBlockOrInlineSetTag(
134119
temporaryImportAlias,
@@ -237,7 +222,9 @@ private String getDoTagToPreserve(
237222
JinjavaInterpreter child
238223
) {
239224
StringJoiner keyValueJoiner = new StringJoiner(",");
240-
String temporaryImportAlias = getTemporaryImportAlias(fullImportAlias);
225+
String temporaryImportAlias = MetaContextVariables.getTemporaryImportAlias(
226+
fullImportAlias
227+
);
241228
Map<String, Object> currentAliasMap = getMapForCurrentContextAlias(
242229
currentImportAlias,
243230
child

src/main/java/com/hubspot/jinjava/lib/tag/eager/importing/FlatEagerImportingStrategy.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
import com.hubspot.jinjava.interpret.DeferredValue;
66
import com.hubspot.jinjava.interpret.DeferredValueException;
77
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
8+
import com.hubspot.jinjava.interpret.MetaContextVariables;
89
import com.hubspot.jinjava.lib.fn.MacroFunction;
910
import com.hubspot.jinjava.lib.tag.ImportTag;
1011
import com.hubspot.jinjava.util.EagerReconstructionUtils;
1112
import java.util.Map;
1213
import java.util.Map.Entry;
13-
import java.util.Set;
1414
import java.util.stream.Collectors;
1515

1616
public class FlatEagerImportingStrategy implements EagerImportingStrategy {
@@ -65,11 +65,8 @@ public void integrateChild(JinjavaInterpreter child) {
6565
@Override
6666
public String getFinalOutput(String output, JinjavaInterpreter child) {
6767
if (importingData.getOriginalInterpreter().getContext().isDeferredExecutionMode()) {
68-
Set<String> metaContextVariables = importingData
69-
.getOriginalInterpreter()
70-
.getContext()
71-
.getComputedMetaContextVariables();
7268
// defer imported variables
69+
Context context = importingData.getOriginalInterpreter().getContext();
7370
EagerReconstructionUtils.buildSetTag(
7471
child
7572
.getContext()
@@ -79,7 +76,9 @@ public String getFinalOutput(String output, JinjavaInterpreter child) {
7976
.filter(entry ->
8077
!(entry.getValue() instanceof DeferredValue) && entry.getValue() != null
8178
)
82-
.filter(entry -> !metaContextVariables.contains(entry.getKey()))
79+
.filter(entry ->
80+
!MetaContextVariables.isMetaContextVariable(entry.getKey(), context)
81+
)
8382
.collect(Collectors.toMap(Entry::getKey, entry -> "")),
8483
importingData.getOriginalInterpreter(),
8584
true

src/main/java/com/hubspot/jinjava/util/DeferredValueUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.hubspot.jinjava.interpret.Context;
77
import com.hubspot.jinjava.interpret.DeferredValue;
88
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
9+
import com.hubspot.jinjava.interpret.MetaContextVariables;
910
import com.hubspot.jinjava.interpret.PartiallyDeferredValue;
1011
import com.hubspot.jinjava.lib.tag.SetTag;
1112
import com.hubspot.jinjava.tree.ExpressionNode;
@@ -119,7 +120,7 @@ private static void markDeferredProperties(Context context, Set<String> props) {
119120
props
120121
.stream()
121122
.filter(prop -> !(context.get(prop) instanceof DeferredValue))
122-
.filter(prop -> !context.getComputedMetaContextVariables().contains(prop))
123+
.filter(prop -> !MetaContextVariables.isMetaContextVariable(prop, context))
123124
.forEach(prop -> {
124125
Object value = context.get(prop);
125126
if (value != null) {

0 commit comments

Comments
 (0)