freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [3/3] incubator-freemarker git commit: Forward ported from 2.3-gae:
Date Tue, 14 Mar 2017 20:48:28 GMT
Forward ported from 2.3-gae:

Added Configuration.isXxxExplictlySet and Configuration.unsetXxx methods for the Configuration
settings: locale, time_zone, default_encoding. (This can be utilized in frameworks to detect
if the application has missed setting these. The backward compatible default values are often
unwanted, as they are the default locale, time zone and file encoding of the Java environment.)

The locale and default_encoding configuration settings now supports the special "JVM default"
value when set from Java .properties file, or via Configuration.setSettings(Properties), or
via the #setting directive. Earlier only the time_zone setting has supported this value.

Ensure that the configuration settings don't depend on the machine that runs the test.


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/755b25a3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/755b25a3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/755b25a3

Branch: refs/heads/3
Commit: 755b25a3e1d6e0c0363609d9a73ba80210df2e81
Parents: 98fd94e
Author: ddekany <ddekany@apache.org>
Authored: Tue Mar 14 21:47:29 2017 +0100
Committer: ddekany <ddekany@apache.org>
Committed: Tue Mar 14 21:48:17 2017 +0100

----------------------------------------------------------------------
 .../apache/freemarker/core/Configurable.java    |  22 ++--
 .../apache/freemarker/core/Configuration.java   | 118 +++++++++++++++++--
 .../freemarker/core/ConfigurationTest.java      |  65 +++++++++-
 .../apache/freemarker/core/SQLTimeZoneTest.java |   2 +
 .../apache/freemarker/test/TemplateTest.java    |  18 +++
 5 files changed, 204 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/755b25a3/src/main/java/org/apache/freemarker/core/Configurable.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/Configurable.java b/src/main/java/org/apache/freemarker/core/Configurable.java
index 122a3c0..c2aeb85 100644
--- a/src/main/java/org/apache/freemarker/core/Configurable.java
+++ b/src/main/java/org/apache/freemarker/core/Configurable.java
@@ -91,9 +91,9 @@ import org.apache.freemarker.core.valueformat.TemplateNumberFormatFactory;
 public class Configurable {
     static final String C_TRUE_FALSE = "true,false";
     
-    private static final String NULL = "null";
-    private static final String DEFAULT = "default";
-    private static final String JVM_DEFAULT = "JVM default";
+    static final String NULL = "null";
+    static final String DEFAULT = "default";
+    static final String JVM_DEFAULT = "JVM default";
     
     /** Legacy, snake case ({@code like_this}) variation of the setting name. @since 2.3.23
*/
     public static final String LOCALE_KEY_SNAKE_CASE = "locale";
@@ -361,8 +361,8 @@ public class Configurable {
     protected Configurable(Version incompatibleImprovements) {
         _CoreAPI.checkVersionNotNullAndSupported(incompatibleImprovements);
         parent = null;
-        locale = Locale.getDefault();
-        timeZone = TimeZone.getDefault();
+        locale = Configuration.getDefaultLocale();
+        timeZone = Configuration.getDefaultTimeZone();
         sqlDataAndTimeTimeZone = null;
         numberFormat = "number";
         timeFormat = "";
@@ -1769,7 +1769,8 @@ public class Configurable {
      * <ul>
      *   <li><p>{@code "locale"}:
      *       See {@link #setLocale(Locale)}.
-     *       <br>String value: local codes with the usual format in Java, such as {@code
"en_US"}.
+     *       <br>String value: local codes with the usual format in Java, such as {@code
"en_US"}, or
+     *       "JVM default" (ignoring case) to use the default locale of the Java environment.
      *
      *   <li><p>{@code "custom_number_formats"}: See {@link #setCustomNumberFormats(Map)}.
      *   <br>String value: Interpreted as an <a href="#fm_obe">object builder
expression</a>.
@@ -1943,7 +1944,8 @@ public class Configurable {
      *       {@code "disable"} for {@link Configuration#DISABLE_AUTO_ESCAPING_POLICY}.
      *       
      *   <li><p>{@code "default_encoding"}:
-     *       See {@link Configuration#setDefaultEncoding(String)}.
+     *       See {@link Configuration#setDefaultEncoding(String)}; since 2.3.26 also accepts
value "JVM default"
+     *       (not case sensitive) to set the Java environment default value.
      *       <br>As the default value is the system default, which can change
      *       from one server to another, <b>you should always set this!</b>
      *       
@@ -2136,7 +2138,11 @@ public class Configurable {
         boolean unknown = false;
         try {
             if (LOCALE_KEY.equals(name)) {
-                setLocale(_StringUtil.deduceLocale(value));
+                if (JVM_DEFAULT.equalsIgnoreCase(value)) {
+                    setLocale(Locale.getDefault());
+                } else {
+                    setLocale(_StringUtil.deduceLocale(value));
+                }
             } else if (NUMBER_FORMAT_KEY_SNAKE_CASE.equals(name) || NUMBER_FORMAT_KEY_CAMEL_CASE.equals(name))
{
                 setNumberFormat(value);
             } else if (CUSTOM_NUMBER_FORMATS_KEY_SNAKE_CASE.equals(name)

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/755b25a3/src/main/java/org/apache/freemarker/core/Configuration.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/core/Configuration.java b/src/main/java/org/apache/freemarker/core/Configuration.java
index 4bf2eae..73e85f1 100644
--- a/src/main/java/org/apache/freemarker/core/Configuration.java
+++ b/src/main/java/org/apache/freemarker/core/Configuration.java
@@ -354,9 +354,6 @@ public class Configuration extends Configurable implements Cloneable,
ParserConf
     /** The default of {@link #getIncompatibleImprovements()}, currently {@link #VERSION_3_0_0}.
*/
     public static final Version DEFAULT_INCOMPATIBLE_IMPROVEMENTS = Configuration.VERSION_3_0_0;
     
-    private static final String NULL = "null";
-    private static final String DEFAULT = "default";
-    
     private static final Version VERSION;
     static {
         try {
@@ -418,7 +415,10 @@ public class Configuration extends Configurable implements Cloneable,
ParserConf
     private boolean objectWrapperExplicitlySet;
     private boolean templateExceptionHandlerExplicitlySet;
     private boolean logTemplateExceptionsExplicitlySet;
-    
+    private boolean localeExplicitlySet;
+    private boolean defaultEncodingExplicitlySet;
+    private boolean timeZoneExplicitlySet;
+
     private HashMap/*<String, TemplateModel>*/ sharedVariables = new HashMap();
 
     /**
@@ -428,7 +428,7 @@ public class Configuration extends Configurable implements Cloneable,
ParserConf
      */
     private HashMap<String, Object> rewrappableSharedVariables = null;
     
-    private String defaultEncoding = _SecurityUtil.getSystemProperty("file.encoding", "utf-8");
+    private String defaultEncoding = getDefaultDefaultEncoding();
     private ConcurrentMap localeToCharsetMap = new ConcurrentHashMap();
     
     /**
@@ -491,11 +491,6 @@ public class Configuration extends Configurable implements Cloneable,
ParserConf
         loadBuiltInSharedVariables();
     }
 
-    @Override
-    public void setTimeZone(TimeZone timeZone) {
-        super.setTimeZone(timeZone);
-    }
-
     private void createTemplateResolver() {
         templateResolver = new DefaultTemplateResolver(
                 null,
@@ -1123,7 +1118,71 @@ public class Configuration extends Configurable implements Cloneable,
ParserConf
     public boolean isObjectWrapperExplicitlySet() {
         return objectWrapperExplicitlySet;
     }
-    
+
+    @Override
+    public void setLocale(Locale locale) {
+        super.setLocale(locale);
+        localeExplicitlySet = true;
+    }
+
+    /**
+     * Resets the setting to its default, as if it was never set.
+     *
+     * @since 2.3.26
+     */
+    public void unsetLocale() {
+        if (localeExplicitlySet) {
+            setLocale(getDefaultLocale());
+            localeExplicitlySet = false;
+        }
+    }
+
+    /**
+     * Tells if {@link #setLocale(Locale)} (or equivalent) was already called on this instance,
or it just holds the
+     * default value.
+     *
+     * @since 2.3.26
+     */
+    public boolean isLocaleExplicitlySet() {
+        return localeExplicitlySet;
+    }
+
+    static Locale getDefaultLocale() {
+        return Locale.getDefault();
+    }
+
+    @Override
+    public void setTimeZone(TimeZone timeZone) {
+        super.setTimeZone(timeZone);
+        timeZoneExplicitlySet = true;
+    }
+
+    /**
+     * Resets the setting to its default, as if it was never set.
+     *
+     * @since 2.3.26
+     */
+    public void unsetTimeZone() {
+        if (timeZoneExplicitlySet) {
+            setTimeZone(getDefaultTimeZone());
+            timeZoneExplicitlySet = false;
+        }
+    }
+
+    /**
+     * Tells if {@link #setTimeZone(TimeZone)} (or equivalent) was already called on this
instance, or it just holds the
+     * default value.
+     *
+     * @since 2.3.26
+     */
+    public boolean isTimeZoneExplicitlySet() {
+        return timeZoneExplicitlySet;
+    }
+
+    static TimeZone getDefaultTimeZone() {
+        return TimeZone.getDefault();
+    }
+
     @Override
     public void setTemplateExceptionHandler(TemplateExceptionHandler templateExceptionHandler)
{
         super.setTemplateExceptionHandler(templateExceptionHandler);
@@ -2056,6 +2115,7 @@ public class Configuration extends Configurable implements Cloneable,
ParserConf
      */
     public void setDefaultEncoding(String encoding) {
         defaultEncoding = encoding;
+        defaultEncodingExplicitlySet = true;
     }
 
     /**
@@ -2068,6 +2128,36 @@ public class Configuration extends Configurable implements Cloneable,
ParserConf
     }
 
     /**
+     * Resets the setting to its default, as if it was never set.
+     *
+     * @since 2.3.26
+     */
+    public void unsetDefaultEncoding() {
+        if (defaultEncodingExplicitlySet) {
+            setDefaultEncoding(getDefaultDefaultEncoding());
+            defaultEncodingExplicitlySet = false;
+        }
+    }
+
+    /**
+     * Tells if {@link #setDefaultEncoding(String)} (or equivalent) was already called on
this instance, or it just holds the
+     * default value.
+     *
+     * @since 2.3.26
+     */
+    public boolean isDefaultEncodingExplicitlySet() {
+        return defaultEncodingExplicitlySet;
+    }
+
+    static private String getDefaultDefaultEncoding() {
+        return getJVMDefaultEncoding();
+    }
+
+    static private String getJVMDefaultEncoding() {
+        return _SecurityUtil.getSystemProperty("file.encoding", "utf-8");
+    }
+
+    /**
      * Gets the preferred character encoding for the given locale, or the 
      * default encoding if no encoding is set explicitly for the specified
      * locale. You can associate encodings with locales using 
@@ -2366,7 +2456,11 @@ public class Configuration extends Configurable implements Cloneable,
ParserConf
             }
             
             if (DEFAULT_ENCODING_KEY_SNAKE_CASE.equals(name) || DEFAULT_ENCODING_KEY_CAMEL_CASE.equals(name))
{
-                setDefaultEncoding(value);
+                if (JVM_DEFAULT.equalsIgnoreCase(value)) {
+                    setDefaultEncoding(getJVMDefaultEncoding());
+                } else {
+                    setDefaultEncoding(value);
+                }
             } else if (LOCALIZED_LOOKUP_KEY_SNAKE_CASE.equals(name) || LOCALIZED_LOOKUP_KEY_CAMEL_CASE.equals(name))
{
                 setLocalizedLookup(_StringUtil.getYesNo(value));
             } else if (WHITESPACE_STRIPPING_KEY_SNAKE_CASE.equals(name)

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/755b25a3/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
index c1650ec..0ad4773 100644
--- a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
+++ b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
@@ -1460,7 +1460,70 @@ public class ConfigurationTest extends TestCase {
         assertNull(cfg.getLazyAutoImports());
         assertTrue(cfg.isLazyAutoImportsSet());
     }
-    
+
+    public void testLocaleSetting() throws TemplateException, ConfigurationException {
+        Configuration cfg = new Configuration(Configuration.VERSION_3_0_0);
+
+        assertEquals(Locale.getDefault(), cfg.getLocale());
+        assertFalse(cfg.isLocaleExplicitlySet());
+
+        Locale nonDefault = Locale.getDefault().equals(Locale.GERMANY) ? Locale.FRANCE :
Locale.GERMANY;
+        cfg.setLocale(nonDefault);
+        assertTrue(cfg.isLocaleExplicitlySet());
+        assertEquals(nonDefault, cfg.getLocale());
+
+        cfg.unsetLocale();
+        assertEquals(Locale.getDefault(), cfg.getLocale());
+        assertFalse(cfg.isLocaleExplicitlySet());
+
+        cfg.setSetting(Configuration.LOCALE_KEY, "JVM default");
+        assertEquals(Locale.getDefault(), cfg.getLocale());
+        assertTrue(cfg.isLocaleExplicitlySet());
+    }
+
+    public void testDefaultEncodingSetting() throws TemplateException, ConfigurationException
{
+        Configuration cfg = new Configuration(Configuration.VERSION_3_0_0);
+
+        String defaultFileEncoding = System.getProperty("file.encoding");
+        assertNotNull(defaultFileEncoding);
+
+        assertEquals(defaultFileEncoding, cfg.getDefaultEncoding());
+        assertFalse(cfg.isDefaultEncodingExplicitlySet());
+
+        String nonDefault = defaultFileEncoding.equalsIgnoreCase("UTF-8") ? "ISO-8859-1"
: "UTF-8";
+        cfg.setDefaultEncoding(nonDefault);
+        assertTrue(cfg.isDefaultEncodingExplicitlySet());
+        assertEquals(nonDefault, cfg.getDefaultEncoding());
+
+        cfg.unsetDefaultEncoding();
+        assertEquals(defaultFileEncoding, cfg.getDefaultEncoding());
+        assertFalse(cfg.isDefaultEncodingExplicitlySet());
+
+        cfg.setSetting(Configuration.DEFAULT_ENCODING_KEY, "JVM default");
+        assertEquals(defaultFileEncoding, cfg.getDefaultEncoding());
+        assertTrue(cfg.isDefaultEncodingExplicitlySet());
+    }
+
+    public void testTimeZoneSetting() throws TemplateException, ConfigurationException {
+        Configuration cfg = new Configuration(Configuration.VERSION_3_0_0);
+
+        assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
+        assertFalse(cfg.isTimeZoneExplicitlySet());
+
+        TimeZone nonDefault = TimeZone.getDefault().equals(_DateUtil.UTC) ? TimeZone.getTimeZone("PST")
: _DateUtil.UTC;
+        cfg.setTimeZone(nonDefault);
+        assertTrue(cfg.isTimeZoneExplicitlySet());
+        assertEquals(nonDefault, cfg.getTimeZone());
+
+        cfg.unsetTimeZone();
+        assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
+        assertFalse(cfg.isTimeZoneExplicitlySet());
+
+        cfg.setSetting(Configuration.TIME_ZONE_KEY, "JVM default");
+        assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
+        assertTrue(cfg.isTimeZoneExplicitlySet());
+    }
+
     @Test
     public void testGetSettingNamesAreSorted() throws Exception {
         Configuration cfg = new Configuration(Configuration.VERSION_3_0_0);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/755b25a3/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java b/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
index 9ade361..aae82f6 100644
--- a/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
+++ b/src/test/java/org/apache/freemarker/core/SQLTimeZoneTest.java
@@ -133,6 +133,7 @@ public class SQLTimeZoneTest extends TemplateTest {
         TimeZone.setDefault(GMT_P02);
         try {
             Configuration cfg = getConfiguration();
+            cfg.unsetTimeZone();
             assertNull(cfg.getSQLDateAndTimeTimeZone());
             assertEquals(TimeZone.getDefault(), cfg.getTimeZone());
             
@@ -148,6 +149,7 @@ public class SQLTimeZoneTest extends TemplateTest {
         TimeZone.setDefault(GMT_P02);
         try {
             Configuration cfg = getConfiguration();
+            cfg.unsetTimeZone();
             cfg.setSQLDateAndTimeTimeZone(GMT_P02);
             
             assertOutput(FTL, OUTPUT_BEFORE_SETTING_GMT_CFG_GMT2 + OUTPUT_AFTER_SETTING_GMT_CFG_SQL_DIFFERENT);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/755b25a3/src/test/java/org/apache/freemarker/test/TemplateTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/test/TemplateTest.java b/src/test/java/org/apache/freemarker/test/TemplateTest.java
index 769ea16..d2eeb72 100644
--- a/src/test/java/org/apache/freemarker/test/TemplateTest.java
+++ b/src/test/java/org/apache/freemarker/test/TemplateTest.java
@@ -28,7 +28,9 @@ import java.io.StringWriter;
 import java.nio.charset.StandardCharsets;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
+import java.util.TimeZone;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.freemarker.core.Configuration;
@@ -60,6 +62,7 @@ public abstract class TemplateTest {
             try {
                 configuration = createConfiguration();
                 addCommonTemplates();
+                applyEnvironmentIndependentDefaults();
             } catch (Exception e) {
                 throw new RuntimeException("Failed to set up configuration for the test",
e);
             }
@@ -67,6 +70,21 @@ public abstract class TemplateTest {
         return configuration;
     }
 
+    /**
+     * Ensure that the configuration settings don't depend on the machine that runs the test.
+     */
+    private void applyEnvironmentIndependentDefaults() {
+        if (!configuration.isLocaleExplicitlySet()) {
+            configuration.setLocale(Locale.US);
+        }
+        if (!configuration.isDefaultEncodingExplicitlySet()) {
+            configuration.setDefaultEncoding(StandardCharsets.UTF_8.name());
+        }
+        if (!configuration.isTimeZoneExplicitlySet()) {
+            configuration.setTimeZone(TimeZone.getTimeZone("GMT+1"));
+        }
+    }
+
     protected final void setConfiguration(Configuration configuration) {
         this.configuration = configuration;
     }


Mime
View raw message