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/01/21 00:21:51 UTC
incubator-freemarker git commit: Removed classic_compatible
(classicCompatible) setting,
which was used to emulate some of the FreeMarker 1.x behavior.
Repository: incubator-freemarker
Updated Branches:
refs/heads/3 38642f504 -> 4cbc134e5
Removed classic_compatible (classicCompatible) setting, which was used to emulate some of the FreeMarker 1.x behavior.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/4cbc134e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/4cbc134e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/4cbc134e
Branch: refs/heads/3
Commit: 4cbc134e5dc83c4d46ba24e142bc72b2ce5b1ecd
Parents: 38642f5
Author: ddekany <dd...@apache.org>
Authored: Sat Jan 21 01:21:38 2017 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sat Jan 21 01:21:38 2017 +0100
----------------------------------------------------------------------
src/main/java/freemarker/core/Assignment.java | 25 +--
.../core/BuiltInsForMultipleTypes.java | 21 ++-
src/main/java/freemarker/core/Configurable.java | 157 +++----------------
src/main/java/freemarker/core/Dot.java | 3 -
.../java/freemarker/core/DynamicKeyName.java | 16 +-
src/main/java/freemarker/core/Environment.java | 5 -
src/main/java/freemarker/core/EvalUtil.java | 89 +++--------
src/main/java/freemarker/core/Expression.java | 2 -
src/main/java/freemarker/core/HashLiteral.java | 18 ++-
.../java/freemarker/core/IteratorBlock.java | 20 +--
src/main/java/freemarker/core/ListLiteral.java | 4 +-
src/main/java/freemarker/core/Macro.java | 6 +-
.../java/freemarker/core/PropertySetting.java | 2 -
.../freemarker/core/TemplateConfiguration.java | 16 +-
.../debug/impl/RmiDebuggedEnvironmentImpl.java | 11 +-
.../java/freemarker/ext/beans/BeanModel.java | 16 --
.../java/freemarker/ext/beans/_BeansAPI.java | 4 -
.../java/freemarker/template/SimpleList.java | 42 -----
.../template/TemplateScalarModel.java | 3 +-
src/manual/en_US/FM3-CHANGE-LOG.txt | 3 +-
.../core/TemplateConfigurationTest.java | 21 +--
.../freemarker/template/ConfigurationTest.java | 12 ++
.../test/templatesuite/TemplateTestCase.java | 25 +--
.../expected/classic-compatible.txt | 41 -----
.../templates/classic-compatible-mode2.ftl | 26 ---
.../templates/classic-compatible.ftl | 54 -------
.../test/templatesuite/templates/setting.ftl | 4 -
.../freemarker/test/templatesuite/testcases.xml | 7 -
28 files changed, 147 insertions(+), 506 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/Assignment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Assignment.java b/src/main/java/freemarker/core/Assignment.java
index bdce203..dd2114e 100644
--- a/src/main/java/freemarker/core/Assignment.java
+++ b/src/main/java/freemarker/core/Assignment.java
@@ -22,7 +22,6 @@ package freemarker.core;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateNumberModel;
-import freemarker.template.TemplateScalarModel;
/**
* An instruction that makes a single assignment, like [#local x=1].
@@ -132,13 +131,7 @@ final class Assignment extends TemplateElement {
TemplateModel value;
if (operatorType == OPERATOR_TYPE_EQUALS) {
value = valueExp.eval(env);
- if (value == null) {
- if (env.isClassicCompatible()) {
- value = TemplateScalarModel.EMPTY_STRING;
- } else {
- throw InvalidReferenceException.getInstance(valueExp, env);
- }
- }
+ valueExp.assertNonNull(value, env);
} else {
TemplateModel lhoValue;
if (namespace == null) {
@@ -149,22 +142,12 @@ final class Assignment extends TemplateElement {
if (operatorType == OPERATOR_TYPE_PLUS_EQUALS) { // Add or concat operation
if (lhoValue == null) {
- if (env.isClassicCompatible()) {
- lhoValue = TemplateScalarModel.EMPTY_STRING;
- } else {
- throw InvalidReferenceException.getInstance(
- variableName, getOperatorTypeAsString(), env);
- }
+ throw InvalidReferenceException.getInstance(
+ variableName, getOperatorTypeAsString(), env);
}
value = valueExp.eval(env);
- if (value == null) {
- if (env.isClassicCompatible()) {
- value = TemplateScalarModel.EMPTY_STRING;
- } else {
- throw InvalidReferenceException.getInstance(valueExp, env);
- }
- }
+ valueExp.assertNonNull(value, env);
value = AddConcatExpression._eval(env, namespaceExp, null, lhoValue, valueExp, value);
} else { // Numerical operation
Number lhoNumber;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
index 81bcf59..bb0c0c0 100644
--- a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
+++ b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
@@ -22,10 +22,8 @@ package freemarker.core;
import java.util.Date;
import java.util.List;
-import freemarker.ext.beans.BeanModel;
import freemarker.ext.beans.OverloadedMethodsModel;
import freemarker.ext.beans.SimpleMethodModel;
-import freemarker.ext.beans._BeansAPI;
import freemarker.template.SimpleDate;
import freemarker.template.SimpleNumber;
import freemarker.template.SimpleScalar;
@@ -123,10 +121,12 @@ class BuiltInsForMultipleTypes {
return new SimpleScalar(env.getCNumberFormat().format(num));
}
+ @Override
public int getMinimumICIVersion() {
return _TemplateAPI.VERSION_INT_2_3_21;
}
+ @Override
public Object getPreviousICIChainMember() {
return prevICIObj;
}
@@ -151,11 +151,13 @@ class BuiltInsForMultipleTypes {
this.defaultFormat = env.getTemplateDateFormat(dateType, Date.class, target, false);
}
+ @Override
public Object exec(List args) throws TemplateModelException {
checkMethodArgCount(args, 0, 1);
return args.size() == 0 ? getAsDateModel() : get((String) args.get(0));
}
+ @Override
public TemplateModel get(String pattern) throws TemplateModelException {
TemplateDateFormat format;
try {
@@ -186,14 +188,17 @@ class BuiltInsForMultipleTypes {
return cachedValue;
}
+ @Override
public Date getAsDate() throws TemplateModelException {
return getAsDateModel().getAsDate();
}
+ @Override
public int getDateType() {
return dateType;
}
+ @Override
public boolean isEmpty() {
return false;
}
@@ -521,11 +526,13 @@ class BuiltInsForMultipleTypes {
this.env = env;
}
+ @Override
public Object exec(List args) throws TemplateModelException {
checkMethodArgCount(args, 2);
return new SimpleScalar((String) args.get(bool.getAsBoolean() ? 0 : 1));
}
+ @Override
public String getAsString() throws TemplateModelException {
// Boolean should have come first... but that change would be non-BC.
if (bool instanceof TemplateScalarModel) {
@@ -562,11 +569,13 @@ class BuiltInsForMultipleTypes {
dateType, EvalUtil.modelToDate(dateModel, target).getClass(), target, true);
}
+ @Override
public Object exec(List args) throws TemplateModelException {
checkMethodArgCount(args, 1);
return formatWith((String) args.get(0));
}
+ @Override
public TemplateModel get(String key)
throws TemplateModelException {
return formatWith(key);
@@ -582,6 +591,7 @@ class BuiltInsForMultipleTypes {
}
}
+ @Override
public String getAsString()
throws TemplateModelException {
if (cachedValue == null) {
@@ -606,6 +616,7 @@ class BuiltInsForMultipleTypes {
return cachedValue;
}
+ @Override
public boolean isEmpty() {
return false;
}
@@ -636,11 +647,13 @@ class BuiltInsForMultipleTypes {
}
}
+ @Override
public Object exec(List args) throws TemplateModelException {
checkMethodArgCount(args, 1);
return get((String) args.get(0));
}
+ @Override
public TemplateModel get(String key) throws TemplateModelException {
TemplateNumberFormat format;
try {
@@ -665,6 +678,7 @@ class BuiltInsForMultipleTypes {
return new SimpleScalar(result);
}
+ @Override
public String getAsString() throws TemplateModelException {
if (cachedValue == null) {
try {
@@ -682,6 +696,7 @@ class BuiltInsForMultipleTypes {
return cachedValue;
}
+ @Override
public boolean isEmpty() {
return false;
}
@@ -703,8 +718,6 @@ class BuiltInsForMultipleTypes {
return new BooleanFormatter((TemplateBooleanModel) model, env);
} else if (model instanceof TemplateScalarModel) {
return new SimpleScalar(((TemplateScalarModel) model).getAsString());
- } else if (env.isClassicCompatible() && model instanceof BeanModel) {
- return new SimpleScalar(_BeansAPI.getAsClassicCompatibleString((BeanModel) model));
} else {
throw new UnexpectedTypeException(
target, model,
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/Configurable.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Configurable.java b/src/main/java/freemarker/core/Configurable.java
index a709deb..748956f 100644
--- a/src/main/java/freemarker/core/Configurable.java
+++ b/src/main/java/freemarker/core/Configurable.java
@@ -149,13 +149,6 @@ public class Configurable {
public static final String SQL_DATE_AND_TIME_TIME_ZONE_KEY = SQL_DATE_AND_TIME_TIME_ZONE_KEY_SNAKE_CASE;
/** Legacy, snake case ({@code like_this}) variation of the setting name. @since 2.3.23 */
- public static final String CLASSIC_COMPATIBLE_KEY_SNAKE_CASE = "classic_compatible";
- /** Modern, camel case ({@code likeThis}) variation of the setting name. @since 2.3.23 */
- public static final String CLASSIC_COMPATIBLE_KEY_CAMEL_CASE = "classicCompatible";
- /** Alias to the {@code ..._SNAKE_CASE} variation due to backward compatibility constraints. */
- public static final String CLASSIC_COMPATIBLE_KEY = CLASSIC_COMPATIBLE_KEY_SNAKE_CASE;
-
- /** Legacy, snake case ({@code like_this}) variation of the setting name. @since 2.3.23 */
public static final String TEMPLATE_EXCEPTION_HANDLER_KEY_SNAKE_CASE = "template_exception_handler";
/** Modern, camel case ({@code likeThis}) variation of the setting name. @since 2.3.23 */
public static final String TEMPLATE_EXCEPTION_HANDLER_KEY_CAMEL_CASE = "templateExceptionHandler";
@@ -279,7 +272,6 @@ public class Configurable {
AUTO_IMPORT_KEY_SNAKE_CASE,
AUTO_INCLUDE_KEY_SNAKE_CASE,
BOOLEAN_FORMAT_KEY_SNAKE_CASE,
- CLASSIC_COMPATIBLE_KEY_SNAKE_CASE,
CUSTOM_DATE_FORMATS_KEY_SNAKE_CASE,
CUSTOM_NUMBER_FORMATS_KEY_SNAKE_CASE,
DATE_FORMAT_KEY_SNAKE_CASE,
@@ -309,7 +301,6 @@ public class Configurable {
AUTO_IMPORT_KEY_CAMEL_CASE,
AUTO_INCLUDE_KEY_CAMEL_CASE,
BOOLEAN_FORMAT_KEY_CAMEL_CASE,
- CLASSIC_COMPATIBLE_KEY_CAMEL_CASE,
CUSTOM_DATE_FORMATS_KEY_CAMEL_CASE,
CUSTOM_NUMBER_FORMATS_KEY_CAMEL_CASE,
DATE_FORMAT_KEY_CAMEL_CASE,
@@ -346,7 +337,6 @@ public class Configurable {
private String booleanFormat;
private String trueStringValue; // deduced from booleanFormat
private String falseStringValue; // deduced from booleanFormat
- private Integer classicCompatible;
private TemplateExceptionHandler templateExceptionHandler;
private ArithmeticEngine arithmeticEngine;
private ObjectWrapper objectWrapper;
@@ -409,9 +399,6 @@ public class Configurable {
dateTimeFormat = "";
properties.setProperty(DATETIME_FORMAT_KEY, dateTimeFormat);
- classicCompatible = Integer.valueOf(0);
- properties.setProperty(CLASSIC_COMPATIBLE_KEY, classicCompatible.toString());
-
templateExceptionHandler = _TemplateAPI.getDefaultTemplateExceptionHandler(
incompatibleImprovements);
properties.setProperty(TEMPLATE_EXCEPTION_HANDLER_KEY, templateExceptionHandler.getClass().getName());
@@ -463,7 +450,6 @@ public class Configurable {
this.parent = parent;
locale = null;
numberFormat = null;
- classicCompatible = null;
templateExceptionHandler = null;
properties = new Properties(parent.properties);
customAttributes = new HashMap(0);
@@ -519,106 +505,6 @@ public class Configurable {
}
/**
- * Toggles the "Classic Compatible" mode. For a comprehensive description
- * of this mode, see {@link #isClassicCompatible()}.
- */
- public void setClassicCompatible(boolean classicCompatibility) {
- this.classicCompatible = Integer.valueOf(classicCompatibility ? 1 : 0);
- properties.setProperty(CLASSIC_COMPATIBLE_KEY, classicCompatibilityIntToString(classicCompatible));
- }
-
- /**
- * Same as {@link #setClassicCompatible(boolean)}, but allows some extra values.
- *
- * @param classicCompatibility {@code 0} means {@code false}, {@code 1} means {@code true},
- * {@code 2} means {@code true} but with emulating bugs in early 2.x classic-compatibility mode. Currently
- * {@code 2} affects how booleans are converted to string; with {@code 1} it's always {@code "true"}/{@code ""},
- * but with {@code 2} it's {@code "true"}/{@code "false"} for values wrapped by {@link BeansWrapper} as then
- * {@link Boolean#toString()} prevails. Note that {@code someBoolean?string} will always consistently format the
- * boolean according the {@code boolean_format} setting, just like in FreeMarker 2.3 and later.
- */
- public void setClassicCompatibleAsInt(int classicCompatibility) {
- if (classicCompatibility < 0 || classicCompatibility > 2) {
- throw new IllegalArgumentException("Unsupported \"classicCompatibility\": " + classicCompatibility);
- }
- this.classicCompatible = Integer.valueOf(classicCompatibility);
- }
-
- private String classicCompatibilityIntToString(Integer i) {
- if (i == null) return null;
- else if (i.intValue() == 0) return MiscUtil.C_FALSE;
- else if (i.intValue() == 1) return MiscUtil.C_TRUE;
- else return i.toString();
- }
-
- /**
- * Returns whether the engine runs in the "Classic Compatibile" mode.
- * When this mode is active, the engine behavior is altered in following
- * way: (these resemble the behavior of the 1.7.x line of FreeMarker engine,
- * now named "FreeMarker Classic", hence the name).
- * <ul>
- * <li>handle undefined expressions gracefully. Namely when an expression
- * "expr" evaluates to null:
- * <ul>
- * <li>
- * in <tt><assign varname=expr></tt> directive,
- * or in <tt>${expr}</tt> directive,
- * or in <tt>otherexpr == expr</tt>,
- * or in <tt>otherexpr != expr</tt>,
- * or in <tt>hash[expr]</tt>,
- * or in <tt>expr[keyOrIndex]</tt> (since 2.3.20),
- * or in <tt>expr.key</tt> (since 2.3.20),
- * then it's treated as empty string.
- * </li>
- * <li>as argument of <tt><list expr as item></tt> or
- * <tt><foreach item in expr></tt>, the loop body is not executed
- * (as if it were a 0-length list)
- * </li>
- * <li>as argument of <tt><if></tt> directive, or on other places where a
- * boolean expression is expected, it's treated as false
- * </li>
- * </ul>
- * </li>
- * <li>Non-boolean models are accepted in <tt><if></tt> directive,
- * or as operands of logical operators. "Empty" models (zero-length string,
- * empty sequence or hash) are evaluated as false, all others are evaluated as
- * true.</li>
- * <li>When boolean value is treated as a string (i.e. output in
- * <tt>${...}</tt> directive, or concatenated with other string), true
- * values are converted to string "true", false values are converted to
- * empty string. Except, if the value of the setting is <tt>2</tt>, it will be
- * formatted according the <tt>boolean_format</tt> setting, just like in
- * 2.3.20 and later.
- * </li>
- * <li>Scalar models supplied to <tt><list></tt> and
- * <tt><foreach></tt> are treated as a one-element list consisting
- * of the passed model.
- * </li>
- * <li>Paths parameter of <tt><include></tt> will be interpreted as
- * absolute path.
- * </li>
- * </ul>
- * In all other aspects, the engine is a 2.1 engine even in compatibility
- * mode - you don't lose any of the new functionality by enabling it.
- */
- public boolean isClassicCompatible() {
- return classicCompatible != null ? classicCompatible.intValue() != 0 : parent.isClassicCompatible();
- }
-
- public int getClassicCompatibleAsInt() {
- return classicCompatible != null ? classicCompatible.intValue() : parent.getClassicCompatibleAsInt();
- }
-
- /**
- * Tells if this setting is set directly in this object or its value is coming from the {@link #getParent() parent}.
- *
- * @since 2.3.24
- */
- public boolean isClassicCompatibleSet() {
- return classicCompatible != null;
- }
-
- /**
* Sets the default locale used for number and date formatting (among others), also the locale used for searching
* localized template variations when no locale was explicitly requested.
*
@@ -1993,12 +1879,6 @@ public class Configurable {
* <li><p>{@code "locale"}:
* See {@link #setLocale(Locale)}.
* <br>String value: local codes with the usual format in Java, such as {@code "en_US"}.
- *
- * <li><p>{@code "classic_compatible"}:
- * See {@link #setClassicCompatible(boolean)} and {@link Configurable#setClassicCompatibleAsInt(int)}.
- * <br>String value: {@code "true"}, {@code "false"}, also since 2.3.20 {@code 0} or {@code 1} or {@code 2}.
- * (Also accepts {@code "yes"}, {@code "no"}, {@code "t"}, {@code "f"}, {@code "y"}, {@code "n"}.)
- * Case insensitive.
*
* <li><p>{@code "custom_number_formats"}: See {@link #setCustomNumberFormats(Map)}.
* <br>String value: Interpreted as an <a href="#fm_obe">object builder expression</a>.
@@ -2412,19 +2292,6 @@ public class Configurable {
} else if (SQL_DATE_AND_TIME_TIME_ZONE_KEY_SNAKE_CASE.equals(name)
|| SQL_DATE_AND_TIME_TIME_ZONE_KEY_CAMEL_CASE.equals(name)) {
setSQLDateAndTimeTimeZone(value.equals("null") ? null : parseTimeZoneSettingValue(value));
- } else if (CLASSIC_COMPATIBLE_KEY_SNAKE_CASE.equals(name)
- || CLASSIC_COMPATIBLE_KEY_CAMEL_CASE.equals(name)) {
- char firstChar;
- if (value != null && value.length() > 0) {
- firstChar = value.charAt(0);
- } else {
- firstChar = 0;
- }
- if (Character.isDigit(firstChar) || firstChar == '+' || firstChar == '-') {
- setClassicCompatibleAsInt(Integer.parseInt(value));
- } else {
- setClassicCompatible(value != null ? StringUtil.getYesNo(value) : false);
- }
} else if (TEMPLATE_EXCEPTION_HANDLER_KEY_SNAKE_CASE.equals(name)
|| TEMPLATE_EXCEPTION_HANDLER_KEY_CAMEL_CASE.equals(name)) {
if (value.indexOf('.') == -1) {
@@ -2632,11 +2499,24 @@ public class Configurable {
* Creates the exception that should be thrown when a setting name isn't recognized.
*/
protected TemplateException unknownSettingException(String name) {
- return new UnknownSettingException(
- getEnvironment(), name, getCorrectedNameForUnknownSetting(name));
+ Version removalVersion = getRemovalVersionForUnknownSetting(name);
+ return removalVersion != null
+ ? new UnknownSettingException(getEnvironment(), name, removalVersion)
+ : new UnknownSettingException(getEnvironment(), name, getCorrectedNameForUnknownSetting(name));
}
/**
+ * If a setting name is unknown because it was removed over time, then returns the version where it was removed,
+ * otherwise returns {@code null}.
+ */
+ protected Version getRemovalVersionForUnknownSetting(String name) {
+ if (name.equals("classic_compatible") || name.equals("classicCompatible")) {
+ return Configuration.VERSION_3_0_0;
+ }
+ return null;
+ }
+
+ /**
* @param name The wrong name
* @return The corrected name, or {@code null} if there's no known correction
* @since 2.3.21
@@ -2668,6 +2548,13 @@ public class Configurable {
correctedName == null
? (Object) "" : new Object[] { ". You may meant: ", new _DelayedJQuote(correctedName) });
}
+
+ private UnknownSettingException(Environment env, String name, Version removedInVersion) {
+ super(env,
+ "Unknown FreeMarker configuration setting: ", new _DelayedJQuote(name),
+ removedInVersion == null
+ ? (Object) "" : new Object[] { ". This setting was removed in version ", removedInVersion });
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/Dot.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Dot.java b/src/main/java/freemarker/core/Dot.java
index 1eb1307..1ebbd9f 100644
--- a/src/main/java/freemarker/core/Dot.java
+++ b/src/main/java/freemarker/core/Dot.java
@@ -42,9 +42,6 @@ final class Dot extends Expression {
if (leftModel instanceof TemplateHashModel) {
return ((TemplateHashModel) leftModel).get(key);
}
- if (leftModel == null && env.isClassicCompatible()) {
- return null; // ${noSuchVar.foo} has just printed nothing in FM 1.
- }
throw new NonHashException(target, leftModel, env);
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/DynamicKeyName.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/DynamicKeyName.java b/src/main/java/freemarker/core/DynamicKeyName.java
index b0addad..993053c 100644
--- a/src/main/java/freemarker/core/DynamicKeyName.java
+++ b/src/main/java/freemarker/core/DynamicKeyName.java
@@ -50,22 +50,10 @@ final class DynamicKeyName extends Expression {
@Override
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel targetModel = target.eval(env);
- if (targetModel == null) {
- if (env.isClassicCompatible()) {
- return null;
- } else {
- throw InvalidReferenceException.getInstance(target, env);
- }
- }
+ target.assertNonNull(targetModel, env);
TemplateModel keyModel = keyExpression.eval(env);
- if (keyModel == null) {
- if (env.isClassicCompatible()) {
- keyModel = TemplateScalarModel.EMPTY_STRING;
- } else {
- keyExpression.assertNonNull(null, env);
- }
- }
+ keyExpression.assertNonNull(keyModel, env);
if (keyModel instanceof TemplateNumberModel) {
int index = keyExpression.modelToNumber(keyModel, env).intValue();
return dealWithNumericalKey(targetModel, index, env);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/Environment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Environment.java b/src/main/java/freemarker/core/Environment.java
index f8921f4..4fa4d1c 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -2699,11 +2699,6 @@ public final class Environment extends Configurable {
*/
public String toFullTemplateName(String baseName, String targetName)
throws MalformedTemplateNameException {
- if (isClassicCompatible()) {
- // Early FM only had absolute names.
- return targetName;
- }
-
return _CacheAPI.toAbsoluteName(configuration.getTemplateNameFormat(), baseName, targetName);
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/EvalUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/EvalUtil.java b/src/main/java/freemarker/core/EvalUtil.java
index 061ae19..e3c01aa 100644
--- a/src/main/java/freemarker/core/EvalUtil.java
+++ b/src/main/java/freemarker/core/EvalUtil.java
@@ -21,8 +21,6 @@ package freemarker.core;
import java.util.Date;
-import freemarker.ext.beans.BeanModel;
-import freemarker.ext.beans._BeansAPI;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateDateModel;
@@ -50,18 +48,13 @@ class EvalUtil {
/**
* @param expr {@code null} is allowed, but may results in less helpful error messages
- * @param env {@code null} is allowed, but may results in lower performance in classic-compatible mode
+ * @param env {@code null} is allowed
*/
static String modelToString(TemplateScalarModel model, Expression expr, Environment env)
throws TemplateModelException {
String value = model.getAsString();
if (value == null) {
- if (env == null) env = Environment.getCurrentEnvironment();
- if (env != null && env.isClassicCompatible()) {
- return "";
- } else {
- throw newModelHasStoredNullException(String.class, model, expr);
- }
+ throw newModelHasStoredNullException(String.class, model, expr);
}
return value;
}
@@ -186,35 +179,27 @@ class EvalUtil {
boolean leftNullReturnsFalse, boolean rightNullReturnsFalse,
Environment env) throws TemplateException {
if (leftValue == null) {
- if (env != null && env.isClassicCompatible()) {
- leftValue = TemplateScalarModel.EMPTY_STRING;
+ if (leftNullReturnsFalse) {
+ return false;
} else {
- if (leftNullReturnsFalse) {
- return false;
+ if (leftExp != null) {
+ throw InvalidReferenceException.getInstance(leftExp, env);
} else {
- if (leftExp != null) {
- throw InvalidReferenceException.getInstance(leftExp, env);
- } else {
- throw new _MiscTemplateException(defaultBlamed, env,
- "The left operand of the comparison was undefined or null.");
- }
+ throw new _MiscTemplateException(defaultBlamed, env,
+ "The left operand of the comparison was undefined or null.");
}
}
}
if (rightValue == null) {
- if (env != null && env.isClassicCompatible()) {
- rightValue = TemplateScalarModel.EMPTY_STRING;
+ if (rightNullReturnsFalse) {
+ return false;
} else {
- if (rightNullReturnsFalse) {
- return false;
+ if (rightExp != null) {
+ throw InvalidReferenceException.getInstance(rightExp, env);
} else {
- if (rightExp != null) {
- throw InvalidReferenceException.getInstance(rightExp, env);
- } else {
- throw new _MiscTemplateException(defaultBlamed, env,
- "The right operand of the comparison was undefined or null.");
- }
+ throw new _MiscTemplateException(defaultBlamed, env,
+ "The right operand of the comparison was undefined or null.");
}
}
}
@@ -285,10 +270,6 @@ class EvalUtil {
boolean leftBool = ((TemplateBooleanModel) leftValue).getAsBoolean();
boolean rightBool = ((TemplateBooleanModel) rightValue).getAsBoolean();
cmpResult = (leftBool ? 1 : 0) - (rightBool ? 1 : 0);
- } else if (env.isClassicCompatible()) {
- String leftSting = leftExp.evalAndCoerceToPlainText(env);
- String rightString = rightExp.evalAndCoerceToPlainText(env);
- cmpResult = env.getCollator().compare(leftSting, rightString);
} else {
if (typeMismatchMeansNotEqual) {
if (operator == CMP_OP_EQUALS) {
@@ -443,7 +424,7 @@ class EvalUtil {
/**
* @param tm
- * If {@code null} that's an exception, unless we are in classic compatible mode.
+ * If {@code null} that's an exception
*
* @param supportsTOM
* Whether the caller {@code coerceModelTo...} method could handle a {@link TemplateMarkupOutputModel}.
@@ -458,43 +439,19 @@ class EvalUtil {
if (tm instanceof TemplateScalarModel) {
return modelToString((TemplateScalarModel) tm, exp, env);
} else if (tm == null) {
- if (env.isClassicCompatible()) {
- return "";
+ if (exp != null) {
+ throw InvalidReferenceException.getInstance(exp, env);
} else {
- if (exp != null) {
- throw InvalidReferenceException.getInstance(exp, env);
- } else {
- throw new InvalidReferenceException(
- "Null/missing value (no more informatoin avilable)",
- env);
- }
+ throw new InvalidReferenceException(
+ "Null/missing value (no more informatoin avilable)",
+ env);
}
} else if (tm instanceof TemplateBooleanModel) {
- // This should be before TemplateScalarModel, but automatic boolean-to-string is only non-error since 2.3.20
- // (and before that when classic_compatible was true), so to keep backward compatibility we couldn't insert
- // this before TemplateScalarModel.
+ // [FM3] This should be before TemplateScalarModel, but automatic boolean-to-string is only non-error since
+ // 2.3.20, so to keep backward compatibility we couldn't insert this before TemplateScalarModel.
boolean booleanValue = ((TemplateBooleanModel) tm).getAsBoolean();
- int compatMode = env.getClassicCompatibleAsInt();
- if (compatMode == 0) {
- return env.formatBoolean(booleanValue, false);
- } else {
- if (compatMode == 1) {
- return booleanValue ? MiscUtil.C_TRUE : "";
- } else if (compatMode == 2) {
- if (tm instanceof BeanModel) {
- // In 2.1, bean-wrapped booleans where strings, so that has overridden the boolean behavior:
- return _BeansAPI.getAsClassicCompatibleString((BeanModel) tm);
- } else {
- return booleanValue ? MiscUtil.C_TRUE : "";
- }
- } else {
- throw new BugException("Unsupported classic_compatible variation: " + compatMode);
- }
- }
+ return env.formatBoolean(booleanValue, false);
} else {
- if (env.isClassicCompatible() && tm instanceof BeanModel) {
- return _BeansAPI.getAsClassicCompatibleString((BeanModel) tm);
- }
if (returnNullOnNonCoercableType) {
return null;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/Expression.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Expression.java b/src/main/java/freemarker/core/Expression.java
index 1b07c7d..3f92c0a 100644
--- a/src/main/java/freemarker/core/Expression.java
+++ b/src/main/java/freemarker/core/Expression.java
@@ -157,8 +157,6 @@ abstract public class Expression extends TemplateObject {
private boolean modelToBoolean(TemplateModel model, Environment env, Configuration cfg) throws TemplateException {
if (model instanceof TemplateBooleanModel) {
return ((TemplateBooleanModel) model).getAsBoolean();
- } else if (env != null ? env.isClassicCompatible() : cfg.isClassicCompatible()) {
- return model != null && !isEmpty(model);
} else {
throw new NonBooleanException(this, model, env);
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/HashLiteral.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/HashLiteral.java b/src/main/java/freemarker/core/HashLiteral.java
index 6d2c1c7..d9bebe1 100644
--- a/src/main/java/freemarker/core/HashLiteral.java
+++ b/src/main/java/freemarker/core/HashLiteral.java
@@ -118,9 +118,7 @@ final class HashLiteral extends Expression {
Expression valExp = (Expression) values.get(i);
String key = keyExp.evalAndCoerceToPlainText(env);
TemplateModel value = valExp.eval(env);
- if (env == null || !env.isClassicCompatible()) {
- valExp.assertNonNull(value, env);
- }
+ valExp.assertNonNull(value, env);
map.put(key, value);
}
} else {
@@ -134,9 +132,7 @@ final class HashLiteral extends Expression {
Expression valExp = (Expression) values.get(i);
String key = keyExp.evalAndCoerceToPlainText(env);
TemplateModel value = valExp.eval(env);
- if (env == null || !env.isClassicCompatible()) {
- valExp.assertNonNull(value, env);
- }
+ valExp.assertNonNull(value, env);
map.put(key, value);
keyList.add(key);
valueList.add(value);
@@ -146,10 +142,12 @@ final class HashLiteral extends Expression {
}
}
+ @Override
public int size() {
return size;
}
+ @Override
public TemplateCollectionModel keys() {
if (keyCollection == null) {
// This can only happen when IcI >= 2.3.21, an the map is a LinkedHashMap.
@@ -158,6 +156,7 @@ final class HashLiteral extends Expression {
return keyCollection;
}
+ @Override
public TemplateCollectionModel values() {
if (valueCollection == null) {
// This can only happen when IcI >= 2.3.21, an the map is a LinkedHashMap.
@@ -166,10 +165,12 @@ final class HashLiteral extends Expression {
return valueCollection;
}
+ @Override
public TemplateModel get(String key) {
return (TemplateModel) map.get(key);
}
+ @Override
public boolean isEmpty() {
return size == 0;
}
@@ -179,24 +180,29 @@ final class HashLiteral extends Expression {
return getCanonicalForm();
}
+ @Override
public KeyValuePairIterator keyValuePairIterator() throws TemplateModelException {
return new KeyValuePairIterator() {
private final TemplateModelIterator keyIterator = keys().iterator();
private final TemplateModelIterator valueIterator = values().iterator();
+ @Override
public boolean hasNext() throws TemplateModelException {
return keyIterator.hasNext();
}
+ @Override
public KeyValuePair next() throws TemplateModelException {
return new KeyValuePair() {
private final TemplateModel key = keyIterator.next();
private final TemplateModel value = valueIterator.next();
+ @Override
public TemplateModel getKey() throws TemplateModelException {
return key;
}
+ @Override
public TemplateModel getValue() throws TemplateModelException {
return value;
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/IteratorBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/IteratorBlock.java b/src/main/java/freemarker/core/IteratorBlock.java
index 61ca93b..0ae8d1d 100644
--- a/src/main/java/freemarker/core/IteratorBlock.java
+++ b/src/main/java/freemarker/core/IteratorBlock.java
@@ -37,7 +37,6 @@ import freemarker.template.TemplateModelException;
import freemarker.template.TemplateModelIterator;
import freemarker.template.TemplateScalarModel;
import freemarker.template.TemplateSequenceModel;
-import freemarker.template.utility.Constants;
/**
* A #list (or #foreach) element, or pre-#else section of it inside a {@link ListElseContainer}.
@@ -97,11 +96,7 @@ final class IteratorBlock extends TemplateElement {
boolean acceptWithResult(Environment env) throws TemplateException, IOException {
TemplateModel listedValue = listedExp.eval(env);
if (listedValue == null) {
- if (env.isClassicCompatible()) {
- listedValue = Constants.EMPTY_SEQUENCE;
- } else {
- listedExp.assertNonNull(null, env);
- }
+ listedExp.assertNonNull(null, env);
}
return env.visitIteratorBlock(new IterationContext(listedValue, loopVarName, loopVar2Name));
@@ -321,17 +316,6 @@ final class IteratorBlock extends TemplateElement {
env.visit(childBuffer);
}
}
- } else if (env.isClassicCompatible()) {
- listNotEmpty = true;
- if (loopVarName != null) {
- loopVar = listedValue;
- hasNext = false;
- }
- try {
- env.visit(childBuffer);
- } catch (BreakInstruction.Break br) {
- // Silently exit "loop"
- }
} else if (listedValue instanceof TemplateHashModelEx
&& !NonSequenceOrCollectionException.isWrappedIterable(listedValue)) {
throw new NonSequenceOrCollectionException(env,
@@ -435,6 +419,7 @@ final class IteratorBlock extends TemplateElement {
return this.loopVar2Name;
}
+ @Override
public TemplateModel getLocalVariable(String name) {
String loopVariableName = this.loopVarName;
if (loopVariableName != null && name.startsWith(loopVariableName)) {
@@ -461,6 +446,7 @@ final class IteratorBlock extends TemplateElement {
return null;
}
+ @Override
public Collection getLocalVariableNames() {
String loopVariableName = this.loopVarName;
if (loopVariableName != null) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/ListLiteral.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ListLiteral.java b/src/main/java/freemarker/core/ListLiteral.java
index db7b4c5..92eba2e 100644
--- a/src/main/java/freemarker/core/ListLiteral.java
+++ b/src/main/java/freemarker/core/ListLiteral.java
@@ -48,9 +48,7 @@ final class ListLiteral extends Expression {
for (Iterator it = items.iterator(); it.hasNext(); ) {
Expression exp = (Expression) it.next();
TemplateModel tm = exp.eval(env);
- if (env == null || !env.isClassicCompatible()) {
- exp.assertNonNull(tm, env);
- }
+ exp.assertNonNull(tm, env);
list.add(tm);
}
return list;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/Macro.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Macro.java b/src/main/java/freemarker/core/Macro.java
index 162cad3..16f2c53 100644
--- a/src/main/java/freemarker/core/Macro.java
+++ b/src/main/java/freemarker/core/Macro.java
@@ -206,7 +206,7 @@ public final class Macro extends TemplateElement implements TemplateModel {
firstReferenceException = e;
}
}
- } else if (!env.isClassicCompatible()) {
+ } else {
boolean argWasSpecified = localVars.containsKey(argName);
throw new _MiscTemplateException(env,
new _ErrorDescriptionBuilder(
@@ -234,7 +234,7 @@ public final class Macro extends TemplateElement implements TemplateModel {
if (hasUnresolvedArg) {
if (firstReferenceException != null) {
throw firstReferenceException;
- } else if (!env.isClassicCompatible()) {
+ } else {
throw InvalidReferenceException.getInstance(firstUnresolvedExpression, env);
}
}
@@ -244,6 +244,7 @@ public final class Macro extends TemplateElement implements TemplateModel {
* @return the local variable of the given name
* or null if it doesn't exist.
*/
+ @Override
public TemplateModel getLocalVariable(String name) throws TemplateModelException {
return localVars.get(name);
}
@@ -259,6 +260,7 @@ public final class Macro extends TemplateElement implements TemplateModel {
localVars.put(name, var);
}
+ @Override
public Collection getLocalVariableNames() throws TemplateModelException {
HashSet result = new HashSet();
for (TemplateModelIterator it = localVars.keys().iterator(); it.hasNext(); ) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/PropertySetting.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/PropertySetting.java b/src/main/java/freemarker/core/PropertySetting.java
index 1cb81a3..858a69a 100644
--- a/src/main/java/freemarker/core/PropertySetting.java
+++ b/src/main/java/freemarker/core/PropertySetting.java
@@ -43,8 +43,6 @@ final class PropertySetting extends TemplateElement {
// Must be sorted alphabetically!
Configurable.BOOLEAN_FORMAT_KEY_CAMEL_CASE,
Configurable.BOOLEAN_FORMAT_KEY_SNAKE_CASE,
- Configurable.CLASSIC_COMPATIBLE_KEY_CAMEL_CASE,
- Configurable.CLASSIC_COMPATIBLE_KEY_SNAKE_CASE,
Configurable.DATE_FORMAT_KEY_CAMEL_CASE,
Configurable.DATE_FORMAT_KEY_SNAKE_CASE,
Configurable.DATETIME_FORMAT_KEY_CAMEL_CASE,
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/core/TemplateConfiguration.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/TemplateConfiguration.java b/src/main/java/freemarker/core/TemplateConfiguration.java
index fe1062a..c91d7fd 100644
--- a/src/main/java/freemarker/core/TemplateConfiguration.java
+++ b/src/main/java/freemarker/core/TemplateConfiguration.java
@@ -169,9 +169,6 @@ public final class TemplateConfiguration extends Configurable implements ParserC
if (tc.isBooleanFormatSet()) {
setBooleanFormat(tc.getBooleanFormat());
}
- if (tc.isClassicCompatibleSet()) {
- setClassicCompatibleAsInt(tc.getClassicCompatibleAsInt());
- }
if (tc.isCustomDateFormatsSet()) {
setCustomDateFormats(mergeMaps(getCustomDateFormats(), tc.getCustomDateFormats(), false));
}
@@ -298,9 +295,6 @@ public final class TemplateConfiguration extends Configurable implements ParserC
if (isBooleanFormatSet() && !template.isBooleanFormatSet()) {
template.setBooleanFormat(getBooleanFormat());
}
- if (isClassicCompatibleSet() && !template.isClassicCompatibleSet()) {
- template.setClassicCompatibleAsInt(getClassicCompatibleAsInt());
- }
if (isCustomDateFormatsSet()) {
template.setCustomDateFormats(
mergeMaps(getCustomDateFormats(), template.getCustomDateFormatsWithoutFallback(), false));
@@ -385,6 +379,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
/**
* The getter pair of {@link #setTagSyntax(int)}.
*/
+ @Override
public int getTagSyntax() {
return tagSyntax != null ? tagSyntax.intValue() : getParentConfiguration().getTagSyntax();
}
@@ -407,6 +402,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
/**
* The getter pair of {@link #setNamingConvention(int)}.
*/
+ @Override
public int getNamingConvention() {
return namingConvention != null ? namingConvention.intValue() : getParentConfiguration().getNamingConvention();
}
@@ -428,6 +424,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
/**
* The getter pair of {@link #getWhitespaceStripping()}.
*/
+ @Override
public boolean getWhitespaceStripping() {
return whitespaceStripping != null ? whitespaceStripping.booleanValue()
: getParentConfiguration().getWhitespaceStripping();
@@ -451,6 +448,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
/**
* The getter pair of {@link #setAutoEscapingPolicy(int)}.
*/
+ @Override
public int getAutoEscapingPolicy() {
return autoEscapingPolicy != null ? autoEscapingPolicy.intValue()
: getParentConfiguration().getAutoEscapingPolicy();
@@ -474,6 +472,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
/**
* The getter pair of {@link #setOutputFormat(OutputFormat)}.
*/
+ @Override
public OutputFormat getOutputFormat() {
return outputFormat != null ? outputFormat : getParentConfiguration().getOutputFormat();
}
@@ -495,6 +494,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
/**
* Getter pair of {@link #setRecognizeStandardFileExtensions(boolean)}.
*/
+ @Override
public boolean getRecognizeStandardFileExtensions() {
return recognizeStandardFileExtensions != null ? recognizeStandardFileExtensions.booleanValue()
: getParentConfiguration().getRecognizeStandardFileExtensions();
@@ -517,6 +517,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
/**
* The getter pair of {@link #setStrictSyntaxMode(boolean)}.
*/
+ @Override
public boolean getStrictSyntaxMode() {
return strictSyntaxMode != null ? strictSyntaxMode.booleanValue()
: getParentConfiguration().getStrictSyntaxMode();
@@ -575,6 +576,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
*
* @since 2.3.25
*/
+ @Override
public int getTabSize() {
return tabSize != null ? tabSize.intValue()
: getParentConfiguration().getTabSize();
@@ -596,6 +598,7 @@ public final class TemplateConfiguration extends Configurable implements ParserC
* @throws IllegalStateException
* If the parent configuration wasn't yet set.
*/
+ @Override
public Version getIncompatibleImprovements() {
checkParentConfigurationSet();
return getParentConfiguration().getIncompatibleImprovements();
@@ -615,7 +618,6 @@ public final class TemplateConfiguration extends Configurable implements ParserC
|| isAutoImportsSet()
|| isAutoIncludesSet()
|| isBooleanFormatSet()
- || isClassicCompatibleSet()
|| isCustomDateFormatsSet()
|| isCustomNumberFormatsSet()
|| isDateFormatSet()
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java b/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java
index ec6e5a4..815f83b 100644
--- a/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java
+++ b/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java
@@ -106,6 +106,7 @@ implements
}
// TODO See in SuppressFBWarnings
+ @Override
@SuppressFBWarnings(value="NN_NAKED_NOTIFY", justification="Will have to be re-desigend; postponed.")
public void resume() {
synchronized (this) {
@@ -113,11 +114,13 @@ implements
}
}
+ @Override
public void stop() {
stopped = true;
resume();
}
+ @Override
public long getId() {
return id;
}
@@ -127,14 +130,17 @@ implements
}
private abstract static class DebugMapModel implements TemplateHashModelEx {
+ @Override
public int size() {
return keySet().size();
}
+ @Override
public TemplateCollectionModel keys() {
return new SimpleCollection(keySet());
}
+ @Override
public TemplateCollectionModel values() throws TemplateModelException {
Collection keys = keySet();
List list = new ArrayList(keys.size());
@@ -145,6 +151,7 @@ implements
return new SimpleCollection(list);
}
+ @Override
public boolean isEmpty() {
return size() == 0;
}
@@ -164,7 +171,6 @@ implements
{
Configurable.ARITHMETIC_ENGINE_KEY,
Configurable.BOOLEAN_FORMAT_KEY,
- Configurable.CLASSIC_COMPATIBLE_KEY,
Configurable.LOCALE_KEY,
Configurable.NUMBER_FORMAT_KEY,
Configurable.OBJECT_WRAPPER_KEY,
@@ -182,6 +188,7 @@ implements
return KEYS;
}
+ @Override
public TemplateModel get(String key) throws TemplateModelException {
String s = configurable.getSetting(key);
return s == null ? null : new SimpleScalar(s);
@@ -199,6 +206,7 @@ implements
return ((Configuration) configurable).getSharedVariableNames();
}
+ @Override
public TemplateModel get(String key) {
return ((Configuration) configurable).getSharedVariable(key);
}
@@ -280,6 +288,7 @@ implements
}
}
+ @Override
public TemplateModel get(String key) throws TemplateModelException {
return ((Environment) configurable).getVariable(key);
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/ext/beans/BeanModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/BeanModel.java b/src/main/java/freemarker/ext/beans/BeanModel.java
index 9ccdfc0..1d6062f 100644
--- a/src/main/java/freemarker/ext/beans/BeanModel.java
+++ b/src/main/java/freemarker/ext/beans/BeanModel.java
@@ -342,22 +342,6 @@ implements
return new CollectionAndSequence(new SimpleSequence(values, wrapper));
}
- /**
- * Used for {@code classic_compatbile} mode; don't use it for anything else.
- * In FreeMarker 1.7 (and also at least in 2.1) {@link BeanModel} was a {@link TemplateScalarModel}. Some internal
- * FreeMarker code tries to emulate FreeMarker classic by calling this method when a {@link TemplateScalarModel} is
- * expected.
- *
- * @return Never {@code null}
- */
- String getAsClassicCompatibleString() {
- if (object == null) {
- return "null";
- }
- String s = object.toString();
- return s != null ? s : "null";
- }
-
@Override
public String toString() {
return object.toString();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/ext/beans/_BeansAPI.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/beans/_BeansAPI.java b/src/main/java/freemarker/ext/beans/_BeansAPI.java
index a2c648d..e0a2d94 100644
--- a/src/main/java/freemarker/ext/beans/_BeansAPI.java
+++ b/src/main/java/freemarker/ext/beans/_BeansAPI.java
@@ -45,10 +45,6 @@ public class _BeansAPI {
private _BeansAPI() { }
- public static String getAsClassicCompatibleString(BeanModel bm) {
- return bm.getAsClassicCompatibleString();
- }
-
public static Object newInstance(Class<?> pClass, Object[] args, BeansWrapper bw)
throws NoSuchMethodException, IllegalArgumentException, InstantiationException,
IllegalAccessException, InvocationTargetException, TemplateModelException {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/template/SimpleList.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/SimpleList.java b/src/main/java/freemarker/template/SimpleList.java
deleted file mode 100644
index 11aee42..0000000
--- a/src/main/java/freemarker/template/SimpleList.java
+++ /dev/null
@@ -1,42 +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 freemarker.template;
-
-/**
- * This is a trivial subclass that exists for backward compatibility
- * with the SimpleList from FreeMarker Classic.
- *
- * <p>This class is thread-safe.
- *
- * @deprecated Use SimpleSequence instead.
- * @see SimpleSequence
- */
-
-@Deprecated
-public class SimpleList extends SimpleSequence {
-
- public SimpleList() {
- }
-
- public SimpleList(java.util.List list) {
- super(list);
- }
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/main/java/freemarker/template/TemplateScalarModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/TemplateScalarModel.java b/src/main/java/freemarker/template/TemplateScalarModel.java
index b57259b..3496f89 100644
--- a/src/main/java/freemarker/template/TemplateScalarModel.java
+++ b/src/main/java/freemarker/template/TemplateScalarModel.java
@@ -32,8 +32,7 @@ public interface TemplateScalarModel extends TemplateModel {
public TemplateModel EMPTY_STRING = new SimpleScalar("");
/**
- * Returns the string representation of this model. Don't return {@code null}, as that will cause exception. (In
- * classic-compatible mode the engine will convert {@code null} into empty string, though.)
+ * Returns the string representation of this model. Don't return {@code null}, as that will cause exception.
*
* <p>
* Objects of this type should be immutable, that is, calling {@link #getAsString()} should always return the same
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/manual/en_US/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/src/manual/en_US/FM3-CHANGE-LOG.txt b/src/manual/en_US/FM3-CHANGE-LOG.txt
index 5311e9c..940b696 100644
--- a/src/manual/en_US/FM3-CHANGE-LOG.txt
+++ b/src/manual/en_US/FM3-CHANGE-LOG.txt
@@ -8,4 +8,5 @@ the FreeMarer 3 changelog here:
Added org.slf4j:slf4j-api as required dependency instead.
- Removed all classes with "main" methods that were part of freemarker.jar. Such tools should be separate artifacts,
not part of the library, and they are often classified as CWE-489 "Leftover Debug Code". The removed classes are:
- freemarker.core.CommandLine, freemarker.ext.dom.Transform, freemarker.template.utility.ToCanonical
\ No newline at end of file
+ freemarker.core.CommandLine, freemarker.ext.dom.Transform, freemarker.template.utility.ToCanonical
+- Removed classic_compatible (classicCompatible) setting, which was used to emulate some of the FreeMarker 1.x behavior
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/test/java/freemarker/core/TemplateConfigurationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/TemplateConfigurationTest.java b/src/test/java/freemarker/core/TemplateConfigurationTest.java
index 13a6405..5392af0 100644
--- a/src/test/java/freemarker/core/TemplateConfigurationTest.java
+++ b/src/test/java/freemarker/core/TemplateConfigurationTest.java
@@ -18,8 +18,15 @@
*/
package freemarker.core;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
@@ -35,7 +42,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -160,7 +166,6 @@ public class TemplateConfigurationTest {
SETTING_ASSIGNMENTS.put("URLEscapingCharset", "utf-16");
SETTING_ASSIGNMENTS.put("autoFlush", false);
SETTING_ASSIGNMENTS.put("booleanFormat", "J,N");
- SETTING_ASSIGNMENTS.put("classicCompatibleAsInt", 2);
SETTING_ASSIGNMENTS.put("dateFormat", "yyyy-#DDD");
SETTING_ASSIGNMENTS.put("dateTimeFormat", "yyyy-#DDD-@HH:mm");
SETTING_ASSIGNMENTS.put("locale", NON_DEFAULT_LOCALE);
@@ -198,13 +203,9 @@ public class TemplateConfigurationTest {
}
public static String getIsSetMethodName(String readMethodName) {
- String isSetMethodName = (readMethodName.startsWith("get") ? "is" + readMethodName.substring(3)
+ return (readMethodName.startsWith("get") ? "is" + readMethodName.substring(3)
: readMethodName)
+ "Set";
- if (isSetMethodName.equals("isClassicCompatibleAsIntSet")) {
- isSetMethodName = "isClassicCompatibleSet";
- }
- return isSetMethodName;
}
public static List<PropertyDescriptor> getTemplateConfigurationSettingPropDescs(
@@ -229,6 +230,7 @@ public class TemplateConfigurationTest {
Collections.sort(settingPropDescs, new Comparator<PropertyDescriptor>() {
+ @Override
public int compare(PropertyDescriptor o1, PropertyDescriptor o2) {
return o1.getName().compareToIgnoreCase(o2.getName());
}
@@ -245,7 +247,6 @@ public class TemplateConfigurationTest {
IGNORED_PROP_NAMES.add("strictBeanModels");
IGNORED_PROP_NAMES.add("parentConfiguration");
IGNORED_PROP_NAMES.add("settings");
- IGNORED_PROP_NAMES.add("classicCompatible");
}
private static final Set<String> CONFIGURABLE_PROP_NAMES;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/test/java/freemarker/template/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/template/ConfigurationTest.java b/src/test/java/freemarker/template/ConfigurationTest.java
index 585940a..cdd4d9e 100644
--- a/src/test/java/freemarker/template/ConfigurationTest.java
+++ b/src/test/java/freemarker/template/ConfigurationTest.java
@@ -1769,6 +1769,17 @@ public class ConfigurationTest extends TestCase {
assertEquals(lNames.size(), cNames.size());
}
+ @Test
+ public void testClassicCompatibleRemoved() {
+ Configuration cfg = new Configuration();
+ try {
+ cfg.setSetting("classicCompatible", "true");
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(), allOf(containsString("removed"), containsString("3.0.0")));
+ }
+ }
+
@SuppressWarnings("boxing")
private void assertStartsWith(List<String> list, List<String> headList) {
int index = 0;
@@ -1792,6 +1803,7 @@ public class ConfigurationTest extends TestCase {
private static class MyScalarModel implements TemplateScalarModel {
+ @Override
public String getAsString() throws TemplateModelException {
return "my";
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java b/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java
index 24b67f8..7535c1a 100644
--- a/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java
+++ b/src/test/java/freemarker/test/templatesuite/TemplateTestCase.java
@@ -432,11 +432,6 @@ public class TemplateTestCase extends FileTestCase {
dataModel.put("bp", Byte.valueOf((byte) 5));
dataModel.put("bip", BigInteger.valueOf(5));
dataModel.put("bdp", BigDecimal.valueOf(0.05));
- } else if (simpleTestName.startsWith("classic-compatible")) {
- dataModel.put("array", new String[] { "a", "b", "c" });
- dataModel.put("beansArray", beansWrapper.wrap(new String[] { "a", "b", "c" }));
- dataModel.put("beanTrue", beansWrapper.wrap(Boolean.TRUE));
- dataModel.put("beanFalse", beansWrapper.wrap(Boolean.FALSE));
} else if (simpleTestName.startsWith("overloaded-methods-2-")) {
dataModel.put("obj", new OverloadedMethods2());
final boolean dow = conf.getObjectWrapper() instanceof DefaultObjectWrapper;
@@ -493,40 +488,48 @@ public class TemplateTestCase extends FileTestCase {
}
static class TestBoolean implements TemplateBooleanModel, TemplateScalarModel {
+ @Override
public boolean getAsBoolean() {
return true;
}
+ @Override
public String getAsString() {
return "de";
}
}
static class TestMethod implements TemplateMethodModel {
- public Object exec(List arguments) {
+ @Override
+ public Object exec(List arguments) {
return "x";
}
}
static class TestNode implements TemplateNodeModel {
- public String getNodeName() {
+ @Override
+ public String getNodeName() {
return "name";
}
- public TemplateNodeModel getParentNode() {
+ @Override
+ public TemplateNodeModel getParentNode() {
return null;
}
- public String getNodeType() {
+ @Override
+ public String getNodeType() {
return "element";
}
- public TemplateSequenceModel getChildNodes() {
+ @Override
+ public TemplateSequenceModel getChildNodes() {
return null;
}
- public String getNodeNamespace() {
+ @Override
+ public String getNodeNamespace() {
return null;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/test/resources/freemarker/test/templatesuite/expected/classic-compatible.txt
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/expected/classic-compatible.txt b/src/test/resources/freemarker/test/templatesuite/expected/classic-compatible.txt
deleted file mode 100644
index c092e3a..0000000
--- a/src/test/resources/freemarker/test/templatesuite/expected/classic-compatible.txt
+++ /dev/null
@@ -1,41 +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.
- */
-[] [null]
-[] [null]
-[] [null]
- 1 22 C
- 1 22 C
-null1 null2
-1 null 2
-[true] []
-[true] []
-[Ljava.lang.String <- All BeanModel-s were strings; not anymore
-[Ljava.lang.String
-[Lcofe.lang.String
-1
-
-ab
-a
-a
-a
-
-2
-2
-2
-1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/test/resources/freemarker/test/templatesuite/templates/classic-compatible-mode2.ftl
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/classic-compatible-mode2.ftl b/src/test/resources/freemarker/test/templatesuite/templates/classic-compatible-mode2.ftl
deleted file mode 100644
index 6a27bb1..0000000
--- a/src/test/resources/freemarker/test/templatesuite/templates/classic-compatible-mode2.ftl
+++ /dev/null
@@ -1,26 +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.
--->
-<@assertEquals expected="" actual=""+false />
-<@assertEquals expected="true" actual=""+true />
-<@assertEquals expected="false" actual=false?string /> <#-- In 2.1 bool?string was error, now it does what 2.3 does -->
-<@assertEquals expected="n" actual=false?string('y', 'n') />
-<@assertEquals expected="false" actual=""+beanFalse />
-<@assertEquals expected="true" actual=""+beanTrue />
-<@assertEquals expected="false" actual=beanFalse?string />
-<@assertEquals expected="n" actual=beanFalse?string('y', 'n') />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/test/resources/freemarker/test/templatesuite/templates/classic-compatible.ftl
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/classic-compatible.ftl b/src/test/resources/freemarker/test/templatesuite/templates/classic-compatible.ftl
deleted file mode 100644
index c3a3ffb..0000000
--- a/src/test/resources/freemarker/test/templatesuite/templates/classic-compatible.ftl
+++ /dev/null
@@ -1,54 +0,0 @@
-<#--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-[${noSuchVar}] [${noSuchVar!'null'}]
-[${noSuchVar.foo.bar}] [${noSuchVar.foo.bar!'null'}]
-[${noSuchVar['foo']}] [${noSuchVar['foo']!'null'}]
-<#assign b = 22>
-<#macro foo a b c>
- ${a?default("A")} ${b?default("B")} ${c?default("C")}
-</#macro>
-<#call foo 1 wrong wrong>
-<@foo 1 wrong wrong />
-<#assign m = {"a": wrong, "b": wrong?default("null2")}>${m.a?default("null1")} ${m.b}
-<#assign xs = [1, wrong, 2]><#list xs as x>${x?default("null")} </#list>
-[${true}] [${false}]
-[${beanTrue}] [${beanFalse}]
-${beansArray?substring(0, 18)} <- All BeanModel-s were strings; not anymore
-${beansArray?string?substring(0, 18)}
-${beansArray?replace('j.v.', 'cofe', 'r')?substring(0, 18)}
-${beansArray?seq_index_of("b")}
-
-<#list ['a', 'b'] as x>${x}</#list>
-<#list ['a'] as x>${x}</#list>
-<#list 'a' as x>${x}</#list>
-<#list 'a' as x>${x}<#break>b</#list>
-
-<#assign x = 1>
-<#assign x = x + 1>
-${x}
-<#assign x = x + noSuchVar>
-${x}
-<#assign x += noSuchVar>
-${x}
-<@assertFails messageRegexp="(?s).*null or missing.*"><#assign noSuchVar = noSuchVar - 1></@>
-<@assertFails messageRegexp="(?s)(?=.*noSuchVar).*assignment.*null or missing.*"><#assign noSuchVar -= 1></@>
-<@assertFails messageRegexp="(?s)(?=.*noSuchVar).*assignment.*null or missing.*"><#assign noSuchVar--></@>
-<@assertFails messageRegexp="(?s)(?=.*noSuchVar).*assignment.*null or missing.*"><#assign noSuchVar++></@>
-<#assign noSuchVar = noSuchVar + 1>
-${noSuchVar}<#-- noSuchVar is "1" string here -->
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/test/resources/freemarker/test/templatesuite/templates/setting.ftl
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/setting.ftl b/src/test/resources/freemarker/test/templatesuite/templates/setting.ftl
index 1def44b..f69b13f 100644
--- a/src/test/resources/freemarker/test/templatesuite/templates/setting.ftl
+++ b/src/test/resources/freemarker/test/templatesuite/templates/setting.ftl
@@ -49,9 +49,5 @@
<#setting url_escaping_charset='UTF-8'>
<@assertEquals expected='%C3%A1' actual='�'?url />
-<@a...@assertFails>
-<#setting classic_compatible=true>
-<@assertEquals expected='[]' actual="[${noSuchWar}]" />
-
<#setting output_encoding="ISO-8859-2">
<@assertEquals expected="ISO-8859-2" actual=.output_encoding />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/4cbc134e/src/test/resources/freemarker/test/templatesuite/testcases.xml
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/test/templatesuite/testcases.xml b/src/test/resources/freemarker/test/templatesuite/testcases.xml
index 25a54e7..d57cf50 100644
--- a/src/test/resources/freemarker/test/templatesuite/testcases.xml
+++ b/src/test/resources/freemarker/test/templatesuite/testcases.xml
@@ -34,7 +34,6 @@
<!ELEMENT setting EMPTY>
<!ATTLIST setting
auto_import CDATA #IMPLIED
- classic_compatible (Y|N|2) #IMPLIED
clear_encoding_map (Y|N) #IMPLIED
input_encoding CDATA #IMPLIED
locale CDATA #IMPLIED
@@ -261,12 +260,6 @@
</testCase>
<testCase name="number-to-date" />
<testCase name="varargs" />
- <testCase name="classic-compatible">
- <setting classic_compatible="Y"/>
- </testCase>
- <testCase name="classic-compatible-mode2" noOutput="true">
- <setting classic_compatible="2"/>
- </testCase>
<testCase name="boolean-formatting" />
<testCase name="number-math-builtins" noOutput="true" />
<testCase name="string-builtin-coercion" noOutput="true" />