You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/08/07 22:41:31 UTC
[5/8] incubator-freemarker git commit: FREEMARKER-64: Removed
TemplateMethodModel,
using TemplateFunctionModel everywhere instead. Some refinement of existing
TemplateCallableModel API-s, most importantly,
the support for null argumenArrayLayout. Removed
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsBasic.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsBasic.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsBasic.java
index ce3ff56..9311626 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsBasic.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsBasic.java
@@ -20,13 +20,13 @@
package org.apache.freemarker.core;
import java.util.ArrayList;
-import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateScalarModel;
@@ -69,20 +69,25 @@ class BuiltInsForStringsBasic {
static class containsBI extends ASTExpBuiltIn {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private final String s;
private BIMethod(String s) {
this.s = s;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- checkMethodArgCount(args, 1);
- return s.contains(getStringMethodArg(args, 0))
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ return s.contains(_CallableUtils.castArgToString(args, 0))
? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
}
@Override
@@ -94,19 +99,24 @@ class BuiltInsForStringsBasic {
static class ends_withBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private String s;
private BIMethod(String s) {
this.s = s;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- checkMethodArgCount(args, 1);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
return s.endsWith(getStringMethodArg(args, 0)) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
}
@Override
@@ -117,19 +127,24 @@ class BuiltInsForStringsBasic {
static class ensure_ends_withBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private String s;
private BIMethod(String s) {
this.s = s;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- checkMethodArgCount(args, 1);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
String suffix = getStringMethodArg(args, 0);
return new SimpleScalar(s.endsWith(suffix) ? s : s + suffix);
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
}
@Override
@@ -140,27 +155,28 @@ class BuiltInsForStringsBasic {
static class ensure_starts_withBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private String s;
private BIMethod(String s) {
this.s = s;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- checkMethodArgCount(args, 1, 3);
-
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
final String checkedPrefix = getStringMethodArg(args, 0);
-
+
final boolean startsWithPrefix;
- final String addedPrefix;
- if (args.size() > 1) {
- addedPrefix = getStringMethodArg(args, 1);
- long flags = args.size() > 2
- ? RegexpHelper.parseFlagString(getStringMethodArg(args, 2))
+ final String addedPrefix;
+ String addedPrefixArg = getStringMethodArg(args, 1, true);
+ String flagsArg = getStringMethodArg(args, 2, true);
+ if (addedPrefixArg != null) {
+ addedPrefix = addedPrefixArg;
+ long flags = flagsArg != null
+ ? RegexpHelper.parseFlagString(flagsArg)
: RegexpHelper.RE_FLAG_REGEXP;
-
+
if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
RegexpHelper.checkOnlyHasNonRegexpFlags(key, flags, true);
if ((flags & RegexpHelper.RE_FLAG_CASE_INSENSITIVE) == 0) {
@@ -172,13 +188,22 @@ class BuiltInsForStringsBasic {
Pattern pattern = RegexpHelper.getPattern(checkedPrefix, (int) flags);
final Matcher matcher = pattern.matcher(s);
startsWithPrefix = matcher.lookingAt();
- }
+ }
} else {
+ if (flagsArg != null) {
+ throw new _MiscTemplateException(
+ "The 2nd parameter must be non-null when the 3rd parameter is non-null");
+ }
startsWithPrefix = s.startsWith(checkedPrefix);
addedPrefix = checkedPrefix;
}
return new SimpleScalar(startsWithPrefix ? s : addedPrefix + s);
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.THREE_POSITIONAL_PARAMETERS;
+ }
}
@Override
@@ -189,26 +214,31 @@ class BuiltInsForStringsBasic {
static class index_ofBI extends ASTExpBuiltIn {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private final String s;
private BIMethod(String s) {
this.s = s;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 1, 2);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
String subStr = getStringMethodArg(args, 0);
- if (argCnt > 1) {
- int startIdx = getNumberMethodArg(args, 1).intValue();
+ Number indexModel = getNumberMethodArg(args, 1, true);
+ if (indexModel != null) {
+ int startIdx = indexModel.intValue();
return new SimpleNumber(findLast ? s.lastIndexOf(subStr, startIdx) : s.indexOf(subStr, startIdx));
} else {
return new SimpleNumber(findLast ? s.lastIndexOf(subStr) : s.indexOf(subStr));
}
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
}
private final boolean findLast;
@@ -225,7 +255,7 @@ class BuiltInsForStringsBasic {
}
static class keep_afterBI extends BuiltInForString {
- class KeepAfterMethod implements TemplateMethodModel {
+ class KeepAfterMethod implements TemplateFunctionModel {
private String s;
KeepAfterMethod(String s) {
@@ -233,12 +263,13 @@ class BuiltInsForStringsBasic {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 1, 2);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
String separatorString = getStringMethodArg(args, 0);
- long flags = argCnt > 1 ? RegexpHelper.parseFlagString(getStringMethodArg(args, 1)) : 0;
-
+
+ String flagsStr = getStringMethodArg(args, 1, true);
+ long flags = flagsStr != null ? RegexpHelper.parseFlagString(flagsStr) : 0;
+
int startIndex;
if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
RegexpHelper.checkOnlyHasNonRegexpFlags(key, flags, true);
@@ -258,9 +289,14 @@ class BuiltInsForStringsBasic {
} else {
startIndex = -1;
}
- }
+ }
return startIndex == -1 ? TemplateScalarModel.EMPTY_STRING : new SimpleScalar(s.substring(startIndex));
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
}
@Override
@@ -271,7 +307,7 @@ class BuiltInsForStringsBasic {
}
static class keep_after_lastBI extends BuiltInForString {
- class KeepAfterMethod implements TemplateMethodModel {
+ class KeepAfterMethod implements TemplateFunctionModel {
private String s;
KeepAfterMethod(String s) {
@@ -279,12 +315,12 @@ class BuiltInsForStringsBasic {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 1, 2);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
String separatorString = getStringMethodArg(args, 0);
- long flags = argCnt > 1 ? RegexpHelper.parseFlagString(getStringMethodArg(args, 1)) : 0;
-
+ String flagString = getStringMethodArg(args, 1, true);
+ long flags = flagString != null ? RegexpHelper.parseFlagString(flagString) : 0;
+
int startIndex;
if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
RegexpHelper.checkOnlyHasNonRegexpFlags(key, flags, true);
@@ -311,9 +347,14 @@ class BuiltInsForStringsBasic {
startIndex = -1;
}
}
- }
+ }
return startIndex == -1 ? TemplateScalarModel.EMPTY_STRING : new SimpleScalar(s.substring(startIndex));
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
}
@Override
@@ -324,7 +365,7 @@ class BuiltInsForStringsBasic {
}
static class keep_beforeBI extends BuiltInForString {
- class KeepUntilMethod implements TemplateMethodModel {
+ class KeepUntilMethod implements TemplateFunctionModel {
private String s;
KeepUntilMethod(String s) {
@@ -332,12 +373,12 @@ class BuiltInsForStringsBasic {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 1, 2);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
String separatorString = getStringMethodArg(args, 0);
- long flags = argCnt > 1 ? RegexpHelper.parseFlagString(getStringMethodArg(args, 1)) : 0;
-
+ String flagString = getStringMethodArg(args, 1, true);
+ long flags = flagString != null ? RegexpHelper.parseFlagString(flagString) : 0;
+
int stopIndex;
if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
RegexpHelper.checkOnlyHasNonRegexpFlags(key, flags, true);
@@ -354,9 +395,14 @@ class BuiltInsForStringsBasic {
} else {
stopIndex = -1;
}
- }
+ }
return stopIndex == -1 ? new SimpleScalar(s) : new SimpleScalar(s.substring(0, stopIndex));
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
}
@Override
@@ -368,7 +414,7 @@ class BuiltInsForStringsBasic {
// TODO
static class keep_before_lastBI extends BuiltInForString {
- class KeepUntilMethod implements TemplateMethodModel {
+ class KeepUntilMethod implements TemplateFunctionModel {
private String s;
KeepUntilMethod(String s) {
@@ -376,12 +422,12 @@ class BuiltInsForStringsBasic {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 1, 2);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
String separatorString = getStringMethodArg(args, 0);
- long flags = argCnt > 1 ? RegexpHelper.parseFlagString(getStringMethodArg(args, 1)) : 0;
-
+ String flagString = getStringMethodArg(args, 1, true);
+ long flags = flagString != null ? RegexpHelper.parseFlagString(flagString) : 0;
+
int stopIndex;
if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
RegexpHelper.checkOnlyHasNonRegexpFlags(key, flags, true);
@@ -405,9 +451,14 @@ class BuiltInsForStringsBasic {
stopIndex = -1;
}
}
- }
+ }
return stopIndex == -1 ? new SimpleScalar(s) : new SimpleScalar(s.substring(0, stopIndex));
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
}
@Override
@@ -435,23 +486,21 @@ class BuiltInsForStringsBasic {
static class padBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private final String s;
private BIMethod(String s) {
this.s = s;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 1, 2);
-
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
int width = getNumberMethodArg(args, 0).intValue();
-
- if (argCnt > 1) {
- String filling = getStringMethodArg(args, 1);
+
+ String filling = getStringMethodArg(args, 1, true);
+ if (filling != null) {
try {
return new SimpleScalar(
leftPadder
@@ -470,6 +519,11 @@ class BuiltInsForStringsBasic {
return new SimpleScalar(leftPadder ? _StringUtil.leftPad(s, width) : _StringUtil.rightPad(s, width));
}
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
}
private final boolean leftPadder;
@@ -486,19 +540,24 @@ class BuiltInsForStringsBasic {
static class remove_beginningBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private String s;
private BIMethod(String s) {
this.s = s;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- checkMethodArgCount(args, 1);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
String prefix = getStringMethodArg(args, 0);
return new SimpleScalar(s.startsWith(prefix) ? s.substring(prefix.length()) : s);
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
}
@Override
@@ -509,19 +568,24 @@ class BuiltInsForStringsBasic {
static class remove_endingBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private String s;
private BIMethod(String s) {
this.s = s;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- checkMethodArgCount(args, 1);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
String suffix = getStringMethodArg(args, 0);
return new SimpleScalar(s.endsWith(suffix) ? s.substring(0, s.length() - suffix.length()) : s);
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
}
@Override
@@ -531,7 +595,7 @@ class BuiltInsForStringsBasic {
}
static class split_BI extends BuiltInForString {
- class SplitMethod implements TemplateMethodModel {
+ class SplitMethod implements TemplateFunctionModel {
private String s;
SplitMethod(String s) {
@@ -539,12 +603,13 @@ class BuiltInsForStringsBasic {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 1, 2);
- String splitString = _CallableUtils.castArgToString(args, 0);
- long flags = argCnt > 1
- ? RegexpHelper.parseFlagString(_CallableUtils.castArgToString(args, 1))
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ int argCnt = args.length;
+ String splitString = getStringMethodArg(args, 0);
+ TemplateModel arg2 = args[1];
+ long flags = arg2 != null
+ ? RegexpHelper.parseFlagString(getStringMethodArg(args, 1))
: 0;
String[] result;
if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
@@ -554,9 +619,14 @@ class BuiltInsForStringsBasic {
} else {
Pattern pattern = RegexpHelper.getPattern(splitString, (int) flags);
result = pattern.split(s);
- }
+ }
return new NativeStringArraySequence(result);
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
}
@Override
@@ -568,19 +638,24 @@ class BuiltInsForStringsBasic {
static class starts_withBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private String s;
private BIMethod(String s) {
this.s = s;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- checkMethodArgCount(args, 1);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
return s.startsWith(getStringMethodArg(args, 0)) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
}
@Override
@@ -593,25 +668,24 @@ class BuiltInsForStringsBasic {
@Override
TemplateModel calculateResult(final String s, final Environment env) throws TemplateException {
- return new TemplateMethodModel() {
-
+ return new TemplateFunctionModel() {
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- int argCount = args.size();
- checkMethodArgCount(argCount, 1, 2);
-
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
int beginIdx = getNumberMethodArg(args, 0).intValue();
-
+
final int len = s.length();
-
+
if (beginIdx < 0) {
throw newIndexLessThan0Exception(0, beginIdx);
} else if (beginIdx > len) {
throw newIndexGreaterThanLengthException(0, beginIdx, len);
}
-
- if (argCount > 1) {
- int endIdx = getNumberMethodArg(args, 1).intValue();
+
+ Number endIdxNumber = getNumberMethodArg(args, 1, true);
+ if (endIdxNumber != null) {
+ int endIdx = endIdxNumber.intValue();
if (endIdx < 0) {
throw newIndexLessThan0Exception(1, endIdx);
} else if (endIdx > len) {
@@ -628,7 +702,12 @@ class BuiltInsForStringsBasic {
return new SimpleScalar(s.substring(beginIdx));
}
}
-
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
+
private TemplateModelException newIndexGreaterThanLengthException(
int argIdx, int idx, final int len) throws TemplateModelException {
return MessageUtil.newMethodArgInvalidValueException(
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsEncoding.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsEncoding.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsEncoding.java
index cee1b49..794fe94 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsEncoding.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsEncoding.java
@@ -22,9 +22,9 @@ package org.apache.freemarker.core;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
-import java.util.List;
-import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.ArgumentArrayLayout;
+import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateScalarModel;
@@ -132,7 +132,7 @@ class BuiltInsForStringsEncoding {
private BuiltInsForStringsEncoding() { }
static abstract class AbstractUrlBIResult implements
- TemplateScalarModel, TemplateMethodModel {
+ TemplateScalarModel, TemplateFunctionModel {
protected final ASTExpBuiltIn parent;
protected final String targetAsString;
@@ -146,10 +146,10 @@ class BuiltInsForStringsEncoding {
}
protected abstract String encodeWithCharset(Charset charset) throws UnsupportedEncodingException;
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- parent.checkMethodArgCount(args.size(), 1);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
try {
String charsetName = _CallableUtils.castArgToString(args,0);
Charset charset;
@@ -164,7 +164,12 @@ class BuiltInsForStringsEncoding {
throw new _TemplateModelException(e, "Failed to execute URL encoding.");
}
}
-
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
+
@Override
public String getAsString() throws TemplateModelException {
if (cachedResult == null) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java
index 6bf7e2a..1bcd592 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsMisc.java
@@ -22,13 +22,12 @@ package org.apache.freemarker.core;
import java.io.IOException;
import java.io.StringReader;
import java.io.Writer;
-import java.util.List;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.ObjectWrapper;
import org.apache.freemarker.core.model.TemplateBooleanModel;
import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateScalarModel;
@@ -219,7 +218,7 @@ class BuiltInsForStringsMisc {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
@@ -254,7 +253,7 @@ class BuiltInsForStringsMisc {
return new ConstructorFunction(target.evalAndCoerceToPlainText(env), env, target.getTemplate());
}
- class ConstructorFunction implements TemplateMethodModel {
+ class ConstructorFunction implements TemplateFunctionModel {
private final Class<?> cl;
private final Environment env;
@@ -273,13 +272,14 @@ class BuiltInsForStringsMisc {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateModelException {
ObjectWrapper ow = env.getObjectWrapper();
if (ow instanceof DefaultObjectWrapper) {
- return ow.wrap(((DefaultObjectWrapper) ow).newInstance(cl, args));
+ return ow.wrap(((DefaultObjectWrapper) ow).newInstance(cl, args, callPlace));
}
- if (!args.isEmpty()) {
+ if (args.length != 0) {
throw new TemplateModelException(
"className?new(args) only supports 0 arguments in the current configuration, because "
+ " the objectWrapper setting value is not a "
@@ -293,6 +293,12 @@ class BuiltInsForStringsMisc {
+ cl.getName() + " with its parameterless constructor; see cause exception", e);
}
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return null;
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsRegexp.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsRegexp.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsRegexp.java
index 025b599..ef73e5f 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsRegexp.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForStringsRegexp.java
@@ -20,13 +20,13 @@
package org.apache.freemarker.core;
import java.util.ArrayList;
-import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.TemplateBooleanModel;
import org.apache.freemarker.core.model.TemplateCollectionModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateModelIterator;
@@ -61,29 +61,35 @@ class BuiltInsForStringsRegexp {
}
static class matchesBI extends BuiltInForString {
- class MatcherBuilder implements TemplateMethodModel {
+ class MatcherBuilder implements TemplateFunctionModel {
String matchString;
MatcherBuilder(String matchString) throws TemplateModelException {
this.matchString = matchString;
}
-
+
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 1, 2);
-
- String patternString = _CallableUtils.castArgToString(args, 0);
- long flags = argCnt > 1
- ? RegexpHelper.parseFlagString(_CallableUtils.castArgToString(args, 1))
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ String patternString = getStringMethodArg(args, 0);
+ String flagString = getStringMethodArg(args, 1, true);
+ long flags = flagString != null
+ ? RegexpHelper.parseFlagString(flagString)
: 0;
if ((flags & RegexpHelper.RE_FLAG_FIRST_ONLY) != 0) {
+ // TODO [FM3] Should be an error?
RegexpHelper.logFlagWarning("?" + key + " doesn't support the \"f\" flag.");
}
Pattern pattern = RegexpHelper.getPattern(patternString, (int) flags);
return new RegexMatchModel(pattern, matchString);
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
}
@Override
@@ -95,7 +101,7 @@ class BuiltInsForStringsRegexp {
static class replace_reBI extends BuiltInForString {
- class ReplaceMethod implements TemplateMethodModel {
+ class ReplaceMethod implements TemplateFunctionModel {
private String s;
ReplaceMethod(String s) {
@@ -103,13 +109,13 @@ class BuiltInsForStringsRegexp {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 2, 3);
- String arg1 = _CallableUtils.castArgToString(args, 0);
- String arg2 = _CallableUtils.castArgToString(args, 1);
- long flags = argCnt > 2
- ? RegexpHelper.parseFlagString(_CallableUtils.castArgToString(args, 2))
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ String arg1 = getStringMethodArg(args, 0);
+ String arg2 = getStringMethodArg(args, 1);
+ String flagString = getStringMethodArg(args, 2, true);
+ long flags = flagString != null
+ ? RegexpHelper.parseFlagString(flagString)
: 0;
String result;
if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
@@ -123,10 +129,15 @@ class BuiltInsForStringsRegexp {
result = (flags & RegexpHelper.RE_FLAG_FIRST_ONLY) != 0
? matcher.replaceFirst(arg2)
: matcher.replaceAll(arg2);
- }
+ }
return new SimpleScalar(result);
}
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.THREE_POSITIONAL_PARAMETERS;
+ }
+
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java b/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java
index ee212db..f697309 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/Environment.java
@@ -2929,7 +2929,7 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
* Superclass of {@link TemplateCallableModel}-s implemented in the template language.
*/
abstract class TemplateLanguageCallable implements TemplateCallableModel {
- private final ASTDirMacroOrFunction callableDefinition;
+ final ASTDirMacroOrFunction callableDefinition;
private final Namespace namespace;
public TemplateLanguageCallable(ASTDirMacroOrFunction callableDefinition, Namespace namespace) {
@@ -2993,7 +2993,8 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
new _ErrorDescriptionBuilder(
"When calling macro ", new _DelayedJQuote(callableDefinition.getName()),
", required parameter ", new _DelayedJQuote(paramDef.getName()),
- (argIdx < getArgumentArrayLayout().getPredefinedPositionalArgumentCount()
+ (argIdx < callableDefinition.getArgumentArrayLayout()
+ .getPredefinedPositionalArgumentCount()
? new Object[] { " (parameter #", (argIdx + 1), ")" }
: ""),
" was either not specified, or had null/missing value.")
@@ -3013,11 +3014,6 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
}
}
- @Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
- return callableDefinition.getArgumentArrayLayout();
- }
-
ASTDirMacroOrFunction getCallableDefinition() {
return callableDefinition;
}
@@ -3053,6 +3049,11 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
return true;
}
+ @Override
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
+ return callableDefinition.getArgumentArrayLayout();
+ }
+
}
/**
@@ -3077,6 +3078,12 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
}
return env.getLastReturnValue();
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return callableDefinition.getArgumentArrayLayout();
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtil.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtil.java b/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtil.java
index a1858b1..8749fd4 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtil.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtil.java
@@ -169,7 +169,7 @@ class MessageUtil {
&& !(argExp instanceof ASTExpVariable)
&& !(argExp instanceof ASTExpDot)
&& !(argExp instanceof ASTExpDynamicKeyName)
- && !(argExp instanceof ASTExpMethodCall)
+ && !(argExp instanceof ASTExpFunctionCall)
&& !(argExp instanceof ASTExpBuiltIn);
if (needParen) sb.append('(');
sb.append(argExp.getCanonicalForm());
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/NonFunctionException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonFunctionException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonFunctionException.java
new file mode 100644
index 0000000..2ae7fdd
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/NonFunctionException.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.freemarker.core;
+
+import org.apache.freemarker.core.model.TemplateFunctionModel;
+import org.apache.freemarker.core.model.TemplateModel;
+
+/**
+ * Indicates that a {@link TemplateFunctionModel} value was expected, but the value had a different type.
+ */
+public class NonFunctionException extends UnexpectedTypeException {
+
+ private static final Class[] EXPECTED_TYPES = new Class[] { TemplateFunctionModel.class };
+
+ public NonFunctionException(Environment env) {
+ super(env, "Expecting method value here");
+ }
+
+ public NonFunctionException(String description, Environment env) {
+ super(env, description);
+ }
+
+ NonFunctionException(Environment env, _ErrorDescriptionBuilder description) {
+ super(env, description);
+ }
+
+ NonFunctionException(
+ ASTExpression blamed, TemplateModel model, Environment env)
+ throws InvalidReferenceException {
+ super(blamed, model, "function", EXPECTED_TYPES, env);
+ }
+
+ NonFunctionException(
+ ASTExpression blamed, TemplateModel model, String tip,
+ Environment env)
+ throws InvalidReferenceException {
+ super(blamed, model, "function", EXPECTED_TYPES, tip, env);
+ }
+
+ NonFunctionException(
+ ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
+ super(blamed, model, "function", EXPECTED_TYPES, tips, env);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/NonMethodException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonMethodException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonMethodException.java
deleted file mode 100644
index 6a51f4c..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonMethodException.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateModel;
-
-/**
- * Indicates that a {@link TemplateMethodModel} value was expected, but the value had a different type.
- */
-public class NonMethodException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { TemplateMethodModel.class };
-
- public NonMethodException(Environment env) {
- super(env, "Expecting method value here");
- }
-
- public NonMethodException(String description, Environment env) {
- super(env, description);
- }
-
- NonMethodException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonMethodException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "method", EXPECTED_TYPES, env);
- }
-
- NonMethodException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "method", EXPECTED_TYPES, tip, env);
- }
-
- NonMethodException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "method", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/_CallableUtils.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_CallableUtils.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_CallableUtils.java
index 0a69e51..4ab59b4 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/_CallableUtils.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_CallableUtils.java
@@ -26,7 +26,6 @@ import java.util.List;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.Constants;
-import org.apache.freemarker.core.model.TemplateCallableModel;
import org.apache.freemarker.core.model.TemplateDirectiveModel;
import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateModel;
@@ -47,18 +46,19 @@ public final class _CallableUtils {
public static void executeWith0Arguments(
TemplateDirectiveModel directive, CallPlace callPlace, Writer out, Environment env)
throws IOException, TemplateException {
- directive.execute(getArgumentArrayWithNoArguments(directive), callPlace, out, env);
+ directive.execute(
+ getArgumentArrayWithNoArguments(directive.getDirectiveArgumentArrayLayout()), callPlace, out, env);
}
public static TemplateModel executeWith0Arguments(
TemplateFunctionModel function, CallPlace callPlace, Environment env)
throws TemplateException {
- return function.execute(getArgumentArrayWithNoArguments(function), callPlace, env);
+ return function.execute(
+ getArgumentArrayWithNoArguments(function.getFunctionArgumentArrayLayout()), callPlace, env);
}
- private static TemplateModel[] getArgumentArrayWithNoArguments(TemplateCallableModel callable) {
- ArgumentArrayLayout argsLayout = callable.getArgumentArrayLayout();
- int totalLength = argsLayout.getTotalLength();
+ private static TemplateModel[] getArgumentArrayWithNoArguments(ArgumentArrayLayout argsLayout) {
+ int totalLength = argsLayout != null ? argsLayout.getTotalLength() : 0;
if (totalLength == 0) {
return Constants.EMPTY_TEMPLATE_MODEL_ARRAY;
} else {
@@ -78,28 +78,37 @@ public final class _CallableUtils {
}
}
- public static Number castArgToNumber(TemplateModel[] args, int argIndex, boolean allowNull)
+ public static Number castArgToNumber(TemplateModel[] args, int argIndex) throws TemplateException {
+ return castArgToNumber(args, argIndex, false);
+ }
+
+ public static Number castArgToNumber(TemplateModel[] args, int argIndex, boolean optional)
+ throws TemplateException {
+ return castArgToNumber(args[argIndex], argIndex, optional);
+ }
+
+ public static Number castArgToNumber(TemplateModel argValue, int argIndex)
throws TemplateException {
- return castArgToNumber(args[argIndex], argIndex, allowNull);
+ return castArgToNumber(argValue, argIndex, false);
}
- public static Number castArgToNumber(TemplateModel argValue, int argIndex, boolean allowNull)
+ public static Number castArgToNumber(TemplateModel argValue, int argIndex, boolean optional)
throws TemplateException {
- return castArgToNumber(argValue, null, argIndex, allowNull);
+ return castArgToNumber(argValue, null, argIndex, optional);
}
- public static Number castArgToNumber(TemplateModel argValue, String argName, boolean allowNull)
+ public static Number castArgToNumber(TemplateModel argValue, String argName, boolean optional)
throws TemplateException {
- return castArgToNumber(argValue, argName, -1, allowNull);
+ return castArgToNumber(argValue, argName, -1, optional);
}
- private static Number castArgToNumber(TemplateModel argValue, String argName, int argIndex, boolean allowNull)
+ private static Number castArgToNumber(TemplateModel argValue, String argName, int argIndex, boolean optional)
throws TemplateException {
if (argValue instanceof TemplateNumberModel) {
return ((TemplateNumberModel) argValue).getAsNumber();
}
if (argValue == null) {
- if (allowNull) {
+ if (optional) {
return null;
}
throw new _MiscTemplateException(
@@ -115,35 +124,39 @@ public final class _CallableUtils {
return castArgToString(args, argIndex, false);
}
- public static String castArgToString(List<? extends TemplateModel> args, int argIndex, boolean allowNull) throws
+ public static String castArgToString(List<? extends TemplateModel> args, int argIndex, boolean optional) throws
TemplateException {
- return castArgToString(args.get(argIndex), argIndex, allowNull);
+ return castArgToString(args.get(argIndex), argIndex, optional);
+ }
+
+ public static String castArgToString(TemplateModel[] args, int argIndex) throws TemplateException {
+ return castArgToString(args, argIndex, false);
}
- public static String castArgToString(TemplateModel[] args, int argIndex, boolean allowNull) throws TemplateException {
- return castArgToString(args[argIndex], argIndex, allowNull);
+ public static String castArgToString(TemplateModel[] args, int argIndex, boolean optional) throws TemplateException {
+ return castArgToString(args[argIndex], argIndex, optional);
}
public static String castArgToString(TemplateModel argValue, int argIndex) throws TemplateException {
return castArgToString(argValue, argIndex, false);
}
- public static String castArgToString(TemplateModel argValue, int argIndex, boolean allowNull) throws TemplateException {
- return castArgToString(argValue, null, argIndex, allowNull);
+ public static String castArgToString(TemplateModel argValue, int argIndex, boolean optional) throws TemplateException {
+ return castArgToString(argValue, null, argIndex, optional);
}
- public static String castArgToString(TemplateModel argValue, String argName, boolean allowNull) throws TemplateException {
- return castArgToString(argValue, argName, -1, allowNull);
+ public static String castArgToString(TemplateModel argValue, String argName, boolean optional) throws TemplateException {
+ return castArgToString(argValue, argName, -1, optional);
}
private static String castArgToString(
TemplateModel argValue, String argName, int argIndex,
- boolean allowNull) throws TemplateException {
+ boolean optional) throws TemplateException {
if (argValue instanceof TemplateScalarModel) {
return _EvalUtil.modelToString((TemplateScalarModel) argValue, null, null);
}
if (argValue == null) {
- if (allowNull) {
+ if (optional) {
return null;
}
throw new _MiscTemplateException(
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java
index d2fe617..89a6fe8 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java
@@ -36,10 +36,10 @@ import java.util.Map;
import java.util.Properties;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.model.impl.JavaMethodModel;
import org.apache.freemarker.core.model.impl.RestrictedObjectWrapper;
import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
import org.apache.freemarker.core.outputformat.impl.PlainTextOutputFormat;
@@ -712,17 +712,17 @@ public class _ObjectBuilderSettingEvaluator {
}
private void setJavaBeanProperties(Object bean,
- List/*<String>*/ namedParamNames, List/*<Object>*/ namedParamValues)
+ List<String> namedParamNames, List<Object> namedParamValues)
throws _ObjectBuilderSettingEvaluationException {
if (namedParamNames.isEmpty()) {
return;
}
- final Class cl = bean.getClass();
- Map/*<String,Method>*/ beanPropSetters;
+ final Class<?> cl = bean.getClass();
+ Map<String, Method> beanPropSetters;
try {
PropertyDescriptor[] propDescs = Introspector.getBeanInfo(cl).getPropertyDescriptors();
- beanPropSetters = new HashMap(propDescs.length * 4 / 3, 1.0f);
+ beanPropSetters = new HashMap<>(propDescs.length * 4 / 3, 1.0f);
for (PropertyDescriptor propDesc : propDescs) {
final Method writeMethod = propDesc.getWriteMethod();
if (writeMethod != null) {
@@ -735,14 +735,14 @@ public class _ObjectBuilderSettingEvaluator {
TemplateHashModel beanTM = null;
for (int i = 0; i < namedParamNames.size(); i++) {
- String name = (String) namedParamNames.get(i);
+ String name = namedParamNames.get(i);
if (!beanPropSetters.containsKey(name)) {
throw new _ObjectBuilderSettingEvaluationException(
"The " + cl.getName() + " class has no writeable JavaBeans property called "
+ _StringUtil.jQuote(name) + ".");
}
- Method beanPropSetter = (Method) beanPropSetters.put(name, null);
+ Method beanPropSetter = beanPropSetters.put(name, null);
if (beanPropSetter == null) {
throw new _ObjectBuilderSettingEvaluationException(
"JavaBeans property " + _StringUtil.jQuote(name) + " is set twice.");
@@ -757,19 +757,20 @@ public class _ObjectBuilderSettingEvaluator {
}
beanTM = (TemplateHashModel) wrappedObj;
}
-
+
TemplateModel m = beanTM.get(beanPropSetter.getName());
if (m == null) {
throw new _ObjectBuilderSettingEvaluationException(
"Can't find " + beanPropSetter + " as FreeMarker method.");
}
- if (!(m instanceof TemplateMethodModel)) {
+ if (!(m instanceof JavaMethodModel)) {
throw new _ObjectBuilderSettingEvaluationException(
- _StringUtil.jQuote(beanPropSetter.getName()) + " wasn't a TemplateMethodModel.");
+ _StringUtil.jQuote(beanPropSetter.getName()) + " wasn't a JavaMethodModel.");
}
List/*TemplateModel*/ args = new ArrayList();
- args.add(env.getObjectWrapper().wrap(namedParamValues.get(i)));
- ((TemplateMethodModel) m).execute(args);
+ ((JavaMethodModel) m).execute(
+ new TemplateModel[] { env.getObjectWrapper().wrap(namedParamValues.get(i)) },
+ NonTemplateCallPlace.INSTANCE);
} catch (Exception e) {
throw new _ObjectBuilderSettingEvaluationException(
"Failed to set " + _StringUtil.jQuote(name), e);
@@ -992,16 +993,16 @@ public class _ObjectBuilderSettingEvaluator {
}
} else {
DefaultObjectWrapper ow = env.getObjectWrapper();
- List/*<TemplateModel>*/ tmArgs = new ArrayList(positionalParamValues.size());
+ TemplateModel[] tmArgs = new TemplateModel[positionalParamValues.size()];
for (int i = 0; i < positionalParamValues.size(); i++) {
try {
- tmArgs.add(ow.wrap(positionalParamValues.get(i)));
+ tmArgs[i] = ow.wrap(positionalParamValues.get(i));
} catch (TemplateModelException e) {
throw new _ObjectBuilderSettingEvaluationException("Failed to wrap arg #" + (i + 1), e);
}
}
try {
- return ow.newInstance(cl, tmArgs);
+ return ow.newInstance(cl, tmArgs, NonTemplateCallPlace.INSTANCE);
} catch (Exception e) {
throw new _ObjectBuilderSettingEvaluationException(
"Failed to call " + cl.getName() + " constructor", e);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebugModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebugModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebugModel.java
index 1c6bc66..5f4c473 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebugModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebugModel.java
@@ -45,7 +45,7 @@ public interface DebugModel extends Remote {
public static final int TYPE_COLLECTION = 32;
public static final int TYPE_HASH = 64;
public static final int TYPE_HASH_EX = 128;
- public static final int TYPE_METHOD = 256;
+ public static final int TYPE_FUNCTION = 256;
public static final int TYPE_DIRECTIVE = 1024;
public static final int TYPE_ENVIRONMENT = 2048;
public static final int TYPE_TEMPLATE = 4096;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/debug/RmiDebugModelImpl.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/debug/RmiDebugModelImpl.java b/freemarker-core/src/main/java/org/apache/freemarker/core/debug/RmiDebugModelImpl.java
index 7ab7ec7..20e9f50 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/debug/RmiDebugModelImpl.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/debug/RmiDebugModelImpl.java
@@ -29,9 +29,9 @@ import org.apache.freemarker.core.model.TemplateBooleanModel;
import org.apache.freemarker.core.model.TemplateCollectionModel;
import org.apache.freemarker.core.model.TemplateDateModel;
import org.apache.freemarker.core.model.TemplateDirectiveModel;
+import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateHashModel;
import org.apache.freemarker.core.model.TemplateHashModelEx;
-import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateModelIterator;
@@ -155,7 +155,7 @@ class RmiDebugModelImpl extends UnicastRemoteObject implements DebugModel {
if (model instanceof TemplateCollectionModel) type += TYPE_COLLECTION;
if (model instanceof TemplateHashModelEx) type += TYPE_HASH_EX;
if (model instanceof TemplateHashModel) type += TYPE_HASH;
- if (model instanceof TemplateMethodModel) type += TYPE_METHOD;
+ if (model instanceof TemplateFunctionModel) type += TYPE_FUNCTION;
if (model instanceof TemplateDirectiveModel) type += TYPE_DIRECTIVE;
return type;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/ArgumentArrayLayout.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/ArgumentArrayLayout.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/ArgumentArrayLayout.java
index 4e1149c..e974570 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/ArgumentArrayLayout.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/ArgumentArrayLayout.java
@@ -25,6 +25,8 @@ import org.apache.freemarker.core.util.StringToIndexMap;
* {@link TemplateCallableModel} subinterfaces define a method called {@code execute}, which has an argument array
* parameter, whose layout this class describes. The layout specifies the (minimum) array length, what's the index
* of which parameters, and if there are varargs parameters, in which case they must not be left {@code null}.
+ * (Note that a {@link TemplateCallableModel} may have {@code null} layout; see the documentation of {@code execute}
+ * for more.)
* <p>
* Each parameter has a constant index in this array, which is the same for all invocations of the same
* {@link TemplateCallableModel} object (regardless if there are omitted optional parameters). Thus, the argument
@@ -87,6 +89,22 @@ public final class ArgumentArrayLayout {
null, false);
/**
+ * Constant to be used when the {@link TemplateCallableModel} has 2 positional parameter, and no others.
+ * (The argument array index of the positional parameters will be 0 and 1.)
+ */
+ public static final ArgumentArrayLayout TWO_POSITIONAL_PARAMETERS = new ArgumentArrayLayout(
+ 2, false,
+ null, false);
+
+ /**
+ * Constant to be used when the {@link TemplateCallableModel} has 3 positional parameter, and no others.
+ * (The argument array index of the positional parameters will be 0, 1, and 2.)
+ */
+ public static final ArgumentArrayLayout THREE_POSITIONAL_PARAMETERS = new ArgumentArrayLayout(
+ 3, false,
+ null, false);
+
+ /**
* Constant to be used when the {@link TemplateCallableModel} has 1 positional varargs parameter, and no others.
* (The argument array index of the positional varargs parameter will be 0.)
* */
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/GeneralPurposeNothing.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/GeneralPurposeNothing.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/GeneralPurposeNothing.java
index 92b0b58..b19b912 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/GeneralPurposeNothing.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/GeneralPurposeNothing.java
@@ -19,7 +19,9 @@
package org.apache.freemarker.core.model;
-import java.util.List;
+import org.apache.freemarker.core.CallPlace;
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.TemplateException;
/**
* Singleton object representing nothing, used by ?if_exists built-in.
@@ -28,7 +30,8 @@ import java.util.List;
*/
final class GeneralPurposeNothing
-implements TemplateBooleanModel, TemplateScalarModel, TemplateSequenceModel, TemplateHashModelEx, TemplateMethodModel {
+implements TemplateBooleanModel, TemplateScalarModel, TemplateSequenceModel, TemplateHashModelEx,
+ TemplateFunctionModel {
public static final TemplateModel INSTANCE = new GeneralPurposeNothing();
@@ -66,10 +69,17 @@ implements TemplateBooleanModel, TemplateScalarModel, TemplateSequenceModel, Tem
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) {
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env) throws TemplateException {
return null;
}
-
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.create(
+ 0, true,
+ null, true);
+ }
+
@Override
public TemplateCollectionModel keys() {
return Constants.EMPTY_COLLECTION;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCallableModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCallableModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCallableModel.java
index 6aa9445..caa612a 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCallableModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateCallableModel.java
@@ -20,14 +20,9 @@
package org.apache.freemarker.core.model;
/**
- * Super interface of {@link TemplateFunctionModel} and {@link TemplateDirectiveModel}; don' extended (or implement) it
- * yourself!
+ * Super interface (marker interface) of {@link TemplateFunctionModel} and {@link TemplateDirectiveModel}; don' extended
+ * (or implement) it yourself!
*/
public interface TemplateCallableModel extends TemplateModel {
-
- /**
- * Returns the argument array layout to use when calling the {@code execute} method.
- */
- ArgumentArrayLayout getArgumentArrayLayout();
-
+ //
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
index 95678d6..be06cba 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateDirectiveModel.java
@@ -5,7 +5,9 @@ import java.io.Writer;
import org.apache.freemarker.core.CallPlace;
import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.NonTemplateCallPlace;
import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.impl.JavaMethodModel;
/**
* A {@link TemplateCallableModel} that progressively writes it result into the {@code out} object, instead of
@@ -26,25 +28,29 @@ public interface TemplateDirectiveModel extends TemplateCallableModel {
* Invokes the directive.
*
* @param args
- * The of argument values. Not {@code null}. If a parameter was omitted on the caller side, the
- * corresponding array element will be {@code null}. The length of the array and the indexes
- * correspont to the {@link ArgumentArrayLayout} returned by {@link #getArgumentArrayLayout()}.
- * If the caller doesn't keep argument layout rules (such as the array is shorter than
- * {@link ArgumentArrayLayout#getTotalLength()}, or the type of the values at
- * {@link ArgumentArrayLayout#getPositionalVarargsArgumentIndex()} or at
- * {@link ArgumentArrayLayout#getNamedVarargsArgumentIndex()} is improper), this method may
- * throws {@link IndexOutOfBoundsException} or {@link ClassCastException}. Thus, user Java code
- * that wishes to call {@link TemplateCallableModel}-s is responsible to ensure that the argument array
- * follows the layout described be {@link ArgumentArrayLayout}, as the {@code execute} method
- * isn't meant to do validations on that level.
+ * The array of argument values. Not {@code null}. If a parameter was omitted on the caller side, the
+ * corresponding array element will be {@code null}. The length of the array and the indexes correspond to
+ * the {@link ArgumentArrayLayout} returned by {@link #getDirectiveArgumentArrayLayout()}. {@link
+ * ArgumentArrayLayout} os not {@code null}m and the caller doesn't keep argument layout rules (such as the
+ * array is shorter than {@link ArgumentArrayLayout#getTotalLength()}, or the type of the values at {@link
+ * ArgumentArrayLayout#getPositionalVarargsArgumentIndex()} or at
+ * {@link ArgumentArrayLayout#getNamedVarargsArgumentIndex()}
+ * is improper), this method may throws {@link IndexOutOfBoundsException} or {@link ClassCastException}.
+ * Thus, user Java code that wishes to call {@link TemplateCallableModel}-s is responsible to ensure that
+ * the argument array follows the layout described be {@link ArgumentArrayLayout}, as the {@code execute}
+ * method isn't meant to do validations on that level.
* @param callPlace
- * The place (in a template, normally) where this directive was called from. Not {@code null}. Note that
- * {@link CallPlace#executeNestedContent(TemplateModel[], Writer, Environment)} can be used to execute the
- * nested content.
+ * The place (in a template, normally) where this directive was called from. Not {@code null}; in case the
+ * call is not from a template, you can use {@link NonTemplateCallPlace#INSTANCE} (or another {@link
+ * NonTemplateCallPlace} instance). Note that {@link CallPlace#executeNestedContent(TemplateModel[], Writer,
+ * Environment)} can be used to execute the nested content (even if there's no nested content; then simply
+ * nothing happens).
* @param out
* Print the output here (if there's any)
* @param env
- * The current processing environment. Not {@code null}.
+ * The current processing environment. Not {@code null} in general, though certain implementations may
+ * specifically allow that, typically, implementations that are just adapters towards FreeMarker-unaware
+ * callables (for example, {@link JavaMethodModel} is like that).
*
* @throws TemplateException
* If any problem occurs that's not an {@link IOException} during writing the template output.
@@ -67,4 +73,13 @@ public interface TemplateDirectiveModel extends TemplateCallableModel {
*/
boolean isNestedContentSupported();
+ /**
+ * Returns the argument array layout to use when calling the {@code {@link #execute(TemplateModel[], CallPlace,
+ * Writer, Environment)}} method, or rarely {@code null}. If it's {@code null} then there can only be positional
+ * arguments, any number of them (though of course the {@code execute} method implementation itself may restricts
+ * the acceptable argument count), and the argument array will be simply as long as the number of arguments
+ * specified at the call place.
+ */
+ ArgumentArrayLayout getDirectiveArgumentArrayLayout();
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateFunctionModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateFunctionModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateFunctionModel.java
index 6b42550..70824ec 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateFunctionModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateFunctionModel.java
@@ -5,6 +5,7 @@ import java.io.Writer;
import org.apache.freemarker.core.CallPlace;
import org.apache.freemarker.core.Environment;
import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.impl.JavaMethodModel;
/**
* A {@link TemplateCallableModel}, which returns its result as a {@link TemplateModel} at the end of its execution.
@@ -35,4 +36,13 @@ public interface TemplateFunctionModel extends TemplateCallableModel {
*/
TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env) throws TemplateException;
+ /**
+ * Returns the argument array layout to use when calling the {@code {@link #execute(TemplateModel[], CallPlace,
+ * Environment)}} method, or rarely {@code null}. If it's {@code null} then there can only be positional
+ * arguments, any number of them (though of course the {@code execute} method implementation itself may restricts
+ * the acceptable argument count), and the argument array will be simply as long as the number of arguments
+ * specified at the call place. This layoutless mode is for example used by {@link JavaMethodModel}-s.
+ */
+ ArgumentArrayLayout getFunctionArgumentArrayLayout();
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModel.java
deleted file mode 100644
index c35a500..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModel.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.freemarker.core.model;
-
-import java.util.List;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core.util.DeepUnwrap;
-
-/**
- * "method" template language data type: Objects that act like functions. Their main application is calling
- * Java methods via {@link org.apache.freemarker.core.model.impl.DefaultObjectWrapper}, but you can implement this
- * interface to invoke top-level functions too.
- *
- * <p>In templates they are used like {@code myMethod(1, "foo")} or {@code myJavaObject.myJavaMethod(1, "foo")}.
- */
-public interface TemplateMethodModel extends TemplateModel {
-
- /**
- * Executes the method call.
- *
- * @param args a {@link List} of {@link TemplateModel}-s,
- * containing the arguments passed to the method. If the implementation absolutely wants
- * to operate on POJOs, it can use the static utility methods in the {@link DeepUnwrap}
- * class to easily obtain them. However, unwrapping is not always possible (or not perfectly), and isn't always
- * efficient, so it's recommended to use the original {@link TemplateModel} value as much as possible.
- *
- * @return the return value of the method, or {@code null}. If the returned value
- * does not implement {@link TemplateModel}, it will be automatically
- * wrapped using the {@link Environment#getObjectWrapper() environment's
- * object wrapper}.
- */
- TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException;
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelException.java
index d38faa4..c9d6aa9 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelException.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateModelException.java
@@ -24,7 +24,9 @@ import org.apache.freemarker.core.TemplateException;
import org.apache.freemarker.core._ErrorDescriptionBuilder;
/**
- * {@link TemplateModel} methods throw this exception if the requested data can't be retrieved.
+ * {@link ObjectWrapper}-s may throw this when wrapping/unwrapping fails, or {@link TemplateModel} methods throw this
+ * if the requested data can't be retrieved. {@link TemplateCallableModel}-s should typically throw
+ * {@link TemplateException} instead (like when a required argument is missing).
*/
public class TemplateModelException extends TemplateException {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java
index bc7ce67..33d5e86 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java
@@ -37,8 +37,8 @@ import org.apache.freemarker.core._DelayedJQuote;
import org.apache.freemarker.core._TemplateModelException;
import org.apache.freemarker.core.model.AdapterTemplateModel;
import org.apache.freemarker.core.model.TemplateCollectionModel;
+import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateHashModelEx;
-import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateModelIterator;
@@ -104,12 +104,11 @@ public class BeanModel
}
/**
- * Uses Beans introspection to locate a property or method with name
- * matching the key name. If a method or property is found, it's wrapped
- * into {@link TemplateMethodModel} (for a method or
- * indexed property), or evaluated on-the-fly and the return value wrapped
- * into appropriate model (for a simple property) Models for various
- * properties and methods are cached on a per-class basis, so the costly
+ * Uses Beans introspection to locate a JavaBean property or method with name
+ * matching the key name. If a method is found, it's wrapped
+ * into {@link TemplateFunctionModel} (a {@link JavaMethodModel} more specifically).
+ * If a JavaBean property is found, its value is returned. Introspection results
+ * for various properties and methods are cached on a per-class basis, so the costly
* introspection is performed only once per property or method of a class.
* (Side-note: this also implies that any class whose method has been called
* will be strongly referred to by the framework and will not become
@@ -212,10 +211,10 @@ public class BeanModel
// cachedModel remains null, as we don't cache these
} else if (desc instanceof Method) {
Method method = (Method) desc;
- resultModel = cachedModel = new JavaMethodModel(
+ resultModel = cachedModel = new SimpleJavaMethodModel(
object, method, ClassIntrospector.getArgTypes(classInfo, method), wrapper);
} else if (desc instanceof OverloadedMethods) {
- resultModel = cachedModel = new OverloadedMethodsModel(
+ resultModel = cachedModel = new OverloadedJavaMethodModel(
object, (OverloadedMethods) desc, wrapper);
}