This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git


The following commit(s) were added to refs/heads/master by this push:
     new 3a1083c688 expose use of freemarker cache and object unwrapping
3a1083c688 is described below

commit 3a1083c6886ea6b5cbd06cb3df486900f8d809d8
Author: Alex Heneveld <[email protected]>
AuthorDate: Thu Aug 3 11:14:44 2023 +0100

    expose use of freemarker cache and object unwrapping
---
 .../core/workflow/WorkflowExpressionResolution.java   |  8 ++++++--
 .../brooklyn/util/core/text/TemplateProcessor.java    | 19 ++++++++++++-------
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExpressionResolution.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExpressionResolution.java
index 14dde15a3a..947eac6a54 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExpressionResolution.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExpressionResolution.java
@@ -130,7 +130,7 @@ public class WorkflowExpressionResolution {
         return null;
     }
 
-    class WorkflowFreemarkerModel implements TemplateHashModel, 
TemplateProcessor.UnwrappableTemplateModel {
+    public class WorkflowFreemarkerModel implements TemplateHashModel, 
TemplateProcessor.UnwrappableTemplateModel {
         @Override
         public Maybe<Object> unwrap() {
             return Maybe.of(context);
@@ -585,6 +585,10 @@ public class WorkflowExpressionResolution {
         return 
Tasks.resolving(expression).as(Object.class).deep().context(context.getEntity()).get();
     }
 
+    public WorkflowFreemarkerModel newWorkflowFreemarkerModel() {
+        return new WorkflowFreemarkerModel();
+    }
+
     public Object processTemplateExpressionString(String expression, 
AllowBrooklynDslMode allowBrooklynDsl) {
         if (expression==null) return null;
         if (expression.startsWith("$brooklyn:") && 
allowBrooklynDsl.isAllowedHere()) {
@@ -599,7 +603,7 @@ public class WorkflowExpressionResolution {
             return expressionTemplateAndDslResolved;
         }
 
-        TemplateHashModel model = new WorkflowFreemarkerModel();
+        TemplateHashModel model = newWorkflowFreemarkerModel();
         Object result;
 
         boolean ourWait = interruptSetIfNeededToPreventWaiting();
diff --git 
a/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java 
b/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java
index ba65c16f7a..8a51d7c1b4 100644
--- 
a/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java
+++ 
b/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java
@@ -83,8 +83,17 @@ public class TemplateProcessor {
     }
 
     static BrooklynFreemarkerUnwrappableObjectWrapper BROOKLYN_WRAPPER = new 
BrooklynFreemarkerUnwrappableObjectWrapper();
+    public static TemplateModel wrapAsTemplateModel(Object o) throws 
TemplateModelException { return BROOKLYN_WRAPPER.wrap(o); }
+    public static Maybe<Object> unwrapTemplateModelMaybe(TemplateModel 
templateModel) { return BROOKLYN_WRAPPER.unwrapMaybe(templateModel); }
 
     static ThreadLocalStack<Map<TemplateModel,Object>> 
TEMPLATE_MODEL_UNWRAP_CACHE = new ThreadLocalStack<>(true);
+    /** A cache is used to be able to retrieve the object from which a 
TemplateModel was created, if needed,
+     *  because Freemarker doesn't support that except on selected 
UnwrappableTemplateModel subclasses.
+     *  Use wrap and unwrap methods above to access.
+     *  Calls to this must be balanced with a 'close' to avoid memory leaks */
+    public static void openLocalTemplateModelCache() { 
TEMPLATE_MODEL_UNWRAP_CACHE.push(MutableMap.of()); }
+    public static void closeLocalTemplateModelCache() { 
TEMPLATE_MODEL_UNWRAP_CACHE.pop(); }
+
     static ThreadLocalStack<String> TEMPLATE_FILE_WANTING_LEGACY_SYNTAX = new 
ThreadLocalStack<>(true);
     static ThreadLocalStack<Boolean> IS_FOR_WORKFLOW = new 
ThreadLocalStack<>(true);
 
@@ -256,10 +265,6 @@ public class TemplateProcessor {
         }
     }
 
-    public static TemplateModel wrapAsTemplateModel(Object o) throws 
TemplateModelException {
-        return BROOKLYN_WRAPPER.wrap(o);
-    }
-
     /** As per {@link #processTemplateContents(String, Map)}, but taking a 
file. */
     public static String processTemplateFile(String templateFileName, 
Map<String, ? extends Object> substitutions) {
         String templateContents;
@@ -948,7 +953,7 @@ public class TemplateProcessor {
                 Environment env = 
template.createProcessingEnvironment(substitutions, null);
                 Maybe<Method> evalMethod = 
Reflections.findMethodMaybe(Expression.class, "eval", Environment.class);
                 try {
-                    TEMPLATE_MODEL_UNWRAP_CACHE.push(MutableMap.of());
+                    openLocalTemplateModelCache();
                     Maybe<Object> model = evalMethod.isAbsent() ? 
Maybe.Absent.castAbsent(evalMethod) : escapedExpression.map(expr -> {
                         try {
                             return Reflections.invokeMethodFromArgs(expr,
@@ -968,7 +973,7 @@ public class TemplateProcessor {
                     });
                     if (model.isPresent()) {
                         if (model.get() instanceof TemplateModel) {
-                            return 
BROOKLYN_WRAPPER.unwrapMaybe((TemplateModel) model.get()).get();
+                            return unwrapTemplateModelMaybe((TemplateModel) 
model.get()).get();
                         } else if (model.get()==null) {
                             // key not found, fall through to below for proper 
error handling
                         } else {
@@ -978,7 +983,7 @@ public class TemplateProcessor {
                         log.warn("Unable to access FreeMarker internals to 
resolve " + templateContents + "; will cast argument as string");
                     }
                 } finally {
-                    TEMPLATE_MODEL_UNWRAP_CACHE.pop();
+                    closeLocalTemplateModelCache();
                 }
             }
 

Reply via email to