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:27 UTC
[1/8] incubator-freemarker git commit: FREEMARKER-64: TemplateModel
and TemplateModelEx changes (but they will be probably replaced by
TemplateFunctionModel later): Removed FM2 `TemplateMethodModel`,
then renamed `TemplateMethodModelEx` to `TemplateMetho
Repository: incubator-freemarker
Updated Branches:
refs/heads/3 a3311d52e -> b867458aa
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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 e8cd15c..ce3ff56 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
@@ -27,7 +27,6 @@ import java.util.regex.Pattern;
import org.apache.freemarker.core.model.TemplateBooleanModel;
import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateScalarModel;
@@ -70,7 +69,7 @@ class BuiltInsForStringsBasic {
static class containsBI extends ASTExpBuiltIn {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private final String s;
@@ -79,9 +78,9 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1);
- return s.indexOf(getStringMethodArg(args, 0)) != -1
+ return s.contains(getStringMethodArg(args, 0))
? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
}
@@ -95,7 +94,7 @@ class BuiltInsForStringsBasic {
static class ends_withBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private String s;
private BIMethod(String s) {
@@ -103,7 +102,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1);
return s.endsWith(getStringMethodArg(args, 0)) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
@@ -118,7 +117,7 @@ class BuiltInsForStringsBasic {
static class ensure_ends_withBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private String s;
private BIMethod(String s) {
@@ -126,7 +125,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1);
String suffix = getStringMethodArg(args, 0);
return new SimpleScalar(s.endsWith(suffix) ? s : s + suffix);
@@ -141,7 +140,7 @@ class BuiltInsForStringsBasic {
static class ensure_starts_withBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private String s;
private BIMethod(String s) {
@@ -149,7 +148,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1, 3);
final String checkedPrefix = getStringMethodArg(args, 0);
@@ -190,7 +189,7 @@ class BuiltInsForStringsBasic {
static class index_ofBI extends ASTExpBuiltIn {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private final String s;
@@ -199,7 +198,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 1, 2);
String subStr = getStringMethodArg(args, 0);
@@ -226,7 +225,7 @@ class BuiltInsForStringsBasic {
}
static class keep_afterBI extends BuiltInForString {
- class KeepAfterMethod implements TemplateMethodModelEx {
+ class KeepAfterMethod implements TemplateMethodModel {
private String s;
KeepAfterMethod(String s) {
@@ -234,7 +233,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 1, 2);
String separatorString = getStringMethodArg(args, 0);
@@ -272,7 +271,7 @@ class BuiltInsForStringsBasic {
}
static class keep_after_lastBI extends BuiltInForString {
- class KeepAfterMethod implements TemplateMethodModelEx {
+ class KeepAfterMethod implements TemplateMethodModel {
private String s;
KeepAfterMethod(String s) {
@@ -280,7 +279,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 1, 2);
String separatorString = getStringMethodArg(args, 0);
@@ -325,7 +324,7 @@ class BuiltInsForStringsBasic {
}
static class keep_beforeBI extends BuiltInForString {
- class KeepUntilMethod implements TemplateMethodModelEx {
+ class KeepUntilMethod implements TemplateMethodModel {
private String s;
KeepUntilMethod(String s) {
@@ -333,7 +332,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 1, 2);
String separatorString = getStringMethodArg(args, 0);
@@ -369,7 +368,7 @@ class BuiltInsForStringsBasic {
// TODO
static class keep_before_lastBI extends BuiltInForString {
- class KeepUntilMethod implements TemplateMethodModelEx {
+ class KeepUntilMethod implements TemplateMethodModel {
private String s;
KeepUntilMethod(String s) {
@@ -377,7 +376,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 1, 2);
String separatorString = getStringMethodArg(args, 0);
@@ -436,7 +435,7 @@ class BuiltInsForStringsBasic {
static class padBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private final String s;
@@ -445,7 +444,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 1, 2);
@@ -487,7 +486,7 @@ class BuiltInsForStringsBasic {
static class remove_beginningBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private String s;
private BIMethod(String s) {
@@ -495,7 +494,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1);
String prefix = getStringMethodArg(args, 0);
return new SimpleScalar(s.startsWith(prefix) ? s.substring(prefix.length()) : s);
@@ -510,7 +509,7 @@ class BuiltInsForStringsBasic {
static class remove_endingBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private String s;
private BIMethod(String s) {
@@ -518,7 +517,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1);
String suffix = getStringMethodArg(args, 0);
return new SimpleScalar(s.endsWith(suffix) ? s.substring(0, s.length() - suffix.length()) : s);
@@ -540,12 +539,14 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 1, 2);
- String splitString = (String) args.get(0);
- long flags = argCnt > 1 ? RegexpHelper.parseFlagString((String) args.get(1)) : 0;
- String[] result = null;
+ String splitString = _CallableUtils.castArgToString(args, 0);
+ long flags = argCnt > 1
+ ? RegexpHelper.parseFlagString(_CallableUtils.castArgToString(args, 1))
+ : 0;
+ String[] result;
if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
RegexpHelper.checkNonRegexpFlags("split", flags);
result = _StringUtil.split(s, splitString,
@@ -567,7 +568,7 @@ class BuiltInsForStringsBasic {
static class starts_withBI extends BuiltInForString {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private String s;
private BIMethod(String s) {
@@ -575,7 +576,7 @@ class BuiltInsForStringsBasic {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1);
return s.startsWith(getStringMethodArg(args, 0)) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
@@ -592,10 +593,10 @@ class BuiltInsForStringsBasic {
@Override
TemplateModel calculateResult(final String s, final Environment env) throws TemplateException {
- return new TemplateMethodModelEx() {
+ return new TemplateMethodModel() {
@Override
- public Object exec(java.util.List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
int argCount = args.size();
checkMethodArgCount(argCount, 1, 2);
@@ -618,9 +619,9 @@ class BuiltInsForStringsBasic {
}
if (beginIdx > endIdx) {
throw MessageUtil.newMethodArgsInvalidValueException("?" + key,
- "The begin index argument, ", Integer.valueOf(beginIdx),
+ "The begin index argument, ", beginIdx,
", shouldn't be greater than the end index argument, ",
- Integer.valueOf(endIdx), ".");
+ endIdx, ".");
}
return new SimpleScalar(s.substring(beginIdx, endIdx));
} else {
@@ -633,15 +634,14 @@ class BuiltInsForStringsBasic {
return MessageUtil.newMethodArgInvalidValueException(
"?" + key, argIdx,
"The index mustn't be greater than the length of the string, ",
- Integer.valueOf(len),
- ", but it was ", Integer.valueOf(idx), ".");
+ len, ", but it was ", idx, ".");
}
private TemplateModelException newIndexLessThan0Exception(
int argIdx, int idx) throws TemplateModelException {
return MessageUtil.newMethodArgInvalidValueException(
"?" + key, argIdx,
- "The index must be at least 0, but was ", Integer.valueOf(idx), ".");
+ "The index must be at least 0, but was ", idx, ".");
}
};
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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 bfb44c6..cee1b49 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
@@ -148,11 +148,11 @@ class BuiltInsForStringsEncoding {
protected abstract String encodeWithCharset(Charset charset) throws UnsupportedEncodingException;
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
parent.checkMethodArgCount(args.size(), 1);
try {
- String charsetName = (String) args.get(0);
- Charset charset = null;
+ String charsetName = _CallableUtils.castArgToString(args,0);
+ Charset charset;
try {
charset = Charset.forName(charsetName);
} catch (UnsupportedCharsetException e) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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 2d50556..6bf7e2a 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
@@ -28,7 +28,7 @@ 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.TemplateMethodModelEx;
+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.TemplateScalarModel;
@@ -72,7 +72,7 @@ class BuiltInsForStringsMisc {
TemplateModel calculateResult(String s, Environment env) throws TemplateException {
Template parentTemplate = getTemplate();
- ASTExpression exp = null;
+ ASTExpression exp;
try {
try {
ParsingConfiguration pCfg = parentTemplate.getParsingConfiguration();
@@ -151,9 +151,11 @@ class BuiltInsForStringsMisc {
ASTExpression sourceExpr = null;
String id = "anonymous_interpreted";
if (model instanceof TemplateSequenceModel) {
- sourceExpr = ((ASTExpression) new ASTExpDynamicKeyName(target, new ASTExpNumberLiteral(Integer.valueOf(0))).copyLocationFrom(target));
+ sourceExpr = ((ASTExpression) new ASTExpDynamicKeyName(target, new ASTExpNumberLiteral(0))
+ .copyLocationFrom(target));
if (((TemplateSequenceModel) model).size() > 1) {
- id = ((ASTExpression) new ASTExpDynamicKeyName(target, new ASTExpNumberLiteral(Integer.valueOf(1))).copyLocationFrom(target)).evalAndCoerceToPlainText(env);
+ id = ((ASTExpression) new ASTExpDynamicKeyName(target, new ASTExpNumberLiteral(1))
+ .copyLocationFrom(target)).evalAndCoerceToPlainText(env);
}
} else if (model instanceof TemplateScalarModel) {
sourceExpr = target;
@@ -252,12 +254,12 @@ class BuiltInsForStringsMisc {
return new ConstructorFunction(target.evalAndCoerceToPlainText(env), env, target.getTemplate());
}
- class ConstructorFunction implements TemplateMethodModelEx {
+ class ConstructorFunction implements TemplateMethodModel {
private final Class<?> cl;
private final Environment env;
- public ConstructorFunction(String classname, Environment env, Template template) throws TemplateException {
+ ConstructorFunction(String classname, Environment env, Template template) throws TemplateException {
this.env = env;
cl = env.getNewBuiltinClassResolver().resolve(classname, env, template);
if (!TemplateModel.class.isAssignableFrom(cl)) {
@@ -271,13 +273,13 @@ class BuiltInsForStringsMisc {
}
@Override
- public Object exec(List arguments) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
ObjectWrapper ow = env.getObjectWrapper();
if (ow instanceof DefaultObjectWrapper) {
- return ((DefaultObjectWrapper) ow).newInstance(cl, arguments);
+ return ow.wrap(((DefaultObjectWrapper) ow).newInstance(cl, args));
}
- if (!arguments.isEmpty()) {
+ if (!args.isEmpty()) {
throw new TemplateModelException(
"className?new(args) only supports 0 arguments in the current configuration, because "
+ " the objectWrapper setting value is not a "
@@ -285,7 +287,7 @@ class BuiltInsForStringsMisc {
" (or its subclass).");
}
try {
- return cl.newInstance();
+ return ow.wrap(cl.newInstance());
} catch (Exception e) {
throw new TemplateModelException("Failed to instantiate "
+ cl.getName() + " with its parameterless constructor; see cause exception", e);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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 0420d64..025b599 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
@@ -70,12 +70,14 @@ class BuiltInsForStringsRegexp {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 1, 2);
- String patternString = (String) args.get(0);
- long flags = argCnt > 1 ? RegexpHelper.parseFlagString((String) args.get(1)) : 0;
+ String patternString = _CallableUtils.castArgToString(args, 0);
+ long flags = argCnt > 1
+ ? RegexpHelper.parseFlagString(_CallableUtils.castArgToString(args, 1))
+ : 0;
if ((flags & RegexpHelper.RE_FLAG_FIRST_ONLY) != 0) {
RegexpHelper.logFlagWarning("?" + key + " doesn't support the \"f\" flag.");
}
@@ -101,12 +103,14 @@ class BuiltInsForStringsRegexp {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 2, 3);
- String arg1 = (String) args.get(0);
- String arg2 = (String) args.get(1);
- long flags = argCnt > 2 ? RegexpHelper.parseFlagString((String) args.get(2)) : 0;
+ String arg1 = _CallableUtils.castArgToString(args, 0);
+ String arg2 = _CallableUtils.castArgToString(args, 1);
+ long flags = argCnt > 2
+ ? RegexpHelper.parseFlagString(_CallableUtils.castArgToString(args, 2))
+ : 0;
String result;
if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) {
RegexpHelper.checkNonRegexpFlags("replace", flags);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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 25ea39d..ee212db 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
@@ -581,7 +581,7 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
try {
TemplateDirectiveModel nodeProcessor = getNodeProcessor(node);
if (nodeProcessor != null) {
- _TemplateCallableModelUtils.executeWith0Arguments(
+ _CallableUtils.executeWith0Arguments(
nodeProcessor, NonTemplateCallPlace.INSTANCE, out, this);
} else if (nodeProcessor == null) {
String nodeType = node.getNodeType();
@@ -640,7 +640,7 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
void fallback() throws TemplateException, IOException {
TemplateDirectiveModel nodeProcessor = getNodeProcessor(currentNodeName, currentNodeNS, nodeNamespaceIndex);
if (nodeProcessor != null) {
- _TemplateCallableModelUtils.executeWith0Arguments(
+ _CallableUtils.executeWith0Arguments(
nodeProcessor, NonTemplateCallPlace.INSTANCE, out, this);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringException.java
index c8cbc6d..6cf29f4 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringException.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringException.java
@@ -19,6 +19,8 @@
package org.apache.freemarker.core;
+import java.io.Serializable;
+
import org.apache.freemarker.core.model.TemplateBooleanModel;
import org.apache.freemarker.core.model.TemplateDateModel;
import org.apache.freemarker.core.model.TemplateModel;
@@ -37,7 +39,9 @@ public class NonStringException extends UnexpectedTypeException {
static final Class[] STRING_COERCABLE_TYPES = new Class[] {
TemplateScalarModel.class, TemplateNumberModel.class, TemplateDateModel.class, TemplateBooleanModel.class
};
-
+
+ private static final Class<?>[] EXPECTED_TYPES = { TemplateScalarModel.class };
+
private static final String DEFAULT_DESCRIPTION
= "Expecting " + NonStringException.STRING_COERCABLE_TYPES_DESC + " value here";
@@ -70,5 +74,11 @@ public class NonStringException extends UnexpectedTypeException {
ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
super(blamed, model, NonStringException.STRING_COERCABLE_TYPES_DESC, STRING_COERCABLE_TYPES, tips, env);
}
-
+
+ NonStringException(
+ Serializable argumentNameOrIndex, TemplateModel model, String[] tips, Environment env)
+ throws InvalidReferenceException {
+ super(argumentNameOrIndex, model, "string", EXPECTED_TYPES, tips, env);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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
new file mode 100644
index 0000000..0a69e51
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_CallableUtils.java
@@ -0,0 +1,156 @@
+/*
+ * 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 java.io.IOException;
+import java.io.Serializable;
+import java.io.Writer;
+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;
+import org.apache.freemarker.core.model.TemplateNumberModel;
+import org.apache.freemarker.core.model.TemplateScalarModel;
+
+/**
+ * For internal use only; don't depend on this, there's no backward compatibility guarantee at all!
+ */
+// TODO [FM3] Most functionality here should be made public on some way. Also BuiltIn-s has some duplicates utiltity
+// methods for this functionality (checking arguments). Need to clean this up.
+public final class _CallableUtils {
+
+ private _CallableUtils() {
+ //
+ }
+
+ public static void executeWith0Arguments(
+ TemplateDirectiveModel directive, CallPlace callPlace, Writer out, Environment env)
+ throws IOException, TemplateException {
+ directive.execute(getArgumentArrayWithNoArguments(directive), callPlace, out, env);
+ }
+
+ public static TemplateModel executeWith0Arguments(
+ TemplateFunctionModel function, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ return function.execute(getArgumentArrayWithNoArguments(function), callPlace, env);
+ }
+
+ private static TemplateModel[] getArgumentArrayWithNoArguments(TemplateCallableModel callable) {
+ ArgumentArrayLayout argsLayout = callable.getArgumentArrayLayout();
+ int totalLength = argsLayout.getTotalLength();
+ if (totalLength == 0) {
+ return Constants.EMPTY_TEMPLATE_MODEL_ARRAY;
+ } else {
+ TemplateModel[] args = new TemplateModel[totalLength];
+
+ int positionalVarargsArgumentIndex = argsLayout.getPositionalVarargsArgumentIndex();
+ if (positionalVarargsArgumentIndex != -1) {
+ args[positionalVarargsArgumentIndex] = Constants.EMPTY_SEQUENCE;
+ }
+
+ int namedVarargsArgumentIndex = argsLayout.getNamedVarargsArgumentIndex();
+ if (namedVarargsArgumentIndex != -1) {
+ args[namedVarargsArgumentIndex] = Constants.EMPTY_SEQUENCE;
+ }
+
+ return args;
+ }
+ }
+
+ public static Number castArgToNumber(TemplateModel[] args, int argIndex, boolean allowNull)
+ throws TemplateException {
+ return castArgToNumber(args[argIndex], argIndex, allowNull);
+ }
+
+ public static Number castArgToNumber(TemplateModel argValue, int argIndex, boolean allowNull)
+ throws TemplateException {
+ return castArgToNumber(argValue, null, argIndex, allowNull);
+ }
+
+ public static Number castArgToNumber(TemplateModel argValue, String argName, boolean allowNull)
+ throws TemplateException {
+ return castArgToNumber(argValue, argName, -1, allowNull);
+ }
+
+ private static Number castArgToNumber(TemplateModel argValue, String argName, int argIndex, boolean allowNull)
+ throws TemplateException {
+ if (argValue instanceof TemplateNumberModel) {
+ return ((TemplateNumberModel) argValue).getAsNumber();
+ }
+ if (argValue == null) {
+ if (allowNull) {
+ return null;
+ }
+ throw new _MiscTemplateException(
+ "The ", argName != null ? new _DelayedJQuote(argName) : new _DelayedOrdinal(argIndex + 1),
+ " argument can't be null.");
+ }
+ throw new NonNumericalException((Serializable) argName != null ? argName : argIndex, argValue, null, null);
+ }
+
+ //
+
+ public static String castArgToString(List<? extends TemplateModel> args, int argIndex) throws TemplateException {
+ return castArgToString(args, argIndex, false);
+ }
+
+ public static String castArgToString(List<? extends TemplateModel> args, int argIndex, boolean allowNull) throws
+ TemplateException {
+ return castArgToString(args.get(argIndex), argIndex, allowNull);
+ }
+
+ public static String castArgToString(TemplateModel[] args, int argIndex, boolean allowNull) throws TemplateException {
+ return castArgToString(args[argIndex], argIndex, allowNull);
+ }
+
+ 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, String argName, boolean allowNull) throws TemplateException {
+ return castArgToString(argValue, argName, -1, allowNull);
+ }
+
+ private static String castArgToString(
+ TemplateModel argValue, String argName, int argIndex,
+ boolean allowNull) throws TemplateException {
+ if (argValue instanceof TemplateScalarModel) {
+ return _EvalUtil.modelToString((TemplateScalarModel) argValue, null, null);
+ }
+ if (argValue == null) {
+ if (allowNull) {
+ return null;
+ }
+ throw new _MiscTemplateException(
+ "The ", argName != null ? new _DelayedJQuote(argName) : new _DelayedOrdinal(argIndex + 1),
+ " argument can't be null.");
+ }
+ throw new NonStringException((Serializable) argName != null ? argName : argIndex, argValue, null, null);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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 3ff249a..d2fe617 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,7 +36,7 @@ import java.util.Map;
import java.util.Properties;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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;
@@ -763,13 +763,13 @@ public class _ObjectBuilderSettingEvaluator {
throw new _ObjectBuilderSettingEvaluationException(
"Can't find " + beanPropSetter + " as FreeMarker method.");
}
- if (!(m instanceof TemplateMethodModelEx)) {
+ if (!(m instanceof TemplateMethodModel)) {
throw new _ObjectBuilderSettingEvaluationException(
- _StringUtil.jQuote(beanPropSetter.getName()) + " wasn't a TemplateMethodModelEx.");
+ _StringUtil.jQuote(beanPropSetter.getName()) + " wasn't a TemplateMethodModel.");
}
List/*TemplateModel*/ args = new ArrayList();
args.add(env.getObjectWrapper().wrap(namedParamValues.get(i)));
- ((TemplateMethodModelEx) m).exec(args);
+ ((TemplateMethodModel) m).execute(args);
} catch (Exception e) {
throw new _ObjectBuilderSettingEvaluationException(
"Failed to set " + _StringUtil.jQuote(name), e);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/_TemplateCallableModelUtils.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_TemplateCallableModelUtils.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_TemplateCallableModelUtils.java
deleted file mode 100644
index 277dc1a..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/_TemplateCallableModelUtils.java
+++ /dev/null
@@ -1,112 +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 java.io.IOException;
-import java.io.Writer;
-
-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;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-
-/**
- * For internal use only; don't depend on this, there's no backward compatibility guarantee at all!
- */
-// TODO [FM3] Most functionality here should be made public on some way
-public final class _TemplateCallableModelUtils {
-
- private _TemplateCallableModelUtils() {
- //
- }
-
- public static void executeWith0Arguments(
- TemplateDirectiveModel directive, CallPlace callPlace, Writer out, Environment env)
- throws IOException, TemplateException {
- directive.execute(getArgumentArrayWithNoArguments(directive), callPlace, out, env);
- }
-
- public static TemplateModel executeWith0Arguments(
- TemplateFunctionModel function, CallPlace callPlace, Environment env)
- throws TemplateException {
- return function.execute(getArgumentArrayWithNoArguments(function), callPlace, env);
- }
-
- private static TemplateModel[] getArgumentArrayWithNoArguments(TemplateCallableModel callable) {
- ArgumentArrayLayout argsLayout = callable.getArgumentArrayLayout();
- int totalLength = argsLayout.getTotalLength();
- if (totalLength == 0) {
- return Constants.EMPTY_TEMPLATE_MODEL_ARRAY;
- } else {
- TemplateModel[] args = new TemplateModel[totalLength];
-
- int positionalVarargsArgumentIndex = argsLayout.getPositionalVarargsArgumentIndex();
- if (positionalVarargsArgumentIndex != -1) {
- args[positionalVarargsArgumentIndex] = Constants.EMPTY_SEQUENCE;
- }
-
- int namedVarargsArgumentIndex = argsLayout.getNamedVarargsArgumentIndex();
- if (namedVarargsArgumentIndex != -1) {
- args[namedVarargsArgumentIndex] = Constants.EMPTY_SEQUENCE;
- }
-
- return args;
- }
- }
-
- public static TemplateNumberModel castArgumentToNumber(TemplateModel[] args, int argIndex, boolean allowNull,
- Environment env) throws TemplateException {
- return getTemplateNumberModel(args[argIndex], argIndex, allowNull, env);
- }
-
- private static TemplateNumberModel getTemplateNumberModel(TemplateModel argValue, int argIndex, boolean allowNull,
- Environment env) throws TemplateException {
- if (argValue instanceof TemplateNumberModel) {
- return (TemplateNumberModel) argValue;
- }
- if (argValue == null) {
- if (allowNull) {
- return null;
- }
- throw new _MiscTemplateException(env,
- "The ", new _DelayedOrdinal(argIndex + 1), " argument can't be null.");
- }
- throw new NonNumericalException(argIndex, argValue, null, env);
- }
-
- public static TemplateNumberModel castArgumentToNumber(TemplateModel argValue, String argName, boolean allowNull,
- Environment env) throws TemplateException {
- if (argValue instanceof TemplateNumberModel) {
- return (TemplateNumberModel) argValue;
- }
- if (argValue == null) {
- if (allowNull) {
- return null;
- }
- throw new _MiscTemplateException(env,
- "The ", new _DelayedJQuote(argName), " argument can't be null.");
- }
- throw new NonNumericalException(argName, argValue, null, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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 0158bd9..1c6bc66 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
@@ -46,7 +46,6 @@ public interface DebugModel extends Remote {
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_METHOD_EX = 512;
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/1333a715/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 e8e8cf1..7ab7ec7 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
@@ -32,7 +32,6 @@ import org.apache.freemarker.core.model.TemplateDirectiveModel;
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.TemplateMethodModelEx;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateModelIterator;
@@ -155,9 +154,8 @@ class RmiDebugModelImpl extends UnicastRemoteObject implements DebugModel {
if (model instanceof TemplateSequenceModel) type += TYPE_SEQUENCE;
if (model instanceof TemplateCollectionModel) type += TYPE_COLLECTION;
if (model instanceof TemplateHashModelEx) type += TYPE_HASH_EX;
- else if (model instanceof TemplateHashModel) type += TYPE_HASH;
- if (model instanceof TemplateMethodModelEx) type += TYPE_METHOD_EX;
- else if (model instanceof TemplateMethodModel) type += TYPE_METHOD;
+ if (model instanceof TemplateHashModel) type += TYPE_HASH;
+ if (model instanceof TemplateMethodModel) type += TYPE_METHOD;
if (model instanceof TemplateDirectiveModel) type += TYPE_DIRECTIVE;
return type;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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 da1c102..92b0b58 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
@@ -28,7 +28,7 @@ import java.util.List;
*/
final class GeneralPurposeNothing
-implements TemplateBooleanModel, TemplateScalarModel, TemplateSequenceModel, TemplateHashModelEx, TemplateMethodModelEx {
+implements TemplateBooleanModel, TemplateScalarModel, TemplateSequenceModel, TemplateHashModelEx, TemplateMethodModel {
public static final TemplateModel INSTANCE = new GeneralPurposeNothing();
@@ -66,7 +66,7 @@ implements TemplateBooleanModel, TemplateScalarModel, TemplateSequenceModel, Tem
}
@Override
- public Object exec(List args) {
+ public TemplateModel execute(List<? extends TemplateModel> args) {
return null;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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
index 5bfe7e3..c35a500 100644
--- 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
@@ -17,44 +17,37 @@
* under the License.
*/
-/*
- * 22 October 1999: This class added by Holger Arendt.
- */
-
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. The name comes from that their original
- * application was calling Java methods via {@link org.apache.freemarker.core.model.impl.DefaultObjectWrapper}.
- *
- * <p>In templates they are used like {@code myMethod("foo", "bar")} or {@code myJavaObject.myJavaMethod("foo", "bar")}.
+ * "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.
*
- * @deprecated Use {@link TemplateMethodModelEx} instead. This interface is from the old times when the only kind of
- * value you could pass in was string.
+ * <p>In templates they are used like {@code myMethod(1, "foo")} or {@code myJavaObject.myJavaMethod(1, "foo")}.
*/
-@Deprecated
public interface TemplateMethodModel extends TemplateModel {
/**
- * Executes the method call. All arguments passed to the method call are
- * coerced to strings before being passed, if the FreeMarker rules allow
- * the coercion. If some of the passed arguments can not be coerced to a
- * string, an exception will be raised in the engine and the method will
- * not be called. If your method would like to act on actual data model
- * objects instead of on their string representations, implement the
- * {@link TemplateMethodModelEx} instead.
- *
- * @param arguments a <tt>List</tt> of <tt>String</tt> objects
- * containing the values of the arguments passed to the method.
+ * 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
+ * wrapped using the {@link Environment#getObjectWrapper() environment's
* object wrapper}.
*/
- Object exec(List arguments) throws TemplateModelException;
-}
+ 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/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModelEx.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModelEx.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModelEx.java
deleted file mode 100644
index 2517d22..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/TemplateMethodModelEx.java
+++ /dev/null
@@ -1,54 +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.util.DeepUnwrap;
-
-/**
- * "extended 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. They are "extended" compared to the deprecated {@link TemplateMethodModel}, which could only
- * accept string parameters.
- *
- * <p>In templates they are used like {@code myMethod(1, "foo")} or {@code myJavaObject.myJavaMethod(1, "foo")}.
- */
-public interface TemplateMethodModelEx extends TemplateMethodModel {
-
- /**
- * Executes the method call.
- *
- * @param arguments 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}.
- */
- @Override
- Object exec(List arguments) throws TemplateModelException;
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/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 aa2f2f1..bc7ce67 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
@@ -38,6 +38,7 @@ 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.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;
@@ -105,7 +106,7 @@ 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 org.apache.freemarker.core.model.TemplateMethodModelEx} (for a method or
+ * 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
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java
index e4436e9..1a0e251 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java
@@ -56,7 +56,7 @@ 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.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelAdapter;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -481,7 +481,7 @@ public class DefaultObjectWrapper implements RichObjectWrapper {
* Wraps a Java method so that it can be called from templates, without wrapping its parent ("this") object. The
* result is almost the same as that you would get by wrapping the parent object then getting the method from the
* resulting {@link TemplateHashModel} by name. Except, if the wrapped method is overloaded, with this method you
- * explicitly select a an overload, while otherwise you would get a {@link TemplateMethodModelEx} that selects an
+ * explicitly select a an overload, while otherwise you would get a {@link TemplateMethodModel} that selects an
* overload each time it's called based on the argument values.
*
* @param object The object whose method will be called, or {@code null} if {@code method} is a static method.
@@ -489,7 +489,7 @@ public class DefaultObjectWrapper implements RichObjectWrapper {
* @param method The method to call, which must be an (inherited) member of the class of {@code object}, as
* described by {@link Method#invoke(Object, Object...)}
*/
- public TemplateMethodModelEx wrap(Object object, Method method) {
+ public TemplateMethodModel wrap(Object object, Method method) {
return new JavaMethodModel(object, method, method.getParameterTypes(), this);
}
@@ -582,7 +582,7 @@ public class DefaultObjectWrapper implements RichObjectWrapper {
// This is for transparent interop with other wrappers (and ourselves)
// Passing the targetClass allows e.g. a Jython-aware method that declares a
// PyObject as its argument to receive a PyObject from a Jython-aware TemplateModel
- // passed as an argument to TemplateMethodModelEx etc.
+ // passed as an argument to TemplateMethodModel etc.
if (model instanceof AdapterTemplateModel) {
Object wrapped = ((AdapterTemplateModel) model).getAdaptedObject(targetClass);
if (targetClass == Object.class || targetClass.isInstance(wrapped)) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java
index 6408117..f89952e 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java
@@ -24,14 +24,15 @@ import java.lang.reflect.Method;
import java.util.List;
import org.apache.freemarker.core._UnexpectedTypeErrorExplainerTemplateModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
/**
- * Wraps a {@link Method} into the {@link TemplateMethodModelEx} interface. It is used by {@link BeanModel} to wrap
+ * Wraps a {@link Method} into the {@link TemplateMethodModel} interface. It is used by {@link BeanModel} to wrap
* non-overloaded methods.
*/
-public final class JavaMethodModel extends SimpleMethod implements TemplateMethodModelEx,
+public final class JavaMethodModel extends SimpleMethod implements TemplateMethodModel,
_UnexpectedTypeErrorExplainerTemplateModel {
private final Object object;
private final DefaultObjectWrapper wrapper;
@@ -53,10 +54,10 @@ public final class JavaMethodModel extends SimpleMethod implements TemplateMetho
* Invokes the method, passing it the arguments from the list.
*/
@Override
- public Object exec(List arguments) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
try {
return wrapper.invokeMethod(object, (Method) getMember(),
- unwrapArguments(arguments, wrapper));
+ unwrapArguments(args, wrapper));
} catch (TemplateModelException e) {
throw e;
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsModel.java
index 9a66a6d..72ca642 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsModel.java
@@ -23,14 +23,14 @@ package org.apache.freemarker.core.model.impl;
import java.util.List;
import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
/**
* Wraps a set of same-name overloaded methods behind {@link TemplateMethodModel} interface,
* like if it was a single method, chooses among them behind the scenes on call-time based on the argument values.
*/
-class OverloadedMethodsModel implements TemplateMethodModelEx {
+class OverloadedMethodsModel implements TemplateMethodModel {
private final Object object;
private final OverloadedMethods overloadedMethods;
private final DefaultObjectWrapper wrapper;
@@ -49,8 +49,8 @@ class OverloadedMethodsModel implements TemplateMethodModelEx {
* unambiguously.
*/
@Override
- public Object exec(List arguments) throws TemplateModelException {
- MemberAndArguments maa = overloadedMethods.getMemberAndArguments(arguments, wrapper);
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
+ MemberAndArguments maa = overloadedMethods.getMemberAndArguments(args, wrapper);
try {
return maa.invokeMethod(wrapper, object);
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java
index 31af451..457c7ef 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java
@@ -31,7 +31,7 @@ import java.util.Set;
import org.apache.freemarker.core._DelayedJQuote;
import org.apache.freemarker.core._TemplateModelException;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -54,9 +54,9 @@ public class ResourceBundleModel
extends
BeanModel
implements
- TemplateMethodModelEx {
+ TemplateMethodModel {
- private Hashtable formats = null;
+ private Hashtable<String, MessageFormat> formats = null;
public ResourceBundleModel(ResourceBundle bundle, DefaultObjectWrapper wrapper) {
super(bundle, wrapper);
@@ -108,13 +108,13 @@ public class ResourceBundleModel
* rest of the arguments. The created MessageFormats are cached for later reuse.
*/
@Override
- public Object exec(List arguments)
+ public TemplateModel execute(List<? extends TemplateModel> args)
throws TemplateModelException {
// Must have at least one argument - the key
- if (arguments.size() < 1)
+ if (args.size() < 1)
throw new TemplateModelException("No message key was specified");
// Read it
- Iterator it = arguments.iterator();
+ Iterator<? extends TemplateModel> it = args.iterator();
String key = unwrap((TemplateModel) it.next()).toString();
try {
if (!it.hasNext()) {
@@ -122,10 +122,10 @@ public class ResourceBundleModel
}
// Copy remaining arguments into an Object[]
- int args = arguments.size() - 1;
- Object[] params = new Object[args];
- for (int i = 0; i < args; ++i)
- params[i] = unwrap((TemplateModel) it.next());
+ int paramsLen = args.size() - 1;
+ Object[] params = new Object[paramsLen];
+ for (int i = 0; i < paramsLen; ++i)
+ params[i] = unwrap(it.next());
// Invoke format
return new BeanAndStringModel(format(key, params), wrapper);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java
index 8a7f082..9c4db4e 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java
@@ -28,6 +28,7 @@ import java.util.Map;
import org.apache.freemarker.core.model.TemplateCollectionModel;
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.slf4j.Logger;
@@ -37,7 +38,7 @@ import org.slf4j.LoggerFactory;
* Wraps the static fields and methods of a class in a
* {@link org.apache.freemarker.core.model.TemplateHashModel}.
* Fields are wrapped using {@link DefaultObjectWrapper#wrap(Object)}, and
- * methods are wrapped into an appropriate {@link org.apache.freemarker.core.model.TemplateMethodModelEx} instance.
+ * methods are wrapped into an appropriate {@link TemplateMethodModel} instance.
* Unfortunately, there is currently no support for bean property-style
* calls of static methods, similar to that in {@link BeanModel}.
*/
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java
index b049c63..2394394 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java
@@ -21,13 +21,13 @@ package org.apache.freemarker.core.model.impl;
import java.util.List;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateSequenceModel;
/**
* A sequence that wraps a {@link List} of {@link TemplateModel}-s. It does not copy the original
- * list. It's mostly useful when implementing {@link TemplateMethodModelEx}-es that collect items from other
+ * list. It's mostly useful when implementing {@link TemplateMethodModel}-es that collect items from other
* {@link TemplateModel}-s.
*/
public class TemplateModelListSequence implements TemplateSequenceModel {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
index fb63309..ff9db12 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
@@ -28,7 +28,7 @@ import org.apache.freemarker.core._UnexpectedTypeErrorExplainerTemplateModel;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.CallPlace;
import org.apache.freemarker.core.model.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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.JavaMethodModel;
@@ -47,7 +47,7 @@ class CustomTagAndELFunctionCombiner {
* @param customTag
* A {@link TemplateDirectiveModel}.
*/
- static TemplateModel combine(TemplateModel customTag, TemplateMethodModelEx elFunction) {
+ static TemplateModel combine(TemplateModel customTag, TemplateMethodModel elFunction) {
if (customTag instanceof TemplateDirectiveModel) {
return elFunction instanceof JavaMethodModel //
? new TemplateDirectiveModelAndSimpleMethodModel( //
@@ -62,7 +62,7 @@ class CustomTagAndELFunctionCombiner {
/**
* Tells if the value can be used as the "custom tag" parameter to
- * {@link #combine(TemplateModel, TemplateMethodModelEx)}.
+ * {@link #combine(TemplateModel, TemplateMethodModel)}.
*/
static boolean canBeCombinedAsCustomTag(TemplateModel tm) {
return (tm instanceof TemplateDirectiveModel) && !(tm instanceof CombinedTemplateModel);
@@ -70,10 +70,10 @@ class CustomTagAndELFunctionCombiner {
/**
* Tells if the value can be used as the "EL function" parameter to
- * {@link #combine(TemplateModel, TemplateMethodModelEx)}.
+ * {@link #combine(TemplateModel, TemplateMethodModel)}.
*/
static boolean canBeCombinedAsELFunction(TemplateModel tm) {
- return tm instanceof TemplateMethodModelEx && !(tm instanceof CombinedTemplateModel);
+ return tm instanceof TemplateMethodModel && !(tm instanceof CombinedTemplateModel);
}
private static class CombinedTemplateModel {
@@ -81,7 +81,7 @@ class CustomTagAndELFunctionCombiner {
}
private static class TemplateDirectiveModelAndSimpleMethodModel extends CombinedTemplateModel
- implements TemplateDirectiveModel, TemplateMethodModelEx,
+ implements TemplateDirectiveModel, TemplateMethodModel,
_UnexpectedTypeErrorExplainerTemplateModel {
private final TemplateDirectiveModel templateDirectiveModel;
@@ -94,8 +94,8 @@ class CustomTagAndELFunctionCombiner {
}
@Override
- public Object exec(List arguments) throws TemplateModelException {
- return simpleMethodModel.exec(arguments);
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
+ return simpleMethodModel.execute(args);
}
@Override
@@ -121,20 +121,20 @@ class CustomTagAndELFunctionCombiner {
}
private static class TemplateDirectiveModelAndTemplateMethodModelEx extends CombinedTemplateModel
- implements TemplateDirectiveModel, TemplateMethodModelEx {
+ implements TemplateDirectiveModel, TemplateMethodModel {
private final TemplateDirectiveModel templateDirectiveModel;
- private final TemplateMethodModelEx templateMethodModelEx;
+ private final TemplateMethodModel templateMethodModelEx;
public TemplateDirectiveModelAndTemplateMethodModelEx( //
- TemplateDirectiveModel templateDirectiveModel, TemplateMethodModelEx templateMethodModelEx) {
+ TemplateDirectiveModel templateDirectiveModel, TemplateMethodModel templateMethodModelEx) {
this.templateDirectiveModel = templateDirectiveModel;
this.templateMethodModelEx = templateMethodModelEx;
}
@Override
- public Object exec(List arguments) throws TemplateModelException {
- return templateMethodModelEx.exec(arguments);
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
+ return templateMethodModelEx.execute(args);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
index 606cef8..98634bd 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
@@ -66,7 +66,7 @@ import org.apache.freemarker.core.Environment;
import org.apache.freemarker.core.model.ObjectWrapper;
import org.apache.freemarker.core.model.TemplateDirectiveModel;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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;
@@ -233,7 +233,7 @@ public class TaglibFactory implements TemplateHashModel {
*
* @return a {@link TemplateHashModel} representing the JSP taglib. Each element of this hash represents a single
* custom tag or EL function from the library, implemented as a {@link TemplateDirectiveModel} or
- * {@link TemplateMethodModelEx}, respectively.
+ * {@link TemplateMethodModel}, respectively.
*/
@Override
public TemplateModel get(final String taglibUri) throws TemplateModelException {
@@ -1777,7 +1777,7 @@ public class TaglibFactory implements TemplateHashModel {
if (replacedTagOrFunction != null) {
if (CustomTagAndELFunctionCombiner.canBeCombinedAsELFunction(replacedTagOrFunction)) {
tagsAndFunctions.put(tagNameCData, CustomTagAndELFunctionCombiner.combine(
- customTagModel, (TemplateMethodModelEx) replacedTagOrFunction));
+ customTagModel, (TemplateMethodModel) replacedTagOrFunction));
} else {
if (LOG.isWarnEnabled()) {
LOG.warn("TLD contains multiple tags with name " + _StringUtil.jQuote(tagNameCData)
@@ -1816,7 +1816,7 @@ public class TaglibFactory implements TemplateHashModel {
locator);
}
- final TemplateMethodModelEx elFunctionModel;
+ final TemplateMethodModel elFunctionModel;
try {
elFunctionModel = defaultObjectWrapper.wrap(null, functionMethod);
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java b/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java
index 38e69b5..43285c5 100644
--- a/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java
+++ b/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java
@@ -33,12 +33,10 @@ import javax.servlet.jsp.tagext.TagSupport;
import javax.xml.parsers.SAXParserFactory;
import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateScalarModel;
import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
import org.apache.freemarker.core.model.impl.SimpleScalar;
-import org.apache.freemarker.servlet.jsp.JspTagModelBase;
-import org.apache.freemarker.servlet.jsp.TaglibFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -84,13 +82,13 @@ public class TLDParsingTest {
tag = (JspTagModelBase) tagsAndFunctions.get("setStringAttributeTag2");
assertNotNull(tag);
- TemplateMethodModelEx function = (TemplateMethodModelEx) tagsAndFunctions.get("toUpperCase");
+ TemplateMethodModel function = (TemplateMethodModel) tagsAndFunctions.get("toUpperCase");
assertNotNull(function);
- TemplateScalarModel result = (TemplateScalarModel) function.exec(Arrays.asList(new SimpleScalar("abc")));
+ TemplateScalarModel result = (TemplateScalarModel) function.execute(Arrays.asList(new SimpleScalar("abc")));
assertEquals("ABC", result.getAsString());
- function = (TemplateMethodModelEx) tagsAndFunctions.get("toUpperCase2");
+ function = (TemplateMethodModel) tagsAndFunctions.get("toUpperCase2");
assertNotNull(function);
- result = (TemplateScalarModel) function.exec(Arrays.asList(new SimpleScalar("abc")));
+ result = (TemplateScalarModel) function.execute(Arrays.asList(new SimpleScalar("abc")));
assertEquals("ABC", result.getAsString());
}
[2/8] incubator-freemarker git commit: FREEMARKER-64: TemplateModel
and TemplateModelEx changes (but they will be probably replaced by
TemplateFunctionModel later): Removed FM2 `TemplateMethodModel`,
then renamed `TemplateMethodModelEx` to `TemplateMetho
Posted by dd...@apache.org.
FREEMARKER-64: TemplateModel and TemplateModelEx changes (but they will be probably replaced by TemplateFunctionModel later): Removed FM2 `TemplateMethodModel`, then renamed `TemplateMethodModelEx` to `TemplateMethodModel`. Then changed it further to return `TemplateModel` (instead of `Object`, which allowed returning a non-wrapped value by design in FM2), changed the parameter `List` to `List<? extends TemplateModel>` (which it was earlier too, but there were no generic paramters back then), and allowed throwing `TemplateException` instead of the more restrictive `TemplateModelException`.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/1333a715
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/1333a715
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/1333a715
Branch: refs/heads/3
Commit: 1333a715f2a305391907eefd74fcb8ad7a48db5f
Parents: 3cacd9e
Author: ddekany <dd...@apache.org>
Authored: Fri Aug 4 23:04:19 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Fri Aug 4 23:33:34 2017 +0200
----------------------------------------------------------------------
FM3-CHANGE-LOG.txt | 10 +-
...a8DefaultObjectWrapperBridgeMethodsTest.java | 23 ++-
.../impl/Java8DefaultObjectWrapperTest.java | 33 ++--
.../impl/AbstractParallelIntrospectionTest.java | 7 +-
.../model/impl/DefaultObjectWrapperTest.java | 55 ++++---
.../core/model/impl/EnumModelsTest.java | 6 +-
.../core/model/impl/ErrorMessagesTest.java | 22 +--
.../impl/FineTuneMethodAppearanceTest.java | 4 +-
.../core/model/impl/StaticModelsTest.java | 6 +-
.../core/templatesuite/models/MultiModel2.java | 17 +-
.../templatesuite/models/SimpleTestMethod.java | 13 +-
.../core/templatesuite/models/TestMethod.java | 8 +-
.../core/userpkg/AllFeaturesDirective.java | 19 ++-
.../core/userpkg/AllFeaturesFunction.java | 20 ++-
.../core/userpkg/TestTemplateCallableModel.java | 14 +-
.../templatesuite/expected/stringbimethods.txt | 2 -
.../templatesuite/templates/stringbimethods.ftl | 4 -
.../freemarker/core/ASTExpListLiteral.java | 27 +---
.../freemarker/core/ASTExpMethodCall.java | 8 +-
.../freemarker/core/BuiltInsForDates.java | 25 ++-
.../core/BuiltInsForExistenceHandling.java | 14 +-
.../core/BuiltInsForMultipleTypes.java | 32 ++--
.../BuiltInsForNestedContentParameters.java | 6 +-
.../freemarker/core/BuiltInsForNodes.java | 4 +-
.../freemarker/core/BuiltInsForSequences.java | 62 ++++----
.../core/BuiltInsForStringsBasic.java | 78 +++++-----
.../core/BuiltInsForStringsEncoding.java | 6 +-
.../freemarker/core/BuiltInsForStringsMisc.java | 22 +--
.../core/BuiltInsForStringsRegexp.java | 18 ++-
.../org/apache/freemarker/core/Environment.java | 4 +-
.../freemarker/core/NonStringException.java | 14 +-
.../apache/freemarker/core/_CallableUtils.java | 156 +++++++++++++++++++
.../core/_ObjectBuilderSettingEvaluator.java | 8 +-
.../core/_TemplateCallableModelUtils.java | 112 -------------
.../freemarker/core/debug/DebugModel.java | 1 -
.../core/debug/RmiDebugModelImpl.java | 6 +-
.../core/model/GeneralPurposeNothing.java | 4 +-
.../core/model/TemplateMethodModel.java | 41 ++---
.../core/model/TemplateMethodModelEx.java | 54 -------
.../freemarker/core/model/impl/BeanModel.java | 3 +-
.../core/model/impl/DefaultObjectWrapper.java | 8 +-
.../core/model/impl/JavaMethodModel.java | 11 +-
.../core/model/impl/OverloadedMethodsModel.java | 8 +-
.../core/model/impl/ResourceBundleModel.java | 20 +--
.../freemarker/core/model/impl/StaticModel.java | 3 +-
.../model/impl/TemplateModelListSequence.java | 4 +-
.../jsp/CustomTagAndELFunctionCombiner.java | 26 ++--
.../freemarker/servlet/jsp/TaglibFactory.java | 8 +-
.../freemarker/servlet/jsp/TLDParsingTest.java | 12 +-
49 files changed, 521 insertions(+), 547 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt
index aab66b7..d38866b 100644
--- a/FM3-CHANGE-LOG.txt
+++ b/FM3-CHANGE-LOG.txt
@@ -135,7 +135,10 @@ Node: Changes already mentioned above aren't repeated here!
- When parameter default expressions are evaluated, only the parameters defined earlier are already set.
So `<#macro m a b=a>` works, but `<#macro m a=b b>` won't work anymore (unless there's `b` outside the
parameter list), as `b` is not yet set when the default of `a` is calculated.
-
+- Built-ins don't convert their parameters to tring anymore; in FM some (not all) of them did, because they
+ were based on the TemplateMethod interface (deprecated even in FM2) that required String paramteters and
+ was auto-converted by FM2.
+
Java API changes
================
@@ -372,6 +375,11 @@ Core / Models and Object wrapping
get method (`get(String)`) had priority over methods of similar name. The generic get method is only recognized from its
name and parameter type, so it's a quite consfusing feature, and might will be removed alltogether.
- Renamed TemplateDateModel.DATETIME to DATE_TIME (to be consistent with "dateTime" used elsewhere).
+- TemplateModel and TemplateModelEx changes (but they will be probably replaced by TemplateFunctionModel later):
+ Removed FM2 `TemplateMethodModel`, then renamed `TemplateMethodModelEx` to `TemplateMethodModel`. Then changed it further to return
+ `TemplateModel` (instead of `Object`, which allowed returning a non-wrapped value by design in FM2), changed the parameter `List` to
+ `List<? extends TemplateModel>` (which it was earlier too, but there were no generic paramters back then), and allowed throwing
+ `TemplateException` instead of the more restrictive `TemplateModelException`.
Core / Template loading and caching
...................................
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
index 495f3f9..abb373e 100644
--- a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
@@ -22,31 +22,30 @@ import static org.junit.Assert.*;
import java.util.Collections;
-import org.junit.Test;
-
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.TemplateException;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.junit.Test;
public class Java8DefaultObjectWrapperBridgeMethodsTest {
@Test
- public void testWithoutDefaultMethod() throws TemplateModelException {
+ public void testWithoutDefaultMethod() throws TemplateException {
test(BridgeMethodsBean.class);
}
@Test
- public void testWithDefaultMethod() throws TemplateModelException {
+ public void testWithDefaultMethod() throws TemplateException {
test(Java8BridgeMethodsWithDefaultMethodBean.class);
}
@Test
- public void testWithDefaultMethod2() throws TemplateModelException {
+ public void testWithDefaultMethod2() throws TemplateException {
test(Java8BridgeMethodsWithDefaultMethodBean2.class);
}
- private void test(Class<?> pClass) throws TemplateModelException {
+ private void test(Class<?> pClass) throws TemplateException {
DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
TemplateHashModel wrapped;
try {
@@ -55,11 +54,11 @@ public class Java8DefaultObjectWrapperBridgeMethodsTest {
throw new IllegalStateException(e);
}
- TemplateMethodModelEx m1 = (TemplateMethodModelEx) wrapped.get("m1");
- assertEquals(BridgeMethodsBean.M1_RETURN_VALUE, "" + m1.exec(Collections.emptyList()));
+ TemplateMethodModel m1 = (TemplateMethodModel) wrapped.get("m1");
+ assertEquals(BridgeMethodsBean.M1_RETURN_VALUE, "" + m1.execute(Collections.emptyList()));
- TemplateMethodModelEx m2 = (TemplateMethodModelEx) wrapped.get("m2");
- assertNull(m2.exec(Collections.emptyList()));
+ TemplateMethodModel m2 = (TemplateMethodModel) wrapped.get("m2");
+ assertNull(m2.execute(Collections.emptyList()));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
index 905d536..08dc5b1 100644
--- a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
@@ -22,20 +22,19 @@ import static org.junit.Assert.*;
import java.util.Collections;
-import org.junit.Test;
-
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.TemplateException;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
-import org.apache.freemarker.core.model.TemplateModelException;
+import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateNumberModel;
import org.apache.freemarker.core.model.TemplateScalarModel;
import org.apache.freemarker.core.model.TemplateSequenceModel;
+import org.junit.Test;
public class Java8DefaultObjectWrapperTest {
@Test
- public void testDefaultMethodRecognized() throws TemplateModelException {
+ public void testDefaultMethodRecognized() throws TemplateException {
DefaultObjectWrapper.Builder owb = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0);
DefaultObjectWrapper ow = owb.build();
TemplateHashModel wrappedBean = (TemplateHashModel) ow.wrap(new Java8DefaultMethodsBean());
@@ -62,11 +61,11 @@ public class Java8DefaultObjectWrapperTest {
// Has only indexed read method, so it's not exposed as a property
assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP));
- TemplateMethodModelEx indexedReadMethod = (TemplateMethodModelEx) wrappedBean.get(
+ TemplateMethodModel indexedReadMethod = (TemplateMethodModel) wrappedBean.get(
Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_GETTER);
assertNotNull(indexedReadMethod);
assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_VALUE,
- ((TemplateScalarModel) indexedReadMethod.exec(Collections.singletonList(new SimpleNumber(0))))
+ ((TemplateScalarModel) indexedReadMethod.execute(Collections.singletonList(new SimpleNumber(0))))
.getAsString
());
}
@@ -115,45 +114,45 @@ public class Java8DefaultObjectWrapperTest {
// Has only indexed read method, so it's not exposed as a property
assertNull(wrappedBean.get(Java8DefaultMethodsBean.INDEXED_PROP_4));
- TemplateMethodModelEx indexedReadMethod = (TemplateMethodModelEx) wrappedBean.get(
+ TemplateMethodModel indexedReadMethod = (TemplateMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.INDEXED_PROP_GETTER_4);
assertNotNull(indexedReadMethod);
assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_4_VALUE,
- ((TemplateScalarModel) indexedReadMethod.exec(Collections.singletonList(new SimpleNumber(0))))
+ ((TemplateScalarModel) indexedReadMethod.execute(Collections.singletonList(new SimpleNumber(0))))
.getAsString());
}
{
- TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+ TemplateMethodModel action = (TemplateMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.NORMAL_ACTION);
assertNotNull(action);
assertEquals(
Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+ ((TemplateScalarModel) action.execute(Collections.emptyList())).getAsString());
}
{
- TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+ TemplateMethodModel action = (TemplateMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.NORMAL_ACTION);
assertNotNull(action);
assertEquals(
Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+ ((TemplateScalarModel) action.execute(Collections.emptyList())).getAsString());
}
{
- TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+ TemplateMethodModel action = (TemplateMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION);
assertNotNull(action);
assertEquals(
Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+ ((TemplateScalarModel) action.execute(Collections.emptyList())).getAsString());
}
{
- TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(
+ TemplateMethodModel action = (TemplateMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION);
assertNotNull(action);
assertEquals(
Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
+ ((TemplateScalarModel) action.execute(Collections.emptyList())).getAsString());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
index bdb9a56..aac56b3 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
@@ -20,6 +20,7 @@
package org.apache.freemarker.core.model.impl;
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.TemplateException;
import org.apache.freemarker.core.model.TemplateHashModel;
import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -111,12 +112,12 @@ public abstract class AbstractParallelIntrospectionTest extends TestCase {
}
private void testMethod(TemplateHashModel h, int objIdx, int mIdx)
- throws TemplateModelException, AssertionError {
+ throws TemplateException, AssertionError {
TemplateMethodModel pv = (TemplateMethodModel) h.get("m" + mIdx);
final int expected = objIdx * 1000 + mIdx;
- final int got = ((TemplateNumberModel) pv.exec(null)).getAsNumber().intValue();
+ final int got = ((TemplateNumberModel) pv.execute(null)).getAsNumber().intValue();
if (got != expected) {
- throw new AssertionError("Method assertation failed; " +
+ throw new AssertionError("Method assertion failed; " +
"expected " + expected + ", but got " + got);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
index 41acce3..dd1c841 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
@@ -52,7 +52,7 @@ import org.apache.freemarker.core.model.TemplateCollectionModel;
import org.apache.freemarker.core.model.TemplateCollectionModelEx;
import org.apache.freemarker.core.model.TemplateHashModel;
import org.apache.freemarker.core.model.TemplateHashModelEx;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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;
@@ -167,7 +167,7 @@ public class DefaultObjectWrapperTest {
@Test
- public void testCustomization() throws TemplateModelException {
+ public void testCustomization() throws TemplateException {
CustomizedDefaultObjectWrapper ow = new CustomizedDefaultObjectWrapper(Configuration.VERSION_3_0_0);
assertEquals(Configuration.VERSION_3_0_0, ow.getIncompatibleImprovements());
@@ -191,16 +191,15 @@ public class DefaultObjectWrapperTest {
assertEquals(1, ow.unwrap(bean.get("x")));
{
// Check method calls, and also if the return value is wrapped with the overidden "wrap".
- final TemplateModel mr = (TemplateModel) ((TemplateMethodModelEx) bean.get("m")).exec(Collections.emptyList());
- assertEquals(
- Collections.singletonList(1),
- ow.unwrap(mr));
+ final TemplateModel mr = ((TemplateMethodModel) bean.get("m")).execute(
+ Collections.<TemplateModel>emptyList());
+ assertEquals(Collections.singletonList(1), ow.unwrap(mr));
assertTrue(DefaultListAdapter.class.isInstance(mr));
}
{
// Check custom TM usage and round trip:
- final TemplateModel mr = (TemplateModel) ((TemplateMethodModelEx) bean.get("incTupple"))
- .exec(Collections.singletonList(ow.wrap(new Tupple<>(1, 2))));
+ final TemplateModel mr = ((TemplateMethodModel) bean.get("incTupple"))
+ .execute(Collections.singletonList(ow.wrap(new Tupple<>(1, 2))));
assertEquals(new Tupple<>(2, 3), ow.unwrap(mr));
assertTrue(TuppleAdapter.class.isInstance(mr));
}
@@ -208,7 +207,7 @@ public class DefaultObjectWrapperTest {
@SuppressWarnings("boxing")
@Test
- public void testCompositeValueWrapping() throws TemplateModelException, ClassNotFoundException {
+ public void testCompositeValueWrapping() throws TemplateException, ClassNotFoundException {
DefaultObjectWrapper ow = new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0).build();
final Map hashMap = new HashMap();
@@ -246,7 +245,7 @@ public class DefaultObjectWrapperTest {
@SuppressWarnings("boxing")
@Test
- public void testMapAdapter() throws TemplateModelException {
+ public void testMapAdapter() throws TemplateException {
HashMap<String, Object> testMap = new LinkedHashMap<>();
testMap.put("a", 1);
testMap.put("b", null);
@@ -303,7 +302,7 @@ public class DefaultObjectWrapperTest {
@SuppressWarnings("boxing")
@Test
- public void testListAdapter() throws TemplateModelException {
+ public void testListAdapter() throws TemplateException {
{
List testList = new ArrayList<>();
testList.add(1);
@@ -326,7 +325,7 @@ public class DefaultObjectWrapperTest {
}
{
- List testList = new LinkedList<>();
+ List<Object> testList = new LinkedList<>();
testList.add(1);
testList.add(null);
testList.add("c");
@@ -442,29 +441,29 @@ public class DefaultObjectWrapperTest {
private void assertRoundtrip(DefaultObjectWrapper dow, Object obj, Class expectedTMClass,
Class expectedPojoClass,
String expectedPojoToString)
- throws TemplateModelException {
+ throws TemplateException {
final TemplateModel objTM = dow.wrap(obj);
assertThat(objTM.getClass(), typeCompatibleWith(expectedTMClass));
final TemplateHashModel testBeanTM = (TemplateHashModel) dow.wrap(new RoundtripTesterBean());
{
- TemplateMethodModelEx getClassM = (TemplateMethodModelEx) testBeanTM.get("getClass");
- Object r = getClassM.exec(Collections.singletonList(objTM));
+ TemplateMethodModel getClassM = (TemplateMethodModel) testBeanTM.get("getClass");
+ TemplateModel r = getClassM.execute(Collections.singletonList(objTM));
final Class rClass = (Class) ((WrapperTemplateModel) r).getWrappedObject();
assertThat(rClass, typeCompatibleWith(expectedPojoClass));
}
if (expectedPojoToString != null) {
- TemplateMethodModelEx getToStringM = (TemplateMethodModelEx) testBeanTM.get("toString");
- Object r = getToStringM.exec(Collections.singletonList(objTM));
+ TemplateMethodModel getToStringM = (TemplateMethodModel) testBeanTM.get("toString");
+ TemplateModel r = getToStringM.execute(Collections.singletonList(objTM));
assertEquals(expectedPojoToString, ((TemplateScalarModel) r).getAsString());
}
}
@SuppressWarnings("boxing")
@Test
- public void testCollectionAdapterBasics() throws TemplateModelException {
+ public void testCollectionAdapterBasics() throws TemplateException {
{
Set set = new TreeSet();
set.add("a");
@@ -538,7 +537,7 @@ public class DefaultObjectWrapperTest {
}
@Test
- public void testIteratorWrapping() throws TemplateModelException, ClassNotFoundException {
+ public void testIteratorWrapping() throws TemplateException, ClassNotFoundException {
final List<String> list = ImmutableList.of("a", "b", "c");
Iterator<String> it = list.iterator();
TemplateCollectionModel coll = (TemplateCollectionModel) OW.wrap(it);
@@ -578,14 +577,14 @@ public class DefaultObjectWrapperTest {
}
@Test
- public void testIteratorApiSupport() throws TemplateModelException {
+ public void testIteratorApiSupport() throws TemplateException {
TemplateModel wrappedIterator = OW.wrap(Collections.emptyIterator());
assertThat(wrappedIterator, instanceOf(DefaultIteratorAdapter.class));
DefaultIteratorAdapter iteratorAdapter = (DefaultIteratorAdapter) wrappedIterator;
TemplateHashModel api = (TemplateHashModel) iteratorAdapter.getAPI();
- assertFalse(((TemplateBooleanModel) ((TemplateMethodModelEx)
- api.get("hasNext")).exec(Collections.emptyList())).getAsBoolean());
+ assertFalse(((TemplateBooleanModel) ((TemplateMethodModel)
+ api.get("hasNext")).execute(Collections.<TemplateModel>emptyList())).getAsBoolean());
}
@SuppressWarnings("boxing")
@@ -651,7 +650,7 @@ public class DefaultObjectWrapperTest {
}
@Test
- public void testEnumerationAdapter() throws TemplateModelException {
+ public void testEnumerationAdapter() throws TemplateException {
Vector<String> vector = new Vector<String>();
vector.add("a");
vector.add("b");
@@ -674,8 +673,8 @@ public class DefaultObjectWrapperTest {
}
TemplateHashModel api = (TemplateHashModel) enumAdapter.getAPI();
- assertFalse(((TemplateBooleanModel) ((TemplateMethodModelEx)
- api.get("hasMoreElements")).exec(Collections.emptyList())).getAsBoolean());
+ assertFalse(((TemplateBooleanModel) ((TemplateMethodModel) api.get("hasMoreElements"))
+ .execute(Collections.<TemplateModel>emptyList())).getAsBoolean());
}
@Test
@@ -725,13 +724,13 @@ public class DefaultObjectWrapperTest {
.wrap(bean);
}
- private void assertSizeThroughAPIModel(int expectedSize, TemplateModel normalModel) throws TemplateModelException {
+ private void assertSizeThroughAPIModel(int expectedSize, TemplateModel normalModel) throws TemplateException {
if (!(normalModel instanceof TemplateModelWithAPISupport)) {
fail();
}
TemplateHashModel apiModel = (TemplateHashModel) ((TemplateModelWithAPISupport) normalModel).getAPI();
- TemplateMethodModelEx sizeMethod = (TemplateMethodModelEx) apiModel.get("size");
- TemplateNumberModel r = (TemplateNumberModel) sizeMethod.exec(Collections.emptyList());
+ TemplateMethodModel sizeMethod = (TemplateMethodModel) apiModel.get("size");
+ TemplateNumberModel r = (TemplateNumberModel) sizeMethod.execute(Collections.<TemplateModel>emptyList());
assertEquals(expectedSize, r.getAsNumber().intValue());
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
index fc19bb7..9373cf5 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
@@ -25,7 +25,7 @@ import java.util.ArrayList;
import org.apache.freemarker.core.Configuration;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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.TemplateScalarModel;
@@ -58,8 +58,8 @@ public class EnumModelsTest {
assertTrue(a instanceof TemplateScalarModel);
assertTrue(a instanceof TemplateHashModel);
assertEquals(((TemplateScalarModel) a).getAsString(), "ts:A");
- TemplateMethodModelEx nameMethod = (TemplateMethodModelEx) ((TemplateHashModel) a).get("name");
- assertEquals(((TemplateScalarModel) nameMethod.exec(new ArrayList())).getAsString(), "A");
+ TemplateMethodModel nameMethod = (TemplateMethodModel) ((TemplateHashModel) a).get("name");
+ assertEquals(((TemplateScalarModel) nameMethod.execute(new ArrayList())).getAsString(), "A");
assertSame(e, enums.get(E.class.getName()));
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
index 29e8b9b..dcb8cf6 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
@@ -27,7 +27,7 @@ import java.util.Date;
import org.apache.freemarker.core.Configuration;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateScalarModel;
import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
@@ -60,9 +60,9 @@ public class ErrorMessagesTest {
TemplateHashModel thm = (TemplateHashModel) ow.wrap(new TestBean());
{
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m1");
+ TemplateMethodModel m = (TemplateMethodModel) thm.get("m1");
try {
- m.exec(Collections.singletonList(html));
+ m.execute(Collections.singletonList(html));
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(
@@ -72,9 +72,9 @@ public class ErrorMessagesTest {
}
{
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m2");
+ TemplateMethodModel m = (TemplateMethodModel) thm.get("m2");
try {
- m.exec(Collections.singletonList(html));
+ m.execute(Collections.singletonList(html));
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(
@@ -84,9 +84,9 @@ public class ErrorMessagesTest {
}
for (String methodName : new String[] { "mOverloaded", "mOverloaded3" }) {
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get(methodName);
+ TemplateMethodModel m = (TemplateMethodModel) thm.get(methodName);
try {
- m.exec(Collections.singletonList(html));
+ m.execute(Collections.singletonList(html));
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(
@@ -97,9 +97,9 @@ public class ErrorMessagesTest {
}
{
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded2");
+ TemplateMethodModel m = (TemplateMethodModel) thm.get("mOverloaded2");
try {
- m.exec(Collections.singletonList(html));
+ m.execute(Collections.singletonList(html));
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(
@@ -110,8 +110,8 @@ public class ErrorMessagesTest {
}
{
- TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded4");
- Object r = m.exec(Collections.singletonList(html));
+ TemplateMethodModel m = (TemplateMethodModel) thm.get("mOverloaded4");
+ Object r = m.execute(Collections.singletonList(html));
if (r instanceof TemplateScalarModel) {
r = ((TemplateScalarModel) r).getAsString();
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
index 92f59fb..eb4d807 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
@@ -23,7 +23,7 @@ import static org.junit.Assert.*;
import org.apache.freemarker.core.Configuration;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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.TemplateScalarModel;
@@ -48,7 +48,7 @@ public class FineTuneMethodAppearanceTest {
assertEquals("v1", ((TemplateScalarModel) thm.get("v1")).getAsString());
assertEquals("v2()", ((TemplateScalarModel) thm.get("v2")).getAsString());
assertEquals("getV3()", ((TemplateScalarModel) thm.get("v3")).getAsString());
- assertTrue(thm.get("getV3") instanceof TemplateMethodModelEx);
+ assertTrue(thm.get("getV3") instanceof TemplateMethodModel);
}
static public class C {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
index 609d632..44da42a 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
@@ -26,7 +26,7 @@ import java.util.ArrayList;
import org.apache.freemarker.core.Configuration;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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.TemplateScalarModel;
@@ -65,8 +65,8 @@ public class StaticModelsTest {
assertEquals(((TemplateScalarModel) f).getAsString(), "F OK");
TemplateModel m = s.get("m");
- assertTrue(m instanceof TemplateMethodModelEx);
- assertEquals(((TemplateScalarModel) ((TemplateMethodModelEx) m).exec(new ArrayList())).getAsString(), "m OK");
+ assertTrue(m instanceof TemplateMethodModel);
+ assertEquals(((TemplateScalarModel) ((TemplateMethodModel) m).execute(new ArrayList())).getAsString(), "m OK");
assertSame(s, statics.get(S.class.getName()));
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java
index e264936..3223652 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java
@@ -19,10 +19,12 @@
package org.apache.freemarker.core.templatesuite.models;
-import java.util.Iterator;
import java.util.List;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core._CallableUtils;
import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateScalarModel;
import org.apache.freemarker.core.model.impl.SimpleScalar;
@@ -44,18 +46,17 @@ public class MultiModel2 implements TemplateScalarModel, TemplateMethodModel {
/**
* Executes a method call.
*
- * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing the values
+ * @param args a <tt>List</tt> of <tt>String</tt> objects containing the values
* of the arguments passed to the method.
* @return the <tt>TemplateModel</tt> produced by the method, or null.
*/
@Override
- public Object exec(List arguments) {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
StringBuilder aResults = new StringBuilder( "Arguments are:<br />" );
- Iterator iList = arguments.iterator();
-
- while ( iList.hasNext() ) {
- aResults.append( (String) iList.next() );
- aResults.append( "<br />" );
+ for (int i = 0; i < args.size(); i++) {
+ TemplateModel arg = args.get(i);
+ aResults.append(_CallableUtils.castArgToString(arg, i));
+ aResults.append("<br />");
}
return new SimpleScalar( aResults.toString() );
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestMethod.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestMethod.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestMethod.java
index 21fc5c0..48352a0 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestMethod.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestMethod.java
@@ -22,6 +22,7 @@ package org.apache.freemarker.core.templatesuite.models;
import java.util.List;
import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.impl.SimpleScalar;
/**
@@ -32,18 +33,18 @@ public class SimpleTestMethod implements TemplateMethodModel {
/**
* Executes a method call.
*
- * @param arguments a <tt>List</tt> of <tt>String</tt> objects containing
+ * @param args a <tt>List</tt> of <tt>String</tt> objects containing
* the values of the arguments passed to the method.
* @return the <tt>TemplateModel</tt> produced by the method, or null.
*/
@Override
- public Object exec(List arguments) {
- if ( arguments.size() == 0 ) {
+ public TemplateModel execute(List<? extends TemplateModel> args) {
+ if ( args.size() == 0 ) {
return new SimpleScalar( "Empty list provided" );
- } else if ( arguments.size() > 1 ) {
- return new SimpleScalar( "Argument size is: " + arguments.size() );
+ } else if ( args.size() > 1 ) {
+ return new SimpleScalar( "Argument size is: " + args.size() );
} else {
- return new SimpleScalar( "Single argument value is: " + arguments.get(0) );
+ return new SimpleScalar( "Single argument value is: " + args.get(0) );
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TestMethod.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TestMethod.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TestMethod.java
index d9087a3..ed97f9e 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TestMethod.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TestMethod.java
@@ -3,10 +3,14 @@ package org.apache.freemarker.core.templatesuite.models;
import java.util.List;
import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.impl.SimpleScalar;
public class TestMethod implements TemplateMethodModel {
+
@Override
- public Object exec(List arguments) {
- return "x";
+ public TemplateModel execute(List<? extends TemplateModel> args) {
+ return new SimpleScalar("x");
}
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
index 3509b78..d9bb394 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
@@ -19,19 +19,18 @@
package org.apache.freemarker.core.userpkg;
-import static org.apache.freemarker.core._TemplateCallableModelUtils.*;
+import static org.apache.freemarker.core._CallableUtils.*;
import java.io.IOException;
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.ArgumentArrayLayout;
-import org.apache.freemarker.core.CallPlace;
import org.apache.freemarker.core.model.TemplateDirectiveModel;
import org.apache.freemarker.core.model.TemplateHashModelEx2;
import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateNumberModel;
import org.apache.freemarker.core.model.TemplateSequenceModel;
import org.apache.freemarker.core.model.impl.SimpleNumber;
import org.apache.freemarker.core.util.StringToIndexMap;
@@ -79,17 +78,17 @@ public class AllFeaturesDirective extends TestTemplateCallableModel implements T
@Override
public void execute(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env)
throws TemplateException, IOException {
- execute(castArgumentToNumber(args, P1_ARG_IDX, p1AllowNull, env),
- castArgumentToNumber(args, P2_ARG_IDX, p2AllowNull, env),
+ execute(castArgToNumber(args, P1_ARG_IDX, p1AllowNull),
+ castArgToNumber(args, P2_ARG_IDX, p2AllowNull),
(TemplateSequenceModel) args[P_VARARGS_ARG_IDX],
- castArgumentToNumber(args[N1_ARG_IDX], N1_ARG_NAME, n1AllowNull, env),
- castArgumentToNumber(args[N2_ARG_IDX], N2_ARG_NAME, n2AllowNull, env),
+ castArgToNumber(args[N1_ARG_IDX], N1_ARG_NAME, n1AllowNull),
+ castArgToNumber(args[N2_ARG_IDX], N2_ARG_NAME, n2AllowNull),
(TemplateHashModelEx2) args[N_VARARGS_ARG_IDX],
out, env, callPlace);
}
- private void execute(TemplateNumberModel p1, TemplateNumberModel p2, TemplateSequenceModel pOthers,
- TemplateNumberModel n1, TemplateNumberModel n2, TemplateHashModelEx2 nOthers,
+ private void execute(Number p1, Number p2, TemplateSequenceModel pOthers,
+ Number n1, Number n2, TemplateHashModelEx2 nOthers,
Writer out, Environment env, CallPlace callPlace) throws IOException, TemplateException {
out.write("#a(");
printParam("p1", p1, out, true);
@@ -107,7 +106,7 @@ public class AllFeaturesDirective extends TestTemplateCallableModel implements T
if (callPlace.hasNestedContent()) {
out.write(" {");
if (p1 != null) {
- int intP1 = p1.getAsNumber().intValue();
+ int intP1 = p1.intValue();
for (int i = 0; i < intP1; i++) {
// We dynamically set as many nested content parameters as many the caller has declared; this is
// unusual, and is for testing purposes only.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java
index 7f1f6c1..5825745 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java
@@ -19,7 +19,7 @@
package org.apache.freemarker.core.userpkg;
-import static org.apache.freemarker.core._TemplateCallableModelUtils.*;
+import static org.apache.freemarker.core._CallableUtils.*;
import java.io.IOException;
import java.io.StringWriter;
@@ -31,7 +31,6 @@ import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateHashModelEx2;
import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateNumberModel;
import org.apache.freemarker.core.model.TemplateSequenceModel;
import org.apache.freemarker.core.model.impl.SimpleScalar;
import org.apache.freemarker.core.util.StringToIndexMap;
@@ -78,18 +77,17 @@ public class AllFeaturesFunction extends TestTemplateCallableModel implements Te
@Override
public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env) throws TemplateException {
- return execute(castArgumentToNumber(args, P1_ARG_IDX, p1AllowNull, env),
- castArgumentToNumber(args, P2_ARG_IDX, p2AllowNull, env),
+ return execute(
+ castArgToNumber(args, P1_ARG_IDX, p1AllowNull),
+ castArgToNumber(args, P2_ARG_IDX, p2AllowNull),
(TemplateSequenceModel) args[P_VARARGS_ARG_IDX],
- castArgumentToNumber(args[N1_ARG_IDX], N1_ARG_NAME, n1AllowNull, env),
- castArgumentToNumber(args[N2_ARG_IDX], N2_ARG_NAME, n2AllowNull, env),
- (TemplateHashModelEx2) args[N_VARARGS_ARG_IDX],
- env);
+ castArgToNumber(args[N1_ARG_IDX], N1_ARG_NAME, n1AllowNull),
+ castArgToNumber(args[N2_ARG_IDX], N2_ARG_NAME, n2AllowNull),
+ (TemplateHashModelEx2) args[N_VARARGS_ARG_IDX]);
}
- private TemplateModel execute(TemplateNumberModel p1, TemplateNumberModel p2, TemplateSequenceModel pOthers,
- TemplateNumberModel n1, TemplateNumberModel n2, TemplateHashModelEx2 nOthers,
- Environment env) throws TemplateException {
+ private TemplateModel execute(Number p1, Number p2, TemplateSequenceModel pOthers,
+ Number n1, Number n2, TemplateHashModelEx2 nOthers) throws TemplateException {
StringWriter out = new StringWriter();
try {
out.write("fa(");
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TestTemplateCallableModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TestTemplateCallableModel.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TestTemplateCallableModel.java
index 9dd34ba..f0a15d7 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TestTemplateCallableModel.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TestTemplateCallableModel.java
@@ -24,20 +24,20 @@ import java.io.Writer;
import org.apache.freemarker.core.model.TemplateCallableModel;
import org.apache.freemarker.core.model.TemplateHashModelEx2;
-import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateNumberModel;
import org.apache.freemarker.core.model.TemplateScalarModel;
import org.apache.freemarker.core.model.TemplateSequenceModel;
import org.apache.freemarker.core.util.FTLUtil;
+import org.apache.freemarker.core.util._StringUtil;
public abstract class TestTemplateCallableModel implements TemplateCallableModel {
- protected void printParam(String name, TemplateModel value, Writer out) throws IOException, TemplateModelException {
+ protected void printParam(String name, Object value, Writer out) throws IOException, TemplateModelException {
printParam(name, value, out, false);
}
- protected void printParam(String name, TemplateModel value, Writer out, boolean first)
+ protected void printParam(String name, Object value, Writer out, boolean first)
throws IOException, TemplateModelException {
if (!first) {
out.write(", ");
@@ -47,7 +47,7 @@ public abstract class TestTemplateCallableModel implements TemplateCallableModel
printValue(value, out);
}
- private void printValue(TemplateModel value, Writer out) throws IOException, TemplateModelException {
+ private void printValue(Object value, Writer out) throws IOException, TemplateModelException {
if (value == null) {
out.write("null");
} else if (value instanceof TemplateNumberModel) {
@@ -79,6 +79,12 @@ public abstract class TestTemplateCallableModel implements TemplateCallableModel
}
}
out.write('}');
+ } else if (value instanceof String) {
+ out.write(_StringUtil.jQuote(value));
+ } else if (value instanceof Number) {
+ out.write(value.toString());
+ } else if (value instanceof Boolean) {
+ out.write(value.toString());
} else {
throw new IllegalArgumentException("Unsupported value class: " + value.getClass().getName());
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/stringbimethods.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/stringbimethods.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/stringbimethods.txt
index 8ef415d..1d4a314 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/stringbimethods.txt
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/stringbimethods.txt
@@ -25,5 +25,3 @@ de
true false
yes no
igen nem
-0.0 1.0
-true true
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/stringbimethods.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/stringbimethods.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/stringbimethods.ftl
index 94954f9..c3bd460 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/stringbimethods.ftl
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/stringbimethods.ftl
@@ -30,7 +30,3 @@ ${a?string} ${b?string}
${a?string("yes", "no")} ${b?string("yes", "no")}
<#setting booleanFormat="igen,nem"/>
${a?string} ${b?string}
-<#setting numberFormat="0.0">
-${a?string(0, 1)} ${b?string(0, 1)}
-<#setting booleanFormat="true,false"/>
-${a?string(0, 1)?isString?string} ${b?string(0, 1)?isString?string}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java
index e5dc679..0fc27da 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java
@@ -26,7 +26,6 @@ import java.util.List;
import java.util.ListIterator;
import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateSequenceModel;
@@ -55,31 +54,7 @@ final class ASTExpListLiteral extends ASTExpression {
}
/**
- * For {@link TemplateMethodModel} calls, but not for {@link TemplateMethodModelEx}-es, returns the list of
- * arguments as {@link String}-s.
- */
- List/*<String>*/ getValueList(Environment env) throws TemplateException {
- int size = items.size();
- switch(size) {
- case 0: {
- return Collections.EMPTY_LIST;
- }
- case 1: {
- return Collections.singletonList(((ASTExpression) items.get(0)).evalAndCoerceToPlainText(env));
- }
- default: {
- List result = new ArrayList(items.size());
- for (ListIterator iterator = items.listIterator(); iterator.hasNext(); ) {
- ASTExpression exp = (ASTExpression) iterator.next();
- result.add(exp.evalAndCoerceToPlainText(env));
- }
- return result;
- }
- }
- }
-
- /**
- * For {@link TemplateMethodModelEx} calls, returns the list of arguments as {@link TemplateModel}-s.
+ * For {@link TemplateMethodModel} calls, returns the list of arguments as {@link TemplateModel}-s.
*/
List<TemplateModel> getModelList(Environment env) throws TemplateException {
int size = items.size();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpMethodCall.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpMethodCall.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpMethodCall.java
index dc8f3ff..581726e 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpMethodCall.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpMethodCall.java
@@ -32,7 +32,6 @@ import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.Constants;
import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateSequenceModel;
import org.apache.freemarker.core.util.CommonSupplier;
@@ -61,11 +60,8 @@ final class ASTExpMethodCall extends ASTExpression implements CallPlace {
TemplateModel targetModel = target.eval(env);
if (targetModel instanceof TemplateMethodModel) {
TemplateMethodModel targetMethod = (TemplateMethodModel) targetModel;
- List argumentStrings =
- targetMethod instanceof TemplateMethodModelEx
- ? arguments.getModelList(env)
- : arguments.getValueList(env);
- Object result = targetMethod.exec(argumentStrings);
+ List<TemplateModel> argumentStrings = arguments.getModelList(env);
+ Object result = targetMethod.execute(argumentStrings);
return env.getObjectWrapper().wrap(result);
} else if (targetModel instanceof TemplateFunctionModel) {
TemplateFunctionModel func = (TemplateFunctionModel) targetModel;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java
index ad11b37..434578d 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java
@@ -25,7 +25,7 @@ import java.util.TimeZone;
import org.apache.freemarker.core.model.AdapterTemplateModel;
import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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.TemplateScalarModel;
@@ -63,11 +63,6 @@ class BuiltInsForDates {
}
}
- protected TemplateModel calculateResult(Date date, int dateType, Environment env) throws TemplateException {
- // TODO Auto-generated method stub
- return null;
- }
-
}
/**
@@ -75,7 +70,7 @@ class BuiltInsForDates {
*/
static class iso_BI extends AbstractISOBI {
- class Result implements TemplateMethodModelEx {
+ class Result implements TemplateMethodModel {
private final Date date;
private final int dateType;
private final Environment env;
@@ -87,10 +82,10 @@ class BuiltInsForDates {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1);
- TemplateModel tzArgTM = (TemplateModel) args.get(0);
+ TemplateModel tzArgTM = args.get(0);
TimeZone tzArg;
Object adaptedObj;
if (tzArgTM instanceof AdapterTemplateModel
@@ -178,15 +173,15 @@ class BuiltInsForDates {
private BuiltInsForDates() { }
static abstract class AbstractISOBI extends BuiltInForDate {
- protected final Boolean showOffset;
- protected final int accuracy;
+ final Boolean showOffset;
+ final int accuracy;
- protected AbstractISOBI(Boolean showOffset, int accuracy) {
+ AbstractISOBI(Boolean showOffset, int accuracy) {
this.showOffset = showOffset;
this.accuracy = accuracy;
}
- protected void checkDateTypeNotUnknown(int dateType)
+ void checkDateTypeNotUnknown(int dateType)
throws TemplateException {
if (dateType == TemplateDateModel.UNKNOWN) {
throw new _MiscTemplateException(new _ErrorDescriptionBuilder(
@@ -196,11 +191,11 @@ class BuiltInsForDates {
}
}
- protected boolean shouldShowOffset(Date date, int dateType, Environment env) {
+ boolean shouldShowOffset(Date date, int dateType, Environment env) {
if (dateType == TemplateDateModel.DATE) {
return false; // ISO 8061 doesn't allow zone for date-only values
} else if (showOffset != null) {
- return showOffset.booleanValue();
+ return showOffset;
} else {
// java.sql.Time values meant to carry calendar field values only, so we don't show offset for them.
return !(date instanceof java.sql.Time);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java
index 6e7cce0..c0d6164 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java
@@ -22,7 +22,7 @@ package org.apache.freemarker.core;
import java.util.List;
import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -63,7 +63,7 @@ class BuiltInsForExistenceHandling {
return model == null ? FIRST_NON_NULL_METHOD : new ConstantMethod(model);
}
- private static class ConstantMethod implements TemplateMethodModelEx {
+ private static class ConstantMethod implements TemplateMethodModel {
private final TemplateModel constant;
ConstantMethod(TemplateModel constant) {
@@ -71,7 +71,7 @@ class BuiltInsForExistenceHandling {
}
@Override
- public Object exec(List args) {
+ public TemplateModel execute(List<? extends TemplateModel> args) {
return constant;
}
}
@@ -80,14 +80,14 @@ class BuiltInsForExistenceHandling {
* A method that goes through the arguments one by one and returns
* the first one that is non-null. If all args are null, returns null.
*/
- private static final TemplateMethodModelEx FIRST_NON_NULL_METHOD =
- new TemplateMethodModelEx() {
+ private static final TemplateMethodModel FIRST_NON_NULL_METHOD =
+ new TemplateMethodModel() {
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
int argCnt = args.size();
if (argCnt == 0) throw MessageUtil.newArgCntError("?default", argCnt, 1, Integer.MAX_VALUE);
for (int i = 0; i < argCnt; i++ ) {
- TemplateModel result = (TemplateModel) args.get(i);
+ TemplateModel result = args.get(i);
if (result != null) return result;
}
return null;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java
index 74f7c15..5e85262 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java
@@ -19,6 +19,7 @@
package org.apache.freemarker.core;
+import java.io.Serializable;
import java.util.Date;
import java.util.List;
@@ -110,7 +111,7 @@ class BuiltInsForMultipleTypes {
private class DateParser
implements
TemplateDateModel,
- TemplateMethodModel,
+ TemplateMethodModel,
TemplateHashModel {
private final String text;
private final Environment env;
@@ -125,9 +126,9 @@ class BuiltInsForMultipleTypes {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
checkMethodArgCount(args, 0, 1);
- return args.size() == 0 ? getAsDateModel() : get((String) args.get(0));
+ return args.size() == 0 ? getAsDateModel() : get(_CallableUtils.castArgToString(args, 0));
}
@Override
@@ -470,8 +471,8 @@ class BuiltInsForMultipleTypes {
private class BooleanFormatter
implements
- TemplateScalarModel,
- TemplateMethodModel {
+ TemplateScalarModel,
+ TemplateMethodModel {
private final TemplateBooleanModel bool;
private final Environment env;
@@ -481,9 +482,14 @@ class BuiltInsForMultipleTypes {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
checkMethodArgCount(args, 2);
- return new SimpleScalar((String) args.get(bool.getAsBoolean() ? 0 : 1));
+ int argIdx = bool.getAsBoolean() ? 0 : 1;
+ TemplateModel result = args.get(argIdx);
+ if (!(result instanceof TemplateScalarModel)) {
+ throw new NonStringException((Serializable) argIdx, result, null, null);
+ }
+ return result;
}
@Override
@@ -505,7 +511,7 @@ class BuiltInsForMultipleTypes {
implements
TemplateScalarModel,
TemplateHashModel,
- TemplateMethodModel {
+ TemplateMethodModel {
private final TemplateDateModel dateModel;
private final Environment env;
private final TemplateDateFormat defaultFormat;
@@ -524,9 +530,9 @@ class BuiltInsForMultipleTypes {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
checkMethodArgCount(args, 1);
- return formatWith((String) args.get(0));
+ return formatWith(_CallableUtils.castArgToString(args, 0));
}
@Override
@@ -580,7 +586,7 @@ class BuiltInsForMultipleTypes {
implements
TemplateScalarModel,
TemplateHashModel,
- TemplateMethodModel {
+ TemplateMethodModel {
private final TemplateNumberModel numberModel;
private final Number number;
private final Environment env;
@@ -602,9 +608,9 @@ class BuiltInsForMultipleTypes {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
checkMethodArgCount(args, 1);
- return get((String) args.get(0));
+ return get(_CallableUtils.castArgToString(args, 0));
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java
index a4c4d8f..89593cd 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java
@@ -22,7 +22,7 @@ import java.util.List;
import org.apache.freemarker.core.ASTDirList.IterationContext;
import org.apache.freemarker.core.model.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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.SimpleNumber;
@@ -131,7 +131,7 @@ class BuiltInsForNestedContentParameters {
static class item_cycleBI extends BuiltInForNestedContentParameter {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private final IterationContext iterCtx;
@@ -140,7 +140,7 @@ class BuiltInsForNestedContentParameters {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1, Integer.MAX_VALUE);
return args.get(iterCtx.getIndex() % args.size());
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNodes.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNodes.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNodes.java
index 39bc546..d5dfe93 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNodes.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNodes.java
@@ -126,7 +126,7 @@ class BuiltInsForNodes {
}
@Override
- public Object exec(List names) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> names) throws TemplateException {
if (names == null || names.isEmpty()) {
return this;
}
@@ -141,7 +141,7 @@ class BuiltInsForNodes {
}
} else {
for (int j = 0; j < names.size(); j++) {
- if (_StringUtil.matchesQName((String) names.get(j), nodeName, nsURI, env)) {
+ if (_StringUtil.matchesQName(_CallableUtils.castArgToString(names, j), nodeName, nsURI, env)) {
result.add(tnm);
break;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1333a715/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForSequences.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForSequences.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForSequences.java
index e131406..9406d33 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForSequences.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForSequences.java
@@ -33,7 +33,7 @@ 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.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModelEx;
+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;
@@ -54,7 +54,7 @@ class BuiltInsForSequences {
static class chunkBI extends BuiltInForSequence {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
private final TemplateSequenceModel tsm;
@@ -63,7 +63,7 @@ class BuiltInsForSequences {
}
@Override
- public Object exec(List args) throws TemplateModelException {
+ public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
checkMethodArgCount(args, 1, 2);
int chunkSize = getNumberMethodArg(args, 0).intValue();
@@ -182,7 +182,7 @@ class BuiltInsForSequences {
static class joinBI extends ASTExpBuiltIn {
- private class BIMethodForCollection implements TemplateMethodModelEx {
+ private class BIMethodForCollection implements TemplateMethodModel {
private final Environment env;
private final TemplateCollectionModel coll;
@@ -193,7 +193,7 @@ class BuiltInsForSequences {
}
@Override
- public Object exec(List args)
+ public TemplateModel execute(List<? extends TemplateModel> args)
throws TemplateModelException {
checkMethodArgCount(args, 1, 3);
final String separator = getStringMethodArg(args, 0);
@@ -218,7 +218,7 @@ class BuiltInsForSequences {
sb.append(_EvalUtil.coerceModelToStringOrUnsupportedMarkup(item, null, null, env));
} catch (TemplateException e) {
throw new _TemplateModelException(e,
- "\"?", key, "\" failed at index ", Integer.valueOf(idx), " with this error:\n\n",
+ "\"?", key, "\" failed at index ", idx, " with this error:\n\n",
MessageUtil.EMBEDDED_MESSAGE_BEGIN,
new _DelayedGetMessageWithoutStackTop(e),
MessageUtil.EMBEDDED_MESSAGE_END);
@@ -295,7 +295,7 @@ class BuiltInsForSequences {
}
static class seq_containsBI extends ASTExpBuiltIn {
- private class BIMethodForCollection implements TemplateMethodModelEx {
+ private class BIMethodForCollection implements TemplateMethodModel {
private TemplateCollectionModel m_coll;
private Environment m_env;
@@ -305,10 +305,10 @@ class BuiltInsForSequences {
}
@Override
- public Object exec(List args)
+ public TemplateModel execute(List<? extends TemplateModel> args)
throws TemplateModelException {
checkMethodArgCount(args, 1);
- TemplateModel arg = (TemplateModel) args.get(0);
+ TemplateModel arg = args.get(0);
TemplateModelIterator it = m_coll.iterator();
int idx = 0;
while (it.hasNext()) {
@@ -321,7 +321,7 @@ class BuiltInsForSequences {
}
- private class BIMethodForSequence implements TemplateMethodModelEx {
+ private class BIMethodForSequence implements TemplateMethodModel {
private TemplateSequenceModel m_seq;
private Environment m_env;
@@ -331,10 +331,10 @@ class BuiltInsForSequences {
}
@Override
- public Object exec(List args)
+ public TemplateModel execute(List<? extends TemplateModel> args)
throws TemplateModelException {
checkMethodArgCount(args, 1);
- TemplateModel arg = (TemplateModel) args.get(0);
+ TemplateModel arg = args.get(0);
int size = m_seq.size();
for (int i = 0; i < size; i++) {
if (modelsEqual(i, m_seq.get(i), arg, m_env))
@@ -364,11 +364,11 @@ class BuiltInsForSequences {
static class seq_index_ofBI extends ASTExpBuiltIn {
- private class BIMethod implements TemplateMethodModelEx {
+ private class BIMethod implements TemplateMethodModel {
- protected final TemplateSequenceModel m_seq;
- protected final TemplateCollectionModel m_col;
- protected final Environment m_env;
+ final TemplateSequenceModel m_seq;
+ final TemplateCollectionModel m_col;
+ final Environment m_env;
private BIMethod(Environment env)
throws TemplateException {
@@ -395,12 +395,12 @@ class BuiltInsForSequences {
}
@Override
- public final Object exec(List args)
+ public final TemplateModel execute(List<? extends TemplateModel> args)
throws TemplateModelException {
int argCnt = args.size();
checkMethodArgCount(argCnt, 1, 2);
- TemplateModel target = (TemplateModel) args.get(0);
+ TemplateModel target = args.get(0);
int foundAtIdx;
if (argCnt > 1) {
int startIndex = getNumberMethodArg(args, 1).intValue();
@@ -423,7 +423,7 @@ class BuiltInsForSequences {
return findInCol(target, 0, Integer.MAX_VALUE);
}
- protected int findInCol(TemplateModel target, int startIndex)
+ int findInCol(TemplateModel target, int startIndex)
throws TemplateModelException {
if (m_dir == 1) {
return findInCol(target, startIndex, Integer.MAX_VALUE);
@@ -432,7 +432,7 @@ class BuiltInsForSequences {
}
}
- protected int findInCol(TemplateModel target,
+ int findInCol(TemplateModel target,
final int allowedRangeStart, final int allowedRangeEnd)
throws TemplateModelException {
if (allowedRangeEnd < 0) return -1;
@@ -525,7 +525,7 @@ class BuiltInsForSequences {
}
static class sort_byBI extends sortBI {
- class BIMethod implements TemplateMethodModelEx {
+ class BIMethod implements TemplateMethodModel {
TemplateSequenceModel seq;
BIMethod(TemplateSequenceModel seq) {
@@ -533,7 +533,7 @@ class BuiltInsForSequences {
}
@Override
- public Object exec(List args)
+ public TemplateModel execute(List<? extends TemplateModel> args)
throws TemplateModelException {
// Should be:
// checkMethodArgCount(args, 1);
@@ -549,18 +549,14 @@ class BuiltInsForSequences {
int ln = seq.size();
subvars = new String[ln];
for (int i = 0; i < ln; i++) {
- Object item = seq.get(i);
- try {
- subvars[i] = ((TemplateScalarModel) item)
- .getAsString();
- } catch (ClassCastException e) {
- if (!(item instanceof TemplateScalarModel)) {
- throw new _TemplateModelException(
- "The argument to ?", key, "(key), when it's a sequence, must be a "
- + "sequence of strings, but the item at index ", Integer.valueOf(i),
- " is not a string.");
- }
+ TemplateModel item = seq.get(i);
+ if (!(item instanceof TemplateScalarModel)) {
+ throw new _TemplateModelException(
+ "The argument to ?", key, "(key), when it's a sequence, must be a "
+ + "sequence of strings, but the item at index ", i,
+ " is not a string.");
}
+ subvars[i] = ((TemplateScalarModel) item).getAsString();
}
} else {
throw new _TemplateModelException(
[7/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
Posted by dd...@apache.org.
FREEMARKER-64: Removed TemplateMethodModel, using TemplateFunctionModel everywhere instead. Some refinement of existing TemplateCallableModel API-s, most importantly, the support for null argumenArrayLayout. Removed `?isMethod` (use `isFunction` instead) and `?isMacro` (use `isDirective` instead).
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/8d5263f2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/8d5263f2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/8d5263f2
Branch: refs/heads/3
Commit: 8d5263f2aa0fca589ed67b6f6ccbbd8780ece5ef
Parents: 1333a71
Author: ddekany <dd...@apache.org>
Authored: Mon Aug 7 20:44:33 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Tue Aug 8 00:11:19 2017 +0200
----------------------------------------------------------------------
.gitignore | 2 +
FM3-CHANGE-LOG.txt | 19 +-
.../core/FM2ASTToFM3SourceConverter.java | 4 +
.../converter/FM2ToFM3ConverterTest.java | 4 +
...a8DefaultObjectWrapperBridgeMethodsTest.java | 19 +-
.../impl/Java8DefaultObjectWrapperTest.java | 43 +--
.../freemarker/core/DirectiveCallPlaceTest.java | 6 +-
.../EnvironmentGetTemplateVariantsTest.java | 2 +-
.../core/TheadInterruptingSupportTest.java | 6 +-
.../impl/AbstractParallelIntrospectionTest.java | 9 +-
.../CommonSupertypeForUnwrappingHintTest.java | 8 +-
.../model/impl/DefaultObjectWrapperTest.java | 34 ++-
.../core/model/impl/EnumModelsTest.java | 11 +-
.../core/model/impl/ErrorMessagesTest.java | 24 +-
.../impl/FineTuneMethodAppearanceTest.java | 3 +-
.../core/model/impl/StaticModelsTest.java | 11 +-
.../templatesuite/CoreTemplateTestSuite.java | 4 +-
.../core/templatesuite/models/MultiModel2.java | 33 +--
.../models/SimpleTestFunction.java | 44 +++
.../templatesuite/models/SimpleTestMethod.java | 50 ----
.../core/templatesuite/models/TestMethod.java | 16 --
.../core/userpkg/AllFeaturesDirective.java | 2 +-
.../core/userpkg/AllFeaturesFunction.java | 2 +-
.../core/userpkg/NamedVarargsOnlyDirective.java | 2 +-
.../userpkg/PositionalVarargsOnlyDirective.java | 2 +-
.../userpkg/PositionalVarargsOnlyFunction.java | 2 +-
.../core/userpkg/TwoNamedParamsDirective.java | 2 +-
.../TwoNestedContentParamsDirective.java | 2 +-
.../userpkg/TwoPositionalParamsDirective.java | 2 +-
.../userpkg/TwoPositionalParamsFunction.java | 2 +-
.../core/userpkg/UpperCaseDirective.java | 2 +-
.../core/valueformat/NumberFormatTest.java | 2 +-
.../org/apache/freemarker/core/ast-builtins.ast | 4 +-
.../org/apache/freemarker/core/ast-range.ast | 6 +-
.../templatesuite/expected/number-literal.txt | 10 +-
.../templatesuite/expected/type-builtins.txt | 28 +-
.../core/templatesuite/templates/list2.ftl | 2 +-
.../templatesuite/templates/number-literal.ftl | 2 +-
.../templates/string-builtins3.ftl | 32 +--
.../templatesuite/templates/type-builtins.ftl | 7 +-
.../freemarker/core/ASTDynamicTopLevelCall.java | 77 +++--
.../apache/freemarker/core/ASTExpBuiltIn.java | 68 +++--
.../freemarker/core/ASTExpFunctionCall.java | 229 +++++++++++++++
.../freemarker/core/ASTExpListLiteral.java | 5 +-
.../freemarker/core/ASTExpMethodCall.java | 226 ---------------
.../freemarker/core/BuiltInsForDates.java | 30 +-
.../core/BuiltInsForExistenceHandling.java | 49 ++--
.../core/BuiltInsForMultipleTypes.java | 114 ++++----
.../BuiltInsForNestedContentParameters.java | 20 +-
.../freemarker/core/BuiltInsForNodes.java | 38 ++-
.../freemarker/core/BuiltInsForSequences.java | 126 ++++----
.../core/BuiltInsForStringsBasic.java | 287 ++++++++++++-------
.../core/BuiltInsForStringsEncoding.java | 19 +-
.../freemarker/core/BuiltInsForStringsMisc.java | 20 +-
.../core/BuiltInsForStringsRegexp.java | 51 ++--
.../org/apache/freemarker/core/Environment.java | 21 +-
.../org/apache/freemarker/core/MessageUtil.java | 2 +-
.../freemarker/core/NonFunctionException.java | 62 ++++
.../freemarker/core/NonMethodException.java | 62 ----
.../apache/freemarker/core/_CallableUtils.java | 61 ++--
.../core/_ObjectBuilderSettingEvaluator.java | 31 +-
.../freemarker/core/debug/DebugModel.java | 2 +-
.../core/debug/RmiDebugModelImpl.java | 4 +-
.../core/model/ArgumentArrayLayout.java | 18 ++
.../core/model/GeneralPurposeNothing.java | 18 +-
.../core/model/TemplateCallableModel.java | 11 +-
.../core/model/TemplateDirectiveModel.java | 45 ++-
.../core/model/TemplateFunctionModel.java | 10 +
.../core/model/TemplateMethodModel.java | 53 ----
.../core/model/TemplateModelException.java | 4 +-
.../freemarker/core/model/impl/BeanModel.java | 17 +-
.../core/model/impl/DefaultObjectWrapper.java | 29 +-
.../core/model/impl/JavaMethodModel.java | 94 ++----
.../model/impl/OverloadedFixArgsMethods.java | 24 +-
.../model/impl/OverloadedJavaMethodModel.java | 86 ++++++
.../core/model/impl/OverloadedMethods.java | 59 ++--
.../core/model/impl/OverloadedMethodsModel.java | 65 -----
.../model/impl/OverloadedMethodsSubset.java | 52 ++--
.../model/impl/OverloadedVarArgsMethods.java | 57 ++--
.../core/model/impl/ResourceBundleModel.java | 40 +--
.../core/model/impl/SimpleJavaMethodModel.java | 123 ++++++++
.../core/model/impl/SimpleMethod.java | 86 +++---
.../freemarker/core/model/impl/StaticModel.java | 16 +-
.../model/impl/TemplateModelListSequence.java | 13 +-
.../freemarker/core/model/impl/_MethodUtil.java | 40 +--
.../apache/freemarker/core/util/FTLUtil.java | 11 +-
freemarker-core/src/main/javacc/FTL.jj | 4 +-
.../apache/freemarker/servlet/IncludePage.java | 2 +-
.../jsp/CustomTagAndELFunctionCombiner.java | 157 ----------
.../freemarker/servlet/jsp/JspTagModelBase.java | 33 +--
.../servlet/jsp/SimpleTagDirectiveModel.java | 2 +-
.../servlet/jsp/TagDirectiveModel.java | 2 +-
.../freemarker/servlet/jsp/TaglibFactory.java | 22 +-
...eDirectiveModelAndTemplateFunctionModel.java | 77 +++++
.../freemarker/servlet/jsp/TLDParsingTest.java | 17 +-
.../test/templateutil/AssertDirective.java | 2 +-
.../templateutil/AssertEqualsDirective.java | 2 +-
.../test/templateutil/AssertFailsDirective.java | 2 +-
.../test/templateutil/NoOutputDirective.java | 2 +-
99 files changed, 1802 insertions(+), 1562 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 0d9f1d4..5407d43 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,5 @@
.directory
.Trash*
+
+**/adhoctest/
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt
index d38866b..685160a 100644
--- a/FM3-CHANGE-LOG.txt
+++ b/FM3-CHANGE-LOG.txt
@@ -86,9 +86,6 @@ Node: Changes already mentioned above aren't repeated here!
translated to `${b}`, while `#{x; m1M3}` is translated to `${x?string('0.0##')}`). The output should remain the same.
- In `#macro` and `#function` the comma must only be used between by-position parameters (earlier the comma was
optional).
- TODO As of this writing, the by-position VS by-name feature isn't implemented yet, so
- comma is to be used for `#function`, and comma must not be used for `#macro` (even though for now macros are always
- allowed to be called with by-position parameters as well, just as in FM2).
- In `#function`, parentheses are now required around parameter list (as in `<#function f(a, b)>`), even if there are
zero parameters (as in `<#function f()>`). In `#macro`, parentheses are not allowed around parameter list anymore
(so `#macro m(a b)` becomes to `#macro m a b`). This is to remain more consistent with the look-and-feel of the
@@ -120,8 +117,10 @@ Node: Changes already mentioned above aren't repeated here!
- Renamed `DirectiveCallPlace` to `CallPlace`
- Removed Environment.getDirectiveCallPlace(), as TemplateDirectiveModel-s now get the CallPlace as the
parameter of the `execute` method.
- - ?isTransform was removed (as there are no transforms anymore).
- Converter note: The template converter tool replaces it with ?isDirective
+ - `?isTransform` was removed (as there are no transforms anymore); use `?isDirective` instead.
+ - `?isMacro` was removed; use `?isDirective` instead, which returns `true` both for macros and directives defined otherwise.
+ - `?isMethod` was removed; use `?isFunction` instead, which returns `true` both for Java methods and functions defined
+ otherwise (such as with `#function`).
- The directive returned by `?interpret` doesn't allow nested content anymore. (It wasn't useful earlier either;
the nested content was simply executed after the interpreted string.)
- Changes in #macro/#functions
@@ -199,7 +198,6 @@ Major changes / features
`TemplateDirectiveModel`, `TemplateTransformModel`). FM3 replaces them with only two new interfaces,
`TemplateDirectiveModel` (differs from the interface with identical name in FM2) and `TemplateFunctionModel`.
(These are both the subinterfaces of another new interface `TemplateCallableModel`.)
- [TODO: TemplateMethodModel[Ex] wasn't yet replaced by TemplateFunctionModel.]
- All callable TempalteModel-s support passing parameters by position and by name, even in the same call
(e.g., `<@heading "Some title" icon="foo.jpg" />`, `sum(1, 2, 3, abs=true)`)
- `#macro` now produces a `TemplateDirectiveModel` and `#function` produces a `TemplateFunctionModel`. (Earlier, the
@@ -375,11 +373,10 @@ Core / Models and Object wrapping
get method (`get(String)`) had priority over methods of similar name. The generic get method is only recognized from its
name and parameter type, so it's a quite consfusing feature, and might will be removed alltogether.
- Renamed TemplateDateModel.DATETIME to DATE_TIME (to be consistent with "dateTime" used elsewhere).
-- TemplateModel and TemplateModelEx changes (but they will be probably replaced by TemplateFunctionModel later):
- Removed FM2 `TemplateMethodModel`, then renamed `TemplateMethodModelEx` to `TemplateMethodModel`. Then changed it further to return
- `TemplateModel` (instead of `Object`, which allowed returning a non-wrapped value by design in FM2), changed the parameter `List` to
- `List<? extends TemplateModel>` (which it was earlier too, but there were no generic paramters back then), and allowed throwing
- `TemplateException` instead of the more restrictive `TemplateModelException`.
+- `TemplateMethod` and `TemplateMethodEx` was removed, taken over by `TemplateFunctionModel`. `TemplateFunctionModel` is
+ the common interface bith for wrapped Java methods and functions defined in the templates, or on any other ways.
+ `OverloadedMethodsModel` and `SimpleMethodModel` were renamed to `OverloadJavaMethodModel` and `SimpleJavaMethodModel`,
+ which of course extend `TemplateFunctionModel`, but allow inocations without `Environment` parameter.
Core / Template loading and caching
...................................
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
----------------------------------------------------------------------
diff --git a/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java b/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
index 57a912f..6d9b25c 100644
--- a/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
+++ b/freemarker-converter/src/main/java/freemarker/core/FM2ASTToFM3SourceConverter.java
@@ -1971,6 +1971,10 @@ public class FM2ASTToFM3SourceConverter {
.put("web_safe", "html")
.put("is_transform", "isDirective")
.put("isTransform", "isDirective")
+ .put("is_macro", "isDirective")
+ .put("isMacro", "isDirective")
+ .put("is_method", "isFunction")
+ .put("isMethod", "isFunction")
.put("iso_utc_fz", "isoUtcFZ")
.put("iso_utc_nz", "isoUtcNZ")
.put("iso_utc_ms_nz", "isoUtcMsNZ")
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
----------------------------------------------------------------------
diff --git a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
index 63c2a92..0790518 100644
--- a/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
+++ b/freemarker-converter/src/test/java/org/freemarker/converter/FM2ToFM3ConverterTest.java
@@ -475,6 +475,10 @@ public class FM2ToFM3ConverterTest extends ConverterTest {
assertConverted("${s?html}", "${s?webSafe}");
assertConverted("${s?isDirective}", "${s?is_transform}");
assertConverted("${s?isDirective}", "${s?isTransform}");
+ assertConverted("${s?isDirective}", "${s?is_macro}");
+ assertConverted("${s?isDirective}", "${s?isMacro}");
+ assertConverted("${s?isFunction}", "${s?is_method}");
+ assertConverted("${s?isFunction}", "${s?isMethod}");
assertConvertedSame("${s ? upperCase\t?\t\tleftPad(5)}");
assertConvertedSame("${s <#--1--> ? <#--2--> upperCase}");
// Runtime params:
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
index abb373e..095dc37 100644
--- a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperBridgeMethodsTest.java
@@ -20,12 +20,11 @@ package org.apache.freemarker.core.model.impl;
import static org.junit.Assert.*;
-import java.util.Collections;
-
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.NonTemplateCallPlace;
import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.Constants;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
import org.junit.Test;
public class Java8DefaultObjectWrapperBridgeMethodsTest {
@@ -53,12 +52,14 @@ public class Java8DefaultObjectWrapperBridgeMethodsTest {
} catch (Exception e) {
throw new IllegalStateException(e);
}
-
- TemplateMethodModel m1 = (TemplateMethodModel) wrapped.get("m1");
- assertEquals(BridgeMethodsBean.M1_RETURN_VALUE, "" + m1.execute(Collections.emptyList()));
-
- TemplateMethodModel m2 = (TemplateMethodModel) wrapped.get("m2");
- assertNull(m2.execute(Collections.emptyList()));
+
+ JavaMethodModel m1 = (JavaMethodModel) wrapped.get("m1");
+ assertEquals(
+ BridgeMethodsBean.M1_RETURN_VALUE,
+ "" + m1.execute(Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE));
+
+ JavaMethodModel m2 = (JavaMethodModel) wrapped.get("m2");
+ assertNull(m2.execute(Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
index 08dc5b1..c2bfad5 100644
--- a/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
+++ b/freemarker-core-test-java8/src/test/java/org/apache/freemarker/core/model/impl/Java8DefaultObjectWrapperTest.java
@@ -20,12 +20,12 @@ package org.apache.freemarker.core.model.impl;
import static org.junit.Assert.*;
-import java.util.Collections;
-
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.NonTemplateCallPlace;
import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.Constants;
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.TemplateNumberModel;
import org.apache.freemarker.core.model.TemplateScalarModel;
import org.apache.freemarker.core.model.TemplateSequenceModel;
@@ -61,13 +61,13 @@ public class Java8DefaultObjectWrapperTest {
// Has only indexed read method, so it's not exposed as a property
assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP));
- TemplateMethodModel indexedReadMethod = (TemplateMethodModel) wrappedBean.get(
+ JavaMethodModel indexedReadMethod = (JavaMethodModel) wrappedBean.get(
Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_GETTER);
assertNotNull(indexedReadMethod);
assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_VALUE,
- ((TemplateScalarModel) indexedReadMethod.execute(Collections.singletonList(new SimpleNumber(0))))
- .getAsString
- ());
+ ((TemplateScalarModel) indexedReadMethod.execute(
+ new TemplateModel[] { new SimpleNumber(0) }, NonTemplateCallPlace.INSTANCE))
+ .getAsString());
}
{
// We see default method indexed read method, but it's invalidated by normal getter in the subclass
@@ -114,45 +114,54 @@ public class Java8DefaultObjectWrapperTest {
// Has only indexed read method, so it's not exposed as a property
assertNull(wrappedBean.get(Java8DefaultMethodsBean.INDEXED_PROP_4));
- TemplateMethodModel indexedReadMethod = (TemplateMethodModel) wrappedBean.get(
+ JavaMethodModel indexedReadMethod = (JavaMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.INDEXED_PROP_GETTER_4);
assertNotNull(indexedReadMethod);
assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_4_VALUE,
- ((TemplateScalarModel) indexedReadMethod.execute(Collections.singletonList(new SimpleNumber(0))))
+ ((TemplateScalarModel) indexedReadMethod.execute(
+ new TemplateModel[] { new SimpleNumber(0) }, NonTemplateCallPlace.INSTANCE))
.getAsString());
}
{
- TemplateMethodModel action = (TemplateMethodModel) wrappedBean.get(
+ JavaMethodModel action = (JavaMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.NORMAL_ACTION);
assertNotNull(action);
assertEquals(
Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.execute(Collections.emptyList())).getAsString());
+ ((TemplateScalarModel) action.execute(
+ Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ .getAsString());
}
{
- TemplateMethodModel action = (TemplateMethodModel) wrappedBean.get(
+ JavaMethodModel action = (JavaMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.NORMAL_ACTION);
assertNotNull(action);
assertEquals(
Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.execute(Collections.emptyList())).getAsString());
+ ((TemplateScalarModel) action.execute(
+ Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ .getAsString());
}
{
- TemplateMethodModel action = (TemplateMethodModel) wrappedBean.get(
+ JavaMethodModel action = (JavaMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION);
assertNotNull(action);
assertEquals(
Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.execute(Collections.emptyList())).getAsString());
+ ((TemplateScalarModel) action.execute(
+ Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ .getAsString());
}
{
- TemplateMethodModel action = (TemplateMethodModel) wrappedBean.get(
+ JavaMethodModel action = (JavaMethodModel) wrappedBean.get(
Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION);
assertNotNull(action);
assertEquals(
Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE,
- ((TemplateScalarModel) action.execute(Collections.emptyList())).getAsString());
+ ((TemplateScalarModel) action.execute(
+ Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ .getAsString());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
index 7ee42c2..25a05ac 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java
@@ -137,7 +137,7 @@ public class DirectiveCallPlaceTest extends TemplateTest {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
@@ -207,7 +207,7 @@ public class DirectiveCallPlaceTest extends TemplateTest {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
@@ -245,7 +245,7 @@ public class DirectiveCallPlaceTest extends TemplateTest {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
index a094ec6..d79e37a 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/EnvironmentGetTemplateVariantsTest.java
@@ -207,7 +207,7 @@ public class EnvironmentGetTemplateVariantsTest extends TemplateTest {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
index 61c5823..1468e59 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TheadInterruptingSupportTest.java
@@ -129,7 +129,7 @@ public class TheadInterruptingSupportTest {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
@@ -150,7 +150,7 @@ public class TheadInterruptingSupportTest {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
@@ -173,7 +173,7 @@ public class TheadInterruptingSupportTest {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
index aac56b3..7d2b3fc 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/AbstractParallelIntrospectionTest.java
@@ -20,9 +20,10 @@
package org.apache.freemarker.core.model.impl;
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.NonTemplateCallPlace;
import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.Constants;
import org.apache.freemarker.core.model.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateNumberModel;
@@ -113,9 +114,11 @@ public abstract class AbstractParallelIntrospectionTest extends TestCase {
private void testMethod(TemplateHashModel h, int objIdx, int mIdx)
throws TemplateException, AssertionError {
- TemplateMethodModel pv = (TemplateMethodModel) h.get("m" + mIdx);
+ JavaMethodModel pv = (JavaMethodModel) h.get("m" + mIdx);
final int expected = objIdx * 1000 + mIdx;
- final int got = ((TemplateNumberModel) pv.execute(null)).getAsNumber().intValue();
+ final int got = ((TemplateNumberModel) pv.execute(
+ Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ .getAsNumber().intValue();
if (got != expected) {
throw new AssertionError("Method assertion failed; " +
"expected " + expected + ", but got " + got);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
index ef15dae..c4e42ab 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/CommonSupertypeForUnwrappingHintTest.java
@@ -22,6 +22,7 @@ package org.apache.freemarker.core.model.impl;
import java.io.Serializable;
import java.util.List;
+import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import junit.framework.TestCase;
@@ -110,17 +111,18 @@ public class CommonSupertypeForUnwrappingHintTest extends TestCase {
}
@Override
- Class[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) {
+ Class<?>[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) {
return memberDesc.getParamTypes();
}
@Override
- void afterWideningUnwrappingHints(Class[] paramTypes, int[] paramNumericalTypes) {
+ void afterWideningUnwrappingHints(Class<?>[] paramTypes, int[] paramNumericalTypes) {
// Do nothing
}
@Override
- MaybeEmptyMemberAndArguments getMemberAndArguments(List tmArgs, DefaultObjectWrapper w) throws TemplateModelException {
+ MaybeEmptyMemberAndArguments getMemberAndArguments(TemplateModel[] tmArgs, DefaultObjectWrapper w) throws
+ TemplateModelException {
throw new RuntimeException("Not implemented in this dummy.");
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
index dd1c841..9ac550c 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
@@ -41,18 +41,19 @@ import java.util.TreeSet;
import java.util.Vector;
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.NonTemplateCallPlace;
import org.apache.freemarker.core.Template;
import org.apache.freemarker.core.TemplateException;
import org.apache.freemarker.core.Version;
import org.apache.freemarker.core._CoreAPI;
import org.apache.freemarker.core.model.AdapterTemplateModel;
+import org.apache.freemarker.core.model.Constants;
import org.apache.freemarker.core.model.ObjectWrapper;
import org.apache.freemarker.core.model.TemplateBooleanModel;
import org.apache.freemarker.core.model.TemplateCollectionModel;
import org.apache.freemarker.core.model.TemplateCollectionModelEx;
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;
@@ -191,15 +192,16 @@ public class DefaultObjectWrapperTest {
assertEquals(1, ow.unwrap(bean.get("x")));
{
// Check method calls, and also if the return value is wrapped with the overidden "wrap".
- final TemplateModel mr = ((TemplateMethodModel) bean.get("m")).execute(
- Collections.<TemplateModel>emptyList());
+ final TemplateModel mr = ((JavaMethodModel) bean.get("m")).execute(
+ Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE);
assertEquals(Collections.singletonList(1), ow.unwrap(mr));
assertTrue(DefaultListAdapter.class.isInstance(mr));
}
{
// Check custom TM usage and round trip:
- final TemplateModel mr = ((TemplateMethodModel) bean.get("incTupple"))
- .execute(Collections.singletonList(ow.wrap(new Tupple<>(1, 2))));
+ final TemplateModel mr = ((JavaMethodModel) bean.get("incTupple"))
+ .execute(new TemplateModel[] { ow.wrap(new Tupple<>(1, 2)) },
+ NonTemplateCallPlace.INSTANCE);
assertEquals(new Tupple<>(2, 3), ow.unwrap(mr));
assertTrue(TuppleAdapter.class.isInstance(mr));
}
@@ -448,15 +450,15 @@ public class DefaultObjectWrapperTest {
final TemplateHashModel testBeanTM = (TemplateHashModel) dow.wrap(new RoundtripTesterBean());
{
- TemplateMethodModel getClassM = (TemplateMethodModel) testBeanTM.get("getClass");
- TemplateModel r = getClassM.execute(Collections.singletonList(objTM));
+ JavaMethodModel getClassM = (JavaMethodModel) testBeanTM.get("getClass");
+ TemplateModel r = getClassM.execute(new TemplateModel[] { objTM }, NonTemplateCallPlace.INSTANCE);
final Class rClass = (Class) ((WrapperTemplateModel) r).getWrappedObject();
assertThat(rClass, typeCompatibleWith(expectedPojoClass));
}
if (expectedPojoToString != null) {
- TemplateMethodModel getToStringM = (TemplateMethodModel) testBeanTM.get("toString");
- TemplateModel r = getToStringM.execute(Collections.singletonList(objTM));
+ JavaMethodModel getToStringM = (JavaMethodModel) testBeanTM.get("toString");
+ TemplateModel r = getToStringM.execute(new TemplateModel[] { objTM }, NonTemplateCallPlace.INSTANCE);
assertEquals(expectedPojoToString, ((TemplateScalarModel) r).getAsString());
}
}
@@ -583,8 +585,9 @@ public class DefaultObjectWrapperTest {
DefaultIteratorAdapter iteratorAdapter = (DefaultIteratorAdapter) wrappedIterator;
TemplateHashModel api = (TemplateHashModel) iteratorAdapter.getAPI();
- assertFalse(((TemplateBooleanModel) ((TemplateMethodModel)
- api.get("hasNext")).execute(Collections.<TemplateModel>emptyList())).getAsBoolean());
+ assertFalse(((TemplateBooleanModel) ((JavaMethodModel)
+ api.get("hasNext")).execute(Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ .getAsBoolean());
}
@SuppressWarnings("boxing")
@@ -673,8 +676,8 @@ public class DefaultObjectWrapperTest {
}
TemplateHashModel api = (TemplateHashModel) enumAdapter.getAPI();
- assertFalse(((TemplateBooleanModel) ((TemplateMethodModel) api.get("hasMoreElements"))
- .execute(Collections.<TemplateModel>emptyList())).getAsBoolean());
+ assertFalse(((TemplateBooleanModel) ((JavaMethodModel) api.get("hasMoreElements"))
+ .execute(Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE)).getAsBoolean());
}
@Test
@@ -729,8 +732,9 @@ public class DefaultObjectWrapperTest {
fail();
}
TemplateHashModel apiModel = (TemplateHashModel) ((TemplateModelWithAPISupport) normalModel).getAPI();
- TemplateMethodModel sizeMethod = (TemplateMethodModel) apiModel.get("size");
- TemplateNumberModel r = (TemplateNumberModel) sizeMethod.execute(Collections.<TemplateModel>emptyList());
+ JavaMethodModel sizeMethod = (JavaMethodModel) apiModel.get("size");
+ TemplateNumberModel r = (TemplateNumberModel) sizeMethod.execute(
+ Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE);
assertEquals(expectedSize, r.getAsNumber().intValue());
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
index 9373cf5..9336388 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/EnumModelsTest.java
@@ -21,11 +21,10 @@ package org.apache.freemarker.core.model.impl;
import static org.junit.Assert.*;
-import java.util.ArrayList;
-
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.NonTemplateCallPlace;
+import org.apache.freemarker.core.model.Constants;
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.TemplateScalarModel;
@@ -58,8 +57,10 @@ public class EnumModelsTest {
assertTrue(a instanceof TemplateScalarModel);
assertTrue(a instanceof TemplateHashModel);
assertEquals(((TemplateScalarModel) a).getAsString(), "ts:A");
- TemplateMethodModel nameMethod = (TemplateMethodModel) ((TemplateHashModel) a).get("name");
- assertEquals(((TemplateScalarModel) nameMethod.execute(new ArrayList())).getAsString(), "A");
+ JavaMethodModel nameMethod = (JavaMethodModel) ((TemplateHashModel) a).get("name");
+ assertEquals(((TemplateScalarModel) nameMethod.execute(
+ Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE)).getAsString(),
+ "A");
assertSame(e, enums.get(E.class.getName()));
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
index dcb8cf6..89b06be 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/ErrorMessagesTest.java
@@ -22,12 +22,12 @@ package org.apache.freemarker.core.model.impl;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
-import java.util.Collections;
import java.util.Date;
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.NonTemplateCallPlace;
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.TemplateScalarModel;
import org.apache.freemarker.core.outputformat.impl.HTMLOutputFormat;
@@ -60,9 +60,9 @@ public class ErrorMessagesTest {
TemplateHashModel thm = (TemplateHashModel) ow.wrap(new TestBean());
{
- TemplateMethodModel m = (TemplateMethodModel) thm.get("m1");
+ JavaMethodModel m = (JavaMethodModel) thm.get("m1");
try {
- m.execute(Collections.singletonList(html));
+ m.execute(new TemplateModel[] { html }, NonTemplateCallPlace.INSTANCE);
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(
@@ -72,9 +72,9 @@ public class ErrorMessagesTest {
}
{
- TemplateMethodModel m = (TemplateMethodModel) thm.get("m2");
+ JavaMethodModel m = (JavaMethodModel) thm.get("m2");
try {
- m.execute(Collections.singletonList(html));
+ m.execute(new TemplateModel[] { html }, NonTemplateCallPlace.INSTANCE);
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(
@@ -84,9 +84,9 @@ public class ErrorMessagesTest {
}
for (String methodName : new String[] { "mOverloaded", "mOverloaded3" }) {
- TemplateMethodModel m = (TemplateMethodModel) thm.get(methodName);
+ JavaMethodModel m = (JavaMethodModel)thm.get(methodName);
try {
- m.execute(Collections.singletonList(html));
+ m.execute(new TemplateModel[] { html }, NonTemplateCallPlace.INSTANCE);
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(
@@ -97,9 +97,9 @@ public class ErrorMessagesTest {
}
{
- TemplateMethodModel m = (TemplateMethodModel) thm.get("mOverloaded2");
+ JavaMethodModel m = (JavaMethodModel)thm.get("mOverloaded2");
try {
- m.execute(Collections.singletonList(html));
+ m.execute(new TemplateModel[] { html }, NonTemplateCallPlace.INSTANCE);
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(
@@ -110,8 +110,8 @@ public class ErrorMessagesTest {
}
{
- TemplateMethodModel m = (TemplateMethodModel) thm.get("mOverloaded4");
- Object r = m.execute(Collections.singletonList(html));
+ JavaMethodModel m = (JavaMethodModel)thm.get("mOverloaded4");
+ Object r = m.execute(new TemplateModel[] { html }, NonTemplateCallPlace.INSTANCE);
if (r instanceof TemplateScalarModel) {
r = ((TemplateScalarModel) r).getAsString();
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
index eb4d807..e5366f6 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/FineTuneMethodAppearanceTest.java
@@ -23,7 +23,6 @@ import static org.junit.Assert.*;
import org.apache.freemarker.core.Configuration;
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.TemplateScalarModel;
@@ -48,7 +47,7 @@ public class FineTuneMethodAppearanceTest {
assertEquals("v1", ((TemplateScalarModel) thm.get("v1")).getAsString());
assertEquals("v2()", ((TemplateScalarModel) thm.get("v2")).getAsString());
assertEquals("getV3()", ((TemplateScalarModel) thm.get("v3")).getAsString());
- assertTrue(thm.get("getV3") instanceof TemplateMethodModel);
+ assertTrue(thm.get("getV3") instanceof JavaMethodModel);
}
static public class C {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
index 44da42a..f888b2c 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/StaticModelsTest.java
@@ -22,11 +22,10 @@ package org.apache.freemarker.core.model.impl;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
-import java.util.ArrayList;
-
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.NonTemplateCallPlace;
+import org.apache.freemarker.core.model.Constants;
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.TemplateScalarModel;
@@ -65,8 +64,10 @@ public class StaticModelsTest {
assertEquals(((TemplateScalarModel) f).getAsString(), "F OK");
TemplateModel m = s.get("m");
- assertTrue(m instanceof TemplateMethodModel);
- assertEquals(((TemplateScalarModel) ((TemplateMethodModel) m).execute(new ArrayList())).getAsString(), "m OK");
+ assertTrue(m instanceof JavaMethodModel);
+ assertEquals(((TemplateScalarModel) ((JavaMethodModel) m).execute(
+ Constants.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE)).getAsString(),
+ "m OK");
assertSame(s, statics.get(S.class.getName()));
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/CoreTemplateTestSuite.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/CoreTemplateTestSuite.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/CoreTemplateTestSuite.java
index 0b21c75..6beb834 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/CoreTemplateTestSuite.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/CoreTemplateTestSuite.java
@@ -36,9 +36,9 @@ import org.apache.freemarker.core.templatesuite.models.JavaObjectInfo;
import org.apache.freemarker.core.templatesuite.models.Listables;
import org.apache.freemarker.core.templatesuite.models.MultiModel1;
import org.apache.freemarker.core.templatesuite.models.OverloadedMethods2;
+import org.apache.freemarker.core.templatesuite.models.SimpleTestFunction;
import org.apache.freemarker.core.templatesuite.models.TestBean;
import org.apache.freemarker.core.templatesuite.models.TestBoolean;
-import org.apache.freemarker.core.templatesuite.models.TestMethod;
import org.apache.freemarker.core.templatesuite.models.TestNode;
import org.apache.freemarker.core.templatesuite.models.VarArgTestModel;
import org.apache.freemarker.test.TemplateTestSuite;
@@ -158,7 +158,7 @@ public class CoreTemplateTestSuite extends TemplateTestSuite {
} else if (simpleTestName.equals("stringbimethods")) {
dataModel.put("multi", new TestBoolean());
} else if (simpleTestName.startsWith("type-builtins")) {
- dataModel.put("testmethod", new TestMethod());
+ dataModel.put("testfunction", new SimpleTestFunction());
dataModel.put("testnode", new TestNode());
dataModel.put("testcollection", new SimpleCollection(new ArrayList<>(), dow));
dataModel.put("testcollectionEx", DefaultNonListCollectionAdapter.adapt(new HashSet<>(), dow));
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java
index 3223652..ad4cbe3 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/MultiModel2.java
@@ -19,11 +19,12 @@
package org.apache.freemarker.core.templatesuite.models;
-import java.util.List;
-
+import org.apache.freemarker.core.CallPlace;
+import org.apache.freemarker.core.Environment;
import org.apache.freemarker.core.TemplateException;
import org.apache.freemarker.core._CallableUtils;
-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.TemplateScalarModel;
import org.apache.freemarker.core.model.impl.SimpleScalar;
@@ -31,34 +32,26 @@ import org.apache.freemarker.core.model.impl.SimpleScalar;
/**
* Testcase to see how FreeMarker deals with multiple Template models.
*/
-public class MultiModel2 implements TemplateScalarModel, TemplateMethodModel {
+public class MultiModel2 implements TemplateScalarModel, TemplateFunctionModel {
- /**
- * Returns the scalar's value as a String.
- *
- * @return the String value of this scalar.
- */
@Override
public String getAsString() {
return "Model2 is alive!";
}
- /**
- * Executes a method call.
- *
- * @param args a <tt>List</tt> of <tt>String</tt> objects containing the values
- * of the arguments passed to the method.
- * @return the <tt>TemplateModel</tt> produced by the method, or null.
- */
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env) throws TemplateException {
StringBuilder aResults = new StringBuilder( "Arguments are:<br />" );
- for (int i = 0; i < args.size(); i++) {
- TemplateModel arg = args.get(i);
- aResults.append(_CallableUtils.castArgToString(arg, i));
+ for (int i = 0; i < args.length; i++) {
+ aResults.append(_CallableUtils.castArgToString(args, i));
aResults.append("<br />");
}
return new SimpleScalar( aResults.toString() );
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestFunction.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestFunction.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestFunction.java
new file mode 100644
index 0000000..0f6f579
--- /dev/null
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestFunction.java
@@ -0,0 +1,44 @@
+/*
+ * 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.templatesuite.models;
+
+import org.apache.freemarker.core.CallPlace;
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.TemplateException;
+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.impl.SimpleScalar;
+
+/**
+ * A simple method model used as a test bed.
+ */
+public class SimpleTestFunction implements TemplateFunctionModel {
+
+ @Override
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env) throws TemplateException {
+ return new SimpleScalar("Argument value is: " + args[0]);
+ }
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestMethod.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestMethod.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestMethod.java
deleted file mode 100644
index 48352a0..0000000
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/SimpleTestMethod.java
+++ /dev/null
@@ -1,50 +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.templatesuite.models;
-
-import java.util.List;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-
-/**
- * A simple method model used as a test bed.
- */
-public class SimpleTestMethod implements TemplateMethodModel {
-
- /**
- * Executes a method call.
- *
- * @param args a <tt>List</tt> of <tt>String</tt> objects containing
- * the values of the arguments passed to the method.
- * @return the <tt>TemplateModel</tt> produced by the method, or null.
- */
- @Override
- public TemplateModel execute(List<? extends TemplateModel> args) {
- if ( args.size() == 0 ) {
- return new SimpleScalar( "Empty list provided" );
- } else if ( args.size() > 1 ) {
- return new SimpleScalar( "Argument size is: " + args.size() );
- } else {
- return new SimpleScalar( "Single argument value is: " + args.get(0) );
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TestMethod.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TestMethod.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TestMethod.java
deleted file mode 100644
index ed97f9e..0000000
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/templatesuite/models/TestMethod.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.apache.freemarker.core.templatesuite.models;
-
-import java.util.List;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.impl.SimpleScalar;
-
-public class TestMethod implements TemplateMethodModel {
-
- @Override
- public TemplateModel execute(List<? extends TemplateModel> args) {
- return new SimpleScalar("x");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
index d9bb394..27a42d9 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesDirective.java
@@ -122,7 +122,7 @@ public class AllFeaturesDirective extends TestTemplateCallableModel implements T
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java
index 5825745..f468be7 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/AllFeaturesFunction.java
@@ -105,7 +105,7 @@ public class AllFeaturesFunction extends TestTemplateCallableModel implements Te
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java
index a087188..268c7fc 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/NamedVarargsOnlyDirective.java
@@ -52,7 +52,7 @@ public class NamedVarargsOnlyDirective extends TestTemplateCallableModel impleme
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java
index 2f9532e..9bccfe5 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyDirective.java
@@ -46,7 +46,7 @@ public class PositionalVarargsOnlyDirective extends TestTemplateCallableModel im
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.POSITIONAL_VARARGS_PARAMETER_ONLY;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyFunction.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyFunction.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyFunction.java
index eb8a3eb..1c0c82c 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyFunction.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/PositionalVarargsOnlyFunction.java
@@ -56,7 +56,7 @@ public class PositionalVarargsOnlyFunction extends TestTemplateCallableModel imp
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
return ARGS_LAYOUT;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java
index 83b5435..3b3ed1c 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNamedParamsDirective.java
@@ -62,7 +62,7 @@ public class TwoNamedParamsDirective extends TestTemplateCallableModel implement
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java
index 6f768f4..e2d7ffb 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoNestedContentParamsDirective.java
@@ -48,7 +48,7 @@ public class TwoNestedContentParamsDirective extends TestTemplateCallableModel i
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java
index 008d8c8..a057bc3 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsDirective.java
@@ -51,7 +51,7 @@ public class TwoPositionalParamsDirective extends TestTemplateCallableModel impl
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsFunction.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsFunction.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsFunction.java
index 58e292b..e406c99 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsFunction.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/TwoPositionalParamsFunction.java
@@ -57,7 +57,7 @@ public class TwoPositionalParamsFunction extends TestTemplateCallableModel imple
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
return ARGS_LAYOUT;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java
index 05e5d6d..3936502 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/userpkg/UpperCaseDirective.java
@@ -47,7 +47,7 @@ public class UpperCaseDirective implements TemplateDirectiveModel {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
index 9bdea77..685ce5a 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/valueformat/NumberFormatTest.java
@@ -186,7 +186,7 @@ public class NumberFormatTest extends TemplateTest {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
index 538dd05..0b0a8f8 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-builtins.ast
@@ -24,7 +24,7 @@
#text // o.a.f.c.ASTStaticText
- content: "\n" // String
${...} // o.a.f.c.ASTDollarInterpolation
- - content: ...(...) // o.a.f.c.ASTExpMethodCall
+ - content: ...(...) // o.a.f.c.ASTExpFunctionCall
- callee: ?leftPad // o.a.f.c.BuiltInsForStringsBasic$padBI
- left-hand operand: x // o.a.f.c.ASTExpVariable
- right-hand operand: "leftPad" // String
@@ -32,7 +32,7 @@
#text // o.a.f.c.ASTStaticText
- content: "\n" // String
${...} // o.a.f.c.ASTDollarInterpolation
- - content: ...(...) // o.a.f.c.ASTExpMethodCall
+ - content: ...(...) // o.a.f.c.ASTExpFunctionCall
- callee: ?leftPad // o.a.f.c.BuiltInsForStringsBasic$padBI
- left-hand operand: x // o.a.f.c.ASTExpVariable
- right-hand operand: "leftPad" // String
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ast
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ast b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ast
index 9d9bb4b..3d66e58 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ast
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/ast-range.ast
@@ -115,12 +115,12 @@
- assignment target: "x" // String
- assignment operator: "=" // String
- assignment source: .. // o.a.f.c.ASTExpRange
- - left-hand operand: ...(...) // o.a.f.c.ASTExpMethodCall
+ - left-hand operand: ...(...) // o.a.f.c.ASTExpFunctionCall
- callee: ?indexOf // o.a.f.c.BuiltInsForStringsBasic$index_ofBI
- left-hand operand: n // o.a.f.c.ASTExpVariable
- right-hand operand: "indexOf" // String
- argument value: "x" // o.a.f.c.ASTExpStringLiteral
- - right-hand operand: ...(...) // o.a.f.c.ASTExpMethodCall
+ - right-hand operand: ...(...) // o.a.f.c.ASTExpFunctionCall
- callee: ?indexOf // o.a.f.c.BuiltInsForStringsBasic$index_ofBI
- left-hand operand: m // o.a.f.c.ASTExpVariable
- right-hand operand: "indexOf" // String
@@ -236,7 +236,7 @@
#text // o.a.f.c.ASTStaticText
- content: "\n" // String
${...} // o.a.f.c.ASTDollarInterpolation
- - content: ...(...) // o.a.f.c.ASTExpMethodCall
+ - content: ...(...) // o.a.f.c.ASTExpFunctionCall
- callee: f // o.a.f.c.ASTExpVariable
- argument value: .. // o.a.f.c.ASTExpRange
- left-hand operand: m // o.a.f.c.ASTExpVariable
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/number-literal.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/number-literal.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/number-literal.txt
index b80bc85..18311bd 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/number-literal.txt
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/number-literal.txt
@@ -69,11 +69,11 @@ twelve
<p>Numbers in method calls:</p>
-Single argument value is: 1
-Single argument value is: 1
-Single argument value is: 12
-Single argument value is: 3
-Single argument value is: 3
+Argument value is: 1
+Argument value is: 1
+Argument value is: 12
+Argument value is: 3
+Argument value is: 3
</body>
</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt
index eeb191e..4d48327 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/expected/type-builtins.txt
@@ -16,17 +16,17 @@
* specific language governing permissions and limitations
* under the License.
*/
-StNuBoMeMaHaHxSeCoCxEnInDiNo
-1 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 1 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 1 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 1 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 1 0 0 0 0 0 0 0 1 0
-0 0 0 0 0 1 1 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 1 0 0 1 1 0 0
-0 0 0 0 0 0 0 0 1 0 1 0 0 0
-0 0 0 0 0 0 0 0 1 1 1 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 1
-1 0 0 0 0 1 1 0 0 0 0 0 0 0
-0 0 0 1 0 0 0 0 0 0 0 0 0 0
-0 0 0 1 0 0 0 0 0 0 0 0 0 0
+StNuBoHaHxSeCoCxEnInFuDiNo
+1 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 1 0 0
+0 0 0 0 0 0 0 0 0 0 0 1 0
+0 0 0 1 1 0 0 0 0 0 0 0 0
+0 0 0 0 0 1 0 0 1 1 0 0 0
+0 0 0 0 0 0 1 0 1 0 0 0 0
+0 0 0 0 0 0 1 1 1 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 1
+1 0 0 1 1 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 1 0 0
+0 0 0 0 0 0 0 0 0 0 1 0 0
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/list2.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/list2.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/list2.ftl
index 9893c1b..7d563ed 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/list2.ftl
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/list2.ftl
@@ -82,7 +82,7 @@
<#function resolve(xs)>
<#assign resolveCallCnt = (resolveCallCnt!0) + 1>
- <#if xs?isMethod>
+ <#if xs?isFunction>
<#return xs()>
<#else>
<#return xs>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/number-literal.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/number-literal.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/number-literal.ftl
index 334841d..348d33b 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/number-literal.ftl
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/number-literal.ftl
@@ -44,7 +44,7 @@
"12" = "twelve",
"2one" = "two-one",
one2 = "one-two",
- call = "org.apache.freemarker.core.templatesuite.models.SimpleTestMethod"?new()
+ call = "org.apache.freemarker.core.templatesuite.models.SimpleTestFunction"?new()
>
<p>A simple test follows:</p>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/string-builtins3.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/string-builtins3.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/string-builtins3.ftl
index 6442c63..ece74f9 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/string-builtins3.ftl
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/string-builtins3.ftl
@@ -35,10 +35,10 @@
<@assertFails message='"m" flag'>
${'x'?keepBefore('x', 'm')}
</...@assertFails>
-<@assertFails message='3'>
+<@assertFails message='Too many arguments'>
${'x'?keepBefore('x', 'i', 'x')}
</...@assertFails>
-<@assertFails message='none'>
+<@assertFails message='argument'>
${'x'?keepBefore()}
</...@assertFails>
@@ -61,10 +61,10 @@
<@assertFails message='"m" flag'>
${'x'?keepBeforeLast('x', 'm')}
</...@assertFails>
-<@assertFails message='3'>
+<@assertFails message='Too many arguments'>
${'x'?keepBeforeLast('x', 'i', 'x')}
</...@assertFails>
-<@assertFails message='none'>
+<@assertFails message='argument'>
${'x'?keepBeforeLast()}
</...@assertFails>
@@ -87,10 +87,10 @@
<@assertFails message='"m" flag'>
${'x'?keepAfter('x', 'm')}
</...@assertFails>
-<@assertFails message='3'>
+<@assertFails message='Too many arguments'>
${'x'?keepAfter('x', 'i', 'x')}
</...@assertFails>
-<@assertFails message='none'>
+<@assertFails message='argument'>
${'x'?keepAfter()}
</...@assertFails>
@@ -115,10 +115,10 @@
<@assertFails message='"m" flag'>
${'x'?keepAfterLast('x', 'm')}
</...@assertFails>
-<@assertFails message='3'>
+<@assertFails message='Too many arguments'>
${'x'?keepAfterLast('x', 'i', 'x')}
</...@assertFails>
-<@assertFails message='none'>
+<@assertFails message='argument'>
${'x'?keepAfterLast()}
</...@assertFails>
@@ -129,10 +129,10 @@
<@assertEquals expected='o' actual='foo'?removeBeginning('fo') />
<@assertEquals expected='' actual='foo'?removeBeginning('foo') />
<@assertEquals expected='foo' actual='foo'?removeBeginning('') />
-<@assertFails message='2'>
+<@assertFails message='Too many arguments'>
${'x'?removeBeginning('x', 'x')}
</...@assertFails>
-<@assertFails message='none'>
+<@assertFails message='argument'>
${'x'?removeBeginning()}
</...@assertFails>
@@ -143,10 +143,10 @@
<@assertEquals expected='b' actual='bar'?removeEnding('ar') />
<@assertEquals expected='' actual='bar'?removeEnding('bar') />
<@assertEquals expected='bar' actual='bar'?removeEnding('') />
-<@assertFails message='2'>
+<@assertFails message='Too many arguments'>
${'x'?removeEnding('x', 'x')}
</...@assertFails>
-<@assertFails message='none'>
+<@assertFails message='argument'>
${'x'?removeEnding()}
</...@assertFails>
@@ -171,10 +171,10 @@
<@assertEquals expected='https://example.com' actual="https://example.com"?ensureStartsWith("[a-z]+://", "http://") />
<@assertEquals expected='http://HTTP://example.com' actual="HTTP://example.com"?ensureStartsWith("[a-z]+://", "http://") />
<@assertEquals expected='HTTP://example.com' actual="HTTP://example.com"?ensureStartsWith("[a-z]+://", "http://", "ir") />
-<@assertFails message='4'>
+<@assertFails message='Too many arguments'>
${'x'?ensureStartsWith('x', 'x', 'x', 'x')}
</...@assertFails>
-<@assertFails message='none'>
+<@assertFails message='argument'>
${'x'?ensureStartsWith()}
</...@assertFails>
@@ -185,10 +185,10 @@
<@assertEquals expected='foo' actual='foo'?ensureEndsWith('') />
<@assertEquals expected='x' actual=''?ensureEndsWith('x') />
<@assertEquals expected='' actual=''?ensureEndsWith('') />
-<@assertFails message='2'>
+<@assertFails message='Too many arguments'>
${'x'?ensureEndsWith('x', 'x')}
</...@assertFails>
-<@assertFails message='none'>
+<@assertFails message='argument'>
${'x'?ensureEndsWith()}
</...@assertFails>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl
index 695bd76..3442824 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/type-builtins.ftl
@@ -17,10 +17,10 @@
under the License.
-->
<#setting booleanFormat="1,0">
-StNuBoMeMaHaHxSeCoCxEnInDiNo
+StNuBoHaHxSeCoCxEnInFuDiNo
<#list [
"a", 1, false,
- testmethod, testmacro,
+ testfunction, testmacro,
{"a":1}, [1], testcollection, testcollectionEx,
testnode,
bean, bean.m, bean.mOverloaded
@@ -28,8 +28,6 @@ StNuBoMeMaHaHxSeCoCxEnInDiNo
${x?isString} <#t>
${x?isNumber} <#t>
${x?isBoolean} <#t>
- ${x?isMethod} <#t>
- ${x?isMacro} <#t>
${x?isHash} <#t>
${x?isHashEx} <#t>
${x?isSequence} <#t>
@@ -37,6 +35,7 @@ StNuBoMeMaHaHxSeCoCxEnInDiNo
${x?isCollectionEx} <#t>
${x?isEnumerable} <#t>
${x?isIndexable} <#t>
+ ${x?isFunction} <#t>
${x?isDirective} <#t>
${x?isNode}<#lt>
</#list>
[4/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java
index 1a0e251..9d797ce 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapper.java
@@ -42,7 +42,9 @@ import java.util.ResourceBundle;
import java.util.Set;
import java.util.WeakHashMap;
+import org.apache.freemarker.core.CallPlace;
import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.NonTemplateCallPlace;
import org.apache.freemarker.core.Version;
import org.apache.freemarker.core._CoreAPI;
import org.apache.freemarker.core._DelayedFTLTypeDescription;
@@ -55,8 +57,8 @@ import org.apache.freemarker.core.model.RichObjectWrapper;
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.TemplateFunctionModel;
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.TemplateModelAdapter;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -481,7 +483,7 @@ public class DefaultObjectWrapper implements RichObjectWrapper {
* Wraps a Java method so that it can be called from templates, without wrapping its parent ("this") object. The
* result is almost the same as that you would get by wrapping the parent object then getting the method from the
* resulting {@link TemplateHashModel} by name. Except, if the wrapped method is overloaded, with this method you
- * explicitly select a an overload, while otherwise you would get a {@link TemplateMethodModel} that selects an
+ * explicitly select an overload, while otherwise you would get a {@link OverloadedJavaMethodModel} that selects an
* overload each time it's called based on the argument values.
*
* @param object The object whose method will be called, or {@code null} if {@code method} is a static method.
@@ -489,8 +491,8 @@ public class DefaultObjectWrapper implements RichObjectWrapper {
* @param method The method to call, which must be an (inherited) member of the class of {@code object}, as
* described by {@link Method#invoke(Object, Object...)}
*/
- public TemplateMethodModel wrap(Object object, Method method) {
- return new JavaMethodModel(object, method, method.getParameterTypes(), this);
+ public TemplateFunctionModel wrap(Object object, Method method) {
+ return new SimpleJavaMethodModel(object, method, method.getParameterTypes(), this);
}
/**
@@ -582,7 +584,7 @@ public class DefaultObjectWrapper implements RichObjectWrapper {
// This is for transparent interop with other wrappers (and ourselves)
// Passing the targetClass allows e.g. a Jython-aware method that declares a
// PyObject as its argument to receive a PyObject from a Jython-aware TemplateModel
- // passed as an argument to TemplateMethodModel etc.
+ // passed as an argument to TemplateFunctionModel etc.
if (model instanceof AdapterTemplateModel) {
Object wrapped = ((AdapterTemplateModel) model).getAdaptedObject(targetClass);
if (targetClass == Object.class || targetClass.isInstance(wrapped)) {
@@ -1040,10 +1042,13 @@ public class DefaultObjectWrapper implements RichObjectWrapper {
* constructor. Overloaded constructors and varargs are supported. Only public constructors will be called.
*
* @param clazz The class whose constructor we will call.
- * @param arguments The list of {@link TemplateModel}-s to pass to the constructor after unwrapping them
+ * @param args The list of {@link TemplateModel}-s to pass to the constructor after unwrapping them
+ * @param callPlace Where the constructor is called from (which may contains information useful for overloaded
+ * constructor selection); you may want to use {@link NonTemplateCallPlace#INSTANCE}.
+ * if you call this from Java code.
* @return The instance created; it's not wrapped into {@link TemplateModel}.
*/
- public Object newInstance(Class<?> clazz, List/*<? extends TemplateModel>*/ arguments)
+ public Object newInstance(Class<?> clazz, TemplateModel[] args, CallPlace callPlace)
throws TemplateModelException {
try {
Object ctors = classIntrospector.get(clazz).get(ClassIntrospector.CONSTRUCTORS_KEY);
@@ -1052,19 +1057,19 @@ public class DefaultObjectWrapper implements RichObjectWrapper {
" has no public constructors.");
}
Constructor<?> ctor = null;
- Object[] objargs;
+ Object[] pojoArgs;
if (ctors instanceof SimpleMethod) {
SimpleMethod sm = (SimpleMethod) ctors;
ctor = (Constructor<?>) sm.getMember();
- objargs = sm.unwrapArguments(arguments, this);
+ pojoArgs = sm.unwrapArguments(args, this);
try {
- return ctor.newInstance(objargs);
+ return ctor.newInstance(pojoArgs);
} catch (Exception e) {
- if (e instanceof TemplateModelException) throw (TemplateModelException) e;
throw _MethodUtil.newInvocationTemplateModelException(null, ctor, e);
}
} else if (ctors instanceof OverloadedMethods) {
- final MemberAndArguments mma = ((OverloadedMethods) ctors).getMemberAndArguments(arguments, this);
+ // TODO [FM3] Utilize optional java type info in callPlace for overloaded method selection
+ final MemberAndArguments mma = ((OverloadedMethods) ctors).getMemberAndArguments(args, this);
try {
return mma.invokeConstructor(this);
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java
index f89952e..6fb04c6 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/JavaMethodModel.java
@@ -19,88 +19,34 @@
package org.apache.freemarker.core.model.impl;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.util.List;
-
-import org.apache.freemarker.core._UnexpectedTypeErrorExplainerTemplateModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.CallPlace;
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.TemplateException;
+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;
/**
- * Wraps a {@link Method} into the {@link TemplateMethodModel} interface. It is used by {@link BeanModel} to wrap
- * non-overloaded methods.
+ * Common super interface (marker interface) for {@link TemplateFunctionModel}-s that stand for Java methods; do not
+ * implement it yourself! It meant to be implemented inside FreeMarker only.
*/
-public final class JavaMethodModel extends SimpleMethod implements TemplateMethodModel,
- _UnexpectedTypeErrorExplainerTemplateModel {
- private final Object object;
- private final DefaultObjectWrapper wrapper;
-
- /**
- * Creates a model for a specific method on a specific object.
- * @param object the object to call the method on, or {@code null} for a static method.
- * @param method the method that will be invoked.
- * @param argTypes Either pass in {@code Method#getParameterTypes() method.getParameterTypes()} here,
- * or reuse an earlier result of that call (for speed). Not {@code null}.
- */
- JavaMethodModel(Object object, Method method, Class[] argTypes, DefaultObjectWrapper wrapper) {
- super(method, argTypes);
- this.object = object;
- this.wrapper = wrapper;
- }
+public interface JavaMethodModel extends TemplateFunctionModel {
/**
- * Invokes the method, passing it the arguments from the list.
+ * Calls {@link #execute(TemplateModel[], CallPlace, Environment)}, but it emphasizes that the
+ * {@link Environment} parameters is ignored, and passes {@code null} for it.
+ *
+ * @param args As {@link #getFunctionArgumentArrayLayout()} always return {@code null} in
+ * {@link JavaMethodModel}-s, the length of this array corresponds to the number of actual arguments
+ * specified on the call site, and all parameters will be positional.
+ *
+ * @param callPlace Same as with {@link #execute(TemplateModel[], CallPlace, Environment)}.
*/
- @Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- try {
- return wrapper.invokeMethod(object, (Method) getMember(),
- unwrapArguments(args, wrapper));
- } catch (TemplateModelException e) {
- throw e;
- } catch (Exception e) {
- throw _MethodUtil.newInvocationTemplateModelException(object, getMember(), e);
- }
- }
-
- @Override
- public String toString() {
- return getMember().toString();
- }
+ TemplateModel execute(TemplateModel[] args, CallPlace callPlace) throws TemplateException;
/**
- * Implementation of experimental interface; don't use it, no backward compatibility guarantee!
+ * Always returns {@code null} for {@link JavaMethodModel}-s; hence, only positional parameters are supported.
*/
@Override
- public Object[] explainTypeError(Class[] expectedClasses) {
- final Member member = getMember();
- if (!(member instanceof Method)) {
- return null; // This shouldn't occur
- }
- Method m = (Method) member;
-
- final Class returnType = m.getReturnType();
- if (returnType == null || returnType == void.class || returnType == Void.class) {
- return null; // Calling it won't help
- }
-
- String mName = m.getName();
- if (mName.startsWith("get") && mName.length() > 3 && Character.isUpperCase(mName.charAt(3))
- && (m.getParameterTypes().length == 0)) {
- return new Object[] {
- "Maybe using obj.something instead of obj.getSomething will yield the desired value." };
- } else if (mName.startsWith("is") && mName.length() > 2 && Character.isUpperCase(mName.charAt(2))
- && (m.getParameterTypes().length == 0)) {
- return new Object[] {
- "Maybe using obj.something instead of obj.isSomething will yield the desired value." };
- } else {
- return new Object[] {
- "Maybe using obj.something(",
- (m.getParameterTypes().length != 0 ? "params" : ""),
- ") instead of obj.something will yield the desired value" };
- }
- }
-
-}
\ No newline at end of file
+ ArgumentArrayLayout getFunctionArgumentArrayLayout();
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedFixArgsMethods.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedFixArgsMethods.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedFixArgsMethods.java
index bff717d..4a8b69b 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedFixArgsMethods.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedFixArgsMethods.java
@@ -18,10 +18,7 @@
*/
package org.apache.freemarker.core.model.impl;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
+import org.apache.freemarker.core.model.Constants;
import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -36,28 +33,28 @@ class OverloadedFixArgsMethods extends OverloadedMethodsSubset {
}
@Override
- Class[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) {
+ Class<?>[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) {
return memberDesc.getParamTypes();
}
@Override
- void afterWideningUnwrappingHints(Class[] paramTypes, int[] paramNumericalTypes) {
+ void afterWideningUnwrappingHints(Class<?>[] paramTypes, int[] paramNumericalTypes) {
// Do nothing
}
@Override
- MaybeEmptyMemberAndArguments getMemberAndArguments(List tmArgs, DefaultObjectWrapper unwrapper)
+ MaybeEmptyMemberAndArguments getMemberAndArguments(TemplateModel[] tmArgs, DefaultObjectWrapper unwrapper)
throws TemplateModelException {
if (tmArgs == null) {
// null is treated as empty args
- tmArgs = Collections.EMPTY_LIST;
+ tmArgs = Constants.EMPTY_TEMPLATE_MODEL_ARRAY;
}
- final int argCount = tmArgs.size();
- final Class[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount();
+ final int argCount = tmArgs.length;
+ final Class<?>[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount();
if (unwrappingHintsByParamCount.length <= argCount) {
return EmptyMemberAndArguments.WRONG_NUMBER_OF_ARGUMENTS;
}
- Class[] unwarppingHints = unwrappingHintsByParamCount[argCount];
+ Class<?>[] unwarppingHints = unwrappingHintsByParamCount[argCount];
if (unwarppingHints == null) {
return EmptyMemberAndArguments.WRONG_NUMBER_OF_ARGUMENTS;
}
@@ -69,10 +66,9 @@ class OverloadedFixArgsMethods extends OverloadedMethodsSubset {
typeFlags = null;
}
- Iterator it = tmArgs.iterator();
- for (int i = 0; i < argCount; ++i) {
+ for (int i = 0; i < argCount; i++) {
Object pojo = unwrapper.tryUnwrapTo(
- (TemplateModel) it.next(),
+ tmArgs[i],
unwarppingHints[i],
typeFlags != null ? typeFlags[i] : 0);
if (pojo == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedJavaMethodModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedJavaMethodModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedJavaMethodModel.java
new file mode 100644
index 0000000..1877687
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedJavaMethodModel.java
@@ -0,0 +1,86 @@
+/*
+ * 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.impl;
+
+
+import org.apache.freemarker.core.CallPlace;
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.TemplateException;
+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;
+
+/**
+ * Wraps a set of same-name overloaded methods behind {@link TemplateFunctionModel} interface,
+ * like if it was a single method; chooses among them behind the scenes on call-time based on the argument values
+ * (and the {@link CallPlace}).
+ *
+ * @see SimpleJavaMethodModel
+ */
+class OverloadedJavaMethodModel implements JavaMethodModel {
+
+ private final Object object;
+ private final OverloadedMethods overloadedMethods;
+ private final DefaultObjectWrapper wrapper;
+
+ OverloadedJavaMethodModel(Object object, OverloadedMethods overloadedMethods, DefaultObjectWrapper wrapper) {
+ this.object = object;
+ this.overloadedMethods = overloadedMethods;
+ this.wrapper = wrapper;
+ }
+
+ @Override
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace) throws TemplateException {
+ return execute(args, callPlace, null);
+ }
+
+ /**
+ * See {@link #execute(TemplateModel[], CallPlace)}; the {@link Environment} parameter can be {@code null} in this
+ * implementation. The actual method to call from several overloaded methods will be chosen based on the classes of
+ * the arguments.
+ *
+ * @throws TemplateModelException
+ * if the method cannot be chosen unambiguously.
+ */
+ @Override
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment envUnused)
+ throws TemplateModelException {
+ // TODO [FM3] Utilize optional java type info in callPlace for overloaded method selection
+ MemberAndArguments maa = overloadedMethods.getMemberAndArguments(args, wrapper);
+ try {
+ return maa.invokeMethod(wrapper, object);
+ } catch (Exception e) {
+ if (e instanceof TemplateModelException) throw (TemplateModelException) e;
+
+ throw _MethodUtil.newInvocationTemplateModelException(
+ object,
+ maa.getCallableMemberDescriptor(),
+ e);
+ }
+ }
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ // Required to return null! See inherited JavaDoc.
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethods.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethods.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethods.java
index 1ba1a56..fad854d 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethods.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethods.java
@@ -23,7 +23,6 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.List;
import org.apache.freemarker.core._DelayedConversionToString;
import org.apache.freemarker.core._ErrorDescriptionBuilder;
@@ -52,12 +51,12 @@ final class OverloadedMethods {
}
void addMethod(Method method) {
- final Class[] paramTypes = method.getParameterTypes();
+ final Class<?>[] paramTypes = method.getParameterTypes();
addCallableMemberDescriptor(new ReflectionCallableMemberDescriptor(method, paramTypes));
}
- void addConstructor(Constructor constr) {
- final Class[] paramTypes = constr.getParameterTypes();
+ void addConstructor(Constructor<?> constr) {
+ final Class<?>[] paramTypes = constr.getParameterTypes();
addCallableMemberDescriptor(new ReflectionCallableMemberDescriptor(constr, paramTypes));
}
@@ -72,7 +71,7 @@ final class OverloadedMethods {
}
}
- MemberAndArguments getMemberAndArguments(List/*<TemplateModel>*/ tmArgs, DefaultObjectWrapper unwrapper)
+ MemberAndArguments getMemberAndArguments(TemplateModel[] tmArgs, DefaultObjectWrapper unwrapper)
throws TemplateModelException {
// Try to find a oms args match:
MaybeEmptyMemberAndArguments fixArgsRes = fixArgMethods.getMemberAndArguments(tmArgs, unwrapper);
@@ -104,7 +103,7 @@ final class OverloadedMethods {
private Object[] toCompositeErrorMessage(
final EmptyMemberAndArguments fixArgsEmptyRes, final EmptyMemberAndArguments varargsEmptyRes,
- List tmArgs) {
+ TemplateModel[] tmArgs) {
final Object[] argsErrorMsg;
if (varargsEmptyRes != null) {
if (fixArgsEmptyRes == null || fixArgsEmptyRes.isNumberOfArgumentsWrong()) {
@@ -123,7 +122,7 @@ final class OverloadedMethods {
return argsErrorMsg;
}
- private Object[] toErrorMessage(EmptyMemberAndArguments res, List/*<TemplateModel>*/ tmArgs) {
+ private Object[] toErrorMessage(EmptyMemberAndArguments res, TemplateModel[] tmArgs) {
final Object[] unwrappedArgs = res.getUnwrappedArguments();
return new Object[] {
res.getErrorDescription(),
@@ -143,23 +142,26 @@ final class OverloadedMethods {
@Override
protected String doConversion(Object obj) {
- final Iterator fixArgMethodsIter = fixArgMethods.getMemberDescriptors();
- final Iterator varargMethodsIter = varargMethods != null ? varargMethods.getMemberDescriptors() : null;
+ final Iterator<ReflectionCallableMemberDescriptor> fixArgMethodsIter
+ = fixArgMethods.getMemberDescriptors();
+ final Iterator<ReflectionCallableMemberDescriptor> varargMethodsIter
+ = varargMethods != null ? varargMethods.getMemberDescriptors() : null;
- boolean hasMethods = fixArgMethodsIter.hasNext() || (varargMethodsIter != null && varargMethodsIter.hasNext());
+ boolean hasMethods = fixArgMethodsIter.hasNext()
+ || (varargMethodsIter != null && varargMethodsIter.hasNext());
if (hasMethods) {
StringBuilder sb = new StringBuilder();
- HashSet fixArgMethods = new HashSet();
+ HashSet<CallableMemberDescriptor> fixArgMethods = new HashSet<>();
while (fixArgMethodsIter.hasNext()) {
if (sb.length() != 0) sb.append(",\n");
sb.append(" ");
- CallableMemberDescriptor callableMemberDesc = (CallableMemberDescriptor) fixArgMethodsIter.next();
+ CallableMemberDescriptor callableMemberDesc = fixArgMethodsIter.next();
fixArgMethods.add(callableMemberDesc);
sb.append(callableMemberDesc.getDeclaration());
}
if (varargMethodsIter != null) {
while (varargMethodsIter.hasNext()) {
- CallableMemberDescriptor callableMemberDesc = (CallableMemberDescriptor) varargMethodsIter.next();
+ CallableMemberDescriptor callableMemberDesc = varargMethodsIter.next();
if (!fixArgMethods.contains(callableMemberDesc)) {
if (sb.length() != 0) sb.append(",\n");
sb.append(" ");
@@ -181,15 +183,16 @@ final class OverloadedMethods {
* allows finding a matching overload.
*/
private void addMarkupBITipAfterNoNoMarchIfApplicable(_ErrorDescriptionBuilder edb,
- List tmArgs) {
- for (int argIdx = 0; argIdx < tmArgs.size(); argIdx++) {
- Object tmArg = tmArgs.get(argIdx);
+ TemplateModel[] tmArgs) {
+ for (int argIdx = 0; argIdx < tmArgs.length; argIdx++) {
+ TemplateModel tmArg = tmArgs[argIdx];
if (tmArg instanceof TemplateMarkupOutputModel) {
- for (Iterator membDescs = fixArgMethods.getMemberDescriptors(); membDescs.hasNext();) {
- CallableMemberDescriptor membDesc = (CallableMemberDescriptor) membDescs.next();
- Class[] paramTypes = membDesc.getParamTypes();
+ for (Iterator<ReflectionCallableMemberDescriptor> membDescs = fixArgMethods.getMemberDescriptors();
+ membDescs.hasNext(); ) {
+ CallableMemberDescriptor membDesc = membDescs.next();
+ Class<?>[] paramTypes = membDesc.getParamTypes();
- Class paramType = null;
+ Class<?> paramType = null;
if (membDesc.isVarargs() && argIdx >= paramTypes.length - 1) {
paramType = paramTypes[paramTypes.length - 1];
if (paramType.isArray()) {
@@ -201,7 +204,7 @@ final class OverloadedMethods {
}
if (paramType != null) {
if (paramType.isAssignableFrom(String.class) && !paramType.isAssignableFrom(tmArg.getClass())) {
- edb.tip(JavaMethodModel.MARKUP_OUTPUT_TO_STRING_TIP);
+ edb.tip(SimpleJavaMethodModel.MARKUP_OUTPUT_TO_STRING_TIP);
return;
}
}
@@ -210,10 +213,10 @@ final class OverloadedMethods {
}
}
- private _DelayedConversionToString getTMActualParameterTypes(List arguments) {
- final String[] argumentTypeDescs = new String[arguments.size()];
- for (int i = 0; i < arguments.size(); i++) {
- argumentTypeDescs[i] = FTLUtil.getTypeDescription((TemplateModel) arguments.get(i));
+ private _DelayedConversionToString getTMActualParameterTypes(TemplateModel[] args) {
+ final String[] argumentTypeDescs = new String[args.length];
+ for (int i = 0; i < args.length; i++) {
+ argumentTypeDescs[i] = FTLUtil.getTypeDescription(args[i]);
}
return new DelayedCallSignatureToString(argumentTypeDescs) {
@@ -227,7 +230,7 @@ final class OverloadedMethods {
}
private Object getUnwrappedActualParameterTypes(Object[] unwrappedArgs) {
- final Class[] argumentTypes = new Class[unwrappedArgs.length];
+ final Class<?>[] argumentTypes = new Class<?>[unwrappedArgs.length];
for (int i = 0; i < unwrappedArgs.length; i++) {
Object unwrappedArg = unwrappedArgs[i];
argumentTypes[i] = unwrappedArg != null ? unwrappedArg.getClass() : null;
@@ -238,7 +241,7 @@ final class OverloadedMethods {
@Override
String argumentToString(Object argType) {
return argType != null
- ? _ClassUtil.getShortClassName((Class) argType)
+ ? _ClassUtil.getShortClassName((Class<?>) argType)
: _ClassUtil.getShortClassNameOfObject(null);
}
@@ -247,7 +250,7 @@ final class OverloadedMethods {
private abstract class DelayedCallSignatureToString extends _DelayedConversionToString {
- public DelayedCallSignatureToString(Object[] argTypeArray) {
+ DelayedCallSignatureToString(Object[] argTypeArray) {
super(argTypeArray);
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsModel.java
deleted file mode 100644
index 72ca642..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsModel.java
+++ /dev/null
@@ -1,65 +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.impl;
-
-
-import java.util.List;
-
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
-
-/**
- * Wraps a set of same-name overloaded methods behind {@link TemplateMethodModel} interface,
- * like if it was a single method, chooses among them behind the scenes on call-time based on the argument values.
- */
-class OverloadedMethodsModel implements TemplateMethodModel {
- private final Object object;
- private final OverloadedMethods overloadedMethods;
- private final DefaultObjectWrapper wrapper;
-
- OverloadedMethodsModel(Object object, OverloadedMethods overloadedMethods, DefaultObjectWrapper wrapper) {
- this.object = object;
- this.overloadedMethods = overloadedMethods;
- this.wrapper = wrapper;
- }
-
- /**
- * Invokes the method, passing it the arguments from the list. The actual
- * method to call from several overloaded methods will be chosen based
- * on the classes of the arguments.
- * @throws TemplateModelException if the method cannot be chosen
- * unambiguously.
- */
- @Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- MemberAndArguments maa = overloadedMethods.getMemberAndArguments(args, wrapper);
- try {
- return maa.invokeMethod(wrapper, object);
- } catch (Exception e) {
- if (e instanceof TemplateModelException) throw (TemplateModelException) e;
-
- throw _MethodUtil.newInvocationTemplateModelException(
- object,
- maa.getCallableMemberDescriptor(),
- e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsSubset.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsSubset.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsSubset.java
index e783af8..aab6d43 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsSubset.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedMethodsSubset.java
@@ -27,6 +27,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.util._ClassUtil;
import org.apache.freemarker.core.util._NullArgumentException;
@@ -52,7 +53,7 @@ abstract class OverloadedMethodsSubset {
ZERO_PARAM_COUNT_TYPE_FLAGS_ARRAY[0] = ALL_ZEROS_ARRAY;
}
- private Class[/*number of args*/][/*arg index*/] unwrappingHintsByParamCount;
+ private Class<?>[/*number of args*/][/*arg index*/] unwrappingHintsByParamCount;
/**
* Tells what types occur at a given parameter position with a bit field. See {@link TypeFlags}.
@@ -61,10 +62,10 @@ abstract class OverloadedMethodsSubset {
// TODO: This can cause memory-leak when classes are re-loaded. However, first the genericClassIntrospectionCache
// and such need to be oms in this regard.
- private final Map/*<ArgumentTypes, MaybeEmptyCallableMemberDescriptor>*/ argTypesToMemberDescCache
- = new ConcurrentHashMap(6, 0.75f, 1);
+ private final Map<ArgumentTypes, MaybeEmptyCallableMemberDescriptor> argTypesToMemberDescCache
+ = new ConcurrentHashMap<>(6, 0.75f, 1);
- private final List/*<ReflectionCallableMemberDescriptor>*/ memberDescs = new LinkedList();
+ private final List<ReflectionCallableMemberDescriptor> memberDescs = new LinkedList<>();
OverloadedMethodsSubset() {
//
@@ -75,7 +76,7 @@ abstract class OverloadedMethodsSubset {
// Warning: Do not modify this array, or put it into unwrappingHintsByParamCount by reference, as the arrays
// inside that are modified!
- final Class[] prepedParamTypes = preprocessParameterTypes(memberDesc);
+ final Class<?>[] prepedParamTypes = preprocessParameterTypes(memberDesc);
final int paramCount = prepedParamTypes.length; // Must be the same as the length of the original param list
// Merge these unwrapping hints with the existing table of hints:
@@ -83,13 +84,13 @@ abstract class OverloadedMethodsSubset {
unwrappingHintsByParamCount = new Class[paramCount + 1][];
unwrappingHintsByParamCount[paramCount] = prepedParamTypes.clone();
} else if (unwrappingHintsByParamCount.length <= paramCount) {
- Class[][] newUnwrappingHintsByParamCount = new Class[paramCount + 1][];
+ Class<?>[][] newUnwrappingHintsByParamCount = new Class[paramCount + 1][];
System.arraycopy(unwrappingHintsByParamCount, 0, newUnwrappingHintsByParamCount, 0,
unwrappingHintsByParamCount.length);
unwrappingHintsByParamCount = newUnwrappingHintsByParamCount;
unwrappingHintsByParamCount[paramCount] = prepedParamTypes.clone();
} else {
- Class[] unwrappingHints = unwrappingHintsByParamCount[paramCount];
+ Class<?>[] unwrappingHints = unwrappingHintsByParamCount[paramCount];
if (unwrappingHints == null) {
unwrappingHintsByParamCount[paramCount] = prepedParamTypes.clone();
} else {
@@ -123,7 +124,7 @@ abstract class OverloadedMethodsSubset {
afterWideningUnwrappingHints(prepedParamTypes, typeFlagsByParamIdx);
}
- Class[][] getUnwrappingHintsByParamCount() {
+ Class<?>[][] getUnwrappingHintsByParamCount() {
return unwrappingHintsByParamCount;
}
@@ -131,12 +132,11 @@ abstract class OverloadedMethodsSubset {
justification="Locks for member descriptor creation only")
final MaybeEmptyCallableMemberDescriptor getMemberDescriptorForArgs(Object[] args, boolean varArg) {
ArgumentTypes argTypes = new ArgumentTypes(args);
- MaybeEmptyCallableMemberDescriptor memberDesc
- = (MaybeEmptyCallableMemberDescriptor) argTypesToMemberDescCache.get(argTypes);
+ MaybeEmptyCallableMemberDescriptor memberDesc = argTypesToMemberDescCache.get(argTypes);
if (memberDesc == null) {
// Synchronized so that we won't unnecessarily invoke the same member desc. for multiple times in parallel.
synchronized (argTypesToMemberDescCache) {
- memberDesc = (MaybeEmptyCallableMemberDescriptor) argTypesToMemberDescCache.get(argTypes);
+ memberDesc = argTypesToMemberDescCache.get(argTypes);
if (memberDesc == null) {
memberDesc = argTypes.getMostSpecific(memberDescs, varArg);
argTypesToMemberDescCache.put(argTypes, memberDesc);
@@ -146,14 +146,14 @@ abstract class OverloadedMethodsSubset {
return memberDesc;
}
- Iterator/*<ReflectionCallableMemberDescriptor>*/ getMemberDescriptors() {
+ Iterator<ReflectionCallableMemberDescriptor> getMemberDescriptors() {
return memberDescs.iterator();
}
- abstract Class[] preprocessParameterTypes(CallableMemberDescriptor memberDesc);
- abstract void afterWideningUnwrappingHints(Class[] paramTypes, int[] paramNumericalTypes);
+ abstract Class<?>[] preprocessParameterTypes(CallableMemberDescriptor memberDesc);
+ abstract void afterWideningUnwrappingHints(Class<?>[] paramTypes, int[] paramNumericalTypes);
- abstract MaybeEmptyMemberAndArguments getMemberAndArguments(List/*<TemplateModel>*/ tmArgs,
+ abstract MaybeEmptyMemberAndArguments getMemberAndArguments(TemplateModel[] tmArgs,
DefaultObjectWrapper unwrapper) throws TemplateModelException;
/**
@@ -168,7 +168,7 @@ abstract class OverloadedMethodsSubset {
* @param c1 Parameter type 1
* @param c2 Parameter type 2
*/
- protected Class getCommonSupertypeForUnwrappingHint(Class c1, Class c2) {
+ Class<?> getCommonSupertypeForUnwrappingHint(Class<?> c1, Class<?> c2) {
if (c1 == c2) return c1;
// This also means that the hint for (Integer, Integer) will be Integer, not just Number. This is consistent
// with how non-overloaded method hints work.
@@ -214,7 +214,7 @@ abstract class OverloadedMethodsSubset {
// - One of classes was a primitive type
// - One of classes was a numerical type (either boxing type or primitive)
- Set commonTypes = _MethodUtil.getAssignables(c1, c2);
+ Set<Class<?>> commonTypes = _MethodUtil.getAssignables(c1, c2);
commonTypes.retainAll(_MethodUtil.getAssignables(c2, c1));
if (commonTypes.isEmpty()) {
// Can happen when at least one of the arguments is an interface, as
@@ -226,11 +226,11 @@ abstract class OverloadedMethodsSubset {
// because of interfaces. I.e., if you call this method for String.class
// and Number.class, you'll have Comparable, Serializable, and Object as
// maximal elements.
- List max = new ArrayList();
- listCommonTypes: for (Iterator commonTypesIter = commonTypes.iterator(); commonTypesIter.hasNext(); ) {
- Class clazz = (Class) commonTypesIter.next();
- for (Iterator maxIter = max.iterator(); maxIter.hasNext(); ) {
- Class maxClazz = (Class) maxIter.next();
+ List<Class<?>> max = new ArrayList<>();
+ listCommonTypes:
+ for (Class<?> clazz : commonTypes) {
+ for (Iterator<Class<?>> maxIter = max.iterator(); maxIter.hasNext(); ) {
+ Class<?> maxClazz = maxIter.next();
if (_MethodUtil.isMoreOrSameSpecificParameterType(maxClazz, clazz, false /*bugfixed [1]*/, 0) != 0) {
// clazz can't be maximal, if there's already a more specific or equal maximal than it.
continue listCommonTypes;
@@ -251,8 +251,8 @@ abstract class OverloadedMethodsSubset {
if (max.size() > 1) { // we have an ambiguity
// Find the non-interface class
- for (Iterator it = max.iterator(); it.hasNext(); ) {
- Class maxCl = (Class) it.next();
+ for (Iterator<Class<?>> it = max.iterator(); it.hasNext(); ) {
+ Class<?> maxCl = it.next();
if (!maxCl.isInterface()) {
if (maxCl != Object.class) { // This actually shouldn't ever happen, but to be sure...
// If it's not Object, we use it as the most specific
@@ -278,7 +278,7 @@ abstract class OverloadedMethodsSubset {
}
}
- return (Class) max.get(0);
+ return max.get(0);
}
/**
@@ -286,7 +286,7 @@ abstract class OverloadedMethodsSubset {
* count or if we are in pre-2.3.21 mode, or {@link #ALL_ZEROS_ARRAY} if there were no parameters that turned
* on a flag. The returned {@code int}-s are one or more {@link TypeFlags} constants binary "or"-ed together.
*/
- final protected int[] getTypeFlags(int paramCount) {
+ final int[] getTypeFlags(int paramCount) {
return typeFlagsByParamCount != null && typeFlagsByParamCount.length > paramCount
? typeFlagsByParamCount[paramCount]
: null;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedVarArgsMethods.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedVarArgsMethods.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedVarArgsMethods.java
index 6547923..8085693 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedVarArgsMethods.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/OverloadedVarArgsMethods.java
@@ -19,10 +19,8 @@
package org.apache.freemarker.core.model.impl;
import java.lang.reflect.Array;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
+import org.apache.freemarker.core.model.Constants;
import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -41,10 +39,10 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
* Replaces the last parameter type with the array component type of it.
*/
@Override
- Class[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) {
- final Class[] preprocessedParamTypes = memberDesc.getParamTypes().clone();
+ Class<?>[] preprocessParameterTypes(CallableMemberDescriptor memberDesc) {
+ final Class<?>[] preprocessedParamTypes = memberDesc.getParamTypes().clone();
int ln = preprocessedParamTypes.length;
- final Class varArgsCompType = preprocessedParamTypes[ln - 1].getComponentType();
+ final Class<?> varArgsCompType = preprocessedParamTypes[ln - 1].getComponentType();
if (varArgsCompType == null) {
throw new BugException("Only varargs methods should be handled here");
}
@@ -53,7 +51,7 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
}
@Override
- void afterWideningUnwrappingHints(Class[] paramTypes, int[] paramNumericalTypes) {
+ void afterWideningUnwrappingHints(Class<?>[] paramTypes, int[] paramNumericalTypes) {
// Overview
// --------
//
@@ -67,7 +65,7 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
// So we only update the already existing hints. Remember that we already have m(t1, t2) there.
final int paramCount = paramTypes.length;
- final Class[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount();
+ final Class<?>[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount();
// The case of e(t1, t2), e(t1, t2, t2), e(t1, t2, t2, t2), ..., where e is an *earlierly* added method.
// When that was added, this method wasn't added yet, so it had no chance updating the hints of this method,
@@ -75,7 +73,7 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
// FIXME: Only needed if m(t1, t2) was filled an empty slot, otherwise whatever was there was already
// widened by the preceding hints, so this will be a no-op.
for (int i = paramCount - 1; i >= 0; i--) {
- final Class[] previousHints = unwrappingHintsByParamCount[i];
+ final Class<?>[] previousHints = unwrappingHintsByParamCount[i];
if (previousHints != null) {
widenHintsToCommonSupertypes(
paramCount,
@@ -88,7 +86,7 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
// so we do that now:
// FIXME: Same as above; it's often unnecessary.
if (paramCount + 1 < unwrappingHintsByParamCount.length) {
- Class[] oneLongerHints = unwrappingHintsByParamCount[paramCount + 1];
+ Class<?>[] oneLongerHints = unwrappingHintsByParamCount[paramCount + 1];
if (oneLongerHints != null) {
widenHintsToCommonSupertypes(
paramCount,
@@ -114,8 +112,8 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
}
private void widenHintsToCommonSupertypes(
- int paramCountOfWidened, Class[] wideningTypes, int[] wideningTypeFlags) {
- final Class[] typesToWiden = getUnwrappingHintsByParamCount()[paramCountOfWidened];
+ int paramCountOfWidened, Class<?>[] wideningTypes, int[] wideningTypeFlags) {
+ final Class<?>[] typesToWiden = getUnwrappingHintsByParamCount()[paramCountOfWidened];
if (typesToWiden == null) {
return; // no such overload exists; nothing to widen
}
@@ -127,7 +125,7 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
typesToWiden[i] = getCommonSupertypeForUnwrappingHint(typesToWiden[i], wideningTypes[i]);
}
if (typesToWidenLen > wideningTypesLen) {
- Class varargsComponentType = wideningTypes[wideningTypesLen - 1];
+ Class<?> varargsComponentType = wideningTypes[wideningTypesLen - 1];
for (int i = wideningTypesLen; i < typesToWidenLen; ++i) {
typesToWiden[i] = getCommonSupertypeForUnwrappingHint(typesToWiden[i], varargsComponentType);
}
@@ -137,20 +135,20 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
}
@Override
- MaybeEmptyMemberAndArguments getMemberAndArguments(List tmArgs, DefaultObjectWrapper unwrapper)
+ MaybeEmptyMemberAndArguments getMemberAndArguments(TemplateModel[] tmArgs, DefaultObjectWrapper unwrapper)
throws TemplateModelException {
if (tmArgs == null) {
// null is treated as empty args
- tmArgs = Collections.EMPTY_LIST;
+ tmArgs = Constants.EMPTY_TEMPLATE_MODEL_ARRAY;
}
- final int argsLen = tmArgs.size();
- final Class[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount();
+ final int argsLen = tmArgs.length;
+ final Class<?>[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount();
final Object[] pojoArgs = new Object[argsLen];
int[] typesFlags = null;
// Going down starting from methods with args.length + 1 parameters, because we must try to match against a case
// where all specified args are fixargs, and we have 0 varargs.
outer: for (int paramCount = Math.min(argsLen + 1, unwrappingHintsByParamCount.length - 1); paramCount >= 0; --paramCount) {
- Class[] unwarappingHints = unwrappingHintsByParamCount[paramCount];
+ Class<?>[] unwarappingHints = unwrappingHintsByParamCount[paramCount];
if (unwarappingHints == null) {
if (paramCount == 0) {
return EmptyMemberAndArguments.WRONG_NUMBER_OF_ARGUMENTS;
@@ -164,11 +162,10 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
}
// Try to unwrap the arguments
- Iterator it = tmArgs.iterator();
- for (int i = 0; i < argsLen; ++i) {
+ for (int i = 0; i < argsLen; i++) {
int paramIdx = i < paramCount ? i : paramCount - 1;
Object pojo = unwrapper.tryUnwrapTo(
- (TemplateModel) it.next(),
+ tmArgs[i],
unwarappingHints[paramIdx],
typesFlags != null ? typesFlags[paramIdx] : 0);
if (pojo == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
@@ -187,7 +184,7 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
if (argsOrErrorIdx instanceof Object[]) {
pojoArgsWithArray = (Object[]) argsOrErrorIdx;
} else {
- return EmptyMemberAndArguments.noCompatibleOverload(((Integer) argsOrErrorIdx).intValue());
+ return EmptyMemberAndArguments.noCompatibleOverload((Integer) argsOrErrorIdx);
}
if (typesFlags != null) {
// Note that overloaded method selection has already accounted for overflow errors when the method
@@ -210,11 +207,11 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
* order (1-based index) of the argument that couldn't be unwrapped.
*/
private Object replaceVarargsSectionWithArray(
- Object[] args, List modelArgs, CallableMemberDescriptor memberDesc, DefaultObjectWrapper unwrapper)
- throws TemplateModelException {
- final Class[] paramTypes = memberDesc.getParamTypes();
+ Object[] args, TemplateModel[] tmArgs, CallableMemberDescriptor memberDesc, DefaultObjectWrapper unwrapper)
+ throws TemplateModelException {
+ final Class<?>[] paramTypes = memberDesc.getParamTypes();
final int paramCount = paramTypes.length;
- final Class varArgsCompType = paramTypes[paramCount - 1].getComponentType();
+ final Class<?> varArgsCompType = paramTypes[paramCount - 1].getComponentType();
final int totalArgCount = args.length;
final int fixArgCount = paramCount - 1;
if (args.length != paramCount) {
@@ -222,18 +219,18 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
System.arraycopy(args, 0, packedArgs, 0, fixArgCount);
Object varargs = Array.newInstance(varArgsCompType, totalArgCount - fixArgCount);
for (int i = fixArgCount; i < totalArgCount; ++i) {
- Object val = unwrapper.tryUnwrapTo((TemplateModel) modelArgs.get(i), varArgsCompType);
+ Object val = unwrapper.tryUnwrapTo(tmArgs[i], varArgsCompType);
if (val == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
- return Integer.valueOf(i + 1);
+ return i + 1;
}
Array.set(varargs, i - fixArgCount, val);
}
packedArgs[fixArgCount] = varargs;
return packedArgs;
} else {
- Object val = unwrapper.tryUnwrapTo((TemplateModel) modelArgs.get(fixArgCount), varArgsCompType);
+ Object val = unwrapper.tryUnwrapTo(tmArgs[fixArgCount], varArgsCompType);
if (val == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
- return Integer.valueOf(fixArgCount + 1);
+ return fixArgCount + 1;
}
Object array = Array.newInstance(varArgsCompType, 1);
Array.set(array, 0, val);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java
index 457c7ef..b4cca30 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ResourceBundleModel.java
@@ -22,16 +22,19 @@ package org.apache.freemarker.core.model.impl;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
+import org.apache.freemarker.core.CallPlace;
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core._CallableUtils;
import org.apache.freemarker.core._DelayedJQuote;
import org.apache.freemarker.core._TemplateModelException;
-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;
@@ -50,11 +53,7 @@ import org.apache.freemarker.core.model.TemplateModelException;
* for MessageFormat with arguments arg1, arg2 and arg3</li>
* </ul>
*/
-public class ResourceBundleModel
- extends
- BeanModel
- implements
- TemplateMethodModel {
+public class ResourceBundleModel extends BeanModel implements TemplateFunctionModel {
private Hashtable<String, MessageFormat> formats = null;
@@ -108,25 +107,23 @@ public class ResourceBundleModel
* rest of the arguments. The created MessageFormats are cached for later reuse.
*/
@Override
- public TemplateModel execute(List<? extends TemplateModel> args)
- throws TemplateModelException {
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env) throws TemplateException {
// Must have at least one argument - the key
- if (args.size() < 1)
- throw new TemplateModelException("No message key was specified");
+ if (args.length < 1)
+ throw new TemplateException("No message key was specified", env);
// Read it
- Iterator<? extends TemplateModel> it = args.iterator();
- String key = unwrap((TemplateModel) it.next()).toString();
+ String key = _CallableUtils.castArgToString(args, 0);
try {
- if (!it.hasNext()) {
+ if (args.length == 1) {
return wrap(((ResourceBundle) object).getObject(key));
}
-
+
// Copy remaining arguments into an Object[]
- int paramsLen = args.size() - 1;
+ int paramsLen = args.length - 1;
Object[] params = new Object[paramsLen];
for (int i = 0; i < paramsLen; ++i)
- params[i] = unwrap(it.next());
-
+ params[i] = unwrap(args[1 + i]);
+
// Invoke format
return new BeanAndStringModel(format(key, params), wrapper);
} catch (MissingResourceException e) {
@@ -136,6 +133,11 @@ public class ResourceBundleModel
}
}
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return null;
+ }
+
/**
* Provides direct access to caching format engine from code (instead of from script).
*/
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/SimpleJavaMethodModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/SimpleJavaMethodModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/SimpleJavaMethodModel.java
new file mode 100644
index 0000000..d27d131
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/SimpleJavaMethodModel.java
@@ -0,0 +1,123 @@
+/*
+ * 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.impl;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+import org.apache.freemarker.core.CallPlace;
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core._UnexpectedTypeErrorExplainerTemplateModel;
+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;
+
+/**
+ * Wraps a {@link Method} into the {@link TemplateFunctionModel} interface. It is used by {@link BeanModel} to wrap
+ * non-overloaded methods.
+ *
+ * @see OverloadedJavaMethodModel
+ */
+public final class SimpleJavaMethodModel extends SimpleMethod implements JavaMethodModel,
+ _UnexpectedTypeErrorExplainerTemplateModel {
+ private final Object object;
+ private final DefaultObjectWrapper wrapper;
+
+ /**
+ * Creates a model for a specific method on a specific object.
+ * @param object the object to call the method on, or {@code null} for a static method.
+ * @param method the method that will be invoked.
+ * @param argTypes Either pass in {@code Method#getParameterTypes() method.getParameterTypes()} here,
+ * or reuse an earlier result of that call (for speed). Not {@code null}.
+ */
+ SimpleJavaMethodModel(Object object, Method method, Class[] argTypes, DefaultObjectWrapper wrapper) {
+ super(method, argTypes);
+ this.object = object;
+ this.wrapper = wrapper;
+ }
+
+ @Override
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace) throws TemplateException {
+ return execute(args, callPlace, null);
+ }
+
+ /**
+ * See {@link #execute(TemplateModel[], CallPlace)}; the {@link Environment} parameter can be {@code null} in
+ * this implementation.
+ */
+ @Override
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment envUnused) throws
+ TemplateException {
+ try {
+ return wrapper.invokeMethod(object, (Method) getMember(), unwrapArguments(args, wrapper));
+ } catch (TemplateModelException e) {
+ throw e;
+ } catch (Exception e) {
+ throw _MethodUtil.newInvocationTemplateModelException(object, getMember(), e);
+ }
+ }
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ // Required to return null! See inherited JavaDoc.
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return getMember().toString();
+ }
+
+ /**
+ * Implementation of experimental interface; don't use it, no backward compatibility guarantee!
+ */
+ @Override
+ public Object[] explainTypeError(Class[] expectedClasses) {
+ final Member member = getMember();
+ if (!(member instanceof Method)) {
+ return null; // This shouldn't occur
+ }
+ Method m = (Method) member;
+
+ final Class returnType = m.getReturnType();
+ if (returnType == null || returnType == void.class || returnType == Void.class) {
+ return null; // Calling it won't help
+ }
+
+ String mName = m.getName();
+ if (mName.startsWith("get") && mName.length() > 3 && Character.isUpperCase(mName.charAt(3))
+ && (m.getParameterTypes().length == 0)) {
+ return new Object[] {
+ "Maybe using obj.something instead of obj.getSomething will yield the desired value." };
+ } else if (mName.startsWith("is") && mName.length() > 2 && Character.isUpperCase(mName.charAt(2))
+ && (m.getParameterTypes().length == 0)) {
+ return new Object[] {
+ "Maybe using obj.something instead of obj.isSomething will yield the desired value." };
+ } else {
+ return new Object[] {
+ "Maybe using obj.something(",
+ (m.getParameterTypes().length != 0 ? "params" : ""),
+ ") instead of obj.something will yield the desired value" };
+ }
+ }
+
+}
\ 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/impl/SimpleMethod.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/SimpleMethod.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/SimpleMethod.java
index d891190..678b9ed 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/SimpleMethod.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/SimpleMethod.java
@@ -20,14 +20,12 @@ package org.apache.freemarker.core.model.impl;
import java.lang.reflect.Array;
import java.lang.reflect.Member;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
import org.apache.freemarker.core._DelayedFTLTypeDescription;
import org.apache.freemarker.core._DelayedOrdinal;
import org.apache.freemarker.core._ErrorDescriptionBuilder;
import org.apache.freemarker.core._TemplateModelException;
+import org.apache.freemarker.core.model.Constants;
import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
import org.apache.freemarker.core.model.TemplateMarkupOutputModel;
import org.apache.freemarker.core.model.TemplateModel;
@@ -35,7 +33,7 @@ import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.util._ClassUtil;
/**
- * This class is used for as a base for non-overloaded method models and for constructors.
+ * This class is used as a base for non-overloaded method models and for constructors.
* (For overloaded methods and constructors see {@link OverloadedMethods}.)
*/
class SimpleMethod {
@@ -45,101 +43,101 @@ class SimpleMethod {
+ "But consider if the Java method whose argument it will be can handle markup strings properly.";
private final Member member;
- private final Class[] argTypes;
+ private final Class<?>[] argTypes;
- protected SimpleMethod(Member member, Class[] argTypes) {
+ SimpleMethod(Member member, Class<?>[] argTypes) {
this.member = member;
this.argTypes = argTypes;
}
- Object[] unwrapArguments(List arguments, DefaultObjectWrapper wrapper) throws TemplateModelException {
- if (arguments == null) {
- arguments = Collections.EMPTY_LIST;
+ Object[] unwrapArguments(TemplateModel[] args, DefaultObjectWrapper wrapper) throws TemplateModelException {
+ if (args == null) {
+ args = Constants.EMPTY_TEMPLATE_MODEL_ARRAY;
}
boolean isVarArg = _MethodUtil.isVarargs(member);
int typesLen = argTypes.length;
if (isVarArg) {
- if (typesLen - 1 > arguments.size()) {
+ if (typesLen - 1 > args.length) {
throw new _TemplateModelException(
_MethodUtil.invocationErrorMessageStart(member),
- " takes at least ", Integer.valueOf(typesLen - 1),
+ " takes at least ", typesLen - 1,
typesLen - 1 == 1 ? " argument" : " arguments", ", but ",
- Integer.valueOf(arguments.size()), " was given.");
+ args.length, " was given.");
}
- } else if (typesLen != arguments.size()) {
+ } else if (typesLen != args.length) {
throw new _TemplateModelException(
_MethodUtil.invocationErrorMessageStart(member),
- " takes ", Integer.valueOf(typesLen), typesLen == 1 ? " argument" : " arguments", ", but ",
- Integer.valueOf(arguments.size()), " was given.");
+ " takes ", typesLen, typesLen == 1 ? " argument" : " arguments", ", but ",
+ args.length, " was given.");
}
- return unwrapArguments(arguments, argTypes, isVarArg, wrapper);
+ return unwrapArguments(args, argTypes, isVarArg, wrapper);
}
- private Object[] unwrapArguments(List args, Class[] argTypes, boolean isVarargs,
+ private Object[] unwrapArguments(TemplateModel[] args, Class<?>[] argTypes, boolean isVarargs,
DefaultObjectWrapper w)
throws TemplateModelException {
if (args == null) return null;
int typesLen = argTypes.length;
- int argsLen = args.size();
+ int argsLen = args.length;
Object[] unwrappedArgs = new Object[typesLen];
// Unwrap arguments:
- Iterator it = args.iterator();
+ int argsIdx = 0;
int normalArgCnt = isVarargs ? typesLen - 1 : typesLen;
- int argIdx = 0;
- while (argIdx < normalArgCnt) {
- Class argType = argTypes[argIdx];
- TemplateModel argVal = (TemplateModel) it.next();
+ int unwrappedArgsIdx = 0;
+ while (unwrappedArgsIdx < normalArgCnt) {
+ Class<?> argType = argTypes[unwrappedArgsIdx];
+ TemplateModel argVal = args[argsIdx++];
Object unwrappedArgVal = w.tryUnwrapTo(argVal, argType);
if (unwrappedArgVal == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
- throw createArgumentTypeMismarchException(argIdx, argVal, argType);
+ throw createArgumentTypeMismatchException(unwrappedArgsIdx, argVal, argType);
}
if (unwrappedArgVal == null && argType.isPrimitive()) {
- throw createNullToPrimitiveArgumentException(argIdx, argType);
+ throw createNullToPrimitiveArgumentException(unwrappedArgsIdx, argType);
}
- unwrappedArgs[argIdx++] = unwrappedArgVal;
+ unwrappedArgs[unwrappedArgsIdx++] = unwrappedArgVal;
}
if (isVarargs) {
// The last argType, which is the vararg type, wasn't processed yet.
- Class varargType = argTypes[typesLen - 1];
- Class varargItemType = varargType.getComponentType();
- if (!it.hasNext()) {
- unwrappedArgs[argIdx++] = Array.newInstance(varargItemType, 0);
+ Class<?> varargType = argTypes[typesLen - 1];
+ Class<?> varargItemType = varargType.getComponentType();
+ if (argsIdx >= args.length) {
+ unwrappedArgs[unwrappedArgsIdx] = Array.newInstance(varargItemType, 0);
} else {
- TemplateModel argVal = (TemplateModel) it.next();
+ TemplateModel argVal = args[argsIdx++];
Object unwrappedArgVal;
// We first try to treat the last argument as a vararg *array*.
// This is consistent to what OverloadedVarArgMethod does.
- if (argsLen - argIdx == 1
+ if (argsLen - unwrappedArgsIdx == 1
&& (unwrappedArgVal = w.tryUnwrapTo(argVal, varargType))
!= ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
// It was a vararg array.
- unwrappedArgs[argIdx++] = unwrappedArgVal;
+ unwrappedArgs[unwrappedArgsIdx] = unwrappedArgVal;
} else {
// It wasn't a vararg array, so we assume it's a vararg
// array *item*, possibly followed by further ones.
- int varargArrayLen = argsLen - argIdx;
+ int varargArrayLen = argsLen - unwrappedArgsIdx;
Object varargArray = Array.newInstance(varargItemType, varargArrayLen);
for (int varargIdx = 0; varargIdx < varargArrayLen; varargIdx++) {
- TemplateModel varargVal = (TemplateModel) (varargIdx == 0 ? argVal : it.next());
+ TemplateModel varargVal = varargIdx == 0 ? argVal : args[argsIdx++];
Object unwrappedVarargVal = w.tryUnwrapTo(varargVal, varargItemType);
if (unwrappedVarargVal == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
- throw createArgumentTypeMismarchException(
- argIdx + varargIdx, varargVal, varargItemType);
+ throw createArgumentTypeMismatchException(
+ unwrappedArgsIdx + varargIdx, varargVal, varargItemType);
}
if (unwrappedVarargVal == null && varargItemType.isPrimitive()) {
- throw createNullToPrimitiveArgumentException(argIdx + varargIdx, varargItemType);
+ throw createNullToPrimitiveArgumentException(unwrappedArgsIdx + varargIdx, varargItemType);
}
Array.set(varargArray, varargIdx, unwrappedVarargVal);
}
- unwrappedArgs[argIdx++] = varargArray;
+ unwrappedArgs[unwrappedArgsIdx] = varargArray;
}
}
}
@@ -147,11 +145,11 @@ class SimpleMethod {
return unwrappedArgs;
}
- private TemplateModelException createArgumentTypeMismarchException(
- int argIdx, TemplateModel argVal, Class targetType) {
+ private TemplateModelException createArgumentTypeMismatchException(
+ int argIdx, TemplateModel argVal, Class<?> targetType) {
_ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
_MethodUtil.invocationErrorMessageStart(member), " couldn't be called: Can't convert the ",
- new _DelayedOrdinal(Integer.valueOf(argIdx + 1)),
+ new _DelayedOrdinal(argIdx + 1),
" argument's value to the target Java type, ", _ClassUtil.getShortClassName(targetType),
". The type of the actual value was: ", new _DelayedFTLTypeDescription(argVal));
if (argVal instanceof TemplateMarkupOutputModel && (targetType.isAssignableFrom(String.class))) {
@@ -160,10 +158,10 @@ class SimpleMethod {
return new _TemplateModelException(desc);
}
- private TemplateModelException createNullToPrimitiveArgumentException(int argIdx, Class targetType) {
+ private TemplateModelException createNullToPrimitiveArgumentException(int argIdx, Class<?> targetType) {
return new _TemplateModelException(
_MethodUtil.invocationErrorMessageStart(member), " couldn't be called: The value of the ",
- new _DelayedOrdinal(Integer.valueOf(argIdx + 1)),
+ new _DelayedOrdinal(argIdx + 1),
" argument was null, but the target Java parameter type (", _ClassUtil.getShortClassName(targetType),
") is primitive and so can't store null.");
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java
index 9c4db4e..fc32348 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/StaticModel.java
@@ -27,20 +27,18 @@ import java.util.Iterator;
import java.util.Map;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Wraps the static fields and methods of a class in a
- * {@link org.apache.freemarker.core.model.TemplateHashModel}.
- * Fields are wrapped using {@link DefaultObjectWrapper#wrap(Object)}, and
- * methods are wrapped into an appropriate {@link TemplateMethodModel} instance.
- * Unfortunately, there is currently no support for bean property-style
- * calls of static methods, similar to that in {@link BeanModel}.
+ * Wraps the static fields and methods of a class in a {@link org.apache.freemarker.core.model.TemplateHashModel}.
+ * Fields are wrapped using {@link DefaultObjectWrapper#wrap(Object)}, and methods are wrapped into an appropriate
+ * {@link TemplateFunctionModel} instance. There is currently no support for bean property-style calls of static
+ * methods, similar to that in {@link BeanModel} (as it's not part for the JavaBeans specification).
*/
final class StaticModel implements TemplateHashModelEx {
@@ -167,10 +165,10 @@ final class StaticModel implements TemplateHashModelEx {
Object value = entry.getValue();
if (value instanceof Method) {
Method method = (Method) value;
- entry.setValue(new JavaMethodModel(null, method,
+ entry.setValue(new SimpleJavaMethodModel(null, method,
method.getParameterTypes(), wrapper));
} else if (value instanceof OverloadedMethods) {
- entry.setValue(new OverloadedMethodsModel(null, (OverloadedMethods) value, wrapper));
+ entry.setValue(new OverloadedJavaMethodModel(null, (OverloadedMethods) value, wrapper));
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java
index 2394394..a93df33 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/TemplateModelListSequence.java
@@ -21,26 +21,29 @@ package org.apache.freemarker.core.model.impl;
import java.util.List;
-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.TemplateSequenceModel;
/**
* A sequence that wraps a {@link List} of {@link TemplateModel}-s. It does not copy the original
- * list. It's mostly useful when implementing {@link TemplateMethodModel}-es that collect items from other
+ * list. It's mostly useful when implementing {@link TemplateFunctionModel}-es that collect items from other
* {@link TemplateModel}-s.
*/
public class TemplateModelListSequence implements TemplateSequenceModel {
- private List/*<TemplateModel>*/ list;
+ private final List<? extends TemplateModel> list;
- public TemplateModelListSequence(List list) {
+ /**
+ * @param list The list of items; will not be copied, will not be modified.
+ */
+ public TemplateModelListSequence(List<? extends TemplateModel> list) {
this.list = list;
}
@Override
public TemplateModel get(int index) {
- return (TemplateModel) list.get(index);
+ return list.get(index);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/_MethodUtil.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/_MethodUtil.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/_MethodUtil.java
index 82da455..004ebaa 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/_MethodUtil.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/_MethodUtil.java
@@ -64,7 +64,7 @@ public final class _MethodUtil {
* </ul>
*/
// TODO Seems that we don't use the full functionality of this anymore, so we could simplify this. See usages.
- public static int isMoreOrSameSpecificParameterType(final Class specific, final Class generic, boolean bugfixed,
+ static int isMoreOrSameSpecificParameterType(final Class<?> specific, final Class<?> generic, boolean bugfixed,
int ifHigherThan) {
if (ifHigherThan >= 4) return 0;
if (generic.isAssignableFrom(specific)) {
@@ -79,7 +79,7 @@ public final class _MethodUtil {
return isWideningPrimitiveNumberConversion(specific, generic) ? 3 : 0;
} else { // => specificIsPrim && !genericIsPrim
if (bugfixed) {
- final Class specificAsBoxed = _ClassUtil.primitiveClassToBoxingClass(specific);
+ final Class<?> specificAsBoxed = _ClassUtil.primitiveClassToBoxingClass(specific);
if (specificAsBoxed == generic) {
// A primitive class is more specific than its boxing class, because it can't store null
return 2;
@@ -110,7 +110,7 @@ public final class _MethodUtil {
} // of: !generic.isAssignableFrom(specific)
}
- private static boolean isWideningPrimitiveNumberConversion(final Class source, final Class target) {
+ private static boolean isWideningPrimitiveNumberConversion(final Class<?> source, final Class<?> target) {
if (target == Short.TYPE && (source == Byte.TYPE)) {
return true;
} else if (target == Integer.TYPE &&
@@ -134,7 +134,7 @@ public final class _MethodUtil {
}
}
- private static boolean isWideningBoxedNumberConversion(final Class source, final Class target) {
+ private static boolean isWideningBoxedNumberConversion(final Class<?> source, final Class<?> target) {
if (target == Short.class && source == Byte.class) {
return true;
} else if (target == Integer.class &&
@@ -161,42 +161,42 @@ public final class _MethodUtil {
/**
* Attention, this doesn't handle primitive classes correctly, nor numerical conversions.
*/
- public static Set getAssignables(Class c1, Class c2) {
- Set s = new HashSet();
+ static Set<Class<?>> getAssignables(Class<?> c1, Class<?> c2) {
+ Set<Class<?>> s = new HashSet<>();
collectAssignables(c1, c2, s);
return s;
}
- private static void collectAssignables(Class c1, Class c2, Set s) {
+ private static void collectAssignables(Class<?> c1, Class<?> c2, Set<Class<?>> s) {
if (c1.isAssignableFrom(c2)) {
s.add(c1);
}
- Class sc = c1.getSuperclass();
+ Class<?> sc = c1.getSuperclass();
if (sc != null) {
collectAssignables(sc, c2, s);
}
- Class[] itf = c1.getInterfaces();
- for (Class anItf : itf) {
+ Class<?>[] itf = c1.getInterfaces();
+ for (Class<?> anItf : itf) {
collectAssignables(anItf, c2, s);
}
}
- public static Class[] getParameterTypes(Member member) {
+ public static Class<?>[] getParameterTypes(Member member) {
if (member instanceof Method) {
return ((Method) member).getParameterTypes();
}
- if (member instanceof Constructor) {
- return ((Constructor) member).getParameterTypes();
+ if (member instanceof Constructor<?>) {
+ return ((Constructor<?>) member).getParameterTypes();
}
throw new IllegalArgumentException("\"member\" must be Method or Constructor");
}
- public static boolean isVarargs(Member member) {
+ static boolean isVarargs(Member member) {
if (member instanceof Method) {
return ((Method) member).isVarArgs();
}
if (member instanceof Constructor) {
- return ((Constructor) member).isVarArgs();
+ return ((Constructor<?>) member).isVarArgs();
}
throw new BugException();
}
@@ -223,7 +223,7 @@ public final class _MethodUtil {
sb.append(member.getName());
sb.append('(');
- Class[] paramTypes = _MethodUtil.getParameterTypes(member);
+ Class<?>[] paramTypes = _MethodUtil.getParameterTypes(member);
for (int i = 0; i < paramTypes.length; i++) {
if (i != 0) sb.append(", ");
String paramTypeDecl = _ClassUtil.getShortClassName(paramTypes[i]);
@@ -239,7 +239,7 @@ public final class _MethodUtil {
return sb.toString();
}
- public static Object[] invocationErrorMessageStart(Member member) {
+ static Object[] invocationErrorMessageStart(Member member) {
return invocationErrorMessageStart(member, member instanceof Constructor);
}
@@ -247,7 +247,7 @@ public final class _MethodUtil {
return new Object[] { "Java ", isConstructor ? "constructor " : "method ", new _DelayedJQuote(member) };
}
- public static TemplateModelException newInvocationTemplateModelException(Object object, Member member, Throwable e) {
+ static TemplateModelException newInvocationTemplateModelException(Object object, Member member, Throwable e) {
return newInvocationTemplateModelException(
object,
member,
@@ -256,7 +256,7 @@ public final class _MethodUtil {
e);
}
- public static TemplateModelException newInvocationTemplateModelException(Object object, CallableMemberDescriptor callableMemberDescriptor, Throwable e) {
+ static TemplateModelException newInvocationTemplateModelException(Object object, CallableMemberDescriptor callableMemberDescriptor, Throwable e) {
return newInvocationTemplateModelException(
object,
new _DelayedConversionToString(callableMemberDescriptor) {
@@ -294,7 +294,7 @@ public final class _MethodUtil {
* Extracts the JavaBeans property from a reader method name, or returns {@code null} if the method name doesn't
* look like a reader method name.
*/
- public static String getBeanPropertyNameFromReaderMethodName(String name, Class<?> returnType) {
+ static String getBeanPropertyNameFromReaderMethodName(String name, Class<?> returnType) {
int start;
if (name.startsWith("get")) {
start = 3;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/util/FTLUtil.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/FTLUtil.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/FTLUtil.java
index 2923647..7c58284 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/FTLUtil.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/util/FTLUtil.java
@@ -34,7 +34,6 @@ 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.TemplateMarkupOutputModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelIterator;
import org.apache.freemarker.core.model.TemplateNodeModel;
@@ -45,6 +44,7 @@ import org.apache.freemarker.core.model.TemplateSequenceModel;
import org.apache.freemarker.core.model.WrapperTemplateModel;
import org.apache.freemarker.core.model.impl.BeanAndStringModel;
import org.apache.freemarker.core.model.impl.BeanModel;
+import org.apache.freemarker.core.model.impl.JavaMethodModel;
/**
* Static utility methods that perform tasks specific to the FreeMarker Template Language (FTL).
@@ -760,7 +760,7 @@ public final class FTLUtil {
}
if (callable instanceof TemplateFunctionModel) {
- String f = "function"; // TODO [FM3][CF] Should say "method" sometimes
+ String f = callable instanceof JavaMethodModel ? "method" : "function";
result = d == null ? f : d + "+" + f;
}
@@ -799,7 +799,8 @@ public final class FTLUtil {
appendTypeName(sb, typeNamesAppended, _CoreAPI.isMacro(cl) ? "macro" : "directive");
}
if (TemplateFunctionModel.class.isAssignableFrom(cl)) {
- appendTypeName(sb, typeNamesAppended, "function"); // TODO [FM3][CF] should say "method" sometimes
+ appendTypeName(sb, typeNamesAppended,
+ JavaMethodModel.class.isAssignableFrom(cl) ? "method" : "function");
}
}
@@ -812,10 +813,6 @@ public final class FTLUtil {
appendTypeName(sb, typeNamesAppended, "iterator");
}
- if (TemplateMethodModel.class.isAssignableFrom(cl)) {
- appendTypeName(sb, typeNamesAppended, "method");
- }
-
if (Environment.Namespace.class.isAssignableFrom(cl)) {
appendTypeName(sb, typeNamesAppended, "namespace");
} else if (TemplateHashModelEx.class.isAssignableFrom(cl)) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/javacc/FTL.jj b/freemarker-core/src/main/javacc/FTL.jj
index 5d1b354..4201d84 100644
--- a/freemarker-core/src/main/javacc/FTL.jj
+++ b/freemarker-core/src/main/javacc/FTL.jj
@@ -2040,7 +2040,7 @@ ASTExpression DynamicKey(ASTExpression exp) :
/**
* production for an arglist part of a method invocation.
*/
-ASTExpMethodCall MethodArgs(ASTExpression exp) :
+ASTExpFunctionCall MethodArgs(ASTExpression exp) :
{
ArrayList args = new ArrayList();
Token end;
@@ -2051,7 +2051,7 @@ ASTExpMethodCall MethodArgs(ASTExpression exp) :
end = <CLOSE_PAREN>
{
args.trimToSize();
- ASTExpMethodCall result = new ASTExpMethodCall(exp, args);
+ ASTExpFunctionCall result = new ASTExpFunctionCall(exp, args);
result.setLocation(template, exp, end);
return result;
}
[8/8] incubator-freemarker git commit: FREEMARKER-64: Merged: FM3
Unification and improvement of function-like constructs
Posted by dd...@apache.org.
FREEMARKER-64: Merged: FM3 Unification and improvement of function-like constructs
Merge commit 'refs/pull/32/head' of https://github.com/apache/incubator-freemarker into 3
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/b867458a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/b867458a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/b867458a
Branch: refs/heads/3
Commit: b867458aa2dd937aeec20ab8cf764d2040815ac8
Parents: a3311d5 8d5263f
Author: ddekany <dd...@apache.org>
Authored: Tue Aug 8 00:40:09 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Tue Aug 8 00:40:57 2017 +0200
----------------------------------------------------------------------
.gitignore | 2 +
FM3-CHANGE-LOG.txt | 19 +-
.../core/FM2ASTToFM3SourceConverter.java | 4 +
.../converter/FM2ToFM3ConverterTest.java | 4 +
...a8DefaultObjectWrapperBridgeMethodsTest.java | 32 +-
.../impl/Java8DefaultObjectWrapperTest.java | 50 ++--
.../freemarker/core/DirectiveCallPlaceTest.java | 6 +-
.../EnvironmentGetTemplateVariantsTest.java | 2 +-
.../core/TheadInterruptingSupportTest.java | 6 +-
.../impl/AbstractParallelIntrospectionTest.java | 14 +-
.../CommonSupertypeForUnwrappingHintTest.java | 8 +-
.../model/impl/DefaultObjectWrapperTest.java | 59 ++--
.../core/model/impl/EnumModelsTest.java | 11 +-
.../core/model/impl/ErrorMessagesTest.java | 24 +-
.../impl/FineTuneMethodAppearanceTest.java | 3 +-
.../core/model/impl/StaticModelsTest.java | 11 +-
.../templatesuite/CoreTemplateTestSuite.java | 4 +-
.../core/templatesuite/models/MultiModel2.java | 40 ++-
.../models/SimpleTestFunction.java | 44 +++
.../templatesuite/models/SimpleTestMethod.java | 49 ---
.../core/templatesuite/models/TestMethod.java | 12 -
.../core/userpkg/AllFeaturesDirective.java | 21 +-
.../core/userpkg/AllFeaturesFunction.java | 22 +-
.../core/userpkg/NamedVarargsOnlyDirective.java | 2 +-
.../userpkg/PositionalVarargsOnlyDirective.java | 2 +-
.../userpkg/PositionalVarargsOnlyFunction.java | 2 +-
.../core/userpkg/TestTemplateCallableModel.java | 14 +-
.../core/userpkg/TwoNamedParamsDirective.java | 2 +-
.../TwoNestedContentParamsDirective.java | 2 +-
.../userpkg/TwoPositionalParamsDirective.java | 2 +-
.../userpkg/TwoPositionalParamsFunction.java | 2 +-
.../core/userpkg/UpperCaseDirective.java | 2 +-
.../core/valueformat/NumberFormatTest.java | 2 +-
.../org/apache/freemarker/core/ast-builtins.ast | 4 +-
.../org/apache/freemarker/core/ast-range.ast | 6 +-
.../templatesuite/expected/number-literal.txt | 10 +-
.../templatesuite/expected/stringbimethods.txt | 2 -
.../templatesuite/expected/type-builtins.txt | 28 +-
.../core/templatesuite/templates/list2.ftl | 2 +-
.../templatesuite/templates/number-literal.ftl | 2 +-
.../templates/string-builtins3.ftl | 32 +-
.../templatesuite/templates/stringbimethods.ftl | 4 -
.../templatesuite/templates/type-builtins.ftl | 7 +-
.../freemarker/core/ASTDynamicTopLevelCall.java | 77 +++--
.../apache/freemarker/core/ASTExpBuiltIn.java | 68 +++--
.../freemarker/core/ASTExpFunctionCall.java | 229 ++++++++++++++
.../freemarker/core/ASTExpListLiteral.java | 30 +-
.../freemarker/core/ASTExpMethodCall.java | 230 --------------
.../freemarker/core/BuiltInsForDates.java | 47 ++-
.../core/BuiltInsForExistenceHandling.java | 49 +--
.../core/BuiltInsForMultipleTypes.java | 120 ++++----
.../BuiltInsForNestedContentParameters.java | 20 +-
.../freemarker/core/BuiltInsForNodes.java | 38 ++-
.../freemarker/core/BuiltInsForSequences.java | 156 +++++-----
.../core/BuiltInsForStringsBasic.java | 299 ++++++++++++-------
.../core/BuiltInsForStringsEncoding.java | 23 +-
.../freemarker/core/BuiltInsForStringsMisc.java | 32 +-
.../core/BuiltInsForStringsRegexp.java | 51 ++--
.../org/apache/freemarker/core/Environment.java | 25 +-
.../org/apache/freemarker/core/MessageUtil.java | 2 +-
.../freemarker/core/NonFunctionException.java | 62 ++++
.../freemarker/core/NonMethodException.java | 62 ----
.../freemarker/core/NonStringException.java | 14 +-
.../apache/freemarker/core/_CallableUtils.java | 169 +++++++++++
.../core/_ObjectBuilderSettingEvaluator.java | 31 +-
.../core/_TemplateCallableModelUtils.java | 112 -------
.../freemarker/core/debug/DebugModel.java | 3 +-
.../core/debug/RmiDebugModelImpl.java | 8 +-
.../core/model/ArgumentArrayLayout.java | 18 ++
.../core/model/GeneralPurposeNothing.java | 18 +-
.../core/model/TemplateCallableModel.java | 11 +-
.../core/model/TemplateDirectiveModel.java | 45 ++-
.../core/model/TemplateFunctionModel.java | 10 +
.../core/model/TemplateMethodModel.java | 60 ----
.../core/model/TemplateMethodModelEx.java | 54 ----
.../core/model/TemplateModelException.java | 4 +-
.../freemarker/core/model/impl/BeanModel.java | 16 +-
.../core/model/impl/DefaultObjectWrapper.java | 29 +-
.../core/model/impl/JavaMethodModel.java | 95 ++----
.../model/impl/OverloadedFixArgsMethods.java | 24 +-
.../model/impl/OverloadedJavaMethodModel.java | 86 ++++++
.../core/model/impl/OverloadedMethods.java | 59 ++--
.../core/model/impl/OverloadedMethodsModel.java | 65 ----
.../model/impl/OverloadedMethodsSubset.java | 52 ++--
.../model/impl/OverloadedVarArgsMethods.java | 57 ++--
.../core/model/impl/ResourceBundleModel.java | 46 +--
.../core/model/impl/SimpleJavaMethodModel.java | 123 ++++++++
.../core/model/impl/SimpleMethod.java | 86 +++---
.../freemarker/core/model/impl/StaticModel.java | 15 +-
.../model/impl/TemplateModelListSequence.java | 13 +-
.../freemarker/core/model/impl/_MethodUtil.java | 40 +--
.../apache/freemarker/core/util/FTLUtil.java | 11 +-
freemarker-core/src/main/javacc/FTL.jj | 4 +-
.../apache/freemarker/servlet/IncludePage.java | 2 +-
.../jsp/CustomTagAndELFunctionCombiner.java | 157 ----------
.../freemarker/servlet/jsp/JspTagModelBase.java | 33 +-
.../servlet/jsp/SimpleTagDirectiveModel.java | 2 +-
.../servlet/jsp/TagDirectiveModel.java | 2 +-
.../freemarker/servlet/jsp/TaglibFactory.java | 22 +-
...eDirectiveModelAndTemplateFunctionModel.java | 77 +++++
.../freemarker/servlet/jsp/TLDParsingTest.java | 19 +-
.../test/templateutil/AssertDirective.java | 2 +-
.../templateutil/AssertEqualsDirective.java | 2 +-
.../test/templateutil/AssertFailsDirective.java | 2 +-
.../test/templateutil/NoOutputDirective.java | 2 +-
105 files changed, 2055 insertions(+), 1841 deletions(-)
----------------------------------------------------------------------
[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
Posted by dd...@apache.org.
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);
}
[6/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java
index 3fe5f74..f579f6f 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDynamicTopLevelCall.java
@@ -101,6 +101,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
TemplateCallableModel callableValue;
TemplateDirectiveModel directive;
TemplateFunctionModel function;
+ ArgumentArrayLayout argsLayout;
boolean nestedContentSupported;
{
TemplateModel callableValueTM = callableValueExp._eval(env);
@@ -108,6 +109,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
callableValue = (TemplateCallableModel) callableValueTM;
directive = (TemplateDirectiveModel) callableValueTM;
function = null;
+ argsLayout = directive.getDirectiveArgumentArrayLayout();
nestedContentSupported = directive.isNestedContentSupported();
} else if (callableValueTM instanceof TemplateFunctionModel) {
if (!allowCallingFunctions) {
@@ -117,6 +119,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
callableValue = (TemplateCallableModel) callableValueTM;
directive = null;
function = (TemplateFunctionModel) callableValue;
+ argsLayout = function.getFunctionArgumentArrayLayout();
nestedContentSupported = false;
} else if (callableValueTM == null) {
throw InvalidReferenceException.getInstance(callableValueExp, env);
@@ -129,7 +132,39 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
throw new _MiscTemplateException(env, "Nested content is not supported by this directive.");
}
- ArgumentArrayLayout argsLayout = callableValue.getArgumentArrayLayout();
+ TemplateModel[] execArgs = argsLayout != null
+ ? getExecuteArgsBasedOnLayout(argsLayout, callableValue, env)
+ : getExecuteArgsWithoutLayout(callableValue, env);
+
+ if (directive != null) {
+ directive.execute(execArgs, this, env.getOut(), env);
+ } else {
+ TemplateModel result = function.execute(execArgs, this, env);
+ if (result == null) {
+ throw new _MiscTemplateException(env, "Function has returned no value (or null)");
+ }
+ // TODO [FM3] Implement it when we have a such language... it should work like `${f()}`.
+ throw new BugException("Top-level function call not yet implemented");
+ }
+
+ return null;
+ }
+
+ private TemplateModel[] getExecuteArgsWithoutLayout(TemplateCallableModel callableValue, Environment env)
+ throws TemplateException {
+ if (namedArgs != null) {
+ throw new _MiscTemplateException(env, getNamedArgumentsNotSupportedMessage(callableValue, namedArgs[0]));
+ }
+ TemplateModel[] execArgs = new TemplateModel[positionalArgs.length];
+ for (int i = 0; i < positionalArgs.length; i++) {
+ ASTExpression positionalArg = positionalArgs[i];
+ execArgs[i] = positionalArg.eval(env);
+ }
+ return execArgs;
+ }
+
+ private TemplateModel[] getExecuteArgsBasedOnLayout(ArgumentArrayLayout argsLayout, TemplateCallableModel callableValue,
+ Environment env) throws TemplateException {
int predefPosArgCnt = argsLayout.getPredefinedPositionalArgumentCount();
int posVarargsArgIdx = argsLayout.getPositionalVarargsArgumentIndex();
@@ -157,7 +192,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
}
execArgs[posVarargsArgIdx] = varargsSeq;
} else if (positionalArgs != null && positionalArgs.length > predefPosArgCnt) {
- checkSupportsAnyParameters(callableValue, env);
+ checkSupportsAnyParameters(callableValue, argsLayout, env);
List<String> validPredefNames = argsLayout.getPredefinedNamedArgumentsMap().getKeys();
_ErrorDescriptionBuilder errorDesc = new _ErrorDescriptionBuilder(
"The target ", FTLUtil.getCallableTypeName(callableValue), " ",
@@ -194,16 +229,11 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
} else {
if (namedVarargsHash == null) {
if (namedVarargsArgumentIndex == -1) {
- checkSupportsAnyParameters(callableValue, env);
+ checkSupportsAnyParameters(callableValue, argsLayout, env);
Collection<String> validNames = predefNamedArgsMap.getKeys();
throw new _MiscTemplateException(env,
validNames == null || validNames.isEmpty()
- ? new Object[] {
- "The called ", FTLUtil.getCallableTypeName(callableValue),
- " can't have arguments that are passed by name (like ",
- new _DelayedJQuote(namedArg.name), "). Try to pass arguments by position "
- + "(i.e, without name, as in ", "<@example 1, 2, 3 />" , ")."
- }
+ ? getNamedArgumentsNotSupportedMessage(callableValue, namedArg)
: new Object[] {
"The called ", FTLUtil.getCallableTypeName(callableValue),
" has no parameter that's passed by name and is called ",
@@ -221,24 +251,23 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
if (namedVarargsArgumentIndex != -1) {
execArgs[namedVarargsArgumentIndex] = namedVarargsHash != null ? namedVarargsHash : Constants.EMPTY_HASH;
}
+ return execArgs;
+ }
- if (directive != null) {
- directive.execute(execArgs, this, env.getOut(), env);
- } else {
- TemplateModel result = function.execute(execArgs, this, env);
- if (result == null) {
- throw new _MiscTemplateException(env, "Function has returned no value (or null)");
- }
- // TODO [FM3] Implement it when we have a such language... it should work like `${f()}`.
- throw new BugException("Top-level function call not yet implemented");
- }
-
- return null;
+ private Object[] getNamedArgumentsNotSupportedMessage(TemplateCallableModel callableValue,
+ NamedArgument namedArg) {
+ return new Object[] {
+ "The called ", FTLUtil.getCallableTypeName(callableValue),
+ " can't have arguments that are passed by name (like ",
+ new _DelayedJQuote(namedArg.name), "). Try to pass arguments by position "
+ + "(i.e, without name, as in ", "<@example 1, 2, 3 />" , ")."
+ };
}
- private void checkSupportsAnyParameters(TemplateCallableModel callableValue, Environment env)
- throws _MiscTemplateException {
- if (callableValue.getArgumentArrayLayout().getTotalLength() == 0) {
+ private void checkSupportsAnyParameters(
+ TemplateCallableModel callableValue, ArgumentArrayLayout argsLayout, Environment env)
+ throws TemplateException {
+ if (argsLayout.getTotalLength() == 0) {
throw new _MiscTemplateException(env,
"The called ", FTLUtil.getCallableTypeName(callableValue), " doesn't support any parameters.");
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java
index a74f83f..c69c297 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpBuiltIn.java
@@ -140,9 +140,8 @@ abstract class ASTExpBuiltIn extends ASTExpression implements Cloneable {
putBI("isHash", new BuiltInsForMultipleTypes.is_hashBI());
putBI("isInfinite", new is_infiniteBI());
putBI("isIndexable", new BuiltInsForMultipleTypes.is_indexableBI());
- putBI("isMacro", new BuiltInsForMultipleTypes.is_macroBI());
putBI("isMarkupOutput", new BuiltInsForMultipleTypes.is_markup_outputBI());
- putBI("isMethod", new BuiltInsForMultipleTypes.is_methodBI());
+ putBI("isFunction", new BuiltInsForMultipleTypes.is_functionBI());
putBI("isNan", new is_nanBI());
putBI("isNode", new BuiltInsForMultipleTypes.is_nodeBI());
putBI("isNumber", new BuiltInsForMultipleTypes.is_numberBI());
@@ -391,7 +390,11 @@ abstract class ASTExpBuiltIn extends ASTExpression implements Cloneable {
protected final void checkMethodArgCount(List args, int expectedCnt) throws TemplateModelException {
checkMethodArgCount(args.size(), expectedCnt);
}
-
+
+ protected final void checkMethodArgCount(TemplateModel[] args, int expectedCnt) throws TemplateModelException {
+ checkMethodArgCount(args.length, expectedCnt);
+ }
+
protected final void checkMethodArgCount(int argCnt, int expectedCnt) throws TemplateModelException {
if (argCnt != expectedCnt) {
throw MessageUtil.newArgCntError("?" + key, argCnt, expectedCnt);
@@ -401,48 +404,79 @@ abstract class ASTExpBuiltIn extends ASTExpression implements Cloneable {
protected final void checkMethodArgCount(List args, int minCnt, int maxCnt) throws TemplateModelException {
checkMethodArgCount(args.size(), minCnt, maxCnt);
}
-
+
+ protected final void checkMethodArgCount(TemplateModel[] args, int minCnt, int maxCnt) throws
+ TemplateModelException {
+ checkMethodArgCount(args.length, minCnt, maxCnt);
+ }
+
protected final void checkMethodArgCount(int argCnt, int minCnt, int maxCnt) throws TemplateModelException {
if (argCnt < minCnt || argCnt > maxCnt) {
throw MessageUtil.newArgCntError("?" + key, argCnt, minCnt, maxCnt);
}
}
- /**
- * Same as {@link #getStringMethodArg}, but checks if {@code args} is big enough, and returns {@code null} if it
- * isn't.
- */
- protected final String getOptStringMethodArg(List args, int argIdx)
- throws TemplateModelException {
- return args.size() > argIdx ? getStringMethodArg(args, argIdx) : null;
+ protected final String getStringMethodArg(TemplateModel[] args, int argIdx) throws TemplateModelException {
+ return getStringMethodArg(args, argIdx, false);
}
-
+
/**
* Gets a method argument and checks if it's a string; it does NOT check if {@code args} is big enough.
*/
- protected final String getStringMethodArg(List args, int argIdx)
+ protected final String getStringMethodArg(TemplateModel[] args, int argIdx, boolean optional)
+ throws TemplateModelException {
+ TemplateModel arg = args[argIdx];
+ return getStringMethodArg(arg, argIdx, optional);
+ }
+
+ protected String getStringMethodArg(TemplateModel arg, int argIdx)
+ throws TemplateModelException {
+ return getStringMethodArg(arg, argIdx, false);
+ }
+
+ protected String getStringMethodArg(TemplateModel arg, int argIdx, boolean optional)
throws TemplateModelException {
- TemplateModel arg = (TemplateModel) args.get(argIdx);
if (!(arg instanceof TemplateScalarModel)) {
+ if (optional && arg == null) {
+ return null;
+ }
throw MessageUtil.newMethodArgMustBeStringException("?" + key, argIdx, arg);
} else {
return _EvalUtil.modelToString((TemplateScalarModel) arg, null, null);
}
}
+ protected final Number getNumberMethodArg(TemplateModel[] args, int argIdx)
+ throws TemplateModelException {
+ return getNumberMethodArg(args, argIdx, false);
+ }
+
/**
* Gets a method argument and checks if it's a number; it does NOT check if {@code args} is big enough.
*/
- protected final Number getNumberMethodArg(List args, int argIdx)
+ protected final Number getNumberMethodArg(TemplateModel[] args, int argIdx, boolean optional)
+ throws TemplateModelException {
+ TemplateModel arg = args[argIdx];
+ return getNumberMethodArg(arg, argIdx, optional);
+ }
+
+ protected Number getNumberMethodArg(TemplateModel arg, int argIdx)
+ throws TemplateModelException {
+ return getNumberMethodArg(arg, argIdx, false);
+ }
+
+ protected Number getNumberMethodArg(TemplateModel arg, int argIdx, boolean optional)
throws TemplateModelException {
- TemplateModel arg = (TemplateModel) args.get(argIdx);
if (!(arg instanceof TemplateNumberModel)) {
+ if (optional && arg == null) {
+ return null;
+ }
throw MessageUtil.newMethodArgMustBeNumberException("?" + key, argIdx, arg);
} else {
return _EvalUtil.modelToNumber((TemplateNumberModel) arg, null);
}
}
-
+
protected final TemplateModelException newMethodArgInvalidValueException(int argIdx, Object[] details) {
return MessageUtil.newMethodArgInvalidValueException("?" + key, argIdx, details);
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpFunctionCall.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpFunctionCall.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpFunctionCall.java
new file mode 100644
index 0000000..40dc6e3
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpFunctionCall.java
@@ -0,0 +1,229 @@
+/*
+ * 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.
+ */
+
+/*
+ * 22 October 1999: This class added by Holger Arendt.
+ */
+
+package org.apache.freemarker.core;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.freemarker.core.model.ArgumentArrayLayout;
+import org.apache.freemarker.core.model.Constants;
+import org.apache.freemarker.core.model.TemplateFunctionModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+import org.apache.freemarker.core.util.CommonSupplier;
+import org.apache.freemarker.core.util.FTLUtil;
+
+
+/**
+ * AST expression node: {@code exp(args)}.
+ */
+final class ASTExpFunctionCall extends ASTExpression implements CallPlace {
+
+ private final ASTExpression target;
+ private final ASTExpListLiteral arguments;
+
+ ASTExpFunctionCall(ASTExpression target, ArrayList arguments) {
+ this(target, new ASTExpListLiteral(arguments));
+ }
+
+ private ASTExpFunctionCall(ASTExpression target, ASTExpListLiteral arguments) {
+ this.target = target;
+ this.arguments = arguments;
+ }
+
+ @Override
+ TemplateModel _eval(Environment env) throws TemplateException {
+ TemplateModel targetModel = target.eval(env);
+
+ if (!(targetModel instanceof TemplateFunctionModel)) {
+ throw new NonFunctionException(target, targetModel, env);
+ }
+ TemplateFunctionModel func = (TemplateFunctionModel) targetModel;
+
+ ArgumentArrayLayout arrayLayout = func.getFunctionArgumentArrayLayout();
+
+ // TODO [FM3] This is just temporary, until we support named args. Then the logic in ASTDynamicTopLevelCall
+ // should be reused.
+
+ TemplateModel[] args;
+ if (arrayLayout != null) {
+ int posVarargsLength;
+ int callArgCnt = arguments.size();
+ int predefPosArgCnt = arrayLayout.getPredefinedPositionalArgumentCount();
+ int posVarargsIdx = arrayLayout.getPositionalVarargsArgumentIndex();
+ if (callArgCnt > predefPosArgCnt) {
+ if (posVarargsIdx == -1) {
+ throw new _MiscTemplateException(env,
+ "Too many arguments; the target ", FTLUtil.getCallableTypeName(func),
+ " only has ", predefPosArgCnt, " parameters.");
+ }
+ }
+
+ List<TemplateModel> callArgList = arguments.getModelList(env);
+
+ args = new TemplateModel[arrayLayout.getTotalLength()];
+ int callPredefArgCnt = Math.min(callArgCnt, predefPosArgCnt);
+ for (int argIdx = 0; argIdx < callPredefArgCnt; argIdx++) {
+ args[argIdx] = callArgList.get(argIdx);
+ }
+
+ if (posVarargsIdx != -1) {
+ TemplateSequenceModel varargsSeq;
+ posVarargsLength = callArgCnt - predefPosArgCnt;
+ if (posVarargsLength <= 0) {
+ varargsSeq = Constants.EMPTY_SEQUENCE;
+ } else {
+ NativeSequence nativeSeq = new NativeSequence(posVarargsLength);
+ varargsSeq = nativeSeq;
+ for (int posVarargIdx = 0; posVarargIdx < posVarargsLength; posVarargIdx++) {
+ nativeSeq.add(callArgList.get(predefPosArgCnt + posVarargIdx));
+ }
+ }
+ args[posVarargsIdx] = varargsSeq;
+ }
+
+ int namedVarargsArgIdx = arrayLayout.getNamedVarargsArgumentIndex();
+ if (namedVarargsArgIdx != -1) {
+ args[namedVarargsArgIdx] = Constants.EMPTY_HASH;
+ }
+ } else {
+ List<TemplateModel> callArgList = arguments.getModelList(env);
+ args = new TemplateModel[callArgList.size()];
+ for (int i = 0; i < callArgList.size(); i++) {
+ args[i] = callArgList.get(i);
+ }
+ }
+
+ return func.execute(args, this, env);
+ }
+
+ @Override
+ public String getCanonicalForm() {
+ StringBuilder buf = new StringBuilder();
+ buf.append(target.getCanonicalForm());
+ buf.append("(");
+ String list = arguments.getCanonicalForm();
+ buf.append(list.substring(1, list.length() - 1));
+ buf.append(")");
+ return buf.toString();
+ }
+
+ @Override
+ String getASTNodeDescriptor() {
+ return "...(...)";
+ }
+
+ TemplateModel getConstantValue() {
+ return null;
+ }
+
+ @Override
+ boolean isLiteral() {
+ return false;
+ }
+
+ @Override
+ protected ASTExpression deepCloneWithIdentifierReplaced_inner(
+ String replacedIdentifier, ASTExpression replacement, ReplacemenetState replacementState) {
+ return new ASTExpFunctionCall(
+ target.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState),
+ (ASTExpListLiteral) arguments.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState));
+ }
+
+ @Override
+ int getParameterCount() {
+ return 1 + arguments.items.size();
+ }
+
+ @Override
+ Object getParameterValue(int idx) {
+ if (idx == 0) {
+ return target;
+ } else if (idx < getParameterCount()) {
+ return arguments.items.get(idx - 1);
+ } else {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ @Override
+ ParameterRole getParameterRole(int idx) {
+ if (idx == 0) {
+ return ParameterRole.CALLEE;
+ } else if (idx < getParameterCount()) {
+ return ParameterRole.ARGUMENT_VALUE;
+ } else {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------------------------
+ // CallPlace API
+
+ @Override
+ public boolean hasNestedContent() {
+ return false;
+ }
+
+ @Override
+ public int getNestedContentParameterCount() {
+ return 0;
+ }
+
+ @Override
+ public void executeNestedContent(TemplateModel[] nestedContentArgs, Writer out, Environment env)
+ throws TemplateException, IOException {
+ // Do nothing
+ }
+
+ @Override
+ public Object getOrCreateCustomData(Object providerIdentity, CommonSupplier<?> supplier)
+ throws CallPlaceCustomDataInitializationException {
+ throw new UnsupportedOperationException("Expression call places don't store custom data");
+ }
+
+ @Override
+ public boolean isCustomDataSupported() {
+ return false;
+ }
+
+ @Override
+ public boolean isNestedOutputCacheable() {
+ return false;
+ }
+
+ @Override
+ public int getFirstTargetJavaParameterTypeIndex() {
+ // TODO [FM3]
+ return -1;
+ }
+
+ @Override
+ public Class<?> getTargetJavaParameterType(int argIndex) {
+ // TODO [FM3]
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java
index 0fc27da..1ddf63c 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpListLiteral.java
@@ -25,7 +25,7 @@ import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
-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.TemplateSequenceModel;
@@ -54,8 +54,9 @@ final class ASTExpListLiteral extends ASTExpression {
}
/**
- * For {@link TemplateMethodModel} calls, returns the list of arguments as {@link TemplateModel}-s.
+ * For {@link TemplateFunctionModel} calls, returns the list of arguments as {@link TemplateModel}-s.
*/
+ // TODO [FM3][CF] This will be removed
List<TemplateModel> getModelList(Environment env) throws TemplateException {
int size = items.size();
switch(size) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpMethodCall.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpMethodCall.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpMethodCall.java
deleted file mode 100644
index 581726e..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpMethodCall.java
+++ /dev/null
@@ -1,226 +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.
- */
-
-/*
- * 22 October 1999: This class added by Holger Arendt.
- */
-
-package org.apache.freemarker.core;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.freemarker.core.model.ArgumentArrayLayout;
-import org.apache.freemarker.core.model.Constants;
-import org.apache.freemarker.core.model.TemplateFunctionModel;
-import org.apache.freemarker.core.model.TemplateMethodModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateSequenceModel;
-import org.apache.freemarker.core.util.CommonSupplier;
-import org.apache.freemarker.core.util.FTLUtil;
-
-
-/**
- * AST expression node: {@code exp(args)}.
- */
-final class ASTExpMethodCall extends ASTExpression implements CallPlace {
-
- private final ASTExpression target;
- private final ASTExpListLiteral arguments;
-
- ASTExpMethodCall(ASTExpression target, ArrayList arguments) {
- this(target, new ASTExpListLiteral(arguments));
- }
-
- private ASTExpMethodCall(ASTExpression target, ASTExpListLiteral arguments) {
- this.target = target;
- this.arguments = arguments;
- }
-
- @Override
- TemplateModel _eval(Environment env) throws TemplateException {
- TemplateModel targetModel = target.eval(env);
- if (targetModel instanceof TemplateMethodModel) {
- TemplateMethodModel targetMethod = (TemplateMethodModel) targetModel;
- List<TemplateModel> argumentStrings = arguments.getModelList(env);
- Object result = targetMethod.execute(argumentStrings);
- return env.getObjectWrapper().wrap(result);
- } else if (targetModel instanceof TemplateFunctionModel) {
- TemplateFunctionModel func = (TemplateFunctionModel) targetModel;
-
- ArgumentArrayLayout arrayLayout = func.getArgumentArrayLayout();
-
- // TODO [FM3] This is just temporary, until we support named args. Then the logic in ASTDynamicTopLevelCall
- // should be reused.
-
- int posVarargsLength;
- int callArgCnt = arguments.size();
- int predefPosArgCnt = arrayLayout.getPredefinedPositionalArgumentCount();
- int posVarargsIdx = arrayLayout.getPositionalVarargsArgumentIndex();
- if (callArgCnt > predefPosArgCnt) {
- if (posVarargsIdx == -1) {
- throw new _MiscTemplateException(env,
- "Too many arguments; the target ", FTLUtil.getCallableTypeName(func),
- " has ", predefPosArgCnt, " arguments.");
- }
- }
-
- List<TemplateModel> callArgList = arguments.getModelList(env);
-
- TemplateModel[] args = new TemplateModel[arrayLayout.getTotalLength()];
- int callPredefArgCnt = Math.min(callArgCnt, predefPosArgCnt);
- for (int argIdx = 0; argIdx < callPredefArgCnt; argIdx++) {
- args[argIdx] = callArgList.get(argIdx);
- }
-
- if (posVarargsIdx != -1) {
- TemplateSequenceModel varargsSeq;
- posVarargsLength = callArgCnt - predefPosArgCnt;
- if (posVarargsLength <= 0) {
- varargsSeq = Constants.EMPTY_SEQUENCE;
- } else {
- NativeSequence nativeSeq = new NativeSequence(posVarargsLength);
- varargsSeq = nativeSeq;
- for (int posVarargIdx = 0; posVarargIdx < posVarargsLength; posVarargIdx++) {
- nativeSeq.add(callArgList.get(predefPosArgCnt + posVarargIdx));
- }
- }
- args[posVarargsIdx] = varargsSeq;
- }
-
- int namedVarargsArgIdx = arrayLayout.getNamedVarargsArgumentIndex();
- if (namedVarargsArgIdx != -1) {
- args[namedVarargsArgIdx] = Constants.EMPTY_HASH;
- }
-
- return func.execute(args, this, env);
- } else {
- throw new NonMethodException(target, targetModel, env);
- }
- }
-
- @Override
- public String getCanonicalForm() {
- StringBuilder buf = new StringBuilder();
- buf.append(target.getCanonicalForm());
- buf.append("(");
- String list = arguments.getCanonicalForm();
- buf.append(list.substring(1, list.length() - 1));
- buf.append(")");
- return buf.toString();
- }
-
- @Override
- String getASTNodeDescriptor() {
- return "...(...)";
- }
-
- TemplateModel getConstantValue() {
- return null;
- }
-
- @Override
- boolean isLiteral() {
- return false;
- }
-
- @Override
- protected ASTExpression deepCloneWithIdentifierReplaced_inner(
- String replacedIdentifier, ASTExpression replacement, ReplacemenetState replacementState) {
- return new ASTExpMethodCall(
- target.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState),
- (ASTExpListLiteral) arguments.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState));
- }
-
- @Override
- int getParameterCount() {
- return 1 + arguments.items.size();
- }
-
- @Override
- Object getParameterValue(int idx) {
- if (idx == 0) {
- return target;
- } else if (idx < getParameterCount()) {
- return arguments.items.get(idx - 1);
- } else {
- throw new IndexOutOfBoundsException();
- }
- }
-
- @Override
- ParameterRole getParameterRole(int idx) {
- if (idx == 0) {
- return ParameterRole.CALLEE;
- } else if (idx < getParameterCount()) {
- return ParameterRole.ARGUMENT_VALUE;
- } else {
- throw new IndexOutOfBoundsException();
- }
- }
-
- // -----------------------------------------------------------------------------------------------------------------
- // CallPlace API
-
- @Override
- public boolean hasNestedContent() {
- return false;
- }
-
- @Override
- public int getNestedContentParameterCount() {
- return 0;
- }
-
- @Override
- public void executeNestedContent(TemplateModel[] nestedContentArgs, Writer out, Environment env)
- throws TemplateException, IOException {
- // Do nothing
- }
-
- @Override
- public Object getOrCreateCustomData(Object providerIdentity, CommonSupplier<?> supplier)
- throws CallPlaceCustomDataInitializationException {
- throw new UnsupportedOperationException("Expression call places don't store custom data");
- }
-
- @Override
- public boolean isCustomDataSupported() {
- return false;
- }
-
- @Override
- public boolean isNestedOutputCacheable() {
- return false;
- }
-
- @Override
- public int getFirstTargetJavaParameterTypeIndex() {
- // TODO [FM3]
- return -1;
- }
-
- @Override
- public Class<?> getTargetJavaParameterType(int argIndex) {
- // TODO [FM3]
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java
index 434578d..3760c77 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForDates.java
@@ -20,14 +20,13 @@
package org.apache.freemarker.core;
import java.util.Date;
-import java.util.List;
import java.util.TimeZone;
import org.apache.freemarker.core.model.AdapterTemplateModel;
+import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.TemplateDateModel;
-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;
import org.apache.freemarker.core.model.impl.SimpleDate;
import org.apache.freemarker.core.model.impl.SimpleScalar;
@@ -70,7 +69,7 @@ class BuiltInsForDates {
*/
static class iso_BI extends AbstractISOBI {
- class Result implements TemplateMethodModel {
+ class Result implements TemplateFunctionModel {
private final Date date;
private final int dateType;
private final Environment env;
@@ -81,19 +80,19 @@ class BuiltInsForDates {
this.env = env;
}
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- checkMethodArgCount(args, 1);
-
- TemplateModel tzArgTM = args.get(0);
- TimeZone tzArg;
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ TemplateModel tzArgTM = args[0];
+ TimeZone tzArg;
Object adaptedObj;
if (tzArgTM instanceof AdapterTemplateModel
&& (adaptedObj =
((AdapterTemplateModel) tzArgTM)
.getAdaptedObject(TimeZone.class))
instanceof TimeZone) {
- tzArg = (TimeZone) adaptedObj;
+ tzArg = (TimeZone) adaptedObj;
} else if (tzArgTM instanceof TemplateScalarModel) {
String tzName = _EvalUtil.modelToString((TemplateScalarModel) tzArgTM, null, null);
try {
@@ -108,17 +107,22 @@ class BuiltInsForDates {
throw MessageUtil.newMethodArgUnexpectedTypeException(
"?" + key, 0, "string or java.util.TimeZone", tzArgTM);
}
-
+
return new SimpleScalar(_DateUtil.dateToISO8601String(
date,
dateType != TemplateDateModel.TIME,
dateType != TemplateDateModel.DATE,
shouldShowOffset(date, dateType, env),
accuracy,
- tzArg,
+ tzArg,
env.getISOBuiltInCalendarFactory()));
}
-
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
+
}
iso_BI(Boolean showOffset, int accuracy) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java
index c0d6164..dfa7c46 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForExistenceHandling.java
@@ -19,12 +19,10 @@
package org.apache.freemarker.core;
-import java.util.List;
-
+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;
/**
* A holder for builtins that deal with null left-hand values.
@@ -56,14 +54,14 @@ class BuiltInsForExistenceHandling {
}
static class defaultBI extends BuiltInsForExistenceHandling.ExistenceBuiltIn {
-
+
@Override
TemplateModel _eval(final Environment env) throws TemplateException {
TemplateModel model = evalMaybeNonexistentTarget(env);
return model == null ? FIRST_NON_NULL_METHOD : new ConstantMethod(model);
}
- private static class ConstantMethod implements TemplateMethodModel {
+ private static class ConstantMethod implements TemplateFunctionModel {
private final TemplateModel constant;
ConstantMethod(TemplateModel constant) {
@@ -71,28 +69,43 @@ class BuiltInsForExistenceHandling {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) {
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
return constant;
}
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return null;
+ }
+
}
/**
* A method that goes through the arguments one by one and returns
* the first one that is non-null. If all args are null, returns null.
*/
- private static final TemplateMethodModel FIRST_NON_NULL_METHOD =
- new TemplateMethodModel() {
- @Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- int argCnt = args.size();
- if (argCnt == 0) throw MessageUtil.newArgCntError("?default", argCnt, 1, Integer.MAX_VALUE);
- for (int i = 0; i < argCnt; i++ ) {
- TemplateModel result = args.get(i);
- if (result != null) return result;
+ private static final TemplateFunctionModel FIRST_NON_NULL_METHOD = new TemplateFunctionModel() {
+
+ @Override
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ int argsLen = args.length;
+ for (int i = 0; i < argsLen; i++ ) {
+ TemplateModel result = args[i];
+ if (result != null) {
+ return result;
}
- return null;
}
- };
+ return null;
+ }
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return null;
+ }
+
+ };
}
static class existsBI extends BuiltInsForExistenceHandling.ExistenceBuiltIn {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java
index 5e85262..b1bd1dd 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForMultipleTypes.java
@@ -19,19 +19,18 @@
package org.apache.freemarker.core;
-import java.io.Serializable;
import java.util.Date;
-import java.util.List;
+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.TemplateCollectionModelEx;
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.TemplateMarkupOutputModel;
-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.TemplateModelWithAPISupport;
@@ -108,29 +107,30 @@ class BuiltInsForMultipleTypes {
}
static class dateBI extends ASTExpBuiltIn {
- private class DateParser
- implements
- TemplateDateModel,
- TemplateMethodModel,
- TemplateHashModel {
+ private class DateParser implements TemplateDateModel, TemplateFunctionModel, TemplateHashModel {
private final String text;
private final Environment env;
private final TemplateDateFormat defaultFormat;
private TemplateDateModel cachedValue;
- DateParser(String text, Environment env)
- throws TemplateException {
+ DateParser(String text, Environment env) throws TemplateException {
this.text = text;
this.env = env;
defaultFormat = env.getTemplateDateFormat(dateType, Date.class, target, false);
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
- checkMethodArgCount(args, 0, 1);
- return args.size() == 0 ? getAsDateModel() : get(_CallableUtils.castArgToString(args, 0));
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ TemplateModel arg1 = args[0];
+ return arg1 == null ? getAsDateModel() : get(_CallableUtils.castArgToString(arg1, 0));
}
-
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
+
@Override
public TemplateModel get(String pattern) throws TemplateModelException {
TemplateDateFormat format;
@@ -258,7 +258,7 @@ class BuiltInsForMultipleTypes {
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel tm = target.eval(env);
target.assertNonNull(tm, env);
- return (tm instanceof TemplateBooleanModel) ?
+ return (tm instanceof TemplateBooleanModel) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
}
@@ -286,7 +286,7 @@ class BuiltInsForMultipleTypes {
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel tm = target.eval(env);
target.assertNonNull(tm, env);
- return (tm instanceof TemplateDateModel) ?
+ return (tm instanceof TemplateDateModel) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
}
@@ -356,32 +356,22 @@ class BuiltInsForMultipleTypes {
}
}
- static class is_macroBI extends ASTExpBuiltIn {
- @Override
- TemplateModel _eval(Environment env) throws TemplateException {
- TemplateModel tm = target.eval(env);
- target.assertNonNull(tm, env);
- return (tm instanceof Environment.TemplateLanguageDirective) ?
- TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
- }
- }
-
static class is_markup_outputBI extends ASTExpBuiltIn {
@Override
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel tm = target.eval(env);
target.assertNonNull(tm, env);
- return (tm instanceof TemplateMarkupOutputModel) ?
+ return (tm instanceof TemplateMarkupOutputModel) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
}
- static class is_methodBI extends ASTExpBuiltIn {
+ static class is_functionBI extends ASTExpBuiltIn {
@Override
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel tm = target.eval(env);
target.assertNonNull(tm, env);
- return (tm instanceof TemplateMethodModel) ?
+ return (tm instanceof TemplateFunctionModel) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
}
@@ -391,7 +381,7 @@ class BuiltInsForMultipleTypes {
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel tm = target.eval(env);
target.assertNonNull(tm, env);
- return (tm instanceof TemplateNodeModel) ?
+ return (tm instanceof TemplateNodeModel) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
}
@@ -401,7 +391,7 @@ class BuiltInsForMultipleTypes {
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel tm = target.eval(env);
target.assertNonNull(tm, env);
- return (tm instanceof TemplateNumberModel) ?
+ return (tm instanceof TemplateNumberModel) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
}
@@ -421,7 +411,7 @@ class BuiltInsForMultipleTypes {
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel tm = target.eval(env);
target.assertNonNull(tm, env);
- return (tm instanceof TemplateScalarModel) ?
+ return (tm instanceof TemplateScalarModel) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
}
@@ -469,10 +459,7 @@ class BuiltInsForMultipleTypes {
static class stringBI extends ASTExpBuiltIn {
- private class BooleanFormatter
- implements
- TemplateScalarModel,
- TemplateMethodModel {
+ private class BooleanFormatter implements TemplateScalarModel, TemplateFunctionModel {
private final TemplateBooleanModel bool;
private final Environment env;
@@ -480,18 +467,23 @@ class BuiltInsForMultipleTypes {
this.bool = bool;
this.env = env;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
- checkMethodArgCount(args, 2);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
int argIdx = bool.getAsBoolean() ? 0 : 1;
- TemplateModel result = args.get(argIdx);
+ TemplateModel result = args[argIdx];
if (!(result instanceof TemplateScalarModel)) {
- throw new NonStringException((Serializable) argIdx, result, null, null);
+ throw new NonStringException(argIdx, result, null, null);
}
return result;
}
-
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
+
@Override
public String getAsString() throws TemplateModelException {
// Boolean should have come first... but that change would be non-BC.
@@ -507,11 +499,7 @@ class BuiltInsForMultipleTypes {
}
}
- private class DateFormatter
- implements
- TemplateScalarModel,
- TemplateHashModel,
- TemplateMethodModel {
+ private class DateFormatter implements TemplateScalarModel, TemplateHashModel, TemplateFunctionModel {
private final TemplateDateModel dateModel;
private final Environment env;
private final TemplateDateFormat defaultFormat;
@@ -528,14 +516,19 @@ class BuiltInsForMultipleTypes {
: env.getTemplateDateFormat(
dateType, _EvalUtil.modelToDate(dateModel, target).getClass(), target, true);
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
- checkMethodArgCount(args, 1);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
return formatWith(_CallableUtils.castArgToString(args, 0));
}
@Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
+
+ @Override
public TemplateModel get(String key)
throws TemplateModelException {
return formatWith(key);
@@ -582,11 +575,7 @@ class BuiltInsForMultipleTypes {
}
}
- private class NumberFormatter
- implements
- TemplateScalarModel,
- TemplateHashModel,
- TemplateMethodModel {
+ private class NumberFormatter implements TemplateScalarModel, TemplateHashModel, TemplateFunctionModel {
private final TemplateNumberModel numberModel;
private final Number number;
private final Environment env;
@@ -606,13 +595,18 @@ class BuiltInsForMultipleTypes {
throw _CoreAPI.ensureIsTemplateModelException("Failed to get default number format", e);
}
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
- checkMethodArgCount(args, 1);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
return get(_CallableUtils.castArgToString(args, 0));
}
-
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
+
@Override
public TemplateModel get(String key) throws TemplateModelException {
TemplateNumberFormat format;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java
index 89593cd..bc4b9dc 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNestedContentParameters.java
@@ -18,13 +18,11 @@
*/
package org.apache.freemarker.core;
-import java.util.List;
-
import org.apache.freemarker.core.ASTDirList.IterationContext;
+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.impl.SimpleNumber;
import org.apache.freemarker.core.model.impl.SimpleScalar;
@@ -131,18 +129,24 @@ class BuiltInsForNestedContentParameters {
static class item_cycleBI extends BuiltInForNestedContentParameter {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private final IterationContext iterCtx;
private BIMethod(IterationContext iterCtx) {
this.iterCtx = iterCtx;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
checkMethodArgCount(args, 1, Integer.MAX_VALUE);
- return args.get(iterCtx.getIndex() % args.size());
+ return args[iterCtx.getIndex() % args.length];
+ }
+
+ @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/BuiltInsForNodes.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNodes.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNodes.java
index d5dfe93..5390dc4 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNodes.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForNodes.java
@@ -19,9 +19,8 @@
package org.apache.freemarker.core;
-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.TemplateNodeModel;
@@ -114,7 +113,7 @@ class BuiltInsForNodes {
// Can't be instantiated
private BuiltInsForNodes() { }
- static class AncestorSequence extends NativeSequence implements TemplateMethodModel {
+ static class AncestorSequence extends NativeSequence implements TemplateFunctionModel {
private static final int INITIAL_CAPACITY = 12;
@@ -124,24 +123,30 @@ class BuiltInsForNodes {
super(INITIAL_CAPACITY);
this.env = env;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> names) throws TemplateException {
- if (names == null || names.isEmpty()) {
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ if (args.length == 0) {
return this;
}
AncestorSequence result = new AncestorSequence(env);
- for (int i = 0; i < size(); i++) {
- TemplateNodeModel tnm = (TemplateNodeModel) get(i);
+ for (int seqIdx = 0; seqIdx < size(); seqIdx++) {
+ TemplateNodeModel tnm = (TemplateNodeModel) get(seqIdx);
String nodeName = tnm.getNodeName();
String nsURI = tnm.getNodeNamespace();
if (nsURI == null) {
- if (names.contains(nodeName)) {
- result.add(tnm);
+ for (int argIdx = 0; argIdx < args.length; argIdx++) {
+ String name = _CallableUtils.castArgToString(args, argIdx);
+ if (name.equals(nodeName)) {
+ result.add(tnm);
+ break;
+ }
}
} else {
- for (int j = 0; j < names.size(); j++) {
- if (_StringUtil.matchesQName(_CallableUtils.castArgToString(names, j), nodeName, nsURI, env)) {
+ for (int argIdx = 0; argIdx < args.length; argIdx++) {
+ if (_StringUtil.matchesQName(
+ _CallableUtils.castArgToString(args, argIdx), nodeName, nsURI, env)) {
result.add(tnm);
break;
}
@@ -150,5 +155,10 @@ class BuiltInsForNodes {
}
return result;
}
- }
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return null;
+ }
+ }
}
\ 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/BuiltInsForSequences.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForSequences.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForSequences.java
index 9406d33..d8cfc91 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForSequences.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInsForSequences.java
@@ -25,15 +25,15 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
-import java.util.List;
import org.apache.freemarker.core.arithmetic.ArithmeticEngine;
+import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.Constants;
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.TemplateFunctionModel;
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.TemplateModelIterator;
@@ -54,7 +54,7 @@ class BuiltInsForSequences {
static class chunkBI extends BuiltInForSequence {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
private final TemplateSequenceModel tsm;
@@ -63,14 +63,16 @@ class BuiltInsForSequences {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- checkMethodArgCount(args, 1, 2);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
int chunkSize = getNumberMethodArg(args, 0).intValue();
-
- return new ChunkedSequence(
- tsm,
- chunkSize,
- args.size() > 1 ? (TemplateModel) args.get(1) : null);
+
+ return new ChunkedSequence(tsm, chunkSize, args[1]);
+ }
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
}
}
@@ -182,7 +184,7 @@ class BuiltInsForSequences {
static class joinBI extends ASTExpBuiltIn {
- private class BIMethodForCollection implements TemplateMethodModel {
+ private class BIMethodForCollection implements TemplateFunctionModel {
private final Environment env;
private final TemplateCollectionModel coll;
@@ -193,17 +195,16 @@ class BuiltInsForSequences {
}
@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 separator = getStringMethodArg(args, 0);
- final String whenEmpty = getOptStringMethodArg(args, 1);
- final String afterLast = getOptStringMethodArg(args, 2);
-
+ final String whenEmpty = getStringMethodArg(args, 1, true);
+ final String afterLast = getStringMethodArg(args, 2, true);
+
StringBuilder sb = new StringBuilder();
-
+
TemplateModelIterator it = coll.iterator();
-
+
int idx = 0;
boolean hadItem = false;
while (it.hasNext()) {
@@ -232,7 +233,12 @@ class BuiltInsForSequences {
if (whenEmpty != null) sb.append(whenEmpty);
}
return new SimpleScalar(sb.toString());
- }
+ }
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.THREE_POSITIONAL_PARAMETERS;
+ }
}
@@ -295,7 +301,7 @@ class BuiltInsForSequences {
}
static class seq_containsBI extends ASTExpBuiltIn {
- private class BIMethodForCollection implements TemplateMethodModel {
+ private class BIMethodForCollection implements TemplateFunctionModel {
private TemplateCollectionModel m_coll;
private Environment m_env;
@@ -305,10 +311,9 @@ class BuiltInsForSequences {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args)
- throws TemplateModelException {
- checkMethodArgCount(args, 1);
- TemplateModel arg = args.get(0);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ TemplateModel arg = args[0];
TemplateModelIterator it = m_coll.iterator();
int idx = 0;
while (it.hasNext()) {
@@ -319,9 +324,14 @@ class BuiltInsForSequences {
return TemplateBooleanModel.FALSE;
}
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
+
}
- private class BIMethodForSequence implements TemplateMethodModel {
+ private class BIMethodForSequence implements TemplateFunctionModel {
private TemplateSequenceModel m_seq;
private Environment m_env;
@@ -331,10 +341,9 @@ class BuiltInsForSequences {
}
@Override
- public TemplateModel execute(List<? extends TemplateModel> args)
- throws TemplateModelException {
- checkMethodArgCount(args, 1);
- TemplateModel arg = args.get(0);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ TemplateModel arg = args[0];
int size = m_seq.size();
for (int i = 0; i < size; i++) {
if (modelsEqual(i, m_seq.get(i), arg, m_env))
@@ -343,6 +352,11 @@ class BuiltInsForSequences {
return TemplateBooleanModel.FALSE;
}
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
+ }
+
}
@Override
@@ -364,7 +378,7 @@ class BuiltInsForSequences {
static class seq_index_ofBI extends ASTExpBuiltIn {
- private class BIMethod implements TemplateMethodModel {
+ private class BIMethod implements TemplateFunctionModel {
final TemplateSequenceModel m_seq;
final TemplateCollectionModel m_col;
@@ -395,21 +409,20 @@ class BuiltInsForSequences {
}
@Override
- public final TemplateModel execute(List<? extends TemplateModel> args)
- throws TemplateModelException {
- int argCnt = args.size();
- checkMethodArgCount(argCnt, 1, 2);
-
- TemplateModel target = args.get(0);
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ TemplateModel target = args[0];
+ Number startIndex = getNumberMethodArg(args, 1, true);
int foundAtIdx;
- if (argCnt > 1) {
- int startIndex = getNumberMethodArg(args, 1).intValue();
+ if (startIndex != null) {
+ // TODO [FM3] Prefer Col?
// In 2.3.x only, we prefer TemplateSequenceModel for
// backward compatibility:
foundAtIdx = m_seq != null
- ? findInSeq(target, startIndex)
- : findInCol(target, startIndex);
+ ? findInSeq(target, startIndex.intValue())
+ : findInCol(target, startIndex.intValue());
} else {
+ // TODO [FM3] Prefer Col?
// In 2.3.x only, we prefer TemplateSequenceModel for
// backward compatibility:
foundAtIdx = m_seq != null
@@ -418,7 +431,12 @@ class BuiltInsForSequences {
}
return foundAtIdx == -1 ? Constants.MINUS_ONE : new SimpleNumber(foundAtIdx);
}
-
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.TWO_POSITIONAL_PARAMETERS;
+ }
+
int findInCol(TemplateModel target) throws TemplateModelException {
return findInCol(target, 0, Integer.MAX_VALUE);
}
@@ -525,25 +543,20 @@ class BuiltInsForSequences {
}
static class sort_byBI extends sortBI {
- class BIMethod implements TemplateMethodModel {
+ class BIMethod implements TemplateFunctionModel {
TemplateSequenceModel seq;
BIMethod(TemplateSequenceModel seq) {
this.seq = seq;
}
-
+
@Override
- public TemplateModel execute(List<? extends TemplateModel> args)
- throws TemplateModelException {
- // Should be:
- // checkMethodArgCount(args, 1);
- // But for BC:
- if (args.size() < 1) throw MessageUtil.newArgCntError("?" + key, args.size(), 1);
-
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
String[] subvars;
- Object obj = args.get(0);
+ TemplateModel obj = args[0];
if (obj instanceof TemplateScalarModel) {
- subvars = new String[]{((TemplateScalarModel) obj).getAsString()};
+ subvars = new String[] { ((TemplateScalarModel) obj).getAsString() };
} else if (obj instanceof TemplateSequenceModel) {
TemplateSequenceModel seq = (TemplateSequenceModel) obj;
int ln = seq.size();
@@ -563,7 +576,12 @@ class BuiltInsForSequences {
"The argument to ?", key, "(key) must be a string (the name of the subvariable), or a "
+ "sequence of strings (the \"path\" to the subvariable).");
}
- return sort(seq, subvars);
+ return sort(seq, subvars);
+ }
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
}
}
[3/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
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java
index c500c8c..0f2a061 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/IncludePage.java
@@ -185,7 +185,7 @@ public class IncludePage implements TemplateDirectiveModel {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
deleted file mode 100644
index ff9db12..0000000
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/CustomTagAndELFunctionCombiner.java
+++ /dev/null
@@ -1,157 +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.servlet.jsp;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.List;
-
-import org.apache.freemarker.core.Environment;
-import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core._UnexpectedTypeErrorExplainerTemplateModel;
-import org.apache.freemarker.core.model.ArgumentArrayLayout;
-import org.apache.freemarker.core.CallPlace;
-import org.apache.freemarker.core.model.TemplateDirectiveModel;
-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.JavaMethodModel;
-import org.apache.freemarker.core.util.BugException;
-import org.apache.freemarker.core.util._ClassUtil;
-
-/**
- * Used when a custom JSP tag and an EL function uses the same name in a tag library, to invoke a single FTL value from
- * the two. As FTL as no separate namespace for "tags" and functions, both aspect has to be implemented by the same
- * value.
- */
-@SuppressWarnings("rawtypes")
-class CustomTagAndELFunctionCombiner {
-
- /**
- * @param customTag
- * A {@link TemplateDirectiveModel}.
- */
- static TemplateModel combine(TemplateModel customTag, TemplateMethodModel elFunction) {
- if (customTag instanceof TemplateDirectiveModel) {
- return elFunction instanceof JavaMethodModel //
- ? new TemplateDirectiveModelAndSimpleMethodModel( //
- (TemplateDirectiveModel) customTag, (JavaMethodModel) elFunction) //
- : new TemplateDirectiveModelAndTemplateMethodModelEx( //
- (TemplateDirectiveModel) customTag, elFunction);
- } else {
- throw new BugException(
- "Unexpected custom JSP tag class: " + _ClassUtil.getShortClassNameOfObject(customTag));
- }
- }
-
- /**
- * Tells if the value can be used as the "custom tag" parameter to
- * {@link #combine(TemplateModel, TemplateMethodModel)}.
- */
- static boolean canBeCombinedAsCustomTag(TemplateModel tm) {
- return (tm instanceof TemplateDirectiveModel) && !(tm instanceof CombinedTemplateModel);
- }
-
- /**
- * Tells if the value can be used as the "EL function" parameter to
- * {@link #combine(TemplateModel, TemplateMethodModel)}.
- */
- static boolean canBeCombinedAsELFunction(TemplateModel tm) {
- return tm instanceof TemplateMethodModel && !(tm instanceof CombinedTemplateModel);
- }
-
- private static class CombinedTemplateModel {
- // Marker only
- }
-
- private static class TemplateDirectiveModelAndSimpleMethodModel extends CombinedTemplateModel
- implements TemplateDirectiveModel, TemplateMethodModel,
- _UnexpectedTypeErrorExplainerTemplateModel {
-
- private final TemplateDirectiveModel templateDirectiveModel;
- private final JavaMethodModel simpleMethodModel;
-
- public TemplateDirectiveModelAndSimpleMethodModel( //
- TemplateDirectiveModel templateDirectiveModel, JavaMethodModel simpleMethodModel) {
- this.templateDirectiveModel = templateDirectiveModel;
- this.simpleMethodModel = simpleMethodModel;
- }
-
- @Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateModelException {
- return simpleMethodModel.execute(args);
- }
-
- @Override
- public Object[] explainTypeError(Class[] expectedClasses) {
- return simpleMethodModel.explainTypeError(expectedClasses);
- }
-
- @Override
- public void execute(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env)
- throws TemplateException, IOException {
- templateDirectiveModel.execute(args, callPlace, out, env);
- }
-
- @Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
- return templateDirectiveModel.getArgumentArrayLayout();
- }
-
- @Override
- public boolean isNestedContentSupported() {
- return templateDirectiveModel.isNestedContentSupported();
- }
- }
-
- private static class TemplateDirectiveModelAndTemplateMethodModelEx extends CombinedTemplateModel
- implements TemplateDirectiveModel, TemplateMethodModel {
-
- private final TemplateDirectiveModel templateDirectiveModel;
- private final TemplateMethodModel templateMethodModelEx;
-
- public TemplateDirectiveModelAndTemplateMethodModelEx( //
- TemplateDirectiveModel templateDirectiveModel, TemplateMethodModel templateMethodModelEx) {
- this.templateDirectiveModel = templateDirectiveModel;
- this.templateMethodModelEx = templateMethodModelEx;
- }
-
- @Override
- public TemplateModel execute(List<? extends TemplateModel> args) throws TemplateException {
- return templateMethodModelEx.execute(args);
- }
-
- @Override
- public void execute(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env)
- throws TemplateException, IOException {
- templateDirectiveModel.execute(args, callPlace, out, env);
- }
-
- @Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
- return templateDirectiveModel.getArgumentArrayLayout();
- }
-
- @Override
- public boolean isNestedContentSupported() {
- return templateDirectiveModel.isNestedContentSupported();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/JspTagModelBase.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/JspTagModelBase.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/JspTagModelBase.java
index 99e8272..01418ba 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/JspTagModelBase.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/JspTagModelBase.java
@@ -29,10 +29,16 @@ import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.DynamicAttributes;
+import javax.servlet.jsp.tagext.JspTag;
+
import org.apache.freemarker.core.Template;
+import org.apache.freemarker.core.TemplateException;
import org.apache.freemarker.core._DelayedJQuote;
import org.apache.freemarker.core._DelayedShortClassName;
import org.apache.freemarker.core._ErrorDescriptionBuilder;
+import org.apache.freemarker.core._MiscTemplateException;
import org.apache.freemarker.core._TemplateModelException;
import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
import org.apache.freemarker.core.model.TemplateHashModelEx2;
@@ -45,7 +51,6 @@ import org.apache.freemarker.servlet.jsp.SimpleTagDirectiveModel.TemplateExcepti
class JspTagModelBase {
protected final String tagName;
private final Class tagClass;
- private final Method dynaSetter;
private final Map propertySetters = new HashMap();
protected JspTagModelBase(String tagName, Class tagClass) throws IntrospectionException {
@@ -59,24 +64,14 @@ class JspTagModelBase {
propertySetters.put(pd.getName(), m);
}
}
- // Check to see if the tag implements the JSP2.0 DynamicAttributes
- // interface, to allow setting of arbitrary attributes
- Method dynaSetter;
- try {
- dynaSetter = tagClass.getMethod("setDynamicAttribute",
- String.class, String.class, Object.class);
- } catch (NoSuchMethodException nsme) {
- dynaSetter = null;
- }
- this.dynaSetter = dynaSetter;
}
Object getTagInstance() throws IllegalAccessException, InstantiationException {
return tagClass.newInstance();
}
- void setupTag(Object tag, TemplateHashModelEx2 args, ObjectWrapperAndUnwrapper wrapper)
- throws TemplateModelException,
+ void setupTag(JspTag tag, TemplateHashModelEx2 args, ObjectWrapperAndUnwrapper wrapper)
+ throws TemplateException,
InvocationTargetException,
IllegalAccessException {
if (args != null && !args.isEmpty()) {
@@ -88,12 +83,18 @@ class JspTagModelBase {
final String paramName = ((TemplateScalarModel) entry.getKey()).getAsString();
Method setterMethod = (Method) propertySetters.get(paramName);
if (setterMethod == null) {
- if (dynaSetter == null) {
+ if (tag instanceof DynamicAttributes) {
+ try {
+ ((DynamicAttributes) tag).setDynamicAttribute(null, paramName, argArray[0]);
+ } catch (JspException e) {
+ throw new _MiscTemplateException(
+ "Failed to set JSP tag dynamic attribute ", new _DelayedJQuote(paramName), ".",
+ e);
+ }
+ } else {
throw new TemplateModelException("Unknown property "
+ _StringUtil.jQuote(paramName.toString())
+ " on instance of " + tagClass.getName());
- } else {
- dynaSetter.invoke(tag, null, paramName, argArray[0]);
}
} else {
if (arg instanceof BigDecimal) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java
index 6035a1f..b4f4a15 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/SimpleTagDirectiveModel.java
@@ -107,7 +107,7 @@ class SimpleTagDirectiveModel extends JspTagModelBase implements TemplateDirecti
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java
index ff5b435..15db96d 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TagDirectiveModel.java
@@ -117,7 +117,7 @@ class TagDirectiveModel extends JspTagModelBase implements TemplateDirectiveMode
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
index 98634bd..a1525af 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
@@ -65,8 +65,8 @@ import org.apache.freemarker.core.ConfigurationException;
import org.apache.freemarker.core.Environment;
import org.apache.freemarker.core.model.ObjectWrapper;
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.TemplateMethodModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
@@ -233,7 +233,7 @@ public class TaglibFactory implements TemplateHashModel {
*
* @return a {@link TemplateHashModel} representing the JSP taglib. Each element of this hash represents a single
* custom tag or EL function from the library, implemented as a {@link TemplateDirectiveModel} or
- * {@link TemplateMethodModel}, respectively.
+ * {@link TemplateFunctionModel}, respectively.
*/
@Override
public TemplateModel get(final String taglibUri) throws TemplateModelException {
@@ -1759,7 +1759,7 @@ public class TaglibFactory implements TemplateHashModel {
final Class<?> tagClass = resoveClassFromTLD(tagClassCData, "custom tag", tagNameCData);
- final TemplateModel customTagModel;
+ final TemplateDirectiveModel customTagModel;
try {
if (Tag.class.isAssignableFrom(tagClass)) {
customTagModel = new TagDirectiveModel(tagNameCData, tagClass);
@@ -1775,9 +1775,10 @@ public class TaglibFactory implements TemplateHashModel {
TemplateModel replacedTagOrFunction = tagsAndFunctions.put(tagNameCData, customTagModel);
if (replacedTagOrFunction != null) {
- if (CustomTagAndELFunctionCombiner.canBeCombinedAsELFunction(replacedTagOrFunction)) {
- tagsAndFunctions.put(tagNameCData, CustomTagAndELFunctionCombiner.combine(
- customTagModel, (TemplateMethodModel) replacedTagOrFunction));
+ if (replacedTagOrFunction instanceof TemplateFunctionModel
+ && !(replacedTagOrFunction instanceof TemplateDirectiveModelAndTemplateFunctionModel)) {
+ tagsAndFunctions.put(tagNameCData, new TemplateDirectiveModelAndTemplateFunctionModel(
+ customTagModel, (TemplateFunctionModel) replacedTagOrFunction));
} else {
if (LOG.isWarnEnabled()) {
LOG.warn("TLD contains multiple tags with name " + _StringUtil.jQuote(tagNameCData)
@@ -1816,7 +1817,7 @@ public class TaglibFactory implements TemplateHashModel {
locator);
}
- final TemplateMethodModel elFunctionModel;
+ final TemplateFunctionModel elFunctionModel;
try {
elFunctionModel = defaultObjectWrapper.wrap(null, functionMethod);
} catch (Exception e) {
@@ -1827,9 +1828,10 @@ public class TaglibFactory implements TemplateHashModel {
TemplateModel replacedTagOrFunction = tagsAndFunctions.put(functionNameCData, elFunctionModel);
if (replacedTagOrFunction != null) {
- if (CustomTagAndELFunctionCombiner.canBeCombinedAsCustomTag(replacedTagOrFunction)) {
- tagsAndFunctions.put(functionNameCData, CustomTagAndELFunctionCombiner.combine(
- replacedTagOrFunction, elFunctionModel));
+ if (replacedTagOrFunction instanceof TemplateDirectiveModel
+ && !(replacedTagOrFunction instanceof TemplateDirectiveModelAndTemplateFunctionModel)) {
+ tagsAndFunctions.put(functionNameCData, new TemplateDirectiveModelAndTemplateFunctionModel(
+ (TemplateDirectiveModel) replacedTagOrFunction, elFunctionModel));
} else {
if (LOG.isWarnEnabled()) {
LOG.warn("TLD contains multiple functions with name "
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TemplateDirectiveModelAndTemplateFunctionModel.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TemplateDirectiveModelAndTemplateFunctionModel.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TemplateDirectiveModelAndTemplateFunctionModel.java
new file mode 100644
index 0000000..e4d74d1
--- /dev/null
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TemplateDirectiveModelAndTemplateFunctionModel.java
@@ -0,0 +1,77 @@
+/*
+ * 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.servlet.jsp;
+
+import java.io.IOException;
+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.ArgumentArrayLayout;
+import org.apache.freemarker.core.model.TemplateDirectiveModel;
+import org.apache.freemarker.core.model.TemplateFunctionModel;
+import org.apache.freemarker.core.model.TemplateModel;
+
+/**
+ * Used when a custom JSP tag and an EL function uses the same name in a tag library, to invoke a single FTL value from
+ * the two. As FTL as no separate namespace for "tags" and functions, both aspect has to be implemented by the same
+ * value.
+ */
+class TemplateDirectiveModelAndTemplateFunctionModel
+ implements TemplateDirectiveModel, TemplateFunctionModel {
+
+ private final TemplateDirectiveModel templateDirectiveModel;
+ private final TemplateFunctionModel templateFunctionModel;
+
+ TemplateDirectiveModelAndTemplateFunctionModel( //
+ TemplateDirectiveModel templateDirectiveModel, TemplateFunctionModel templateMethodModelEx) {
+ this.templateDirectiveModel = templateDirectiveModel;
+ this.templateFunctionModel = templateMethodModelEx;
+ }
+
+ @Override
+ public void execute(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env)
+ throws TemplateException, IOException {
+ templateDirectiveModel.execute(args, callPlace, out, env);
+ }
+
+ @Override
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
+ return templateDirectiveModel.getDirectiveArgumentArrayLayout();
+ }
+
+ @Override
+ public boolean isNestedContentSupported() {
+ return templateDirectiveModel.isNestedContentSupported();
+ }
+
+ @Override
+ public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
+ return templateFunctionModel.getFunctionArgumentArrayLayout();
+ }
+
+ @Override
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
+ throws TemplateException {
+ return templateFunctionModel.execute(args, callPlace, env);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java b/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java
index 43285c5..3cc6993 100644
--- a/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java
+++ b/freemarker-servlet/src/test/java/org/apache/freemarker/servlet/jsp/TLDParsingTest.java
@@ -23,7 +23,6 @@ import static org.junit.Assert.*;
import java.io.InputStream;
import java.net.URL;
-import java.util.Arrays;
import java.util.Map;
import javax.servlet.ServletContextEvent;
@@ -33,9 +32,11 @@ import javax.servlet.jsp.tagext.TagSupport;
import javax.xml.parsers.SAXParserFactory;
import org.apache.freemarker.core.Configuration;
-import org.apache.freemarker.core.model.TemplateMethodModel;
+import org.apache.freemarker.core.NonTemplateCallPlace;
+import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateScalarModel;
import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.model.impl.JavaMethodModel;
import org.apache.freemarker.core.model.impl.SimpleScalar;
import org.junit.Before;
import org.junit.Test;
@@ -74,7 +75,7 @@ public class TLDParsingTest {
assertEquals(1, tldParser.getListeners().size());
assertTrue(tldParser.getListeners().get(0) instanceof ExampleContextListener);
- Map tagsAndFunctions = tldParser.getTagsAndFunctions();
+ Map<String, TemplateModel> tagsAndFunctions = tldParser.getTagsAndFunctions();
assertEquals(4, tagsAndFunctions.size());
JspTagModelBase tag = (JspTagModelBase) tagsAndFunctions.get("setStringAttributeTag");
@@ -82,13 +83,15 @@ public class TLDParsingTest {
tag = (JspTagModelBase) tagsAndFunctions.get("setStringAttributeTag2");
assertNotNull(tag);
- TemplateMethodModel function = (TemplateMethodModel) tagsAndFunctions.get("toUpperCase");
+ JavaMethodModel function = (JavaMethodModel) tagsAndFunctions.get("toUpperCase");
assertNotNull(function);
- TemplateScalarModel result = (TemplateScalarModel) function.execute(Arrays.asList(new SimpleScalar("abc")));
+ TemplateScalarModel result = (TemplateScalarModel) function.execute(
+ new TemplateModel[] { new SimpleScalar("abc") }, NonTemplateCallPlace.INSTANCE);
assertEquals("ABC", result.getAsString());
- function = (TemplateMethodModel) tagsAndFunctions.get("toUpperCase2");
+ function = (JavaMethodModel) tagsAndFunctions.get("toUpperCase2");
assertNotNull(function);
- result = (TemplateScalarModel) function.execute(Arrays.asList(new SimpleScalar("abc")));
+ result = (TemplateScalarModel) function.execute(
+ new TemplateModel[] { new SimpleScalar("abc") }, NonTemplateCallPlace.INSTANCE);
assertEquals("ABC", result.getAsString());
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java
index 2e7ecfc..eb6930b 100644
--- a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java
+++ b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertDirective.java
@@ -56,7 +56,7 @@ public class AssertDirective implements TemplateDirectiveModel {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.SINGLE_POSITIONAL_PARAMETER;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java
index 6734fbc..51baeb4 100644
--- a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java
+++ b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertEqualsDirective.java
@@ -78,7 +78,7 @@ public class AssertEqualsDirective implements TemplateDirectiveModel {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java
index e8120fc..6fe1505 100644
--- a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java
+++ b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/AssertFailsDirective.java
@@ -136,7 +136,7 @@ public class AssertFailsDirective implements TemplateDirectiveModel {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ARGS_LAYOUT;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8d5263f2/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java
----------------------------------------------------------------------
diff --git a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java
index a8a7bee..1e33dab 100644
--- a/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java
+++ b/freemarker-test-utils/src/main/java/org/apache/freemarker/test/templateutil/NoOutputDirective.java
@@ -45,7 +45,7 @@ public class NoOutputDirective implements TemplateDirectiveModel {
}
@Override
- public ArgumentArrayLayout getArgumentArrayLayout() {
+ public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
return ArgumentArrayLayout.PARAMETERLESS;
}