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/16 23:24:48 UTC
[1/3] incubator-freemarker git commit: FREEMARKER-65: Utilities for
argument validation: Work in progress. Changes in this commit:
Repository: incubator-freemarker
Updated Branches:
refs/heads/3 e941aedc1 -> f231e64fe
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 0f11a18..d1019e1 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
@@ -19,487 +19,27 @@
package org.apache.freemarker.core;
-import static org.apache.freemarker.core.util.TemplateLanguageUtils.*;
+import static org.apache.freemarker.core.util.TemplateLanguageUtils.getCallableTypeName;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
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.TemplateHashModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelWithOriginName;
-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.CallableUtils;
import org.apache.freemarker.core.util.StringToIndexMap;
-import org.apache.freemarker.core.util.TemplateLanguageUtils;
import org.apache.freemarker.core.util._CollectionUtils;
/**
* For internal use only; don't depend on this, there's no backward compatibility guarantee at all!
+ * The published part of this API is in {@link CallableUtils}.
*/
-// 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 {
-
- public static final TemplateModel[] EMPTY_TEMPLATE_MODEL_ARRAY = new TemplateModel[0];
-
- private _CallableUtils() {
- //
- }
-
- /** Convenience method for calling {@link #newGenericExecuteException(TemplateCallableModel, boolean, String)}. */
- public static TemplateException newGenericExecuteException(
- TemplateFunctionModel callable, String errorDescription) {
- return newGenericExecuteException(callable, true, errorDescription);
- }
-
- /** Convenience method for calling {@link #newGenericExecuteException(TemplateCallableModel, boolean, String)}. */
- public static TemplateException newGenericExecuteException(
- TemplateDirectiveModel callable, String errorDescription) {
- return newGenericExecuteException(callable, false, errorDescription);
- }
-
- /**
- * @param errorDescription Complete sentence describing the problem. This will be after
- * {@code "When calling xxx: "}.
- */
- public static TemplateException newGenericExecuteException(
- TemplateCallableModel callable, boolean calledAsFunction, String errorDescription) {
- return new TemplateException(
- getMessagePartWhenCallingSomethingColon(callable, calledAsFunction),
- errorDescription);
- }
-
- public static TemplateException newArgumentValueException(
- int argIdx, String problemDescription,
- TemplateDirectiveModel callable) {
- return newArgumentValueException(
- argIdx, problemDescription, callable, false);
- }
-
- public static TemplateException newArgumentValueException(
- int argIdx, String problemDescription,
- TemplateFunctionModel callable) {
- return newArgumentValueException(
- argIdx, problemDescription, callable, true);
- }
-
- /**
- * @param problemDescription The continuation of a sentence like {@code "When calling xxx: The 1st argument "}, for
- * example {@code "must be a positive number."}.
- */
- public static TemplateException newArgumentValueException(
- int argIdx, String problemDescription,
- TemplateCallableModel callable, boolean calledAsFunction) {
- return new TemplateException(
- getMessageArgumentProblem(
- callable, argIdx,
- problemDescription,
- calledAsFunction));
- }
-
- /**
- * Convenience method to call
- * {@link #newArgumentValueTypeException(TemplateModel, int, Class, TemplateCallableModel, boolean)}.
- */
- public static TemplateException newArgumentValueTypeException(
- TemplateModel argValue, int argIdx, Class<? extends TemplateModel> expectedType,
- TemplateDirectiveModel callable) {
- return newArgumentValueTypeException(
- argValue, argIdx, expectedType,
- callable, false);
- }
-
- /**
- * Convenience method to call
- * {@link #newArgumentValueTypeException(TemplateModel, int, Class, TemplateCallableModel, boolean)}.
- */
- public static TemplateException newArgumentValueTypeException(
- TemplateModel argValue, int argIdx, Class<? extends TemplateModel> expectedType,
- TemplateFunctionModel callable) {
- return newArgumentValueTypeException(
- argValue, argIdx, expectedType,
- callable, true);
- }
-
- public static TemplateException newArgumentValueTypeException(
- TemplateModel argValue, int argIdx, Class<? extends TemplateModel> expectedType,
- TemplateCallableModel callable, boolean calledAsFunction) {
- return new TemplateException(
- getMessageBadArgumentType(argValue, argIdx,
- new Class[] { expectedType },
- TemplateLanguageUtils.getTypeName(expectedType),
- callable, calledAsFunction));
- }
-
- /**
- * Convenience method for calling
- * {@link #newArgumentValueTypeException(TemplateModel, int, Class[], String, TemplateCallableModel, boolean)}.
- */
- public static TemplateException newArgumentValueTypeException(
- TemplateModel argValue, int argIdx, Class[] expectedTypes, String expectedTypeDescription,
- TemplateDirectiveModel callable) {
- return newArgumentValueTypeException(
- argValue, argIdx, expectedTypes, expectedTypeDescription,
- callable, false);
- }
-
- /**
- * Convenience method for calling
- * {@link #newArgumentValueTypeException(TemplateModel, int, Class[], String, TemplateCallableModel, boolean)}.
- */
- public static TemplateException newArgumentValueTypeException(
- TemplateModel argValue, int argIdx, Class[] expectedTypes, String expectedTypeDescription,
- TemplateFunctionModel callable) {
- return newArgumentValueTypeException(
- argValue, argIdx, expectedTypes, expectedTypeDescription,
- callable, true);
- }
-
- /**
- * @param expectedTypeDescription Something like "string or number".
- */
- public static TemplateException newArgumentValueTypeException(
- TemplateModel argValue, int argIdx, Class[] expectedTypes, String expectedTypeDescription,
- TemplateCallableModel callable, boolean calledAsFunction) {
- return new TemplateException(
- getMessageBadArgumentType(argValue, argIdx,
- expectedTypes,
- expectedTypeDescription,
- callable, calledAsFunction));
- }
-
- public static TemplateException newNullOrOmittedArgumentException(int argIdx, TemplateFunctionModel callable) {
- return newNullOrOmittedArgumentException(argIdx, callable, true);
- }
-
- public static TemplateException newNullOrOmittedArgumentException(int argIdx, TemplateDirectiveModel callable) {
- return newNullOrOmittedArgumentException(argIdx, callable, false);
- }
-
- public static TemplateException newNullOrOmittedArgumentException(int argIdx, TemplateCallableModel callable,
- boolean calledAsFunction) {
- return newArgumentValueException(argIdx, "can't be omitted or null.", callable, calledAsFunction);
- }
-
- /**
- * Something like {@code "When calling function \"lib.ftl:foo\": " or "When calling ?leftPad: "}
- */
- private static Object getMessagePartWhenCallingSomethingColon(
- TemplateCallableModel callable, boolean calledAsFunction) {
- return callable instanceof ASTExpBuiltIn.BuiltInCallable
- ? new Object[] { "When calling ?", ((ASTExpBuiltIn.BuiltInCallable) callable).getBuiltInName() + ": " }
- : new Object[] {
- "When calling ",
- getCallableTypeName(callable, calledAsFunction),
- " ",
- callable instanceof TemplateModelWithOriginName
- ? new _DelayedJQuote(((TemplateModelWithOriginName) callable).getOriginName())
- : new _DelayedShortClassName(callable.getClass()),
- ": "
- };
- }
-
- private static Object getMessagePartsTheSomethingArgument(ArgumentArrayLayout argsLayout, int argsArrayIndex) {
- if (argsArrayIndex < 0) {
- throw new IllegalArgumentException("argsArrayIndex can't be negative");
- }
- if (argsLayout == null || argsArrayIndex < argsLayout.getPredefinedPositionalArgumentCount()) {
- return new Object[] { "The ", new _DelayedOrdinal(argsArrayIndex + 1), " argument " };
- } else if (argsLayout.getPositionalVarargsArgumentIndex() == argsArrayIndex) {
- return argsLayout.getNamedVarargsArgumentIndex() != -1 ? "The positional varargs argument "
- : "The varargs argument ";
- } else if (argsLayout.getNamedVarargsArgumentIndex() == argsArrayIndex) {
- return "The named varargs argument ";
- } else {
- String argName = argsLayout.getPredefinedNamedArgumentsMap().getKeyOfValue(argsArrayIndex);
- return argName != null
- ? new Object[] { "The ", new _DelayedJQuote(argName), " argument " }
- : "The argument "; // Shouldn't occur...
- }
- }
-
- static Object[] getMessageArgumentProblem(TemplateCallableModel callable, int argIndex, Object
- problemDescription, boolean calledAsFunction) {
- return new Object[] {
- getMessagePartWhenCallingSomethingColon(callable, calledAsFunction),
- getMessagePartsTheSomethingArgument(
- calledAsFunction ? ((TemplateFunctionModel) callable).getFunctionArgumentArrayLayout()
- : ((TemplateDirectiveModel) callable).getDirectiveArgumentArrayLayout(),
- argIndex),
- problemDescription
- };
- }
-
- private static _ErrorDescriptionBuilder getMessageBadArgumentType(
- TemplateModel argValue, int argIdx, Class<? extends TemplateModel>[] expectedTypes,
- String expectedTypesDesc, TemplateCallableModel callable,
- boolean calledAsFunction) {
- _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
- getMessageArgumentProblem(
- callable, argIdx,
- new Object[]{ " should be ", new _DelayedAOrAn(expectedTypesDesc), ", but was ",
- new _DelayedAOrAn(new _DelayedTemplateLanguageTypeDescription(argValue)),
- "." },
- calledAsFunction));
- if (argValue instanceof _UnexpectedTypeErrorExplainerTemplateModel) {
- Object[] tip = ((_UnexpectedTypeErrorExplainerTemplateModel) argValue).explainTypeError(expectedTypes);
- if (tip != null) {
- desc.tip(tip);
- }
- }
- return desc;
- }
-
- public static void executeWith0Arguments(
- TemplateDirectiveModel directive, CallPlace callPlace, Writer out, Environment env)
- throws IOException, TemplateException {
- 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.getFunctionArgumentArrayLayout()), callPlace, env);
- }
-
- private static TemplateModel[] getArgumentArrayWithNoArguments(ArgumentArrayLayout argsLayout) {
- int totalLength = argsLayout != null ? argsLayout.getTotalLength() : 0;
- if (totalLength == 0) {
- return EMPTY_TEMPLATE_MODEL_ARRAY;
- } else {
- TemplateModel[] args = new TemplateModel[totalLength];
-
- int positionalVarargsArgumentIndex = argsLayout.getPositionalVarargsArgumentIndex();
- if (positionalVarargsArgumentIndex != -1) {
- args[positionalVarargsArgumentIndex] = TemplateSequenceModel.EMPTY_SEQUENCE;
- }
-
- int namedVarargsArgumentIndex = argsLayout.getNamedVarargsArgumentIndex();
- if (namedVarargsArgumentIndex != -1) {
- args[namedVarargsArgumentIndex] = TemplateSequenceModel.EMPTY_SEQUENCE;
- }
-
- return args;
- }
- }
-
- // String arg:
-
- /**
- * Convenience method to call
- * {@link #castArgumentValueToString(TemplateModel, int, TemplateCallableModel, boolean, boolean)
- * castArgumentValueToString(args[argIndex], argIndex, callable, true, false)}.
- */
- public static String getStringArgument(
- TemplateModel[] args, int argIndex, TemplateFunctionModel callable)
- throws TemplateException {
- return castArgumentValueToString(args[argIndex], argIndex, callable, true, false);
- }
-
- /**
- * Convenience method to call
- * {@link #castArgumentValueToString(TemplateModel, int, TemplateCallableModel, boolean, boolean)
- * castArgumentValueToString(args[argIndex], argIndex, callable, false, false)}.
- */
- public static String getStringArgument(
- TemplateModel[] args, int argIndex, TemplateDirectiveModel callable)
- throws TemplateException {
- return castArgumentValueToString(args[argIndex], argIndex, callable, false, false);
- }
-
- /**
- * Convenience method to call
- * {@link #castArgumentValueToString(TemplateModel, int, TemplateCallableModel, boolean, boolean)
- * castArgumentValueToString(args[argIndex], argIndex, callable, true, true)}.
- */
- public static String getOptionalStringArgument(
- TemplateModel[] args, int argIndex, TemplateFunctionModel callable)
- throws TemplateException {
- return castArgumentValueToString(args[argIndex], argIndex, callable, true, true);
- }
-
- /**
- * Convenience method to call
- * {@link #castArgumentValueToString(TemplateModel, int, TemplateCallableModel, boolean, boolean)
- * castArgumentValueToString(args[argIndex], argIndex, callable, false, true)}.
- */
- public static String getOptionalStringArgument(
- TemplateModel[] args, int argIndex, TemplateDirectiveModel callable)
- throws TemplateException {
- return castArgumentValueToString(args[argIndex], argIndex, callable, false, true);
- }
-
- /**
- * Checks if the argument value is a string; it does NOT check if {@code args} is big enough.
- *
- * @param calledAsFunction
- * If {@code callable} was called as function (as opposed to called as a directive)
- * @param optional
- * If we allow a {@code null} return value
- *
- * @return Null {@code null} if the argument was omitted or {@code null}
- *
- * @throws TemplateException
- * If the argument is not of the proper type or is non-optional yet {@code null}. The error message
- * describes the problem in detail.
- */
- public static String castArgumentValueToString(
- TemplateModel argValue, int argIdx, TemplateCallableModel callable,
- boolean calledAsFunction, boolean optional)
- throws TemplateException {
- if (argValue instanceof TemplateScalarModel) {
- return _EvalUtils.modelToString((TemplateScalarModel) argValue, null);
- }
- if (argValue == null) {
- if (optional) {
- return null;
- }
- throw newNullOrOmittedArgumentException(argIdx, callable, calledAsFunction);
- }
- throw newArgumentValueTypeException(argValue, argIdx, TemplateScalarModel.class, callable, calledAsFunction);
- }
-
- // Number arg:
-
- public static Number getNumberArgument(
- TemplateModel[] args, int argIndex, TemplateFunctionModel callable)
- throws TemplateException {
- return castArgumentValueToNumber(args[argIndex], argIndex, callable, true, false);
- }
-
- public static Number getNumberArgument(
- TemplateModel[] args, int argIndex, TemplateDirectiveModel callable)
- throws TemplateException {
- return castArgumentValueToNumber(args[argIndex], argIndex, callable, false, false);
- }
-
- public static Number getOptionalNumberArgument(
- TemplateModel[] args, int argIndex, TemplateFunctionModel callable)
- throws TemplateException {
- return castArgumentValueToNumber(args[argIndex], argIndex, callable, true, true);
- }
-
- public static Number getOptionalNumberArgument(
- TemplateModel[] args, int argIndex, TemplateDirectiveModel callable)
- throws TemplateException {
- return castArgumentValueToNumber(args[argIndex], argIndex, callable, false, true);
- }
-
- public static Number castArgumentValueToNumber(
- TemplateModel argValue, int argIdx, TemplateCallableModel callable,
- boolean calledAsFunction, boolean optional)
- throws TemplateException {
- if (argValue instanceof TemplateNumberModel) {
- return _EvalUtils.modelToNumber((TemplateNumberModel) argValue, null);
- }
- if (argValue == null) {
- if (optional) {
- return null;
- }
- throw newNullOrOmittedArgumentException(argIdx, callable, calledAsFunction);
- }
- throw newArgumentValueTypeException(
- argValue, argIdx, TemplateNumberModel.class, callable,
- calledAsFunction);
- }
-
- // TODO boolean, etc.
-
- // Argument count
-
- /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
- public static void checkArgumentCount(int argCnt, int expectedCnt, TemplateFunctionModel callable)
- throws TemplateException {
- checkArgumentCount(argCnt, expectedCnt, callable, true);
- }
-
- /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
- public static void checkArgumentCount(int argCnt, int expectedCnt, TemplateDirectiveModel callable)
- throws TemplateException {
- checkArgumentCount(argCnt, expectedCnt, callable, false);
- }
-
- /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
- public static void checkArgumentCount(int argCnt, int expectedCnt,
- TemplateCallableModel callable, boolean calledAsFunction) throws TemplateException {
- checkArgumentCount(argCnt, expectedCnt, expectedCnt, callable, calledAsFunction);
- }
-
- /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
- public static void checkArgumentCount(int argCnt, int minCnt, int maxCnt, TemplateFunctionModel callable)
- throws TemplateException {
- checkArgumentCount(argCnt, minCnt, maxCnt, callable, true);
- }
-
- /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
- public static void checkArgumentCount(int argCnt, int minCnt, int maxCnt, TemplateDirectiveModel callable)
- throws TemplateException {
- checkArgumentCount(argCnt, minCnt, maxCnt, callable, false);
- }
-
- /**
- * Useful when the {@link ArgumentArrayLayout} is {@code null} and so the argument array length is not fixed,
- * to check if the number of arguments is in the given range.
- */
- public static void checkArgumentCount(int argCnt, int minCnt, int maxCnt,
- TemplateCallableModel callable, boolean calledAsFunction) throws TemplateException {
- if (argCnt < minCnt || argCnt > maxCnt) {
- throw new TemplateException(
- getMessagePartWhenCallingSomethingColon(callable, calledAsFunction),
- getMessagePartExpectedNArgumentButHadM(argCnt, minCnt, maxCnt));
- }
- }
-
- private static Object[] getMessagePartExpectedNArgumentButHadM(int argCnt, int minCnt, int maxCnt) {
- ArrayList<Object> desc = new ArrayList<>(20);
-
- desc.add("Expected ");
-
- if (minCnt == maxCnt) {
- if (maxCnt == 0) {
- desc.add("no");
- } else {
- desc.add(maxCnt);
- }
- } else if (maxCnt - minCnt == 1) {
- desc.add(minCnt);
- desc.add(" or ");
- desc.add(maxCnt);
- } else {
- desc.add(minCnt);
- if (maxCnt != Integer.MAX_VALUE) {
- desc.add(" to ");
- desc.add(maxCnt);
- } else {
- desc.add(" or more (unlimited)");
- }
- }
- desc.add(" argument");
- if (maxCnt > 1) desc.add("s");
-
- desc.add(" but has received ");
- if (argCnt == 0) {
- desc.add("none");
- } else {
- desc.add(argCnt);
- }
- desc.add(".");
-
- return desc.toArray();
- }
-
- //
-
+public class _CallableUtils {
static TemplateModel[] getExecuteArgs(
ASTExpression[] positionalArgs, NamedArgument[] namedArgs, ArgumentArrayLayout argsLayout,
TemplateCallableModel callable, boolean calledAsFunction,
@@ -528,7 +68,7 @@ public final class _CallableUtils {
execArgs[i] = positionalArg.eval(env);
}
} else {
- execArgs = EMPTY_TEMPLATE_MODEL_ARRAY;
+ execArgs = CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY;
}
return execArgs;
}
@@ -638,7 +178,7 @@ public final class _CallableUtils {
}
private static Object[] getNamedArgumentsNotSupportedMessage(TemplateCallableModel callable,
- NamedArgument namedArg, boolean calledAsFunction) {
+ _CallableUtils.NamedArgument namedArg, boolean calledAsFunction) {
return new Object[] {
getMessagePartWhenCallingSomethingColon(callable, calledAsFunction),
"This ", getCallableTypeName(callable, calledAsFunction),
@@ -663,6 +203,24 @@ public final class _CallableUtils {
}
}
+ /**
+ * Something like {@code "When calling function \"lib.ftl:foo\": " or "When calling ?leftPad: "}
+ */
+ public static Object getMessagePartWhenCallingSomethingColon(
+ TemplateCallableModel callable, boolean calledAsFunction) {
+ return callable instanceof ASTExpBuiltIn.BuiltInCallable
+ ? new Object[] { "When calling ?", ((ASTExpBuiltIn.BuiltInCallable) callable).getBuiltInName() + ": " }
+ : new Object[] {
+ "When calling ",
+ getCallableTypeName(callable, calledAsFunction),
+ " ",
+ callable instanceof TemplateModelWithOriginName
+ ? new _DelayedJQuote(((TemplateModelWithOriginName) callable).getOriginName())
+ : new _DelayedShortClassName(callable.getClass()),
+ ": "
+ };
+ }
+
static final class NamedArgument {
private final String name;
private final ASTExpression value;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/_CoreAPI.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_CoreAPI.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_CoreAPI.java
index c904afa..df7042b 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/_CoreAPI.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_CoreAPI.java
@@ -69,6 +69,10 @@ public final class _CoreAPI {
return Environment.TemplateLanguageFunction.class.isAssignableFrom(cl);
}
+ public static boolean isTemplateLanguageCallable(Class<? extends TemplateModel> cl) {
+ return Environment.TemplateLanguageCallable.class.isAssignableFrom(cl);
+ }
+
public static void checkVersionNotNullAndSupported(Version incompatibleImprovements) {
_NullArgumentException.check("incompatibleImprovements", incompatibleImprovements);
int iciV = incompatibleImprovements.intValue();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java
index e9a7967..17f6459 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java
@@ -19,6 +19,8 @@
package org.apache.freemarker.core;
+import static org.apache.freemarker.core.MessageUtils.*;
+
import java.util.Date;
import org.apache.freemarker.core.arithmetic.ArithmeticEngine;
@@ -57,7 +59,7 @@ public class _EvalUtils {
/**
* @param expr {@code null} is allowed, but may results in less helpful error messages
*/
- static String modelToString(TemplateScalarModel model, ASTExpression expr)
+ public static String modelToString(TemplateScalarModel model, ASTExpression expr)
throws TemplateModelException {
String value = model.getAsString();
if (value == null) {
@@ -69,7 +71,7 @@ public class _EvalUtils {
/**
* @param expr {@code null} is allowed, but may results in less helpful error messages
*/
- static Number modelToNumber(TemplateNumberModel model, ASTExpression expr)
+ public static Number modelToNumber(TemplateNumberModel model, ASTExpression expr)
throws TemplateModelException {
Number value = model.getAsNumber();
if (value == null) throw newModelHasStoredNullException(Number.class, model, expr);
@@ -79,7 +81,7 @@ public class _EvalUtils {
/**
* @param expr {@code null} is allowed, but may results in less helpful error messages
*/
- static Date modelToDate(TemplateDateModel model, ASTExpression expr)
+ public static Date modelToDate(TemplateDateModel model, ASTExpression expr)
throws TemplateModelException {
Date value = model.getAsDate();
if (value == null) throw newModelHasStoredNullException(Date.class, model, expr);
@@ -447,7 +449,7 @@ public class _EvalUtils {
throw InvalidReferenceException.getInstance(exp, env);
} else {
throw new InvalidReferenceException(
- "Null/missing value (no more informatoin avilable)",
+ "Null/missing value (no more information available)",
env);
}
} else if (tm instanceof TemplateBooleanModel) {
@@ -459,37 +461,31 @@ public class _EvalUtils {
if (returnNullOnNonCoercableType) {
return null;
}
- if (seqHint != null && (tm instanceof TemplateSequenceModel || tm instanceof TemplateCollectionModel)) {
- if (supportsTOM) {
- throw new NonStringOrTemplateOutputException(exp, tm, seqHint, env);
- } else {
- throw new NonStringException(exp, tm, seqHint, env);
- }
- } else {
- if (supportsTOM) {
- throw new NonStringOrTemplateOutputException(exp, tm, env);
- } else {
- throw new NonStringException(exp, tm, env);
- }
- }
+
+ throw newUnexpectedOperandTypeException(
+ exp, tm,
+ supportsTOM ? STRING_COERCABLE_TYPES_OR_TOM_DESC : STRING_COERCABLE_TYPES_DESC,
+ supportsTOM ? EXPECTED_TYPES_STRING_COERCABLE_TYPES_AND_TOM : EXPECTED_TYPES_STRING_COERCABLE,
+ seqHint != null && (tm instanceof TemplateSequenceModel || tm instanceof TemplateCollectionModel)
+ ? new Object[] { seqHint }
+ : null,
+ env);
}
}
private static String ensureFormatResultString(Object formatResult, ASTExpression exp, Environment env)
- throws NonStringException {
+ throws TemplateException {
if (formatResult instanceof String) {
return (String) formatResult;
}
assertFormatResultNotNull(formatResult);
- TemplateMarkupOutputModel mo = (TemplateMarkupOutputModel) formatResult;
- _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
+ throw new TemplateException(env, new _ErrorDescriptionBuilder(
"Value was formatted to convert it to string, but the result was markup of ouput format ",
- new _DelayedJQuote(mo.getOutputFormat()), ".")
+ new _DelayedJQuote(((TemplateMarkupOutputModel) formatResult).getOutputFormat()), ".")
.tip("Use value?string to force formatting to plain text.")
- .blame(exp);
- throw new NonStringException(null, desc);
+ .blame(exp));
}
static String assertFormatResultNotNull(String r) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 285021c..ecd4ebb 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
@@ -34,7 +34,11 @@ implements TemplateBooleanModel, TemplateScalarModel, TemplateSequenceModel, Tem
TemplateFunctionModel {
public static final TemplateModel INSTANCE = new GeneralPurposeNothing();
-
+
+ private static final ArgumentArrayLayout ARGS_LAYOUT = ArgumentArrayLayout.create(
+ 0, true,
+ null, true);
+
private GeneralPurposeNothing() {
}
@@ -75,9 +79,7 @@ implements TemplateBooleanModel, TemplateScalarModel, TemplateSequenceModel, Tem
@Override
public ArgumentArrayLayout getFunctionArgumentArrayLayout() {
- return ArgumentArrayLayout.create(
- 0, true,
- null, true);
+ return ARGS_LAYOUT;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 2f1a506..7f57c68 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,7 +18,7 @@
*/
package org.apache.freemarker.core.model.impl;
-import org.apache.freemarker.core._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -47,7 +47,7 @@ class OverloadedFixArgsMethods extends OverloadedMethodsSubset {
throws TemplateModelException {
if (tmArgs == null) {
// null is treated as empty args
- tmArgs = _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY;
+ tmArgs = CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY;
}
final int argCount = tmArgs.length;
final Class<?>[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 8b325ed..fd5c5ee 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
@@ -20,7 +20,7 @@ package org.apache.freemarker.core.model.impl;
import java.lang.reflect.Array;
-import org.apache.freemarker.core._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -139,7 +139,7 @@ class OverloadedVarArgsMethods extends OverloadedMethodsSubset {
throws TemplateModelException {
if (tmArgs == null) {
// null is treated as empty args
- tmArgs = _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY;
+ tmArgs = CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY;
}
final int argsLen = tmArgs.length;
final Class<?>[][] unwrappingHintsByParamCount = getUnwrappingHintsByParamCount();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 f794083..b5fb41c 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
@@ -30,7 +30,7 @@ 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.util.CallableUtils;
import org.apache.freemarker.core._DelayedJQuote;
import org.apache.freemarker.core._TemplateModelException;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
@@ -112,7 +112,7 @@ public class ResourceBundleModel extends BeanModel implements TemplateFunctionMo
if (args.length < 1)
throw new TemplateException("No message key was specified", env);
// Read it
- String key = _CallableUtils.getStringArgument(args, 0, this);
+ String key = CallableUtils.getStringArgument(args, 0, this);
try {
if (args.length == 1) {
return wrap(((ResourceBundle) object).getObject(key));
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 c1786af..78c624c 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
@@ -21,7 +21,7 @@ package org.apache.freemarker.core.model.impl;
import java.lang.reflect.Array;
import java.lang.reflect.Member;
-import org.apache.freemarker.core._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core._DelayedTemplateLanguageTypeDescription;
import org.apache.freemarker.core._DelayedOrdinal;
import org.apache.freemarker.core._ErrorDescriptionBuilder;
@@ -52,7 +52,7 @@ class SimpleMethod {
Object[] unwrapArguments(TemplateModel[] args, DefaultObjectWrapper wrapper) throws TemplateModelException {
if (args == null) {
- args = _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY;
+ args = CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY;
}
boolean isVarArg = _MethodUtils.isVarargs(member);
int typesLen = argTypes.length;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java
new file mode 100644
index 0000000..a208612
--- /dev/null
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CallableUtils.java
@@ -0,0 +1,496 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+
+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._DelayedAOrAn;
+import org.apache.freemarker.core._DelayedJQuote;
+import org.apache.freemarker.core._DelayedOrdinal;
+import org.apache.freemarker.core._DelayedTemplateLanguageTypeDescription;
+import org.apache.freemarker.core._ErrorDescriptionBuilder;
+import org.apache.freemarker.core._EvalUtils;
+import org.apache.freemarker.core._UnexpectedTypeErrorExplainerTemplateModel;
+import org.apache.freemarker.core.model.ArgumentArrayLayout;
+import org.apache.freemarker.core.model.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;
+import org.apache.freemarker.core.model.TemplateSequenceModel;
+
+/**
+ * For internal use only; don't depend on this, there's no backward compatibility guarantee at all!
+ */
+public final class CallableUtils {
+
+ public static final TemplateModel[] EMPTY_TEMPLATE_MODEL_ARRAY = new TemplateModel[0];
+
+ private CallableUtils() {
+ //
+ }
+
+ /** Convenience method for calling {@link #newGenericExecuteException(TemplateCallableModel, boolean, String)}. */
+ public static TemplateException newGenericExecuteException(
+ TemplateFunctionModel callable, String errorDescription) {
+ return newGenericExecuteException(callable, true, errorDescription);
+ }
+
+ /** Convenience method for calling {@link #newGenericExecuteException(TemplateCallableModel, boolean, String)}. */
+ public static TemplateException newGenericExecuteException(
+ TemplateDirectiveModel callable, String errorDescription) {
+ return newGenericExecuteException(callable, false, errorDescription);
+ }
+
+ /**
+ * @param errorDescription Complete sentence describing the problem. This will be after
+ * {@code "When calling xxx: "}.
+ */
+ public static TemplateException newGenericExecuteException(
+ TemplateCallableModel callable, boolean calledAsFunction, String errorDescription) {
+ return new TemplateException(
+ _CallableUtils.getMessagePartWhenCallingSomethingColon(callable, calledAsFunction),
+ errorDescription);
+ }
+
+ public static TemplateException newArgumentValueException(
+ int argIdx, String problemDescription,
+ TemplateDirectiveModel callable) {
+ return newArgumentValueException(
+ argIdx, problemDescription, callable, false);
+ }
+
+ public static TemplateException newArgumentValueException(
+ int argIdx, String problemDescription,
+ TemplateFunctionModel callable) {
+ return newArgumentValueException(
+ argIdx, problemDescription, callable, true);
+ }
+
+ /**
+ * @param problemDescription The continuation of a sentence like {@code "When calling xxx: The 1st argument "}, for
+ * example {@code "must be a positive number."}.
+ */
+ public static TemplateException newArgumentValueException(
+ int argIdx, String problemDescription,
+ TemplateCallableModel callable, boolean calledAsFunction) {
+ return _newArgumentValueException(argIdx, problemDescription, callable, calledAsFunction, null);
+ }
+
+ // TODO [FM3] How to expose tips API?
+ public static TemplateException _newArgumentValueException(
+ int argIdx, String problemDescription,
+ TemplateCallableModel callable, boolean calledAsFunction,
+ Object[] tips) {
+ return new TemplateException(
+ new _ErrorDescriptionBuilder(
+ getMessageArgumentProblem(callable, argIdx, problemDescription, calledAsFunction)
+ ).tips(tips));
+ }
+
+ /**
+ * Convenience method to call
+ * {@link #newArgumentValueTypeException(TemplateModel, int, Class, TemplateCallableModel, boolean)}.
+ */
+ public static TemplateException newArgumentValueTypeException(
+ TemplateModel argValue, int argIdx, Class<? extends TemplateModel> expectedType,
+ TemplateDirectiveModel callable) {
+ return newArgumentValueTypeException(
+ argValue, argIdx, expectedType,
+ callable, false);
+ }
+
+ /**
+ * Convenience method to call
+ * {@link #newArgumentValueTypeException(TemplateModel, int, Class, TemplateCallableModel, boolean)}.
+ */
+ public static TemplateException newArgumentValueTypeException(
+ TemplateModel argValue, int argIdx, Class<? extends TemplateModel> expectedType,
+ TemplateFunctionModel callable) {
+ return newArgumentValueTypeException(
+ argValue, argIdx, expectedType,
+ callable, true);
+ }
+
+ public static TemplateException newArgumentValueTypeException(
+ TemplateModel argValue, int argIdx, Class<? extends TemplateModel> expectedType,
+ TemplateCallableModel callable, boolean calledAsFunction) {
+ return new TemplateException(
+ getMessageBadArgumentType(argValue, argIdx,
+ new Class[] { expectedType },
+ TemplateLanguageUtils.getTypeName(expectedType),
+ callable, calledAsFunction));
+ }
+
+ /**
+ * Convenience method for calling
+ * {@link #newArgumentValueTypeException(TemplateModel, int, Class[], String, TemplateCallableModel, boolean)}.
+ */
+ public static TemplateException newArgumentValueTypeException(
+ TemplateModel argValue, int argIdx, Class[] expectedTypes, String expectedTypeDescription,
+ TemplateDirectiveModel callable) {
+ return newArgumentValueTypeException(
+ argValue, argIdx, expectedTypes, expectedTypeDescription,
+ callable, false);
+ }
+
+ /**
+ * Convenience method for calling
+ * {@link #newArgumentValueTypeException(TemplateModel, int, Class[], String, TemplateCallableModel, boolean)}.
+ */
+ public static TemplateException newArgumentValueTypeException(
+ TemplateModel argValue, int argIdx, Class[] expectedTypes, String expectedTypeDescription,
+ TemplateFunctionModel callable) {
+ return newArgumentValueTypeException(
+ argValue, argIdx, expectedTypes, expectedTypeDescription,
+ callable, true);
+ }
+
+ /**
+ * @param expectedTypeDescription Something like "string or number".
+ */
+ public static TemplateException newArgumentValueTypeException(
+ TemplateModel argValue, int argIdx, Class[] expectedTypes, String expectedTypeDescription,
+ TemplateCallableModel callable, boolean calledAsFunction) {
+ return new TemplateException(
+ getMessageBadArgumentType(argValue, argIdx,
+ expectedTypes,
+ expectedTypeDescription,
+ callable, calledAsFunction));
+ }
+
+ public static TemplateException newNullOrOmittedArgumentException(int argIdx, TemplateFunctionModel callable) {
+ return newNullOrOmittedArgumentException(argIdx, callable, true);
+ }
+
+ public static TemplateException newNullOrOmittedArgumentException(int argIdx, TemplateDirectiveModel callable) {
+ return newNullOrOmittedArgumentException(argIdx, callable, false);
+ }
+
+ public static TemplateException newNullOrOmittedArgumentException(int argIdx, TemplateCallableModel callable,
+ boolean calledAsFunction) {
+ return _newNullOrOmittedArgumentException(argIdx, callable, calledAsFunction, null);
+ }
+
+ // TODO [FM3] How to expose tips API?
+ public static TemplateException _newNullOrOmittedArgumentException(int argIdx, TemplateCallableModel callable,
+ boolean calledAsFunction, Object[] tips) {
+ return _newArgumentValueException(argIdx, "can't be omitted or null.", callable, calledAsFunction, tips);
+ }
+
+ private static Object getMessagePartsTheSomethingArgument(ArgumentArrayLayout argsLayout, int argsArrayIndex) {
+ if (argsArrayIndex < 0) {
+ throw new IllegalArgumentException("argsArrayIndex can't be negative");
+ }
+ if (argsLayout == null || argsArrayIndex < argsLayout.getPredefinedPositionalArgumentCount()) {
+ return new Object[] { "The ", new _DelayedOrdinal(argsArrayIndex + 1), " argument " };
+ } else if (argsLayout.getPositionalVarargsArgumentIndex() == argsArrayIndex) {
+ return argsLayout.getNamedVarargsArgumentIndex() != -1 ? "The positional varargs argument "
+ : "The varargs argument ";
+ } else if (argsLayout.getNamedVarargsArgumentIndex() == argsArrayIndex) {
+ return "The named varargs argument ";
+ } else {
+ String argName = argsLayout.getPredefinedNamedArgumentsMap().getKeyOfValue(argsArrayIndex);
+ return argName != null
+ ? new Object[] { "The ", new _DelayedJQuote(argName), " argument " }
+ : "The argument "; // Shouldn't occur...
+ }
+ }
+
+ static Object[] getMessageArgumentProblem(TemplateCallableModel callable, int argIndex, Object
+ problemDescription, boolean calledAsFunction) {
+ return new Object[] {
+ _CallableUtils.getMessagePartWhenCallingSomethingColon(callable, calledAsFunction),
+ getMessagePartsTheSomethingArgument(
+ calledAsFunction ? ((TemplateFunctionModel) callable).getFunctionArgumentArrayLayout()
+ : ((TemplateDirectiveModel) callable).getDirectiveArgumentArrayLayout(),
+ argIndex),
+ problemDescription
+ };
+ }
+
+ private static _ErrorDescriptionBuilder getMessageBadArgumentType(
+ TemplateModel argValue, int argIdx, Class<? extends TemplateModel>[] expectedTypes,
+ String expectedTypesDesc, TemplateCallableModel callable,
+ boolean calledAsFunction) {
+ _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder(
+ getMessageArgumentProblem(
+ callable, argIdx,
+ new Object[]{ " should be ", new _DelayedAOrAn(expectedTypesDesc), ", but was ",
+ new _DelayedAOrAn(new _DelayedTemplateLanguageTypeDescription(argValue)),
+ "." },
+ calledAsFunction));
+ if (argValue instanceof _UnexpectedTypeErrorExplainerTemplateModel) {
+ Object[] tip = ((_UnexpectedTypeErrorExplainerTemplateModel) argValue).explainTypeError(expectedTypes);
+ if (tip != null) {
+ desc.tip(tip);
+ }
+ }
+ return desc;
+ }
+
+ public static void executeWith0Arguments(
+ TemplateDirectiveModel directive, CallPlace callPlace, Writer out, Environment env)
+ throws IOException, TemplateException {
+ 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.getFunctionArgumentArrayLayout()), callPlace, env);
+ }
+
+ private static TemplateModel[] getArgumentArrayWithNoArguments(ArgumentArrayLayout argsLayout) {
+ int totalLength = argsLayout != null ? argsLayout.getTotalLength() : 0;
+ if (totalLength == 0) {
+ return EMPTY_TEMPLATE_MODEL_ARRAY;
+ } else {
+ TemplateModel[] args = new TemplateModel[totalLength];
+
+ int positionalVarargsArgumentIndex = argsLayout.getPositionalVarargsArgumentIndex();
+ if (positionalVarargsArgumentIndex != -1) {
+ args[positionalVarargsArgumentIndex] = TemplateSequenceModel.EMPTY_SEQUENCE;
+ }
+
+ int namedVarargsArgumentIndex = argsLayout.getNamedVarargsArgumentIndex();
+ if (namedVarargsArgumentIndex != -1) {
+ args[namedVarargsArgumentIndex] = TemplateSequenceModel.EMPTY_SEQUENCE;
+ }
+
+ return args;
+ }
+ }
+
+ // String arg:
+
+ /**
+ * Convenience method to call
+ * {@link #castArgumentValueToString(TemplateModel, int, TemplateCallableModel, boolean, boolean)
+ * castArgumentValueToString(args[argIndex], argIndex, callable, true, false)}.
+ */
+ public static String getStringArgument(
+ TemplateModel[] args, int argIndex, TemplateFunctionModel callable)
+ throws TemplateException {
+ return castArgumentValueToString(args[argIndex], argIndex, callable, true, false);
+ }
+
+ /**
+ * Convenience method to call
+ * {@link #castArgumentValueToString(TemplateModel, int, TemplateCallableModel, boolean, boolean)
+ * castArgumentValueToString(args[argIndex], argIndex, callable, false, false)}.
+ */
+ public static String getStringArgument(
+ TemplateModel[] args, int argIndex, TemplateDirectiveModel callable)
+ throws TemplateException {
+ return castArgumentValueToString(args[argIndex], argIndex, callable, false, false);
+ }
+
+ /**
+ * Convenience method to call
+ * {@link #castArgumentValueToString(TemplateModel, int, TemplateCallableModel, boolean, boolean)
+ * castArgumentValueToString(args[argIndex], argIndex, callable, true, true)}.
+ */
+ public static String getOptionalStringArgument(
+ TemplateModel[] args, int argIndex, TemplateFunctionModel callable)
+ throws TemplateException {
+ return castArgumentValueToString(args[argIndex], argIndex, callable, true, true);
+ }
+
+ /**
+ * Convenience method to call
+ * {@link #castArgumentValueToString(TemplateModel, int, TemplateCallableModel, boolean, boolean)
+ * castArgumentValueToString(args[argIndex], argIndex, callable, false, true)}.
+ */
+ public static String getOptionalStringArgument(
+ TemplateModel[] args, int argIndex, TemplateDirectiveModel callable)
+ throws TemplateException {
+ return castArgumentValueToString(args[argIndex], argIndex, callable, false, true);
+ }
+
+ /**
+ * Checks if the argument value is a string; it does NOT check if {@code args} is big enough.
+ *
+ * @param calledAsFunction
+ * If {@code callable} was called as function (as opposed to called as a directive)
+ * @param optional
+ * If we allow a {@code null} return value
+ *
+ * @return Null {@code null} if the argument was omitted or {@code null}
+ *
+ * @throws TemplateException
+ * If the argument is not of the proper type or is non-optional yet {@code null}. The error message
+ * describes the problem in detail.
+ */
+ public static String castArgumentValueToString(
+ TemplateModel argValue, int argIdx, TemplateCallableModel callable,
+ boolean calledAsFunction, boolean optional)
+ throws TemplateException {
+ if (argValue instanceof TemplateScalarModel) {
+ return _EvalUtils.modelToString((TemplateScalarModel) argValue, null);
+ }
+ if (argValue == null) {
+ if (optional) {
+ return null;
+ }
+ throw newNullOrOmittedArgumentException(argIdx, callable, calledAsFunction);
+ }
+ throw newArgumentValueTypeException(argValue, argIdx, TemplateScalarModel.class, callable, calledAsFunction);
+ }
+
+ // Number arg:
+
+ public static Number getNumberArgument(
+ TemplateModel[] args, int argIndex, TemplateFunctionModel callable)
+ throws TemplateException {
+ return castArgumentValueToNumber(args[argIndex], argIndex, callable, true, false);
+ }
+
+ public static Number getNumberArgument(
+ TemplateModel[] args, int argIndex, TemplateDirectiveModel callable)
+ throws TemplateException {
+ return castArgumentValueToNumber(args[argIndex], argIndex, callable, false, false);
+ }
+
+ public static Number getOptionalNumberArgument(
+ TemplateModel[] args, int argIndex, TemplateFunctionModel callable)
+ throws TemplateException {
+ return castArgumentValueToNumber(args[argIndex], argIndex, callable, true, true);
+ }
+
+ public static Number getOptionalNumberArgument(
+ TemplateModel[] args, int argIndex, TemplateDirectiveModel callable)
+ throws TemplateException {
+ return castArgumentValueToNumber(args[argIndex], argIndex, callable, false, true);
+ }
+
+ public static Number castArgumentValueToNumber(
+ TemplateModel argValue, int argIdx, TemplateCallableModel callable,
+ boolean calledAsFunction, boolean optional)
+ throws TemplateException {
+ if (argValue instanceof TemplateNumberModel) {
+ return _EvalUtils.modelToNumber((TemplateNumberModel) argValue, null);
+ }
+ if (argValue == null) {
+ if (optional) {
+ return null;
+ }
+ throw newNullOrOmittedArgumentException(argIdx, callable, calledAsFunction);
+ }
+ throw newArgumentValueTypeException(
+ argValue, argIdx, TemplateNumberModel.class, callable,
+ calledAsFunction);
+ }
+
+ // TODO boolean, etc.
+
+ // Argument count
+
+ /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
+ public static void checkArgumentCount(int argCnt, int expectedCnt, TemplateFunctionModel callable)
+ throws TemplateException {
+ checkArgumentCount(argCnt, expectedCnt, callable, true);
+ }
+
+ /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
+ public static void checkArgumentCount(int argCnt, int expectedCnt, TemplateDirectiveModel callable)
+ throws TemplateException {
+ checkArgumentCount(argCnt, expectedCnt, callable, false);
+ }
+
+ /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
+ public static void checkArgumentCount(int argCnt, int expectedCnt,
+ TemplateCallableModel callable, boolean calledAsFunction) throws TemplateException {
+ checkArgumentCount(argCnt, expectedCnt, expectedCnt, callable, calledAsFunction);
+ }
+
+ /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
+ public static void checkArgumentCount(int argCnt, int minCnt, int maxCnt, TemplateFunctionModel callable)
+ throws TemplateException {
+ checkArgumentCount(argCnt, minCnt, maxCnt, callable, true);
+ }
+
+ /** Convenience method for calling {@link #checkArgumentCount(int, int, int, TemplateCallableModel, boolean)}. */
+ public static void checkArgumentCount(int argCnt, int minCnt, int maxCnt, TemplateDirectiveModel callable)
+ throws TemplateException {
+ checkArgumentCount(argCnt, minCnt, maxCnt, callable, false);
+ }
+
+ /**
+ * Useful when the {@link ArgumentArrayLayout} is {@code null} and so the argument array length is not fixed,
+ * to check if the number of arguments is in the given range.
+ */
+ public static void checkArgumentCount(int argCnt, int minCnt, int maxCnt,
+ TemplateCallableModel callable, boolean calledAsFunction) throws TemplateException {
+ if (argCnt < minCnt || argCnt > maxCnt) {
+ throw new TemplateException(
+ _CallableUtils.getMessagePartWhenCallingSomethingColon(callable, calledAsFunction),
+ getMessagePartExpectedNArgumentButHadM(argCnt, minCnt, maxCnt));
+ }
+ }
+
+ private static Object[] getMessagePartExpectedNArgumentButHadM(int argCnt, int minCnt, int maxCnt) {
+ ArrayList<Object> desc = new ArrayList<>(20);
+
+ desc.add("Expected ");
+
+ if (minCnt == maxCnt) {
+ if (maxCnt == 0) {
+ desc.add("no");
+ } else {
+ desc.add(maxCnt);
+ }
+ } else if (maxCnt - minCnt == 1) {
+ desc.add(minCnt);
+ desc.add(" or ");
+ desc.add(maxCnt);
+ } else {
+ desc.add(minCnt);
+ if (maxCnt != Integer.MAX_VALUE) {
+ desc.add(" to ");
+ desc.add(maxCnt);
+ } else {
+ desc.add(" or more (unlimited)");
+ }
+ }
+ desc.add(" argument");
+ if (maxCnt > 1) desc.add("s");
+
+ desc.add(" but has received ");
+ if (argCnt == 0) {
+ desc.add("none");
+ } else {
+ desc.add(argCnt);
+ }
+ desc.add(".");
+
+ return desc.toArray();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java
index 749ccd5..9b980d9 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/util/TemplateLanguageUtils.java
@@ -840,12 +840,18 @@ public final class TemplateLanguageUtils {
}
if (TemplateCallableModel.class.isAssignableFrom(cl)) {
+ boolean recognized = false;
if (TemplateDirectiveModel.class.isAssignableFrom(cl)) {
appendTypeName(sb, typeNamesAppended, _CoreAPI.isMacro(cl) ? "macro" : "directive");
+ recognized = true;
}
if (TemplateFunctionModel.class.isAssignableFrom(cl)) {
appendTypeName(sb, typeNamesAppended,
JavaMethodModel.class.isAssignableFrom(cl) ? "method" : "function");
+ recognized = true;
+ }
+ if (!recognized && _CoreAPI.isTemplateLanguageCallable(cl)) {
+ appendTypeName(sb, typeNamesAppended, "macro or function defined with template language");
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 613b252..4a3295f 100644
--- a/freemarker-core/src/main/javacc/FTL.jj
+++ b/freemarker-core/src/main/javacc/FTL.jj
@@ -2248,8 +2248,8 @@ ASTDollarInterpolation ASTDollarInterpolation() :
begin = <DOLLAR_INTERPOLATION_OPENING>
exp = ASTExpression()
{
- notHashLiteral(exp, NonStringException.STRING_COERCABLE_TYPES_DESC);
- notListLiteral(exp, NonStringException.STRING_COERCABLE_TYPES_DESC);
+ notHashLiteral(exp, MessageUtils.STRING_COERCABLE_TYPES_DESC);
+ notListLiteral(exp, MessageUtils.STRING_COERCABLE_TYPES_DESC);
}
end = <CLOSING_CURLY_BRACKET>
{
[2/3] incubator-freemarker git commit: FREEMARKER-65: Utilities for
argument validation: Work in progress. Changes in this commit:
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 d31c885..119a1b8 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
@@ -19,7 +19,7 @@
package org.apache.freemarker.core;
-import static org.apache.freemarker.core._CallableUtils.*;
+import static org.apache.freemarker.core.util.CallableUtils.*;
import java.util.ArrayList;
import java.util.StringTokenizer;
@@ -34,6 +34,7 @@ import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateScalarModel;
import org.apache.freemarker.core.model.impl.SimpleNumber;
import org.apache.freemarker.core.model.impl.SimpleScalar;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.util._StringUtils;
class BuiltInsForStringsBasic {
@@ -71,7 +72,7 @@ class BuiltInsForStringsBasic {
static class containsBI extends ASTExpBuiltIn {
- private class BIMethod implements TemplateFunctionModel {
+ private class BIMethod extends BuiltInCallableImpl implements TemplateFunctionModel {
private final String s;
@@ -82,7 +83,7 @@ class BuiltInsForStringsBasic {
@Override
public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
throws TemplateException {
- return s.contains(_CallableUtils.getStringArgument(args, 0, this))
+ return s.contains(CallableUtils.getStringArgument(args, 0, this))
? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
@@ -257,6 +258,7 @@ class BuiltInsForStringsBasic {
}
static class keep_afterBI extends BuiltInForString {
+
class KeepAfterMethod extends BuiltInCallableImpl implements TemplateFunctionModel {
private String s;
@@ -367,6 +369,7 @@ class BuiltInsForStringsBasic {
}
static class keep_beforeBI extends BuiltInForString {
+
class KeepUntilMethod extends BuiltInCallableImpl implements TemplateFunctionModel {
private String s;
@@ -414,8 +417,8 @@ class BuiltInsForStringsBasic {
}
- // TODO
static class keep_before_lastBI extends BuiltInForString {
+
class KeepUntilMethod extends BuiltInCallableImpl implements TemplateFunctionModel {
private String s;
@@ -597,6 +600,7 @@ class BuiltInsForStringsBasic {
}
static class split_BI extends BuiltInForString {
+
class SplitMethod extends BuiltInCallableImpl implements TemplateFunctionModel {
private String s;
@@ -639,7 +643,7 @@ class BuiltInsForStringsBasic {
static class starts_withBI extends BuiltInForString {
- private class BIMethod implements TemplateFunctionModel {
+ private class BIMethod extends BuiltInCallableImpl implements TemplateFunctionModel {
private String s;
private BIMethod(String s) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 7a3fe12..8c6a6df 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
@@ -19,7 +19,7 @@
package org.apache.freemarker.core;
-import static org.apache.freemarker.core._CallableUtils.getStringArgument;
+import static org.apache.freemarker.core.util.CallableUtils.getStringArgument;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 ab1dbb3..d2e5f48 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
@@ -159,10 +159,10 @@ class BuiltInsForStringsMisc {
} else if (model instanceof TemplateScalarModel) {
sourceExpr = target;
} else {
- throw new UnexpectedTypeException(
+ throw MessageUtils.newUnexpectedOperandTypeException(
target, model,
"sequence or string", new Class[] { TemplateSequenceModel.class, TemplateScalarModel.class },
- env);
+ null, env);
}
String templateSource = sourceExpr.evalAndCoerceToPlainText(env);
Template parentTemplate = env.getCurrentTemplate();
@@ -236,7 +236,10 @@ class BuiltInsForStringsMisc {
try {
return new SimpleNumber(env.getArithmeticEngine().toNumber(s));
} catch (NumberFormatException nfe) {
- throw NonNumericalException.newMalformedNumberException(this, s, env);
+ throw new TemplateException(
+ new _ErrorDescriptionBuilder(
+ "Can't convert this string to number: ", new _DelayedJQuote(s))
+ .blame(this));
}
}
}
@@ -253,7 +256,7 @@ class BuiltInsForStringsMisc {
return new ConstructorFunction(target.evalAndCoerceToPlainText(env), env, target.getTemplate());
}
- class ConstructorFunction implements TemplateFunctionModel {
+ class ConstructorFunction extends BuiltInCallableImpl implements TemplateFunctionModel {
private final Class<?> cl;
private final Environment env;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 6879477..15ea886 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
@@ -19,7 +19,7 @@
package org.apache.freemarker.core;
-import static org.apache.freemarker.core._CallableUtils.*;
+import static org.apache.freemarker.core.util.CallableUtils.*;
import java.util.ArrayList;
import java.util.regex.Matcher;
@@ -54,9 +54,11 @@ class BuiltInsForStringsRegexp {
return new NativeStringArraySequence(((RegexMatchModel.MatchWithGroups) targetModel).groups);
} else {
- throw new UnexpectedTypeException(target, targetModel,
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ target, targetModel,
"regular expression matcher",
new Class[] { RegexMatchModel.class, RegexMatchModel.MatchWithGroups.class },
+ null,
env);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 fcf9471..7e7703d 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
@@ -19,6 +19,8 @@
package org.apache.freemarker.core;
+import static org.apache.freemarker.core.util.CallableUtils.*;
+
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
@@ -64,6 +66,7 @@ import org.apache.freemarker.core.model.impl.SimpleHash;
import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException;
import org.apache.freemarker.core.templateresolver.TemplateResolver;
import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.util.StringToIndexMap;
import org.apache.freemarker.core.util._DateUtils;
import org.apache.freemarker.core.util._DateUtils.DateToISO8601CalendarFactory;
@@ -582,7 +585,7 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
try {
TemplateDirectiveModel nodeProcessor = getNodeProcessor(node);
if (nodeProcessor != null) {
- _CallableUtils.executeWith0Arguments(
+ CallableUtils.executeWith0Arguments(
nodeProcessor, NonTemplateCallPlace.INSTANCE, out, this);
} else if (nodeProcessor == null) {
String nodeType = node.getNodeType();
@@ -641,7 +644,7 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
void fallback() throws TemplateException, IOException {
TemplateDirectiveModel nodeProcessor = getNodeProcessor(currentNodeName, currentNodeNS, nodeNamespaceIndex);
if (nodeProcessor != null) {
- _CallableUtils.executeWith0Arguments(
+ CallableUtils.executeWith0Arguments(
nodeProcessor, NonTemplateCallPlace.INSTANCE, out, this);
}
}
@@ -2999,22 +3002,23 @@ public final class Environment extends MutableProcessingConfiguration<Environmen
} else {
// TODO [FM3] Had to give different messages depending on if the argument was omitted, or if
// it was null, but this will be fixed with the null related refactoring.
- throw new TemplateException(Environment.this,
- new _ErrorDescriptionBuilder(
- _CallableUtils.getMessageArgumentProblem(
- this, argIdx,
- " can't be null or omitted.",
- isFunction())
- )
- .tip("If the parameter value expression on the caller side is known to "
+ throw _newNullOrOmittedArgumentException(
+ argIdx, this, isFunction(),
+ new Object[] {
+ "If the parameter value expression on the caller side is known to "
+ "be legally null/missing, you may want to specify a default "
+ "value for it on the caller side with the \"!\" operator, like "
- + "paramValue!defaultValue.")
- .tip("If the parameter was omitted on the caller side, and the omission was "
- + "deliberate, you may consider making the parameter optional in the macro "
- + "by specifying a default value for it, like <#macro macroName "
- + "paramName=defaultExpr>."
- )
+ + "paramValue!defaultValue.",
+ new Object[]{
+ "If the parameter was omitted on the caller side, and the omission "
+ + "was deliberate, you may consider making the parameter optional in "
+ + "the macro by specifying a default value for it, like ",
+ (isFunction()
+ ? "<#function functionName(paramName=defaultExpr)>"
+ : "<#macro macroName paramName=defaultExpr>"),
+ "."
+ }
+ }
);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtils.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtils.java b/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtils.java
index 0edbee6..d1db6e6 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtils.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/MessageUtils.java
@@ -19,7 +19,17 @@
package org.apache.freemarker.core;
+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.TemplateMarkupOutputModel;
+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.BugException;
+import org.apache.freemarker.core.util.TemplateLanguageUtils;
import org.apache.freemarker.core.util._StringUtils;
import org.apache.freemarker.core.valueformat.TemplateDateFormat;
import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
@@ -52,6 +62,29 @@ class MessageUtils {
static final String EMBEDDED_MESSAGE_END = "\n---end-message---";
static final String ERROR_MESSAGE_HR = "----";
+
+ static final String STRING_COERCABLE_TYPES_DESC
+ = "string or something automatically convertible to string (number, date or boolean)";
+ static final Class[] EXPECTED_TYPES_STRING_COERCABLE = new Class[] {
+ TemplateScalarModel.class, TemplateNumberModel.class, TemplateDateModel.class, TemplateBooleanModel.class
+ };
+
+ static final String STRING_COERCABLE_TYPES_OR_TOM_DESC
+ = STRING_COERCABLE_TYPES_DESC + ", or \"template output\"";
+ static final Class[] EXPECTED_TYPES_STRING_COERCABLE_TYPES_AND_TOM;
+ static {
+ EXPECTED_TYPES_STRING_COERCABLE_TYPES_AND_TOM = new Class[EXPECTED_TYPES_STRING_COERCABLE.length + 1];
+ int i;
+ for (i = 0; i < EXPECTED_TYPES_STRING_COERCABLE.length; i++) {
+ EXPECTED_TYPES_STRING_COERCABLE_TYPES_AND_TOM[i] = EXPECTED_TYPES_STRING_COERCABLE[i];
+ }
+ EXPECTED_TYPES_STRING_COERCABLE_TYPES_AND_TOM[i] = TemplateMarkupOutputModel.class;
+ }
+
+ static final String SEQUENCE_OR_COLLECTION = "sequence or collection";
+ static final Class[] EXPECTED_TYPES_SEQUENCE_OR_COLLECTION = new Class[] {
+ TemplateSequenceModel.class, TemplateCollectionModel.class
+ };
// Can't be instantiated
private MessageUtils() { }
@@ -178,9 +211,9 @@ class MessageUtils {
static TemplateModelException newCantFormatUnknownTypeDateException(
ASTExpression dateSourceExpr, UnknownDateTypeFormattingUnsupportedException cause) {
return new _TemplateModelException(cause, null, new _ErrorDescriptionBuilder(
- MessageUtils.UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE)
+ UNKNOWN_DATE_TO_STRING_ERROR_MESSAGE)
.blame(dateSourceExpr)
- .tips(MessageUtils.UNKNOWN_DATE_TO_STRING_TIPS));
+ .tips(UNKNOWN_DATE_TO_STRING_TIPS));
}
static TemplateException newCantFormatDateException(TemplateDateFormat format, ASTExpression dataSrcExp,
@@ -235,5 +268,83 @@ class MessageUtils {
}
}
}
-
+
+ static TemplateException newUnexpectedOperandTypeException(
+ ASTExpression blamed, TemplateModel model, Class<? extends TemplateModel> expectedType, Environment env)
+ throws InvalidReferenceException {
+ return newUnexpectedOperandTypeException(blamed, model, null, new Class[] { expectedType }, null, env);
+ }
+
+ static TemplateException newUnexpectedOperandTypeException(
+ ASTExpression blamed, TemplateModel model, String expectedTypesDesc, Class[] expectedTypes, Object[] tips,
+ Environment env)
+ throws InvalidReferenceException {
+ return new TemplateException(null, env, blamed, newUnexpectedOperandTypeDescriptionBuilder(
+ blamed,
+ null,
+ model, expectedTypesDesc, expectedTypes, env)
+ .tips(tips));
+ }
+
+ static TemplateException newUnexpectedAssignmentTargetTypeException(
+ String blamedAssignmentTargetVarName, TemplateModel model, Class<? extends TemplateModel> expectedType,
+ Environment env)
+ throws InvalidReferenceException {
+ return newUnexpectedAssignmentTargetTypeException(
+ blamedAssignmentTargetVarName, model, null, new Class[] { expectedType }, null, env);
+ }
+
+ /**
+ * Used for assignments that use {@code +=} and such.
+ */
+ static TemplateException newUnexpectedAssignmentTargetTypeException(
+ String blamedAssignmentTargetVarName, TemplateModel model, String expectedTypesDesc, Class[] expectedTypes,
+ Object[] tips,
+ Environment env)
+ throws InvalidReferenceException {
+ return new TemplateException(null, env, null, newUnexpectedOperandTypeDescriptionBuilder(
+ null,
+ blamedAssignmentTargetVarName,
+ model, expectedTypesDesc, expectedTypes, env).tips(tips));
+ }
+
+ private static _ErrorDescriptionBuilder newUnexpectedOperandTypeDescriptionBuilder(
+ ASTExpression blamed, String blamedAssignmentTargetVarName,
+ TemplateModel model, String expectedTypesDesc, Class<? extends TemplateModel>[] expectedTypes, Environment env)
+ throws InvalidReferenceException {
+ if (model == null) {
+ throw InvalidReferenceException.getInstance(blamed, env);
+ }
+
+ if (expectedTypesDesc == null) {
+ if (expectedTypes.length != 1) {
+ throw new BugException("Can't generate expectedTypesDesc");
+ }
+ expectedTypesDesc = TemplateLanguageUtils.getTypeName(expectedTypes[0]);
+ }
+ _ErrorDescriptionBuilder errorDescBuilder = new _ErrorDescriptionBuilder(
+ "Expected ", new _DelayedAOrAn(expectedTypesDesc), ", but ",
+ (
+ blamedAssignmentTargetVarName != null
+ ? new Object[] {
+ "assignment target variable ",
+ new _DelayedJQuote(blamedAssignmentTargetVarName) }
+ : blamed != null
+ ? "this"
+ : "the expression"
+ ),
+ " has evaluated to ",
+ new _DelayedAOrAn(new _DelayedTemplateLanguageTypeDescription(model)),
+ (blamed != null ? ":" : ".")
+ )
+ .blame(blamed).showBlamer(true);
+ if (model instanceof _UnexpectedTypeErrorExplainerTemplateModel) {
+ Object[] tip = ((_UnexpectedTypeErrorExplainerTemplateModel) model).explainTypeError(expectedTypes);
+ if (tip != null) {
+ errorDescBuilder.tip(tip);
+ }
+ }
+ return errorDescBuilder;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonBooleanException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonBooleanException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonBooleanException.java
deleted file mode 100644
index 3844fd0..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonBooleanException.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.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateModel;
-
-/**
- * Indicates that a {@link TemplateBooleanModel} value was expected, but the value had a different type.
- */
-public class NonBooleanException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { TemplateBooleanModel.class };
-
- public NonBooleanException(Environment env) {
- super(env, "Expecting boolean value here");
- }
-
- public NonBooleanException(String description, Environment env) {
- super(env, description);
- }
-
- NonBooleanException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonBooleanException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "boolean", EXPECTED_TYPES, env);
- }
-
- NonBooleanException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "boolean", EXPECTED_TYPES, tip, env);
- }
-
- NonBooleanException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "boolean", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonDateException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonDateException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonDateException.java
deleted file mode 100644
index 2e63e48..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonDateException.java
+++ /dev/null
@@ -1,58 +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.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModel;
-
-/**
- * Indicates that a {@link TemplateDateModel} value was expected, but the value had a different type.
- */
-public class NonDateException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { TemplateDateModel.class };
-
- public NonDateException(Environment env) {
- super(env, "Expecting date/time value here");
- }
-
- public NonDateException(String description, Environment env) {
- super(env, description);
- }
-
- NonDateException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "date/time", EXPECTED_TYPES, env);
- }
-
- NonDateException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "date/time", EXPECTED_TYPES, tip, env);
- }
-
- NonDateException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "date/time", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonDirectiveException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonDirectiveException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonDirectiveException.java
deleted file mode 100644
index 2053361..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonDirectiveException.java
+++ /dev/null
@@ -1,63 +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.TemplateDirectiveModel;
-import org.apache.freemarker.core.model.TemplateModel;
-
-/**
- * Indicates that a {@link TemplateDirectiveModel} was expected, but the value had a different type.
- */
-class NonDirectiveException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] {
- TemplateDirectiveModel.class, ASTDirMacroOrFunction.class };
-
- public NonDirectiveException(Environment env) {
- super(env, "Expecting user-defined directive, transform or macro value here");
- }
-
- public NonDirectiveException(String description, Environment env) {
- super(env, description);
- }
-
- NonDirectiveException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonDirectiveException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "user-defined directive, transform or macro", EXPECTED_TYPES, env);
- }
-
- NonDirectiveException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "user-defined directive, transform or macro", EXPECTED_TYPES, tip, env);
- }
-
- NonDirectiveException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "user-defined directive, transform or macro", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonExtendedHashException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonExtendedHashException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonExtendedHashException.java
deleted file mode 100644
index 5614b23..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonExtendedHashException.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.TemplateHashModelEx;
-import org.apache.freemarker.core.model.TemplateModel;
-
-/**
- * Indicates that a {@link TemplateHashModelEx} value was expected, but the value had a different type.
- */
-public class NonExtendedHashException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { TemplateHashModelEx.class };
-
- public NonExtendedHashException(Environment env) {
- super(env, "Expecting extended hash value here");
- }
-
- public NonExtendedHashException(String description, Environment env) {
- super(env, description);
- }
-
- NonExtendedHashException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonExtendedHashException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "extended hash", EXPECTED_TYPES, env);
- }
-
- NonExtendedHashException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "extended hash", EXPECTED_TYPES, tip, env);
- }
-
- NonExtendedHashException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "extended hash", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonExtendedNodeException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonExtendedNodeException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonExtendedNodeException.java
deleted file mode 100644
index 4c69b05..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonExtendedNodeException.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.TemplateModel;
-import org.apache.freemarker.core.model.TemplateNodeModelEx;
-
-/**
- * Indicates that a {@link TemplateNodeModelEx} value was expected, but the value had a different type.
- */
-public class NonExtendedNodeException extends UnexpectedTypeException {
-
- private static final Class<?>[] EXPECTED_TYPES = new Class[] { TemplateNodeModelEx.class };
-
- public NonExtendedNodeException(Environment env) {
- super(env, "Expecting extended node value here");
- }
-
- public NonExtendedNodeException(String description, Environment env) {
- super(env, description);
- }
-
- NonExtendedNodeException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonExtendedNodeException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "extended node", EXPECTED_TYPES, env);
- }
-
- NonExtendedNodeException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "extended node", EXPECTED_TYPES, tip, env);
- }
-
- NonExtendedNodeException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "extended node", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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
deleted file mode 100644
index 2ae7fdd..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonFunctionException.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.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/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonHashException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonHashException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonHashException.java
deleted file mode 100644
index eb56312..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonHashException.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.TemplateHashModel;
-import org.apache.freemarker.core.model.TemplateModel;
-
-/**
- * Indicates that a {@link TemplateHashModel} value was expected, but the value had a different type.
- */
-public class NonHashException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { TemplateHashModel.class };
-
- public NonHashException(Environment env) {
- super(env, "Expecting hash value here");
- }
-
- public NonHashException(String description, Environment env) {
- super(env, description);
- }
-
- NonHashException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonHashException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "hash", EXPECTED_TYPES, env);
- }
-
- NonHashException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "hash", EXPECTED_TYPES, tip, env);
- }
-
- NonHashException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "hash", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonMarkupOutputException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonMarkupOutputException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonMarkupOutputException.java
deleted file mode 100644
index cdc0728..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonMarkupOutputException.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.TemplateMarkupOutputModel;
-import org.apache.freemarker.core.model.TemplateModel;
-
-/**
- * Indicates that a {@link TemplateMarkupOutputModel} value was expected, but the value had a different type.
- */
-public class NonMarkupOutputException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { TemplateMarkupOutputModel.class };
-
- public NonMarkupOutputException(Environment env) {
- super(env, "Expecting markup output value here");
- }
-
- public NonMarkupOutputException(String description, Environment env) {
- super(env, description);
- }
-
- NonMarkupOutputException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonMarkupOutputException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "markup output", EXPECTED_TYPES, env);
- }
-
- NonMarkupOutputException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "markup output", EXPECTED_TYPES, tip, env);
- }
-
- NonMarkupOutputException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "markup output", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonNamespaceException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonNamespaceException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonNamespaceException.java
deleted file mode 100644
index 1433e02..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonNamespaceException.java
+++ /dev/null
@@ -1,61 +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.TemplateModel;
-
-/**
- * Indicates that a {@link Environment.Namespace} value was expected, but the value had a different type.
- */
-class NonNamespaceException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { Environment.Namespace.class };
-
- public NonNamespaceException(Environment env) {
- super(env, "Expecting namespace value here");
- }
-
- public NonNamespaceException(String description, Environment env) {
- super(env, description);
- }
-
- NonNamespaceException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonNamespaceException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "namespace", EXPECTED_TYPES, env);
- }
-
- NonNamespaceException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "namespace", EXPECTED_TYPES, tip, env);
- }
-
- NonNamespaceException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "namespace", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonNodeException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonNodeException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonNodeException.java
deleted file mode 100644
index f6e693f..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonNodeException.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.TemplateModel;
-import org.apache.freemarker.core.model.TemplateNodeModel;
-
-/**
- * Indicates that a {@link TemplateNodeModel} value was expected, but the value had a different type.
- */
-public class NonNodeException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { TemplateNodeModel.class };
-
- public NonNodeException(Environment env) {
- super(env, "Expecting node value here");
- }
-
- public NonNodeException(String description, Environment env) {
- super(env, description);
- }
-
- NonNodeException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonNodeException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "node", EXPECTED_TYPES, env);
- }
-
- NonNodeException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "node", EXPECTED_TYPES, tip, env);
- }
-
- NonNodeException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "node", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonNumericalException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonNumericalException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonNumericalException.java
deleted file mode 100644
index e943bad..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonNumericalException.java
+++ /dev/null
@@ -1,84 +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.TemplateCallableModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-
-/**
- * Indicates that a {@link TemplateNumberModel} value was expected, but the value had a different type.
- */
-public class NonNumericalException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { TemplateNumberModel.class };
-
- public NonNumericalException(Environment env) {
- super(env, "Expecting numerical value here");
- }
-
- public NonNumericalException(String description, Environment env) {
- super(env, description);
- }
-
- NonNumericalException(_ErrorDescriptionBuilder description, Environment env) {
- super(env, description);
- }
-
- NonNumericalException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "number", EXPECTED_TYPES, env);
- }
-
- NonNumericalException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "number", EXPECTED_TYPES, tip, env);
- }
-
- NonNumericalException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "number", EXPECTED_TYPES, tips, env);
- }
-
- NonNumericalException(
- String assignmentTargetVarName, TemplateModel model, String[] tips, Environment env)
- throws InvalidReferenceException {
- super(assignmentTargetVarName, model, "number", EXPECTED_TYPES, tips, env);
- }
-
-
- NonNumericalException(
- TemplateCallableModel callableModel, int argArrayIndex,
- TemplateModel model, String[] tips, Environment env)
- throws InvalidReferenceException {
- super(callableModel, argArrayIndex, model, "number", EXPECTED_TYPES, tips, env);
- }
-
- static NonNumericalException newMalformedNumberException(ASTExpression blamed, String text, Environment env) {
- return new NonNumericalException(
- new _ErrorDescriptionBuilder("Can't convert this string to number: ", new _DelayedJQuote(text))
- .blame(blamed),
- env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonSequenceException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonSequenceException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonSequenceException.java
deleted file mode 100644
index 738bb35..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonSequenceException.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.TemplateModel;
-import org.apache.freemarker.core.model.TemplateSequenceModel;
-
-/**
- * Indicates that a {@link TemplateSequenceModel} value was expected, but the value had a different type.
- */
-public class NonSequenceException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] { TemplateSequenceModel.class };
-
- public NonSequenceException(Environment env) {
- super(env, "Expecting sequence value here");
- }
-
- public NonSequenceException(String description, Environment env) {
- super(env, description);
- }
-
- NonSequenceException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonSequenceException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "sequence", EXPECTED_TYPES, env);
- }
-
- NonSequenceException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, "sequence", EXPECTED_TYPES, tip, env);
- }
-
- NonSequenceException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "sequence", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonSequenceOrCollectionException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonSequenceOrCollectionException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonSequenceOrCollectionException.java
deleted file mode 100644
index c229808..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonSequenceOrCollectionException.java
+++ /dev/null
@@ -1,90 +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.TemplateCollectionModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateSequenceModel;
-import org.apache.freemarker.core.model.WrapperTemplateModel;
-import org.apache.freemarker.core.util._CollectionUtils;
-
-/**
- * Indicates that a {@link TemplateSequenceModel} or {@link TemplateCollectionModel} value was expected, but the value
- * had a different type.
- */
-public class NonSequenceOrCollectionException extends UnexpectedTypeException {
-
- private static final Class[] EXPECTED_TYPES = new Class[] {
- TemplateSequenceModel.class, TemplateCollectionModel.class
- };
- private static final String ITERABLE_SUPPORT_HINT = "The problematic value is a java.lang.Iterable. Using "
- + "DefaultObjectWrapper(..., iterableSupport=true) as the objectWrapper setting of the FreeMarker "
- + "configuration should solve this.";
-
- public NonSequenceOrCollectionException(Environment env) {
- super(env, "Expecting sequence or collection value here");
- }
-
- public NonSequenceOrCollectionException(String description, Environment env) {
- super(env, description);
- }
-
- NonSequenceOrCollectionException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonSequenceOrCollectionException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- this(blamed, model, _CollectionUtils.EMPTY_OBJECT_ARRAY, env);
- }
-
- NonSequenceOrCollectionException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- this(blamed, model, new Object[] { tip }, env);
- }
-
- NonSequenceOrCollectionException(
- ASTExpression blamed, TemplateModel model, Object[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, "sequence or collection", EXPECTED_TYPES, extendTipsIfIterable(model, tips), env);
- }
-
- private static Object[] extendTipsIfIterable(TemplateModel model, Object[] tips) {
- if (isWrappedIterable(model)) {
- final int tipsLen = tips != null ? tips.length : 0;
- Object[] extendedTips = new Object[tipsLen + 1];
- for (int i = 0; i < tipsLen; i++) {
- extendedTips[i] = tips[i];
- }
- extendedTips[tipsLen] = ITERABLE_SUPPORT_HINT;
- return extendedTips;
- } else {
- return tips;
- }
- }
-
- public static boolean isWrappedIterable(TemplateModel model) {
- return model instanceof WrapperTemplateModel
- && ((WrapperTemplateModel) model).getWrappedObject() instanceof Iterable;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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
deleted file mode 100644
index ec02f73..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringException.java
+++ /dev/null
@@ -1,84 +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.TemplateBooleanModel;
-import org.apache.freemarker.core.model.TemplateCallableModel;
-import org.apache.freemarker.core.model.TemplateDateModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateNumberModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-
-/**
- * Indicates that a {@link TemplateScalarModel} value was expected (or maybe something that can be automatically coerced
- * to that), but the value had a different type.
- */
-public class NonStringException extends UnexpectedTypeException {
-
- static final String STRING_COERCABLE_TYPES_DESC
- = "string or something automatically convertible to string (number, date or boolean)";
-
- 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";
-
- public NonStringException(Environment env) {
- super(env, DEFAULT_DESCRIPTION);
- }
-
- public NonStringException(String description, Environment env) {
- super(env, description);
- }
-
- NonStringException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonStringException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, NonStringException.STRING_COERCABLE_TYPES_DESC, STRING_COERCABLE_TYPES, env);
- }
-
- NonStringException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, NonStringException.STRING_COERCABLE_TYPES_DESC, STRING_COERCABLE_TYPES, tip, env);
- }
-
- NonStringException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, NonStringException.STRING_COERCABLE_TYPES_DESC, STRING_COERCABLE_TYPES, tips, env);
- }
-
- NonStringException(
- TemplateCallableModel callableModel, int argArrayIndex,
- TemplateModel model, String[] tips, Environment env)
- throws InvalidReferenceException {
- super(callableModel, argArrayIndex, model, "string", EXPECTED_TYPES, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringOrTemplateOutputException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringOrTemplateOutputException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringOrTemplateOutputException.java
deleted file mode 100644
index ddeb811..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/NonStringOrTemplateOutputException.java
+++ /dev/null
@@ -1,78 +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.TemplateMarkupOutputModel;
-import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateScalarModel;
-
-/**
- * Indicates that a {@link TemplateScalarModel} (or maybe something that can be automatically coerced
- * to that) or {@link TemplateMarkupOutputModel} value was expected, but the value had a different type.
- */
-public class NonStringOrTemplateOutputException extends UnexpectedTypeException {
-
- static final String STRING_COERCABLE_TYPES_OR_TOM_DESC
- = NonStringException.STRING_COERCABLE_TYPES_DESC + ", or \"template output\"";
-
- static final Class[] STRING_COERCABLE_TYPES_AND_TOM;
- static {
- STRING_COERCABLE_TYPES_AND_TOM = new Class[NonStringException.STRING_COERCABLE_TYPES.length + 1];
- int i;
- for (i = 0; i < NonStringException.STRING_COERCABLE_TYPES.length; i++) {
- STRING_COERCABLE_TYPES_AND_TOM[i] = NonStringException.STRING_COERCABLE_TYPES[i];
- }
- STRING_COERCABLE_TYPES_AND_TOM[i] = TemplateMarkupOutputModel.class;
- }
-
- private static final String DEFAULT_DESCRIPTION
- = "Expecting " + NonStringOrTemplateOutputException.STRING_COERCABLE_TYPES_OR_TOM_DESC + " value here";
-
- public NonStringOrTemplateOutputException(Environment env) {
- super(env, DEFAULT_DESCRIPTION);
- }
-
- public NonStringOrTemplateOutputException(String description, Environment env) {
- super(env, description);
- }
-
- NonStringOrTemplateOutputException(Environment env, _ErrorDescriptionBuilder description) {
- super(env, description);
- }
-
- NonStringOrTemplateOutputException(
- ASTExpression blamed, TemplateModel model, Environment env)
- throws InvalidReferenceException {
- super(blamed, model, NonStringOrTemplateOutputException.STRING_COERCABLE_TYPES_OR_TOM_DESC, STRING_COERCABLE_TYPES_AND_TOM, env);
- }
-
- NonStringOrTemplateOutputException(
- ASTExpression blamed, TemplateModel model, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(blamed, model, NonStringOrTemplateOutputException.STRING_COERCABLE_TYPES_OR_TOM_DESC, STRING_COERCABLE_TYPES_AND_TOM, tip, env);
- }
-
- NonStringOrTemplateOutputException(
- ASTExpression blamed, TemplateModel model, String[] tips, Environment env) throws InvalidReferenceException {
- super(blamed, model, NonStringOrTemplateOutputException.STRING_COERCABLE_TYPES_OR_TOM_DESC, STRING_COERCABLE_TYPES_AND_TOM, tips, env);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/TemplateException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/TemplateException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/TemplateException.java
index 06cb20f..bcbb645 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/TemplateException.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/TemplateException.java
@@ -39,6 +39,7 @@ public class TemplateException extends Exception {
= "FTL stack trace (\"~\" means nesting-related):";
// Set in constructor:
+ // TODO [FM3] These all must be final, or else tha class is not thread safe
private transient _ErrorDescriptionBuilder descriptionBuilder;
private final transient Environment env;
private final transient ASTExpression blamedExpression;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/UnexpectedTypeException.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/UnexpectedTypeException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/UnexpectedTypeException.java
deleted file mode 100644
index 10401fd..0000000
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/UnexpectedTypeException.java
+++ /dev/null
@@ -1,171 +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.TemplateCallableModel;
-import org.apache.freemarker.core.model.TemplateModel;
-
-/**
- * The type of a value differs from what was expected.
- */
-public class UnexpectedTypeException extends TemplateException {
-
- public UnexpectedTypeException(Environment env, String description) {
- super(description, env);
- }
-
- UnexpectedTypeException(Environment env, _ErrorDescriptionBuilder description) {
- super(null, env, null, description);
- }
-
- UnexpectedTypeException(
- ASTExpression blamed, TemplateModel model, String expectedTypesDesc, Class[] expectedTypes, Environment env)
- throws InvalidReferenceException {
- super(null, env, blamed, newDescriptionBuilder(
- blamed,
- null,
- null, -1,
- model, expectedTypesDesc, expectedTypes,
- env));
- }
-
- UnexpectedTypeException(
- ASTExpression blamed, TemplateModel model, String expectedTypesDesc, Class[] expectedTypes, String tip,
- Environment env)
- throws InvalidReferenceException {
- super(null, env, blamed, newDescriptionBuilder(
- blamed,
- null,
- null, -1,
- model, expectedTypesDesc, expectedTypes,
- env)
- .tip(tip));
- }
-
- UnexpectedTypeException(
- ASTExpression blamed, TemplateModel model, String expectedTypesDesc, Class[] expectedTypes, Object[] tips,
- Environment env)
- throws InvalidReferenceException {
- super(null, env, blamed, newDescriptionBuilder(
- blamed,
- null,
- null, -1,
- model, expectedTypesDesc, expectedTypes, env)
- .tips(tips));
- }
-
- /**
- * Used for assignments that use {@code +=} and such.
- */
- UnexpectedTypeException(
- String blamedAssignmentTargetVarName, TemplateModel model, String expectedTypesDesc, Class[] expectedTypes,
- Object[] tips,
- Environment env)
- throws InvalidReferenceException {
- super(null, env, null, newDescriptionBuilder(
- null,
- blamedAssignmentTargetVarName,
- null, -1,
- model, expectedTypesDesc, expectedTypes, env).tips(tips));
- }
-
- /**
- * Used when the value of a directive/function argument has a different type than that the directive/function
- * expects.
- */
- UnexpectedTypeException(
- TemplateCallableModel callableModel, int argArrayIndex,
- TemplateModel model, String expectedTypesDesc, Class[] expectedTypes,
- Object[] tips,
- Environment env)
- throws InvalidReferenceException {
- super(null, env, null, newDescriptionBuilder(
- null,
- null,
- callableModel, argArrayIndex,
- model,
- expectedTypesDesc, expectedTypes, env).tips(tips));
- }
-
- private static _ErrorDescriptionBuilder newDescriptionBuilder(
- ASTExpression blamed, String blamedAssignmentTargetVarName,
- TemplateCallableModel callableModel, int argArrayIndex,
- TemplateModel model, String expectedTypesDesc, Class<? extends TemplateModel>[] expectedTypes, Environment env)
- throws InvalidReferenceException {
- if (model == null) {
- throw InvalidReferenceException.getInstance(blamed, env);
- }
-
- _ErrorDescriptionBuilder errorDescBuilder = new _ErrorDescriptionBuilder(
- callableModel == null
- ? unexpectedTypeErrorDescription(
- expectedTypesDesc,
- blamed,
- blamedAssignmentTargetVarName,
- model)
- : unexpectedTypeErrorDescription(
- expectedTypesDesc,
- blamed,
- callableModel, argArrayIndex,
- model))
- .blame(blamed).showBlamer(true);
- if (model instanceof _UnexpectedTypeErrorExplainerTemplateModel) {
- Object[] tip = ((_UnexpectedTypeErrorExplainerTemplateModel) model).explainTypeError(expectedTypes);
- if (tip != null) {
- errorDescBuilder.tip(tip);
- }
- }
- return errorDescBuilder;
- }
-
- private static Object[] unexpectedTypeErrorDescription(
- String expectedTypesDesc,
- ASTExpression blamed,
- String blamedAssignmentTargetVarName,
- TemplateModel model) {
- return new Object[] {
- "Expected ", new _DelayedAOrAn(expectedTypesDesc), ", but ", (
- blamedAssignmentTargetVarName != null
- ? new Object[] {
- "assignment target variable ",
- new _DelayedJQuote(blamedAssignmentTargetVarName) }
- : blamed != null
- ? "this"
- : "the expression"
- ),
- " has evaluated to ",
- new _DelayedAOrAn(new _DelayedTemplateLanguageTypeDescription(model)),
- (blamed != null ? ":" : ".")};
- }
-
- private static Object[] unexpectedTypeErrorDescription(
- String expectedTypesDesc,
- ASTExpression blamed,
- TemplateCallableModel callableModel, int argArrayIndex,
- TemplateModel actualValue) {
- // TODO
- return new Object[]{
- blamed, " expects ", new _DelayedAOrAn(expectedTypesDesc), " as its ", argArrayIndex, " arg, but it "
- + "was " + new _DelayedAOrAn(new _DelayedTemplateLanguageTypeDescription(actualValue)),
- (blamed != null ? ":" : ".")
- };
- }
-
-}
[3/3] incubator-freemarker git commit: FREEMARKER-65: Utilities for
argument validation: Work in progress. Changes in this commit:
Posted by dd...@apache.org.
FREEMARKER-65: Utilities for argument validation: Work in progress. Changes in this commit:
- Added org.apache.freemarker.core.util.CallableUtils (published API), to help in implementing (and invoking) TemplateCallableModel-s.
- Removed UnexpectedTypeException (a `TemplateException subclass) and its subclasses (NonStringException, etc.),
using simple TemplateException instead. Catching these exceptions specifically wasn't very useful, while they
have bloated the public API (and the code).
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/f231e64f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/f231e64f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/f231e64f
Branch: refs/heads/3
Commit: f231e64fe8e4e9a2786966506aeef79d0dd36fcd
Parents: e941aed
Author: ddekany <dd...@apache.org>
Authored: Wed Aug 16 17:21:41 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Thu Aug 17 01:24:25 2017 +0200
----------------------------------------------------------------------
FM3-CHANGE-LOG.txt | 5 +-
...a8DefaultObjectWrapperBridgeMethodsTest.java | 6 +-
.../impl/Java8DefaultObjectWrapperTest.java | 10 +-
.../freemarker/core/OutputFormatTest.java | 2 +-
.../core/TemplateCallableModelTest.java | 1 +
.../impl/AbstractParallelIntrospectionTest.java | 4 +-
.../model/impl/DefaultObjectWrapperTest.java | 10 +-
.../core/model/impl/EnumModelsTest.java | 4 +-
.../core/model/impl/StaticModelsTest.java | 4 +-
.../core/templatesuite/models/MultiModel2.java | 4 +-
.../core/userpkg/AllFeaturesDirective.java | 2 +-
.../core/userpkg/AllFeaturesFunction.java | 2 +-
.../templates/boolean-formatting.ftl | 2 +-
.../freemarker/core/ASTDirAssignment.java | 9 +-
.../apache/freemarker/core/ASTDirInclude.java | 14 +-
.../org/apache/freemarker/core/ASTDirList.java | 23 +-
.../apache/freemarker/core/ASTDirRecurse.java | 6 +-
.../org/apache/freemarker/core/ASTDirVisit.java | 5 +-
.../freemarker/core/ASTDynamicTopLevelCall.java | 5 +-
.../freemarker/core/ASTExpAddOrConcat.java | 78 ++-
.../org/apache/freemarker/core/ASTExpDot.java | 2 +-
.../freemarker/core/ASTExpDynamicKeyName.java | 69 +--
.../freemarker/core/ASTExpFunctionCall.java | 3 +-
.../freemarker/core/ASTExpHashLiteral.java | 6 +-
.../freemarker/core/ASTExpNegateOrPlus.java | 2 +-
.../org/apache/freemarker/core/ASTExpRange.java | 6 -
.../apache/freemarker/core/ASTExpression.java | 4 +-
.../apache/freemarker/core/BuiltInForDate.java | 17 +-
.../freemarker/core/BuiltInForHashEx.java | 2 +-
.../core/BuiltInForLegacyEscaping.java | 3 +-
.../freemarker/core/BuiltInForMarkupOutput.java | 2 +-
.../apache/freemarker/core/BuiltInForNode.java | 8 +-
.../freemarker/core/BuiltInForNodeEx.java | 2 +-
.../freemarker/core/BuiltInForSequence.java | 3 +-
.../freemarker/core/BuiltInsForDates.java | 4 +-
.../core/BuiltInsForExistenceHandling.java | 3 +-
.../core/BuiltInsForMultipleTypes.java | 30 +-
.../BuiltInsForNestedContentParameters.java | 5 +-
.../freemarker/core/BuiltInsForNodes.java | 5 +-
.../freemarker/core/BuiltInsForSequences.java | 36 +-
.../core/BuiltInsForStringsBasic.java | 14 +-
.../core/BuiltInsForStringsEncoding.java | 2 +-
.../freemarker/core/BuiltInsForStringsMisc.java | 11 +-
.../core/BuiltInsForStringsRegexp.java | 6 +-
.../org/apache/freemarker/core/Environment.java | 36 +-
.../apache/freemarker/core/MessageUtils.java | 117 ++++-
.../freemarker/core/NonBooleanException.java | 62 ---
.../freemarker/core/NonDateException.java | 58 ---
.../freemarker/core/NonDirectiveException.java | 63 ---
.../core/NonExtendedHashException.java | 62 ---
.../core/NonExtendedNodeException.java | 62 ---
.../freemarker/core/NonFunctionException.java | 62 ---
.../freemarker/core/NonHashException.java | 62 ---
.../core/NonMarkupOutputException.java | 62 ---
.../freemarker/core/NonNamespaceException.java | 61 ---
.../freemarker/core/NonNodeException.java | 62 ---
.../freemarker/core/NonNumericalException.java | 84 ----
.../freemarker/core/NonSequenceException.java | 62 ---
.../core/NonSequenceOrCollectionException.java | 90 ----
.../freemarker/core/NonStringException.java | 84 ----
.../NonStringOrTemplateOutputException.java | 78 ---
.../freemarker/core/TemplateException.java | 1 +
.../core/UnexpectedTypeException.java | 171 -------
.../apache/freemarker/core/_CallableUtils.java | 490 +-----------------
.../org/apache/freemarker/core/_CoreAPI.java | 4 +
.../org/apache/freemarker/core/_EvalUtils.java | 42 +-
.../core/model/GeneralPurposeNothing.java | 10 +-
.../model/impl/OverloadedFixArgsMethods.java | 4 +-
.../model/impl/OverloadedVarArgsMethods.java | 4 +-
.../core/model/impl/ResourceBundleModel.java | 4 +-
.../core/model/impl/SimpleMethod.java | 4 +-
.../freemarker/core/util/CallableUtils.java | 496 +++++++++++++++++++
.../core/util/TemplateLanguageUtils.java | 6 +
freemarker-core/src/main/javacc/FTL.jj | 4 +-
74 files changed, 927 insertions(+), 1921 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt
index 0d6a14b..0c69572 100644
--- a/FM3-CHANGE-LOG.txt
+++ b/FM3-CHANGE-LOG.txt
@@ -471,7 +471,10 @@ Core / Miscellaneous
- CallPlaceCustomDataInitializationException is not a checked exception anymore (now it extends RuntimeException)
- Renamed `FTLUtil` to `TemplateLanguageUtils` (as the FTL name will be abandoned in FM3, and supporting multiple
languages are planned in the future)
-
+- Removed `UnexpectedTypeException` (a `TemplateException` subclass) and its subclasses (`NonStringException`, etc.),
+ using simple `TemplateException` instead. Catching these exceptions specifically wasn't very useful, while they
+ have bloated the public API (and the code).
+- Added `org.apache.freemarker.core.util.CallableUtils`, to help in implementing (and invoking) `TemplateCallableModel`-s.
Build / development process changes
-----------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 62bb7af..9c87b53 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
@@ -23,7 +23,7 @@ import static org.junit.Assert.*;
import org.apache.freemarker.core.Configuration;
import org.apache.freemarker.core.NonTemplateCallPlace;
import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.model.TemplateHashModel;
import org.junit.Test;
@@ -56,10 +56,10 @@ public class Java8DefaultObjectWrapperBridgeMethodsTest {
JavaMethodModel m1 = (JavaMethodModel) wrapped.get("m1");
assertEquals(
BridgeMethodsBean.M1_RETURN_VALUE,
- "" + m1.execute(_CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE));
+ "" + m1.execute(CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE));
JavaMethodModel m2 = (JavaMethodModel) wrapped.get("m2");
- assertNull(m2.execute(_CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE));
+ assertNull(m2.execute(CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 cf628ad..fcd8f23 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
@@ -23,7 +23,7 @@ import static org.junit.Assert.*;
import org.apache.freemarker.core.Configuration;
import org.apache.freemarker.core.NonTemplateCallPlace;
import org.apache.freemarker.core.TemplateException;
-import org.apache.freemarker.core._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.model.TemplateHashModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateNumberModel;
@@ -129,7 +129,7 @@ public class Java8DefaultObjectWrapperTest {
assertEquals(
Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
((TemplateScalarModel) action.execute(
- _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
.getAsString());
}
@@ -140,7 +140,7 @@ public class Java8DefaultObjectWrapperTest {
assertEquals(
Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE,
((TemplateScalarModel) action.execute(
- _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
.getAsString());
}
{
@@ -150,7 +150,7 @@ public class Java8DefaultObjectWrapperTest {
assertEquals(
Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION_RETURN_VALUE,
((TemplateScalarModel) action.execute(
- _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
.getAsString());
}
{
@@ -160,7 +160,7 @@ public class Java8DefaultObjectWrapperTest {
assertEquals(
Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE,
((TemplateScalarModel) action.execute(
- _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
.getAsString());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
index 2bda427..51a0070 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/OutputFormatTest.java
@@ -598,7 +598,7 @@ public class OutputFormatTest extends TemplateTest {
"noSuchVar", "null or missing");
assertErrorContains(
"${'x'?markupString}",
- "xpected", "markup output", "string");
+ "xpected", "markupOutput", "string");
}
@Test
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java
index cbe1c5c..ec7b225 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/TemplateCallableModelTest.java
@@ -249,6 +249,7 @@ public class TemplateCallableModelTest extends TemplateTest {
assertErrorContains("${'x'?leftPad(null)}", "?leftPad", "1st", "null");
addTemplate("foo.ftl", "<#macro m n1></#macro>");
assertErrorContains("<#import 'foo.ftl' as f><@f.m/>", "macro", "\"foo.ftl:m\"");
+ assertErrorContains("<#function myF(p1)></#function><#assign f2 = myF>${f2()}", "\"myF\"");
addToDataModel("bean", new TestBean());
assertErrorContains("${bean.intMP()}", "method", "org.apache.freemarker.test.TemplateTest$TestBean.intMP");
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 cbccd66..49d4009 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
@@ -22,7 +22,7 @@ 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._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.model.TemplateHashModel;
import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateNumberModel;
@@ -117,7 +117,7 @@ public abstract class AbstractParallelIntrospectionTest extends TestCase {
JavaMethodModel pv = (JavaMethodModel) h.get("m" + mIdx);
final int expected = objIdx * 1000 + mIdx;
final int got = ((TemplateNumberModel) pv.execute(
- _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
.getAsNumber().intValue();
if (got != expected) {
throw new AssertionError("Method assertion failed; " +
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 a1dfba6..0f9722e 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
@@ -45,7 +45,7 @@ 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._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core._CoreAPI;
import org.apache.freemarker.core.model.AdapterTemplateModel;
import org.apache.freemarker.core.model.ObjectWrapper;
@@ -193,7 +193,7 @@ public class DefaultObjectWrapperTest {
{
// Check method calls, and also if the return value is wrapped with the overidden "wrap".
final TemplateModel mr = ((JavaMethodModel) bean.get("m")).execute(
- _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE);
+ CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE);
assertEquals(Collections.singletonList(1), ow.unwrap(mr));
assertTrue(DefaultListAdapter.class.isInstance(mr));
}
@@ -586,7 +586,7 @@ public class DefaultObjectWrapperTest {
TemplateHashModel api = (TemplateHashModel) iteratorAdapter.getAPI();
assertFalse(((TemplateBooleanModel) ((JavaMethodModel)
- api.get("hasNext")).execute(_CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
+ api.get("hasNext")).execute(CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE))
.getAsBoolean());
}
@@ -677,7 +677,7 @@ public class DefaultObjectWrapperTest {
TemplateHashModel api = (TemplateHashModel) enumAdapter.getAPI();
assertFalse(((TemplateBooleanModel) ((JavaMethodModel) api.get("hasMoreElements"))
- .execute(_CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE)).getAsBoolean());
+ .execute(CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE)).getAsBoolean());
}
@Test
@@ -734,7 +734,7 @@ public class DefaultObjectWrapperTest {
TemplateHashModel apiModel = (TemplateHashModel) ((TemplateModelWithAPISupport) normalModel).getAPI();
JavaMethodModel sizeMethod = (JavaMethodModel) apiModel.get("size");
TemplateNumberModel r = (TemplateNumberModel) sizeMethod.execute(
- _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE);
+ CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE);
assertEquals(expectedSize, r.getAsNumber().intValue());
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 7dc7879..89b6ec5 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
@@ -23,7 +23,7 @@ import static org.junit.Assert.*;
import org.apache.freemarker.core.Configuration;
import org.apache.freemarker.core.NonTemplateCallPlace;
-import org.apache.freemarker.core._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.model.TemplateHashModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -59,7 +59,7 @@ public class EnumModelsTest {
assertEquals(((TemplateScalarModel) a).getAsString(), "ts:A");
JavaMethodModel nameMethod = (JavaMethodModel) ((TemplateHashModel) a).get("name");
assertEquals(((TemplateScalarModel) nameMethod.execute(
- _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE)).getAsString(),
+ CallableUtils.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/f231e64f/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 2487105..241b349 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
@@ -24,7 +24,7 @@ import static org.junit.Assert.*;
import org.apache.freemarker.core.Configuration;
import org.apache.freemarker.core.NonTemplateCallPlace;
-import org.apache.freemarker.core._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.model.TemplateHashModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.TemplateModelException;
@@ -66,7 +66,7 @@ public class StaticModelsTest {
TemplateModel m = s.get("m");
assertTrue(m instanceof JavaMethodModel);
assertEquals(((TemplateScalarModel) ((JavaMethodModel) m).execute(
- _CallableUtils.EMPTY_TEMPLATE_MODEL_ARRAY, NonTemplateCallPlace.INSTANCE)).getAsString(),
+ CallableUtils.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/f231e64f/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 e56c0a2..96e4a7a 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
@@ -22,7 +22,7 @@ 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._CallableUtils;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateModel;
@@ -43,7 +43,7 @@ public class MultiModel2 implements TemplateScalarModel, TemplateFunctionModel {
public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env) throws TemplateException {
StringBuilder aResults = new StringBuilder( "Arguments are:<br />" );
for (int i = 0; i < args.length; i++) {
- aResults.append(_CallableUtils.getStringArgument(args, i, this));
+ aResults.append(CallableUtils.getStringArgument(args, i, this));
aResults.append("<br />");
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 3931a67..9302345 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,7 +19,7 @@
package org.apache.freemarker.core.userpkg;
-import static org.apache.freemarker.core._CallableUtils.*;
+import static org.apache.freemarker.core.util.CallableUtils.*;
import java.io.IOException;
import java.io.Writer;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 261c369..e6ad111 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._CallableUtils.*;
+import static org.apache.freemarker.core.util.CallableUtils.*;
import org.apache.freemarker.core.CallPlace;
import org.apache.freemarker.core.Environment;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/boolean-formatting.ftl
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/boolean-formatting.ftl b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/boolean-formatting.ftl
index 72dc253..95bee38 100644
--- a/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/boolean-formatting.ftl
+++ b/freemarker-core-test/src/test/resources/org/apache/freemarker/core/templatesuite/templates/boolean-formatting.ftl
@@ -47,7 +47,7 @@
<#setting booleanFormat = 'y,n'>
<#assign x = false>
<#assign n = 123><#assign m = { x: 'foo', n: 'bar' }><@assertEquals actual=m['n'] + m['123'] expected='foobar' />
-<@assertFails exception="UnexpectedTypeException">${m[false]}</@>
+<@assertFails message="boolean">${m[false]}</@>
<@assertFails message="can't compare">${x == 'false'}</@>
<@assertFails message="can't compare">${x != 'false'}</@>
<@assertFails message="can't convert">${booleanVsStringMethods.expectsString(x)}</@>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java
index 09bf4ea..7efa95c 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirAssignment.java
@@ -123,7 +123,11 @@ final class ASTDirAssignment extends ASTDirective {
try {
namespace = (Environment.Namespace) namespaceTM;
} catch (ClassCastException e) {
- throw new NonNamespaceException(namespaceExp, namespaceTM, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ namespaceExp, namespaceTM,
+ "namespace",
+ new Class[] { Environment.Namespace.class },
+ null, env);
}
if (namespace == null) {
throw InvalidReferenceException.getInstance(namespaceExp, env);
@@ -158,7 +162,8 @@ final class ASTDirAssignment extends ASTDirective {
} else if (lhoValue == null) {
throw InvalidReferenceException.getInstance(variableName, getOperatorTypeAsString(), env);
} else {
- throw new NonNumericalException(variableName, lhoValue, null, env);
+ throw MessageUtils.newUnexpectedAssignmentTargetTypeException(
+ variableName, lhoValue, TemplateNumberModel.class, env);
}
if (operatorType == OPERATOR_TYPE_PLUS_PLUS) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirInclude.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirInclude.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirInclude.java
index 37cc017..76ce1f6 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirInclude.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirInclude.java
@@ -22,7 +22,6 @@ package org.apache.freemarker.core;
import java.io.IOException;
import org.apache.freemarker.core.templateresolver.MalformedTemplateNameException;
-import org.apache.freemarker.core.util.BugException;
import org.apache.freemarker.core.util._StringUtils;
/**
@@ -45,16 +44,11 @@ final class ASTDirInclude extends ASTDirective {
this.ignoreMissingExp = ignoreMissingExp;
if (ignoreMissingExp != null && ignoreMissingExp.isLiteral()) {
try {
- try {
- ignoreMissingExpPrecalcedValue = Boolean.valueOf(
- ignoreMissingExp.evalToBoolean(template.getConfiguration()));
- } catch (NonBooleanException e) {
- throw new ParseException("Expected a boolean as the value of the \"ignore_missing\" attribute",
- ignoreMissingExp, e);
- }
+ ignoreMissingExpPrecalcedValue = Boolean.valueOf(
+ ignoreMissingExp.evalToBoolean(template.getConfiguration()));
} catch (TemplateException e) {
- // evaluation of literals must not throw a TemplateException
- throw new BugException(e);
+ throw new ParseException("Expected a boolean as the value of the \"ignore_missing\" attribute",
+ ignoreMissingExp, e);
}
} else {
ignoreMissingExpPrecalcedValue = null;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirList.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirList.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirList.java
index 7878e97..2182a5c 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirList.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirList.java
@@ -304,17 +304,19 @@ final class ASTDirList extends ASTDirective {
env.visit(childBuffer);
}
}
- } else if (listedValue instanceof TemplateHashModelEx
- && !NonSequenceOrCollectionException.isWrappedIterable(listedValue)) {
- throw new NonSequenceOrCollectionException(env,
+ } else if (listedValue instanceof TemplateHashModelEx) {
+ throw new TemplateException(env,
new _ErrorDescriptionBuilder("The value you try to list is ",
new _DelayedAOrAn(new _DelayedTemplateLanguageTypeDescription(listedValue)),
", thus you must declare two nested content parameters after the \"as\"; one for the "
+ "key, and another for the value, like ", "<#... as k, v>", ")."
));
} else {
- throw new NonSequenceOrCollectionException(
- listedExp, listedValue, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ listedExp, listedValue,
+ MessageUtils.SEQUENCE_OR_COLLECTION,
+ MessageUtils.EXPECTED_TYPES_SEQUENCE_OR_COLLECTION,
+ null, env);
}
return listNotEmpty;
}
@@ -359,13 +361,14 @@ final class ASTDirList extends ASTDirective {
do {
nestedContentParam = keysIter.next();
if (!(nestedContentParam instanceof TemplateScalarModel)) {
- throw new NonStringException(env,
+ throw new TemplateException(env,
new _ErrorDescriptionBuilder(
"When listing key-value pairs of traditional hash "
+ "implementations, all keys must be strings, but one of them "
+ "was ",
new _DelayedAOrAn(
- new _DelayedTemplateLanguageTypeDescription(nestedContentParam)),
+ new _DelayedTemplateLanguageTypeDescription(
+ nestedContentParam)),
"."
).tip("The listed value's TemplateModel class was ",
new _DelayedShortClassName(listedValue.getClass()),
@@ -389,15 +392,15 @@ final class ASTDirList extends ASTDirective {
}
} else if (listedValue instanceof TemplateCollectionModel
|| listedValue instanceof TemplateSequenceModel) {
- throw new NonSequenceOrCollectionException(env,
+ throw new TemplateException(env,
new _ErrorDescriptionBuilder("The value you try to list is ",
new _DelayedAOrAn(new _DelayedTemplateLanguageTypeDescription(listedValue)),
", thus you must declare only one nested content parameter after the \"as\" (there's "
+ "no separate key and value)."
));
} else {
- throw new NonExtendedHashException(
- listedExp, listedValue, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ listedExp, listedValue, TemplateHashModelEx.class, env);
}
return hashNotEmpty;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirRecurse.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirRecurse.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirRecurse.java
index 17842ec..7fe528b 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirRecurse.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirRecurse.java
@@ -44,7 +44,8 @@ final class ASTDirRecurse extends ASTDirective {
ASTElement[] accept(Environment env) throws IOException, TemplateException {
TemplateModel node = targetNode == null ? null : targetNode.eval(env);
if (node != null && !(node instanceof TemplateNodeModel)) {
- throw new NonNodeException(targetNode, node, "node", env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ targetNode, node, TemplateNodeModel.class, env);
}
TemplateModel nss = namespaces == null ? null : namespaces.eval(env);
@@ -60,7 +61,8 @@ final class ASTDirRecurse extends ASTDirective {
nss = ss;
} else if (!(nss instanceof TemplateSequenceModel)) {
if (namespaces != null) {
- throw new NonSequenceException(namespaces, nss, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ namespaces, nss, TemplateSequenceModel.class, env);
} else {
// Should not occur
throw new TemplateException(env, "Expecting a sequence of namespaces after \"using\"");
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirVisit.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirVisit.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirVisit.java
index fd49371..b7438a0 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirVisit.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirVisit.java
@@ -43,7 +43,7 @@ final class ASTDirVisit extends ASTDirective {
ASTElement[] accept(Environment env) throws IOException, TemplateException {
TemplateModel node = targetNode.eval(env);
if (!(node instanceof TemplateNodeModel)) {
- throw new NonNodeException(targetNode, node, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(targetNode, node, TemplateNodeModel.class, env);
}
TemplateModel nss = namespaces == null ? null : namespaces.eval(env);
@@ -59,7 +59,8 @@ final class ASTDirVisit extends ASTDirective {
nss = ss;
} else if (!(nss instanceof TemplateSequenceModel)) {
if (namespaces != null) {
- throw new NonSequenceException(namespaces, nss, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ namespaces, nss, TemplateSequenceModel.class, env);
} else {
// Should not occur
throw new TemplateException(env, "Expecting a sequence of namespaces after \"using\"");
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 e4b3c17..7e713bd 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
@@ -98,7 +98,7 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
nestedContentSupported = directive.isNestedContentSupported();
} else if (callableValueTM instanceof TemplateFunctionModel) {
if (!allowCallingFunctions) {
- throw new NonDirectiveException(
+ throw new TemplateException(
"Calling functions is not allowed. You can only call directives (like macros) here.", env);
}
callableValue = (TemplateCallableModel) callableValueTM;
@@ -109,7 +109,8 @@ class ASTDynamicTopLevelCall extends ASTDirective implements CallPlace {
} else if (callableValueTM == null) {
throw InvalidReferenceException.getInstance(callableValueExp, env);
} else {
- throw new NonDirectiveException(callableValueExp, callableValueTM, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ callableValueExp, callableValueTM, TemplateDirectiveModel.class, env);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpAddOrConcat.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpAddOrConcat.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpAddOrConcat.java
index 4385dac..79081e8 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpAddOrConcat.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpAddOrConcat.java
@@ -76,53 +76,43 @@ final class ASTExpAddOrConcat extends ASTExpression {
} else {
boolean hashConcatPossible
= leftModel instanceof TemplateHashModel && rightModel instanceof TemplateHashModel;
- try {
- // We try string addition first. If hash addition is possible, then instead of throwing exception
- // we return null and do hash addition instead. (We can't simply give hash addition a priority, like
- // with sequence addition above, as FTL strings are often also FTL hashes.)
- Object leftOMOrStr = _EvalUtils.coerceModelToStringOrMarkup(
- leftModel, leftExp, /* returnNullOnNonCoercableType = */ hashConcatPossible, null,
- env);
- if (leftOMOrStr == null) {
- return _eval_concatenateHashes(leftModel, rightModel);
- }
+ // We try string addition first. If hash addition is possible, then instead of throwing exception
+ // we return null and do hash addition instead. (We can't simply give hash addition a priority, like
+ // with sequence addition above, as FTL strings are often also FTL hashes.)
+ Object leftOMOrStr = _EvalUtils.coerceModelToStringOrMarkup(
+ leftModel, leftExp, /* returnNullOnNonCoercableType = */ hashConcatPossible, null,
+ env);
+ if (leftOMOrStr == null) {
+ return _eval_concatenateHashes(leftModel, rightModel);
+ }
- // Same trick with null return as above.
- Object rightOMOrStr = _EvalUtils.coerceModelToStringOrMarkup(
- rightModel, rightExp, /* returnNullOnNonCoercableType = */ hashConcatPossible, null,
- env);
- if (rightOMOrStr == null) {
- return _eval_concatenateHashes(leftModel, rightModel);
- }
+ // Same trick with null return as above.
+ Object rightOMOrStr = _EvalUtils.coerceModelToStringOrMarkup(
+ rightModel, rightExp, /* returnNullOnNonCoercableType = */ hashConcatPossible, null,
+ env);
+ if (rightOMOrStr == null) {
+ return _eval_concatenateHashes(leftModel, rightModel);
+ }
- if (leftOMOrStr instanceof String) {
- if (rightOMOrStr instanceof String) {
- return new SimpleScalar(((String) leftOMOrStr).concat((String) rightOMOrStr));
- } else { // rightOMOrStr instanceof TemplateMarkupOutputModel
- TemplateMarkupOutputModel<?> rightMO = (TemplateMarkupOutputModel<?>) rightOMOrStr;
- return _EvalUtils.concatMarkupOutputs(parent,
- rightMO.getOutputFormat().fromPlainTextByEscaping((String) leftOMOrStr),
- rightMO);
- }
- } else { // leftOMOrStr instanceof TemplateMarkupOutputModel
- TemplateMarkupOutputModel<?> leftMO = (TemplateMarkupOutputModel<?>) leftOMOrStr;
- if (rightOMOrStr instanceof String) { // markup output
- return _EvalUtils.concatMarkupOutputs(parent,
- leftMO,
- leftMO.getOutputFormat().fromPlainTextByEscaping((String) rightOMOrStr));
- } else { // rightOMOrStr instanceof TemplateMarkupOutputModel
- return _EvalUtils.concatMarkupOutputs(parent,
- leftMO,
- (TemplateMarkupOutputModel<?>) rightOMOrStr);
- }
+ if (leftOMOrStr instanceof String) {
+ if (rightOMOrStr instanceof String) {
+ return new SimpleScalar(((String) leftOMOrStr).concat((String) rightOMOrStr));
+ } else { // rightOMOrStr instanceof TemplateMarkupOutputModel
+ TemplateMarkupOutputModel<?> rightMO = (TemplateMarkupOutputModel<?>) rightOMOrStr;
+ return _EvalUtils.concatMarkupOutputs(parent,
+ rightMO.getOutputFormat().fromPlainTextByEscaping((String) leftOMOrStr),
+ rightMO);
}
- } catch (NonStringOrTemplateOutputException e) {
- // 2.4: Remove this catch; it's for BC, after reworking hash addition so it doesn't rely on this. But
- // user code might throws this (very unlikely), and then in 2.3.x we did catch that too, incorrectly.
- if (hashConcatPossible) {
- return _eval_concatenateHashes(leftModel, rightModel);
- } else {
- throw e;
+ } else { // leftOMOrStr instanceof TemplateMarkupOutputModel
+ TemplateMarkupOutputModel<?> leftMO = (TemplateMarkupOutputModel<?>) leftOMOrStr;
+ if (rightOMOrStr instanceof String) { // markup output
+ return _EvalUtils.concatMarkupOutputs(parent,
+ leftMO,
+ leftMO.getOutputFormat().fromPlainTextByEscaping((String) rightOMOrStr));
+ } else { // rightOMOrStr instanceof TemplateMarkupOutputModel
+ return _EvalUtils.concatMarkupOutputs(parent,
+ leftMO,
+ (TemplateMarkupOutputModel<?>) rightOMOrStr);
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDot.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDot.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDot.java
index c1da34e..1e67fad 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDot.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDot.java
@@ -41,7 +41,7 @@ final class ASTExpDot extends ASTExpression {
if (leftModel instanceof TemplateHashModel) {
return ((TemplateHashModel) leftModel).get(key);
}
- throw new NonHashException(target, leftModel, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, leftModel, TemplateHashModel.class, env);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDynamicKeyName.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDynamicKeyName.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDynamicKeyName.java
index 7633ea9..658be00 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDynamicKeyName.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpDynamicKeyName.java
@@ -58,16 +58,18 @@ final class ASTExpDynamicKeyName extends ASTExpression {
if (keyModel instanceof RangeModel) {
return dealWithRangeKey(targetModel, (RangeModel) keyModel, env);
}
- throw new UnexpectedTypeException(keyExpression, keyModel, "number, range, or string",
- new Class[] { TemplateNumberModel.class, TemplateScalarModel.class, ASTExpRange.class }, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(keyExpression, keyModel,
+ "number, range, or string",
+ new Class[] { TemplateNumberModel.class, TemplateScalarModel.class, ASTExpRange.class },
+ null, env);
}
static private Class[] NUMERICAL_KEY_LHO_EXPECTED_TYPES;
static {
- NUMERICAL_KEY_LHO_EXPECTED_TYPES = new Class[1 + NonStringException.STRING_COERCABLE_TYPES.length];
+ NUMERICAL_KEY_LHO_EXPECTED_TYPES = new Class[1 + MessageUtils.EXPECTED_TYPES_STRING_COERCABLE.length];
NUMERICAL_KEY_LHO_EXPECTED_TYPES[0] = TemplateSequenceModel.class;
- for (int i = 0; i < NonStringException.STRING_COERCABLE_TYPES.length; i++) {
- NUMERICAL_KEY_LHO_EXPECTED_TYPES[i + 1] = NonStringException.STRING_COERCABLE_TYPES[i];
+ for (int i = 0; i < MessageUtils.EXPECTED_TYPES_STRING_COERCABLE.length; i++) {
+ NUMERICAL_KEY_LHO_EXPECTED_TYPES[i + 1] = MessageUtils.EXPECTED_TYPES_STRING_COERCABLE[i];
}
}
@@ -84,35 +86,37 @@ final class ASTExpDynamicKeyName extends ASTExpression {
size = Integer.MAX_VALUE;
}
return index < size ? tsm.get(index) : null;
- }
-
+ }
+
+ String s;
try {
- String s = target.evalAndCoerceToPlainText(env);
- try {
- return new SimpleScalar(s.substring(index, index + 1));
- } catch (IndexOutOfBoundsException e) {
- if (index < 0) {
- throw new TemplateException("Negative index not allowed: ", Integer.valueOf(index));
- }
- if (index >= s.length()) {
- throw new TemplateException(
- "String index out of range: The index was ", Integer.valueOf(index),
- " (0-based), but the length of the string is only ", Integer.valueOf(s.length()) , ".");
- }
- throw new RuntimeException("Can't explain exception", e);
- }
- } catch (NonStringException e) {
- throw new UnexpectedTypeException(
+ s = target.evalAndCoerceToPlainText(env);
+ } catch (TemplateException e) {
+ // TODO [FM3] Wrong, as we don't know why this was thrown. I think we just shouldn't coerce.
+ throw MessageUtils.newUnexpectedOperandTypeException(
target, targetModel,
- "sequence or " + NonStringException.STRING_COERCABLE_TYPES_DESC,
+ "sequence or " + MessageUtils.STRING_COERCABLE_TYPES_DESC,
NUMERICAL_KEY_LHO_EXPECTED_TYPES,
(targetModel instanceof TemplateHashModel
- ? "You had a numberical value inside the []. Currently that's only supported for "
- + "sequences (lists) and strings. To get a Map item with a non-string key, "
- + "use myMap?api.get(myKey)."
+ ? new Object[] { "You had a numberical value inside the []. Currently that's only "
+ + "supported for sequences (lists) and strings. To get a Map item with a "
+ + "non-string key, use myMap?api.get(myKey)." }
: null),
env);
}
+ try {
+ return new SimpleScalar(s.substring(index, index + 1));
+ } catch (IndexOutOfBoundsException e) {
+ if (index < 0) {
+ throw new TemplateException("Negative index not allowed: ", Integer.valueOf(index));
+ }
+ if (index >= s.length()) {
+ throw new TemplateException(
+ "String index out of range: The index was ", Integer.valueOf(index),
+ " (0-based), but the length of the string is only ", Integer.valueOf(s.length()) , ".");
+ }
+ throw new RuntimeException("Can't explain exception", e);
+ }
}
private TemplateModel dealWithStringKey(TemplateModel targetModel, String key, Environment env)
@@ -120,7 +124,7 @@ final class ASTExpDynamicKeyName extends ASTExpression {
if (targetModel instanceof TemplateHashModel) {
return((TemplateHashModel) targetModel).get(key);
}
- throw new NonHashException(target, targetModel, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, targetModel, TemplateHashModel.class, env);
}
private TemplateModel dealWithRangeKey(TemplateModel targetModel, RangeModel range, Environment env)
@@ -134,11 +138,12 @@ final class ASTExpDynamicKeyName extends ASTExpression {
targetSeq = null;
try {
targetStr = target.evalAndCoerceToPlainText(env);
- } catch (NonStringException e) {
- throw new UnexpectedTypeException(
+ } catch (TemplateException e) {
+ // TODO [FM3] Wrong, as we don't know why this was thrown. I think we just shouldn't coerce.
+ throw MessageUtils.newUnexpectedOperandTypeException(
target, target.eval(env),
- "sequence or " + NonStringException.STRING_COERCABLE_TYPES_DESC,
- NUMERICAL_KEY_LHO_EXPECTED_TYPES, env);
+ "sequence or " + MessageUtils.STRING_COERCABLE_TYPES_DESC,
+ NUMERICAL_KEY_LHO_EXPECTED_TYPES, null, env);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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
index 1d60af7..07985c8 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpFunctionCall.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpFunctionCall.java
@@ -61,7 +61,8 @@ final class ASTExpFunctionCall extends ASTExpression implements CallPlace {
{
TemplateModel functionUncasted = functionExp.eval(env);
if (!(functionUncasted instanceof TemplateFunctionModel)) {
- throw new NonFunctionException(functionExp, functionUncasted, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ functionExp, functionUncasted, TemplateFunctionModel.class, env);
}
function = (TemplateFunctionModel) functionUncasted;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpHashLiteral.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpHashLiteral.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpHashLiteral.java
index 32af9bb..463110e 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpHashLiteral.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpHashLiteral.java
@@ -49,7 +49,7 @@ final class ASTExpHashLiteral extends ASTExpression {
@Override
TemplateModel _eval(Environment env) throws TemplateException {
- return new SequenceHash(env);
+ return new LinkedHash(env);
}
@Override
@@ -106,12 +106,12 @@ final class ASTExpHashLiteral extends ASTExpression {
return new ASTExpHashLiteral(clonedKeys, clonedValues);
}
- private class SequenceHash implements TemplateHashModelEx2 {
+ private class LinkedHash implements TemplateHashModelEx2 {
private HashMap<String, TemplateModel> map;
private TemplateCollectionModel keyCollection, valueCollection; // ordered lists of keys and values
- SequenceHash(Environment env) throws TemplateException {
+ LinkedHash(Environment env) throws TemplateException {
map = new LinkedHashMap<>();
for (int i = 0; i < size; i++) {
ASTExpression keyExp = (ASTExpression) keys.get(i);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpNegateOrPlus.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpNegateOrPlus.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpNegateOrPlus.java
index dc41129..820e2e7 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpNegateOrPlus.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpNegateOrPlus.java
@@ -48,7 +48,7 @@ final class ASTExpNegateOrPlus extends ASTExpression {
try {
targetModel = (TemplateNumberModel) tm;
} catch (ClassCastException cce) {
- throw new NonNumericalException(target, tm, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, tm, TemplateNumberModel.class, env);
}
if (!isMinus) {
return targetModel;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpRange.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpRange.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpRange.java
index 6932827..7b86e3e 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpRange.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpRange.java
@@ -58,12 +58,6 @@ final class ASTExpRange extends ASTExpression {
return new ListableRightUnboundedRangeModel(begin);
}
}
-
- // Surely this way we can tell that it won't be a boolean without evaluating the range, but why was this important?
- @Override
- boolean evalToBoolean(Environment env) throws TemplateException {
- throw new NonBooleanException(this, new BoundedRangeModel(0, 0, false, false), env);
- }
@Override
public String getCanonicalForm() {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpression.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpression.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpression.java
index 97f82a5..0994685 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpression.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpression.java
@@ -113,7 +113,7 @@ abstract class ASTExpression extends ASTNode {
if (model instanceof TemplateNumberModel) {
return _EvalUtils.modelToNumber((TemplateNumberModel) model, this);
} else {
- throw new NonNumericalException(this, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(this, model, TemplateNumberModel.class, env);
}
}
@@ -148,7 +148,7 @@ abstract class ASTExpression extends ASTNode {
if (model instanceof TemplateBooleanModel) {
return ((TemplateBooleanModel) model).getAsBoolean();
} else {
- throw new NonBooleanException(this, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(this, model, TemplateBooleanModel.class, env);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForDate.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForDate.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForDate.java
index 44fda23..b47ff1a 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForDate.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForDate.java
@@ -33,24 +33,11 @@ abstract class BuiltInForDate extends ASTExpBuiltIn {
TemplateDateModel tdm = (TemplateDateModel) model;
return calculateResult(_EvalUtils.modelToDate(tdm, target), tdm.getDateType(), env);
} else {
- throw newNonDateException(env, model, target);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, model, TemplateDateModel.class, env);
}
}
/** Override this to implement the built-in. */
- protected abstract TemplateModel calculateResult(
- Date date, int dateType, Environment env)
- throws TemplateException;
-
- static TemplateException newNonDateException(Environment env, TemplateModel model, ASTExpression target)
- throws InvalidReferenceException {
- TemplateException e;
- if (model == null) {
- e = InvalidReferenceException.getInstance(target, env);
- } else {
- e = new NonDateException(target, model, "date", env);
- }
- return e;
- }
+ protected abstract TemplateModel calculateResult(Date date, int dateType, Environment env) throws TemplateException;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForHashEx.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForHashEx.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForHashEx.java
index ec21061..1988f5e 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForHashEx.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForHashEx.java
@@ -31,7 +31,7 @@ abstract class BuiltInForHashEx extends ASTExpBuiltIn {
if (model instanceof TemplateHashModelEx) {
return calculateResult((TemplateHashModelEx) model, env);
}
- throw new NonExtendedHashException(target, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, model, TemplateHashModelEx.class, env);
}
abstract TemplateModel calculateResult(TemplateHashModelEx hashExModel, Environment env)
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForLegacyEscaping.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForLegacyEscaping.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForLegacyEscaping.java
index e1f46d1..6082a3d 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForLegacyEscaping.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForLegacyEscaping.java
@@ -20,6 +20,7 @@ package org.apache.freemarker.core;
import org.apache.freemarker.core.model.TemplateMarkupOutputModel;
import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.TemplateScalarModel;
/**
* A string built-in whose usage is banned when auto-escaping with a markup-output format is active.
@@ -39,7 +40,7 @@ abstract class BuiltInForLegacyEscaping extends BuiltInBannedWhenAutoEscaping {
if (mo.getOutputFormat().isLegacyBuiltInBypassed(key)) {
return mo;
}
- throw new NonStringException(target, tm, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, tm, TemplateScalarModel.class, env);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForMarkupOutput.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForMarkupOutput.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForMarkupOutput.java
index fa617c2..384e491 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForMarkupOutput.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForMarkupOutput.java
@@ -30,7 +30,7 @@ abstract class BuiltInForMarkupOutput extends ASTExpBuiltIn {
throws TemplateException {
TemplateModel model = target.eval(env);
if (!(model instanceof TemplateMarkupOutputModel)) {
- throw new NonMarkupOutputException(target, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, model, TemplateMarkupOutputModel.class, env);
}
return calculateResult((TemplateMarkupOutputModel) model);
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNode.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNode.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNode.java
index ca0cd61..afe7111 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNode.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNode.java
@@ -24,6 +24,7 @@ import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateNodeModel;
abstract class BuiltInForNode extends ASTExpBuiltIn {
+
@Override
TemplateModel _eval(Environment env)
throws TemplateException {
@@ -31,9 +32,10 @@ abstract class BuiltInForNode extends ASTExpBuiltIn {
if (model instanceof TemplateNodeModel) {
return calculateResult((TemplateNodeModel) model, env);
} else {
- throw new NonNodeException(target, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, model, TemplateNodeModel.class, env);
}
}
- abstract TemplateModel calculateResult(TemplateNodeModel nodeModel, Environment env)
- throws TemplateModelException;
+
+ abstract TemplateModel calculateResult(TemplateNodeModel nodeModel, Environment env) throws TemplateModelException;
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNodeEx.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNodeEx.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNodeEx.java
index 8360cbd..67d0383 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNodeEx.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForNodeEx.java
@@ -29,7 +29,7 @@ abstract class BuiltInForNodeEx extends ASTExpBuiltIn {
if (model instanceof TemplateNodeModelEx) {
return calculateResult((TemplateNodeModelEx) model, env);
} else {
- throw new NonExtendedNodeException(target, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, model, TemplateNodeModelEx.class, env);
}
}
abstract TemplateModel calculateResult(TemplateNodeModelEx nodeModel, Environment env)
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForSequence.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForSequence.java b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForSequence.java
index 4aca088..bac6c7f 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForSequence.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/BuiltInForSequence.java
@@ -20,7 +20,6 @@
package org.apache.freemarker.core;
import org.apache.freemarker.core.model.TemplateModel;
-import org.apache.freemarker.core.model.TemplateModelException;
import org.apache.freemarker.core.model.TemplateSequenceModel;
abstract class BuiltInForSequence extends ASTExpBuiltIn {
@@ -29,7 +28,7 @@ abstract class BuiltInForSequence extends ASTExpBuiltIn {
throws TemplateException {
TemplateModel model = target.eval(env);
if (!(model instanceof TemplateSequenceModel)) {
- throw new NonSequenceException(target, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, model, TemplateSequenceModel.class, env);
}
return calculateResult((TemplateSequenceModel) model);
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 c237613..f69cfe9 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
@@ -19,7 +19,7 @@
package org.apache.freemarker.core;
-import static org.apache.freemarker.core._CallableUtils.*;
+import static org.apache.freemarker.core.util.CallableUtils.*;
import java.util.Date;
import java.util.TimeZone;
@@ -60,7 +60,7 @@ class BuiltInsForDates {
}
return new SimpleDate(_EvalUtils.modelToDate(tdm, target), dateType);
} else {
- throw BuiltInForDate.newNonDateException(env, model, target);
+ throw MessageUtils.newUnexpectedOperandTypeException(target, model, TemplateDateModel.class, env);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 dfa7c46..f7c5258 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
@@ -69,8 +69,7 @@ class BuiltInsForExistenceHandling {
}
@Override
- public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
- throws TemplateException {
+ public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env) {
return constant;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 6b70721..048d633 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,7 +19,7 @@
package org.apache.freemarker.core;
-import static org.apache.freemarker.core._CallableUtils.getOptionalStringArgument;
+import static org.apache.freemarker.core.util.CallableUtils.getOptionalStringArgument;
import java.util.Date;
@@ -44,6 +44,7 @@ import org.apache.freemarker.core.model.impl.SimpleDate;
import org.apache.freemarker.core.model.impl.SimpleNumber;
import org.apache.freemarker.core.model.impl.SimpleScalar;
import org.apache.freemarker.core.util.BugException;
+import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.valueformat.TemplateDateFormat;
import org.apache.freemarker.core.valueformat.TemplateNumberFormat;
import org.apache.freemarker.core.valueformat.TemplateValueFormatException;
@@ -64,10 +65,10 @@ class BuiltInsForMultipleTypes {
return new SimpleScalar(((TemplateBooleanModel) model).getAsBoolean()
? TemplateBooleanFormat.C_TRUE : TemplateBooleanFormat.C_FALSE);
} else {
- throw new UnexpectedTypeException(
+ throw MessageUtils.newUnexpectedOperandTypeException(
target, model,
"number or boolean", new Class[] { TemplateNumberModel.class, TemplateBooleanModel.class },
- env);
+ null, env);
}
}
@@ -424,9 +425,9 @@ class BuiltInsForMultipleTypes {
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel tm = target.eval(env);
if (!(tm instanceof Environment.TemplateLanguageCallable)) {
- throw new UnexpectedTypeException(
+ throw MessageUtils.newUnexpectedOperandTypeException(
target, tm,
- "macro or function", new Class[] { Environment.TemplateLanguageCallable.class },
+ Environment.TemplateLanguageCallable.class,
env);
}
return ((Environment.TemplateLanguageCallable) tm).getNamespace();
@@ -446,7 +447,7 @@ class BuiltInsForMultipleTypes {
} else if (model instanceof TemplateHashModelEx) {
size = ((TemplateHashModelEx) model).size();
} else {
- throw new UnexpectedTypeException(
+ throw MessageUtils.newUnexpectedOperandTypeException(
target, model,
"extended-hash or sequence or extended collection",
new Class[] {
@@ -454,6 +455,7 @@ class BuiltInsForMultipleTypes {
TemplateSequenceModel.class,
TemplateCollectionModelEx.class
},
+ null,
env);
}
return new SimpleNumber(size);
@@ -479,7 +481,7 @@ class BuiltInsForMultipleTypes {
TemplateModel result = args[argIdx];
if (!(result instanceof TemplateScalarModel)) {
// Cause usual type exception
- _CallableUtils.castArgumentValueToString(result, argIdx, this, true, false);
+ CallableUtils.castArgumentValueToString(result, argIdx, this, true, false);
}
return result;
}
@@ -526,7 +528,7 @@ class BuiltInsForMultipleTypes {
@Override
public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
throws TemplateException {
- return formatWith(_CallableUtils.getStringArgument(args, 0, this));
+ return formatWith(CallableUtils.getStringArgument(args, 0, this));
}
@Override
@@ -606,7 +608,7 @@ class BuiltInsForMultipleTypes {
@Override
public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
throws TemplateException {
- return get(_CallableUtils.getStringArgument(args, 0, this));
+ return get(CallableUtils.getStringArgument(args, 0, this));
}
@Override
@@ -670,15 +672,15 @@ class BuiltInsForMultipleTypes {
return new BooleanFormatter((TemplateBooleanModel) model, env);
} else if (model instanceof TemplateScalarModel) {
return new SimpleScalar(((TemplateScalarModel) model).getAsString());
- } else {
- throw new UnexpectedTypeException(
+ } else {
+ throw MessageUtils.newUnexpectedOperandTypeException(
target, model,
"number, date, boolean or string",
new Class[] {
TemplateNumberModel.class, TemplateDateModel.class, TemplateBooleanModel.class,
TemplateScalarModel.class
},
- env);
+ null, env);
}
}
}
@@ -697,10 +699,10 @@ class BuiltInsForMultipleTypes {
return new SimpleScalar(((TemplateBooleanModel) model).getAsBoolean()
? TemplateBooleanFormat.C_TRUE : TemplateBooleanFormat.C_FALSE);
} else {
- throw new UnexpectedTypeException(
+ throw MessageUtils.newUnexpectedOperandTypeException(
target, model,
"number or boolean", new Class[] { TemplateNumberModel.class, TemplateBooleanModel.class },
- env);
+ null, env);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 9b35b63..3767523 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,8 +18,6 @@
*/
package org.apache.freemarker.core;
-import static org.apache.freemarker.core._CallableUtils.checkArgumentCount;
-
import org.apache.freemarker.core.ASTDirList.IterationContext;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.TemplateBooleanModel;
@@ -27,6 +25,7 @@ import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.impl.SimpleNumber;
import org.apache.freemarker.core.model.impl.SimpleScalar;
+import org.apache.freemarker.core.util.CallableUtils;
class BuiltInsForNestedContentParameters {
@@ -142,7 +141,7 @@ class BuiltInsForNestedContentParameters {
@Override
public TemplateModel execute(TemplateModel[] args, CallPlace callPlace, Environment env)
throws TemplateException {
- _CallableUtils.checkArgumentCount(args.length, 1, Integer.MAX_VALUE, this);
+ CallableUtils.checkArgumentCount(args.length, 1, Integer.MAX_VALUE, this);
return args[iterCtx.getIndex() % args.length];
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 ae23e18..5174c3e 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,7 +19,7 @@
package org.apache.freemarker.core;
-import static org.apache.freemarker.core._CallableUtils.getStringArgument;
+import static org.apache.freemarker.core.util.CallableUtils.getStringArgument;
import org.apache.freemarker.core.model.ArgumentArrayLayout;
import org.apache.freemarker.core.model.TemplateFunctionModel;
@@ -47,8 +47,7 @@ class BuiltInsForNodes {
return result;
}
- class AncestorSequence extends NativeSequence implements TemplateFunctionModel,
- BuiltInCallable {
+ class AncestorSequence extends NativeSequence implements TemplateFunctionModel, BuiltInCallable {
private static final int INITIAL_CAPACITY = 12;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/f231e64f/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 0e8dd2b..857e7e3 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
@@ -19,7 +19,7 @@
package org.apache.freemarker.core;
-import static org.apache.freemarker.core._CallableUtils.*;
+import static org.apache.freemarker.core.util.CallableUtils.*;
import java.io.Serializable;
import java.text.Collator;
@@ -55,7 +55,7 @@ class BuiltInsForSequences {
static class chunkBI extends BuiltInForSequence {
- private class BIMethod implements TemplateFunctionModel {
+ private class BIMethod extends BuiltInCallableImpl implements TemplateFunctionModel {
private final TemplateSequenceModel tsm;
@@ -160,7 +160,11 @@ class BuiltInsForSequences {
} else if (model instanceof TemplateCollectionModel) {
return calculateResultForColletion((TemplateCollectionModel) model);
} else {
- throw new NonSequenceOrCollectionException(target, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ target, model,
+ MessageUtils.SEQUENCE_OR_COLLECTION,
+ MessageUtils.EXPECTED_TYPES_SEQUENCE_OR_COLLECTION,
+ null, env);
}
}
@@ -255,7 +259,11 @@ class BuiltInsForSequences {
} else if (model instanceof TemplateSequenceModel) {
return new BIMethodForCollection(env, new CollectionAndSequence((TemplateSequenceModel) model));
} else {
- throw new NonSequenceOrCollectionException(target, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ target, model,
+ MessageUtils.SEQUENCE_OR_COLLECTION,
+ MessageUtils.EXPECTED_TYPES_SEQUENCE_OR_COLLECTION,
+ null, env);
}
}
@@ -302,7 +310,7 @@ class BuiltInsForSequences {
}
static class seq_containsBI extends ASTExpBuiltIn {
- private class BIMethodForCollection implements TemplateFunctionModel {
+ private class BIMethodForCollection extends BuiltInCallableImpl implements TemplateFunctionModel {
private TemplateCollectionModel m_coll;
private Environment m_env;
@@ -332,7 +340,7 @@ class BuiltInsForSequences {
}
- private class BIMethodForSequence implements TemplateFunctionModel {
+ private class BIMethodForSequence extends BuiltInCallableImpl implements TemplateFunctionModel {
private TemplateSequenceModel m_seq;
private Environment m_env;
@@ -371,7 +379,11 @@ class BuiltInsForSequences {
} else if (model instanceof TemplateCollectionModel) {
return new BIMethodForCollection((TemplateCollectionModel) model, env);
} else {
- throw new NonSequenceOrCollectionException(target, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ target, model,
+ MessageUtils.SEQUENCE_OR_COLLECTION,
+ MessageUtils.EXPECTED_TYPES_SEQUENCE_OR_COLLECTION,
+ null, env);
}
}
@@ -379,7 +391,7 @@ class BuiltInsForSequences {
static class seq_index_ofBI extends ASTExpBuiltIn {
- private class BIMethod implements TemplateFunctionModel {
+ private class BIMethod extends BuiltInCallableImpl implements TemplateFunctionModel {
final TemplateSequenceModel m_seq;
final TemplateCollectionModel m_col;
@@ -403,7 +415,11 @@ class BuiltInsForSequences {
? (TemplateCollectionModel) model
: null;
if (m_seq == null && m_col == null) {
- throw new NonSequenceOrCollectionException(target, model, env);
+ throw MessageUtils.newUnexpectedOperandTypeException(
+ target, model,
+ MessageUtils.SEQUENCE_OR_COLLECTION,
+ MessageUtils.EXPECTED_TYPES_SEQUENCE_OR_COLLECTION,
+ null, env);
}
m_env = env;
@@ -544,7 +560,7 @@ class BuiltInsForSequences {
}
static class sort_byBI extends sortBI {
- class BIMethod implements TemplateFunctionModel {
+ class BIMethod extends BuiltInCallableImpl implements TemplateFunctionModel {
TemplateSequenceModel seq;
BIMethod(TemplateSequenceModel seq) {