FREEMARKER-55: introducing CallableUtils#getAndUnwrap...(...) utils.

Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/3f6ee183
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/3f6ee183
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/3f6ee183

Branch: refs/heads/3
Commit: 3f6ee183ab87e193c4eaa465652d5d8b204cd992
Parents: 40bd07b
Author: Woonsan Ko <woon...@apache.org>
Authored: Wed Sep 13 12:14:08 2017 -0400
Committer: Woonsan Ko <woon...@apache.org>
Committed: Wed Sep 13 12:14:08 2017 -0400

----------------------------------------------------------------------
 .../freemarker/core/util/CallableUtils.java     | 153 +++++++++++++++++++
 .../AbstractSpringTemplateCallableModel.java    |  46 ++++++
 .../AbstractSpringTemplateDirectiveModel.java   |  23 +--
 .../AbstractSpringTemplateFunctionModel.java    |  23 +--
 .../freemarker/spring/model/EvalFunction.java   |   2 +-
 .../spring/model/MessageFunction.java           |   6 +-
 .../model/SpringTemplateCallableHashModel.java  |   4 +-
 .../spring/model/TransformFunction.java         |  12 +-
 8 files changed, 214 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3f6ee183/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java
----------------------------------------------------------------------
diff --git 
a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java
 
b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java
index 9bf96e2..0c8f09f 100644
--- 
a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java
+++ 
b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java
@@ -35,6 +35,7 @@ import org.apache.freemarker.core._ErrorDescriptionBuilder;
 import org.apache.freemarker.core._EvalUtils;
 import org.apache.freemarker.core._UnexpectedTypeErrorExplainerTemplateModel;
 import org.apache.freemarker.core.model.ArgumentArrayLayout;
+import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
 import org.apache.freemarker.core.model.TemplateBooleanModel;
 import org.apache.freemarker.core.model.TemplateCallableModel;
 import org.apache.freemarker.core.model.TemplateDirectiveModel;
@@ -302,6 +303,20 @@ public final class CallableUtils {
         return desc;
     }
 
+    private static _ErrorDescriptionBuilder getMessageBadGenericArgumentType(
+            Object argValue, int argIdx, Class<? extends TemplateModel>[] 
expectedTypes,
+            String expectedTypesDesc, TemplateCallableModel callable,
+            boolean calledAsFunction) {
+        _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
+                getMessageArgumentProblem(
+                        callable, argIdx,
+                        new Object[]{ "should be ", new 
_DelayedAOrAn(expectedTypesDesc), ", but was ",
+                                new _DelayedAOrAn(argValue.getClass()),
+                                "." },
+                        calledAsFunction));
+        return desc;
+    }
+
     public static void executeWith0Arguments(
             TemplateDirectiveModel directive, CallPlace callPlace, Writer out, 
Environment env)
             throws IOException, TemplateException {
@@ -717,6 +732,144 @@ public final class CallableUtils {
                 calledAsFunction);
     }
 
+    // getAndUnwrapArgument(...)'s and getOptionalAndUnwrapArgument(...)'s
+
+    /**
+     * Convenience method to call
+     * {@link #unwrapAndCastArgumentValue(TemplateModel, int, Class, boolean, 
TemplateModel, TemplateCallableModel, boolean)}.
+     */
+    public static <T> T getAndUnwrapArgument(
+            TemplateModel[] args, int argIndex, Class<T> type, 
TemplateFunctionModel callable,
+            ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper)
+            throws TemplateException {
+        return unwrapAndCastArgumentValue(args[argIndex], argIndex, type, 
false, null, callable, true,
+                objectWrapperAndUnwrapper);
+    }
+
+    /**
+     * Convenience method to call
+     * {@link #unwrapAndCastArgumentValue(TemplateModel, int, Class, boolean, 
TemplateModel, TemplateCallableModel, boolean)}.
+     */
+    public static <T> T getAndUnwrapArgument(
+            TemplateModel[] args, int argIndex, Class<T> type, 
TemplateDirectiveModel callable,
+            ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper)
+            throws TemplateException {
+        return unwrapAndCastArgumentValue(args[argIndex], argIndex, type, 
false, null, callable, false,
+                objectWrapperAndUnwrapper);
+    }
+
+    /**
+     * Convenience method to call
+     * {@link #unwrapAndCastArgumentValue(TemplateModel, int, Class, boolean, 
TemplateModel, TemplateCallableModel, boolean)}.
+     */
+    public static <T> T getOptionalAndUnwrapArgument(
+            TemplateModel[] args, int argIndex, Class<T> type, 
TemplateFunctionModel callable,
+            ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper)
+            throws TemplateException {
+        return unwrapAndCastArgumentValue(args[argIndex], argIndex, type, 
true, null, callable, true,
+                objectWrapperAndUnwrapper);
+    }
+
+    /**
+     * Convenience method to call
+     * {@link #unwrapAndCastArgumentValue(TemplateModel, int, Class, boolean, 
TemplateModel, TemplateCallableModel, boolean)}.
+     */
+    public static <T> T getOptionalAndUnwrapArgument(
+            TemplateModel[] args, int argIndex, Class<T> type, 
TemplateDirectiveModel callable,
+            ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper)
+            throws TemplateException {
+        return unwrapAndCastArgumentValue(args[argIndex], argIndex, type, 
true, null, callable, false,
+                objectWrapperAndUnwrapper);
+    }
+
+    /**
+     * Convenience method to call
+     * {@link #unwrapAndCastArgumentValue(TemplateModel, int, Class, boolean, 
TemplateModel, TemplateCallableModel, boolean)}.
+     */
+    public static <T> T getOptionalAndUnwrapArgument(
+            TemplateModel[] args, int argIndex, Class<T> type, T defaultValue, 
TemplateFunctionModel callable,
+            ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper)
+            throws TemplateException {
+        return unwrapAndCastArgumentValue(args[argIndex], argIndex, type, 
true, defaultValue, callable, true,
+                objectWrapperAndUnwrapper);
+    }
+
+    /**
+     * Convenience method to call
+     * {@link #unwrapAndCastArgumentValue(TemplateModel, int, Class, boolean, 
TemplateModel, TemplateCallableModel, boolean)}.
+     */
+    public static <T> T getOptionalAndUnwrapArgument(
+            TemplateModel[] args, int argIndex, Class<T> type, T defaultValue, 
TemplateDirectiveModel callable,
+            ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper)
+            throws TemplateException {
+        return unwrapAndCastArgumentValue(args[argIndex], argIndex, type, 
true, defaultValue, callable, false,
+                objectWrapperAndUnwrapper);
+    }
+
+    /**
+     * Unwrap the argument to a plain Java object first and checks if the 
argument value is of the proper type,
+     * also, if it's {@code null}/omitted, in which case it can throw an 
exception or return a default value.
+     * <p>
+     * The point of this method is not only to decrease the boiler plate 
needed for these common checks, but also to
+     * standardize the error message content. If the checks themselves don't 
fit your needs, you should still use {@link
+     * #newArgumentValueTypeException(TemplateModel, int, Class, 
TemplateCallableModel, boolean)} and its overloads,
+     * also {@link #newNullOrOmittedArgumentException(int, 
TemplateCallableModel, boolean)} and its overloads to
+     * generate similar error messages.
+     *
+     * @param argValue
+     *         The argument value at the position of {@code argIdx}.
+     * @param argIdx
+     *         The index in the {@code args} array (assumed to be a valid 
index. This is information is needed for
+     *         proper error messages.
+     * @param type
+     *         The expected class of the unwrapped argument as plain Java 
object (not a {@link TemplateModel} subinterface).
+     *         {@code null} if there are no type restrictions.
+     * @param optional
+     *         If we allow the parameter to be {@code null} or omitted.
+     * @param defaultValue
+     *         The value to return if the parameter was {@code null} or 
omitted.
+     * @param callable
+     *         The {@link TemplateCallableModel} whose argument we cast; 
required for printing proper error message.
+     * @param calledAsFunction
+     *         Tells if the {@code callable} was called as function (as 
opposed to called as a directive). This
+     *         information is needed because a {@link TemplateCallableModel} 
might implements both {@link
+     *         TemplateFunctionModel} and {@link TemplateDirectiveModel}, in 
which case this method couldn't tell if the
+     *         argument of which we are casting.
+     * @param objectWrapperAndUnwrapper
+     *         The ObjectWrapperAndUnwrapper instance to use when unwrapping 
the argument to a plain Java object.
+     *
+     * @return The argument value of the proper type.
+     *
+     * @throws TemplateException
+     *         If the argument is not of the proper type or is non-optional 
yet {@code null}/omitted. The error message
+     *         describes the problem in detail, and is meant to be shown for 
the template author.
+     */
+    public static <T> T unwrapAndCastArgumentValue(
+            TemplateModel argValue, int argIdx, Class<T> type,
+            boolean optional, T defaultValue, TemplateCallableModel callable,
+            boolean calledAsFunction, ObjectWrapperAndUnwrapper 
objectWrapperAndUnwrapper)
+            throws TemplateException {
+        if (objectWrapperAndUnwrapper == null) {
+            throw newGenericExecuteException("ObjectWrapperAndUnwrapper 
shouldn't be null.", callable,
+                    calledAsFunction);
+        }
+        final Object argValueObject = (argValue != null) ? 
objectWrapperAndUnwrapper.unwrap(argValue) : null;
+        if (argValueObject == null) {
+            if (optional) {
+                return defaultValue;
+            }
+            throw newNullOrOmittedArgumentException(argIdx, callable, 
calledAsFunction);
+        }
+        if (type == null || type.isInstance(argValueObject)) {
+            return (T) argValueObject;
+        }
+        throw new TemplateException(
+                getMessageBadGenericArgumentType(argValue, argIdx,
+                        new Class[] { type },
+                        type.getName(),
+                        callable, calledAsFunction));
+    }
+
     // Other type of arg:
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3f6ee183/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java
----------------------------------------------------------------------
diff --git 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java
 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java
index 03142d6..1c3d71b 100644
--- 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java
+++ 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java
@@ -24,12 +24,16 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.apache.freemarker.core.Environment;
 import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.ObjectWrapper;
 import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
 import org.apache.freemarker.core.model.TemplateCallableModel;
+import org.apache.freemarker.core.model.TemplateFunctionModel;
 import org.apache.freemarker.core.model.TemplateModel;
 import org.apache.freemarker.core.model.TemplateStringModel;
+import org.apache.freemarker.core.util.CallableUtils;
 import org.springframework.web.servlet.support.BindStatus;
 import org.springframework.web.servlet.support.RequestContext;
+import org.springframework.web.servlet.view.AbstractTemplateView;
 
 /**
  * Abstract TemplateCallableModel for derived classes to support Spring MVC 
based templating environment.
@@ -66,6 +70,48 @@ abstract class AbstractSpringTemplateCallableModel 
implements TemplateCallableMo
     }
 
     /**
+     * Find {@link ObjectWrapperAndUnwrapper} from the environment.
+     * @param env environment
+     * @param calledAsFunction whether or not this is called from a {@link 
TemplateFunctionModel}.
+     * @return {@link ObjectWrapperAndUnwrapper} from the environment
+     * @throws TemplateException if the ObjectWrapper in the environment is 
not an ObjectWrapperAndUnwrapper
+     */
+    protected ObjectWrapperAndUnwrapper 
getObjectWrapperAndUnwrapper(Environment env, boolean calledAsFunction)
+            throws TemplateException {
+        final ObjectWrapper objectWrapper = env.getObjectWrapper();
+
+        if (!(objectWrapper instanceof ObjectWrapperAndUnwrapper)) {
+            CallableUtils.newGenericExecuteException(
+                    "The ObjectWrapper of environment isn't an instance of 
ObjectWrapperAndUnwrapper.", this,
+                    calledAsFunction);
+        }
+
+        return (ObjectWrapperAndUnwrapper) objectWrapper;
+    }
+
+    /**
+     * Find Spring {@link RequestContext} from the environment.
+     * @param env environment
+     * @param calledAsFunction whether or not this is called from a {@link 
TemplateFunctionModel}.
+     * @return Spring {@link RequestContext} from the environment
+     * @throws TemplateException if Spring {@link RequestContext} from the 
environment is not found
+     */
+    protected RequestContext getRequestContext(final Environment env, boolean 
calledAsFunction)
+            throws TemplateException {
+        TemplateModel rcModel = 
env.getVariable(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE);
+
+        if (rcModel == null) {
+            CallableUtils.newGenericExecuteException(
+                    
AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE + " not found.", 
this, false);
+        }
+
+        RequestContext requestContext = (RequestContext) 
getObjectWrapperAndUnwrapper(env, calledAsFunction)
+                .unwrap(rcModel);
+
+        return requestContext;
+    }
+
+    /**
      * Find {@link BindStatus} with no {@code htmlEscape} option from {@link 
RequestContext} by the {@code path}
      * and wrap it as a {@link TemplateModel}.
      * <P>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3f6ee183/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java
----------------------------------------------------------------------
diff --git 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java
 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java
index a02558f..c91b387 100644
--- 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java
+++ 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java
@@ -28,13 +28,10 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.freemarker.core.CallPlace;
 import org.apache.freemarker.core.Environment;
 import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.ObjectWrapper;
 import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
 import org.apache.freemarker.core.model.TemplateDirectiveModel;
 import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.util.CallableUtils;
 import org.springframework.web.servlet.support.RequestContext;
-import org.springframework.web.servlet.view.AbstractTemplateView;
 
 /**
  * Abstract TemplateDirectiveModel for derived classes to support Spring MVC 
based templating environment.
@@ -61,23 +58,9 @@ abstract class AbstractSpringTemplateDirectiveModel extends 
AbstractSpringTempla
     @Override
     public final void execute(TemplateModel[] args, CallPlace callPlace, 
Writer out, Environment env)
             throws TemplateException, IOException {
-        final ObjectWrapper objectWrapper = env.getObjectWrapper();
-
-        if (!(objectWrapper instanceof ObjectWrapperAndUnwrapper)) {
-            CallableUtils.newGenericExecuteException(
-                    "The ObjectWrapper of environment isn't an instance of 
ObjectWrapperAndUnwrapper.", this, false);
-        }
-
-        TemplateModel rcModel = 
env.getVariable(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE);
-
-        if (rcModel == null) {
-            CallableUtils.newGenericExecuteException(
-                    
AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE + " not found.", 
this, false);
-        }
-
-        RequestContext requestContext = (RequestContext) 
((ObjectWrapperAndUnwrapper) objectWrapper).unwrap(rcModel);
-
-        executeInternal(args, callPlace, out, env, (ObjectWrapperAndUnwrapper) 
objectWrapper, requestContext);
+        final ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper = 
getObjectWrapperAndUnwrapper(env, false);
+        final RequestContext requestContext = getRequestContext(env, false);
+        executeInternal(args, callPlace, out, env, objectWrapperAndUnwrapper, 
requestContext);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3f6ee183/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java
----------------------------------------------------------------------
diff --git 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java
 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java
index 90bd3df..afb3262 100644
--- 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java
+++ 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java
@@ -25,13 +25,10 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.freemarker.core.CallPlace;
 import org.apache.freemarker.core.Environment;
 import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.model.ObjectWrapper;
 import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
 import org.apache.freemarker.core.model.TemplateFunctionModel;
 import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.util.CallableUtils;
 import org.springframework.web.servlet.support.RequestContext;
-import org.springframework.web.servlet.view.AbstractTemplateView;
 
 /**
  * Abstract TemplateFunctionModel for derived classes to support Spring MVC 
based templating environment.
@@ -57,23 +54,9 @@ abstract class AbstractSpringTemplateFunctionModel extends 
AbstractSpringTemplat
      */
     @Override
     public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, 
Environment env) throws TemplateException {
-        final ObjectWrapper objectWrapper = env.getObjectWrapper();
-
-        if (!(objectWrapper instanceof ObjectWrapperAndUnwrapper)) {
-            CallableUtils.newGenericExecuteException(
-                    "The ObjectWrapper of environment isn't an instance of 
ObjectWrapperAndUnwrapper.", this, true);
-        }
-
-        TemplateModel rcModel = 
env.getVariable(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE);
-
-        if (rcModel == null) {
-            CallableUtils.newGenericExecuteException(
-                    
AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE + " not found.", 
this, true);
-        }
-
-        RequestContext requestContext = (RequestContext) 
((ObjectWrapperAndUnwrapper) objectWrapper).unwrap(rcModel);
-
-        return executeInternal(args, callPlace, env, 
(ObjectWrapperAndUnwrapper) objectWrapper, requestContext);
+        final ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper = 
getObjectWrapperAndUnwrapper(env, true);
+        final RequestContext requestContext = getRequestContext(env, true);
+        return executeInternal(args, callPlace, env, 
objectWrapperAndUnwrapper, requestContext);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3f6ee183/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/EvalFunction.java
----------------------------------------------------------------------
diff --git 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/EvalFunction.java
 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/EvalFunction.java
index 2c257c4..4710f6d 100644
--- 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/EvalFunction.java
+++ 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/EvalFunction.java
@@ -106,7 +106,7 @@ class EvalFunction extends 
AbstractSpringTemplateFunctionModel {
 
         EvaluationContext evaluationContext = null;
         final SpringTemplateCallableHashModel springTemplateModel = 
getSpringTemplateCallableHashModel(env);
-        TemplateModel evaluationContextModel = 
springTemplateModel.get(EVALUATION_CONTEXT_VAR_NAME);
+        TemplateModel evaluationContextModel = 
springTemplateModel.getEvaluationContextModel();
 
         if (evaluationContextModel != null) {
             evaluationContext = (EvaluationContext) 
objectWrapperAndUnwrapper.unwrap(evaluationContextModel);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3f6ee183/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java
----------------------------------------------------------------------
diff --git 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java
 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java
index c7b6db5..7ce8d40 100644
--- 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java
+++ 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java
@@ -108,10 +108,8 @@ class MessageFunction extends 
AbstractSpringTemplateFunctionModel {
 
         String message = null;
 
-        final TemplateModel messageResolvableModel = 
CallableUtils.getOptionalArgument(args,
-                MESSAGE_RESOLVABLE_PARAM_IDX, TemplateModel.class, this);
-        final MessageSourceResolvable messageResolvable = 
(messageResolvableModel != null)
-                ? (MessageSourceResolvable) 
objectWrapperAndUnwrapper.unwrap(messageResolvableModel) : null;
+        final MessageSourceResolvable messageResolvable = 
CallableUtils.getOptionalAndUnwrapArgument(args,
+                MESSAGE_RESOLVABLE_PARAM_IDX, MessageSourceResolvable.class, 
this, objectWrapperAndUnwrapper);
 
         if (messageResolvable != null) {
             message = messageSource.getMessage(messageResolvable, 
requestContext.getLocale());

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3f6ee183/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/SpringTemplateCallableHashModel.java
----------------------------------------------------------------------
diff --git 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/SpringTemplateCallableHashModel.java
 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/SpringTemplateCallableHashModel.java
index 8afb4ab..40f7d59 100644
--- 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/SpringTemplateCallableHashModel.java
+++ 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/SpringTemplateCallableHashModel.java
@@ -48,12 +48,12 @@ public final class SpringTemplateCallableHashModel 
implements TemplateHashModel,
      * in Spring Framework JSP tag libraries.
      */
     // NOTE: The model name, "nestedPathModel", must be different from the 
"nestedPath" directive model's name.
-    public static final String NESTED_PATH_MODEL = "nestedPathModel";
+    private static final String NESTED_PATH_MODEL = "nestedPathModel";
 
     /**
      * Name of the internal evaluation context template model used by 
<code>EvalFunction</code> to cache <code>EvaluationContext</code>.
      */
-    public static final String EVALUATION_CONTEXT_MODEL = 
"evaluationContextModel";
+    private static final String EVALUATION_CONTEXT_MODEL = 
"evaluationContextModel";
 
     private Map<String, TemplateModel> modelsMap = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3f6ee183/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/TransformFunction.java
----------------------------------------------------------------------
diff --git 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/TransformFunction.java
 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/TransformFunction.java
index 96258a7..cac1dd6 100644
--- 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/TransformFunction.java
+++ 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/TransformFunction.java
@@ -73,14 +73,10 @@ class TransformFunction extends 
AbstractSpringTemplateFunctionModel {
     protected TemplateModel executeInternal(TemplateModel[] args, CallPlace 
callPlace, Environment env,
             ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper, 
RequestContext requestContext)
                     throws TemplateException {
-        final TemplateModel editorModel = 
CallableUtils.getOptionalArgument(args, PROPERTY_EDITOR_PARAM_IDX,
-                TemplateModel.class, this);
-        final PropertyEditor editor = (editorModel != null)
-                ? (PropertyEditor) 
objectWrapperAndUnwrapper.unwrap(editorModel) : null;
-
-        final TemplateModel valueModel = 
CallableUtils.getOptionalArgument(args, VALUE_PARAM_IDX, TemplateModel.class,
-                this);
-        final Object value = (valueModel != null) ? 
objectWrapperAndUnwrapper.unwrap(valueModel) : null;
+        final PropertyEditor editor = 
CallableUtils.getOptionalAndUnwrapArgument(args, PROPERTY_EDITOR_PARAM_IDX,
+                PropertyEditor.class, this, objectWrapperAndUnwrapper);
+        final Object value = CallableUtils.getOptionalAndUnwrapArgument(args, 
VALUE_PARAM_IDX,
+                null, this, objectWrapperAndUnwrapper);
 
         String valueAsString = null;
 

Reply via email to