(Minor code cleanup, and javadoc improvements.)
diff --git a/freemarker-core/src/main/java/freemarker/core/InvalidReferenceException.java b/freemarker-core/src/main/java/freemarker/core/InvalidReferenceException.java
index d6a75bf..45cf6ef 100644
--- a/freemarker-core/src/main/java/freemarker/core/InvalidReferenceException.java
+++ b/freemarker-core/src/main/java/freemarker/core/InvalidReferenceException.java
@@ -33,8 +33,8 @@
try {
Environment.setCurrentEnvironment(null);
FAST_INSTANCE = new InvalidReferenceException(
- "Invalid reference. Details are unavilable, as this should have been handled by an FTL construct. "
- + "If it wasn't, that's problably a bug in FreeMarker.",
+ "Invalid reference. Details are unavailable, as this should have been handled by an FTL construct. "
+ + "If it wasn't, that's probably a bug in FreeMarker.",
null);
} finally {
Environment.setCurrentEnvironment(prevEnv);
diff --git a/freemarker-core/src/main/java/freemarker/core/MethodCall.java b/freemarker-core/src/main/java/freemarker/core/MethodCall.java
index 180438c..2ece2a0 100644
--- a/freemarker-core/src/main/java/freemarker/core/MethodCall.java
+++ b/freemarker-core/src/main/java/freemarker/core/MethodCall.java
@@ -74,7 +74,7 @@
buf.append(target.getCanonicalForm());
buf.append("(");
String list = arguments.getCanonicalForm();
- buf.append(list.substring(1, list.length() - 1));
+ buf.append(list, 1, list.length() - 1);
buf.append(")");
return buf.toString();
}
diff --git a/freemarker-core/src/main/java/freemarker/core/NonMethodException.java b/freemarker-core/src/main/java/freemarker/core/NonMethodException.java
index 4ba3009..0740dd6 100644
--- a/freemarker-core/src/main/java/freemarker/core/NonMethodException.java
+++ b/freemarker-core/src/main/java/freemarker/core/NonMethodException.java
@@ -36,6 +36,10 @@
super(env, "Expecting method value here");
}
+ /**
+ * @param env Can be {@code null}, if we are in a thread that's running a template currently (because then we can
+ * find the {@link Environment}).
+ */
public NonMethodException(String description, Environment env) {
super(env, description);
}
diff --git a/freemarker-core/src/main/java/freemarker/ext/beans/BeanModel.java b/freemarker-core/src/main/java/freemarker/ext/beans/BeanModel.java
index eacf7b2..79110b9 100644
--- a/freemarker-core/src/main/java/freemarker/ext/beans/BeanModel.java
+++ b/freemarker-core/src/main/java/freemarker/ext/beans/BeanModel.java
@@ -65,18 +65,17 @@
private static final Logger LOG = Logger.getLogger("freemarker.beans");
protected final Object object;
protected final BeansWrapper wrapper;
-
+
// We use this to represent an unknown value as opposed to known value of null (JR)
static final TemplateModel UNKNOWN = new SimpleScalar("UNKNOWN");
-
+
static final ModelFactory FACTORY =
- new ModelFactory()
- {
- @Override
- public TemplateModel create(Object object, ObjectWrapper wrapper) {
- return new BeanModel(object, (BeansWrapper) wrapper);
- }
- };
+ new ModelFactory() {
+ @Override
+ public TemplateModel create(Object object, ObjectWrapper wrapper) {
+ return new BeanModel(object, (BeansWrapper) wrapper);
+ }
+ };
// I've tried to use a volatile ConcurrentHashMap field instead of HashMap + synchronized(this), but oddly it was
// a bit slower, at least on Java 8 u66.
@@ -111,7 +110,7 @@
wrapper.getClassIntrospector().get(object.getClass());
}
}
-
+
/**
* Uses Beans introspection to locate a property or method with name
* matching the key name. If a method or property is found, it's wrapped
diff --git a/freemarker-core/src/main/java/freemarker/ext/beans/MethodAppearanceFineTuner.java b/freemarker-core/src/main/java/freemarker/ext/beans/MethodAppearanceFineTuner.java
index 80731e0..98c6416 100644
--- a/freemarker-core/src/main/java/freemarker/ext/beans/MethodAppearanceFineTuner.java
+++ b/freemarker-core/src/main/java/freemarker/ext/beans/MethodAppearanceFineTuner.java
@@ -38,8 +38,11 @@
* Implement this to tweak certain aspects of how methods appear in the
* data-model. {@link BeansWrapper} will pass in all Java methods here that
* it intends to expose in the data-model as methods (so you can do
- * {@code obj.foo()} in the template).
- * With this method you can do the following tweaks:
+ * {@code obj.foo()} in the template). This also applies to JavaBeans property read methods, like
+ * {@code public int getX()}, even if the bean property value itself is already exposed (with name {@code x}, in
+ * this example).
+ *
+ * <p>With this method you can do the following tweaks:
* <ul>
* <li>Hide a method that would be otherwise shown by calling
* {@link MethodAppearanceDecision#setExposeMethodAs(String)}
@@ -61,19 +64,19 @@
* setMethodShadowsProperty(false)} as well, if the method name is exactly
* the same as the property name).
* The default is {@code null}, which means that no fake property is
- * created for the method. You need not and shouldn't set this
- * to non-{@code null} for the getter methods of real JavaBean
- * properties, as those are automatically shown as properties anyway.
+ * created for the method. You need not, and shouldn't set this
+ * to non-{@code null} for the property read (get/is) methods of real JavaBeans
+ * properties, as bean properties are not seen as methods, and are exposed independently of this mechanism.
* The property name in the {@link PropertyDescriptor} can be anything,
* but the method (or methods) in it must belong to the class that
- * is given as the {@code clazz} parameter or it must be inherited from
+ * is given as the {@code clazz} parameter, or it must be inherited from
* that class, otherwise the behavior is undefined, and errors can occur later.
* {@link IndexedPropertyDescriptor}-s are supported.
- * If a real JavaBean property of the same name exists, or a fake property
+ * If a real JavaBeans property of the same name exists, or a fake property
* of the same name was already assigned earlier, it won't be
* replaced by the new one by default, however this can be changed with
* {@link MethodAppearanceDecision#setReplaceExistingProperty(boolean)}.
- * <li>Prevent the method to hide a JavaBean property (fake or real) of
+ * <li>Prevent the method to hide a JavaBeans property (fake or real) of
* the same name by calling
* {@link MethodAppearanceDecision#setMethodShadowsProperty(boolean)}
* with {@code false}. The default is {@code true}, so if you have
@@ -82,8 +85,8 @@
* of the property value, which is often undesirable.
* </ul>
*
- * <p>Note that you can expose a Java method both as a method and as a
- * JavaBean property on the same time, however you have to chose different
+ * <p>Note that you can expose a Java method both as a method, and as a
+ * JavaBeans property on the same time, however you have to chose different
* names for them to prevent shadowing.
*
* @param in Describes the method about which the decision will have to be made.
diff --git a/freemarker-core/src/main/java/freemarker/template/Configuration.java b/freemarker-core/src/main/java/freemarker/template/Configuration.java
index 331f5ae..97a22cb 100644
--- a/freemarker-core/src/main/java/freemarker/template/Configuration.java
+++ b/freemarker-core/src/main/java/freemarker/template/Configuration.java
@@ -491,7 +491,7 @@
public static final Version VERSION_2_3_32 = new Version(2, 3, 32);
/** FreeMarker version 2.3.33 (an {@link #Configuration(Version) incompatible improvements break-point}) */
- public static final Version VERSION_2_3_33 = new Version(2, 3, 32);
+ public static final Version VERSION_2_3_33 = new Version(2, 3, 33);
/** The default of {@link #getIncompatibleImprovements()}, currently {@link #VERSION_2_3_0}. */
public static final Version DEFAULT_INCOMPATIBLE_IMPROVEMENTS = Configuration.VERSION_2_3_0;
diff --git a/freemarker-core/src/main/java/freemarker/template/TemplateHashModel.java b/freemarker-core/src/main/java/freemarker/template/TemplateHashModel.java
index fb83bc4..91a5013 100644
--- a/freemarker-core/src/main/java/freemarker/template/TemplateHashModel.java
+++ b/freemarker-core/src/main/java/freemarker/template/TemplateHashModel.java
@@ -30,10 +30,11 @@
/**
* Gets a {@code TemplateModel} from the hash.
*
- * @param key the name by which the {@code TemplateModel}
- * is identified in the template.
- * @return the {@code TemplateModel} referred to by the key,
- * or null if not found.
+ * @param key
+ * The name by which the {@code TemplateModel} is identified in the template.
+ *
+ * @return
+ * The {@code TemplateModel} referred to by the key, or {@code null} if not found.
*/
TemplateModel get(String key) throws TemplateModelException;
diff --git a/freemarker-core/src/test/java/freemarker/test/TemplateTest.java b/freemarker-test-utils/src/main/java/freemarker/test/TemplateTest.java
similarity index 100%
rename from freemarker-core/src/test/java/freemarker/test/TemplateTest.java
rename to freemarker-test-utils/src/main/java/freemarker/test/TemplateTest.java