You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by di...@apache.org on 2021/07/23 10:32:04 UTC
[sling-org-apache-sling-scripting-sightly] 02/02: Merge branch
'master' into issue/SLING-10654
This is an automated email from the ASF dual-hosted git repository.
diru pushed a commit to branch issue/SLING-10654
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly.git
commit 2603a64365291ea722b6e36be96514246da70b0a
Merge: 474697c e6acc53
Author: Dirk Rudolph <dr...@adobe.com>
AuthorDate: Fri Jul 23 12:31:44 2021 +0200
Merge branch 'master' into issue/SLING-10654
pom.xml | 37 +++---
.../engine/extension/FormatFilterExtension.java | 80 +++++-------
.../extension/FormatFilterExtensionTest.java | 145 ++++++++++++++++++++-
3 files changed, 199 insertions(+), 63 deletions(-)
diff --cc src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java
index f7cf405,ff438de..6ec400e
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java
@@@ -55,25 -60,6 +62,9 @@@ public class FormatFilterExtension impl
private static final Logger LOG = LoggerFactory.getLogger(FormatFilterExtension.class);
private static final Pattern PLACEHOLDER_REGEX = Pattern.compile("\\{\\d+}");
+ private static final Pattern COMPLEX_PLACEHOLDER_REGEX = Pattern.compile("\\{\\d+,[^}]+}");
- private static final String FORMAT_OPTION = "format";
- private static final String TYPE_OPTION = "type";
- private static final String LOCALE_OPTION = "locale";
- private static final String TIMEZONE_OPTION = "timezone";
-
- private static final String DATE_FORMAT_TYPE = "date";
- private static final String NUMBER_FORMAT_TYPE = "number";
- private static final String STRING_FORMAT_TYPE = "string";
+
- static {
- try {
- FormatFilterExtension.class.getClassLoader().loadClass("com.ibm.icu.text.MessageFormat");
- hasIcuSupport = true;
- } catch (ClassNotFoundException ex) {
- LOG.trace("Initialize without ICU support: {}", ex.getMessage(), ex);
- hasIcuSupport = false;
- }
- }
++ private boolean hasIcuSupport = true;
@Override
public Object call(final RenderContext renderContext, Object... arguments) {
@@@ -100,14 -79,15 +91,15 @@@
return getNumberFormattedString(runtimeObjectModel, source, options, formatObject);
}
if (hasPlaceHolders) {
- return getFormattedString(runtimeObjectModel, source, formatObject);
+ return getFormattedString(runtimeObjectModel, source, options, formatObject, hasComplexPlaceholders);
}
+
try {
- // somebody will hate me for this
- new SimpleDateFormat(source);
+ // try to parse as DateTimeFormatter
+ DateTimeFormatter.ofPattern(source);
return getDateFormattedString(runtimeObjectModel, source, options, formatObject);
- } catch (IllegalArgumentException e) {
- // ignore
+ } catch (IllegalArgumentException ex) {
+ LOG.trace("Not a datetime format: {}", source, ex);
}
try {
// for this too, but such is life
diff --cc src/test/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtensionTest.java
index 63fd1e9,f168883..76f5c63
--- a/src/test/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtensionTest.java
+++ b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtensionTest.java
@@@ -18,8 -18,12 +18,13 @@@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.engine.extension;
+ import java.time.LocalDateTime;
+ import java.time.ZoneId;
+import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.Date;
import java.util.HashMap;
+ import java.util.Map;
import javax.script.Bindings;
import javax.script.SimpleBindings;
@@@ -29,9 -34,10 +35,12 @@@ import org.apache.sling.scripting.sight
import org.apache.sling.scripting.sightly.render.RuntimeObjectModel;
import org.junit.Test;
+import com.google.common.collect.ImmutableMap;
+
+ import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertEquals;
+ import static org.junit.Assert.assertNull;
+ import static org.junit.Assume.assumeThat;
public class FormatFilterExtensionTest {
@@@ -50,30 -56,134 +59,160 @@@
}
};
private final FormatFilterExtension subject = new FormatFilterExtension();
+ private final Date testDate = Date.from(LocalDateTime.of(1918, 12, 1, 0, 0, 0, 0)
+ .atZone(ZoneId.of("UTC"))
+ .toInstant());
+
+ @Test
+ public void testDateFormatNull() {
+ assertNull(subject.call(renderContext, "default", new HashMap<String, Object>() {{
+ put(FormatFilterExtension.TYPE_OPTION, "date");
+ put(FormatFilterExtension.FORMAT, null);
+ }}));
+ }
+
+ @Test
+ public void testDateFormatNoDateObject() {
+ assertNull(subject.call(renderContext, "yyyy-MM-dd", Collections.singletonMap(FormatFilterExtension.FORMAT, new Object())));
+ }
+
+ @Test(expected = SightlyException.class)
+ public void testDateFormatFalseFormat() {
+ assertDate(null, "yT", null, null);
+ }
+
+ @Test
+ public void testDateFormatWithUTC() {
+ assertDate("1918-12-01 00:00:00.000Z", "yyyy-MM-dd HH:mm:ss.SSSXXX", "UTC", null);
+ }
+
+ @Test
+ public void testDateFormatWithZoneOffset() {
+ assertDate("1918-12-01 02:00:00.000+02:00", "yyyy-MM-dd HH:mm:ss.SSSXXX", "GMT+02:00", null);
+ }
+
+ @Test
+ public void testDateFormatWithZoneOffsetRFC822() {
+ assertDate("1918-12-01 02:00:00.000+0200", "yyyy-MM-dd HH:mm:ss.SSSZ", "GMT+02:00", null);
+ }
+
+ @Test
+ public void testDateFormatWithZoneName() {
+ assertDate("1918-12-01 02:00:00.000(GMT+02:00)", "yyyy-MM-dd HH:mm:ss.SSS(z)", "GMT+02:00", null);
+ }
+
+ /**
+ * When using jdk9 or newer, make sure to set the {@code java.locale.providers = COMPAT,SPI}
+ *
+ * @see <a href="https://docs.oracle.com/javase/9/docs/api/java/util/spi/LocaleServiceProvider.html">LocaleServiceProvider</a>
+ */
+ @Test
+ public void testDateFormatWithEscapedCharacters() {
+ assumeJdk8LocaleData();
+ assertDate("01 December '18 12:00 AM; day in year: 335; week in year: 49",
+ "dd MMMM ''yy hh:mm a; 'day in year': D; 'week in year': w",
+ "UTC",
+ null);
+ }
+
+ /**
+ * When using jdk9 or newer, make sure to set the {@code java.locale.providers = COMPAT,SPI}
+ *
+ * @see <a href="https://docs.oracle.com/javase/9/docs/api/java/util/spi/LocaleServiceProvider.html">LocaleServiceProvider</a>
+ */
+ @Test
+ public void testDateFormatWithLocale() {
+ assumeJdk8LocaleData();
+ assertDate("Sonntag, 1 Dez 1918", "EEEE, d MMM y", "UTC", "de");
+ }
+
+ /**
+ * When using jdk9 or newer, make sure to set the {@code java.locale.providers = COMPAT,SPI}
+ *
+ * @see <a href="https://docs.oracle.com/javase/9/docs/api/java/util/spi/LocaleServiceProvider.html">LocaleServiceProvider</a>
+ */
+ @Test
+ public void testDateFormatWithFormatStyleShort() {
+ assumeJdk8LocaleData();
+ assertDate("01/12/18", "short", "GMT+02:00", "fr");
+ }
+
+ @Test
+ public void testDateFormatWithFormatStyleMedium() {
+ assertDate("1 déc. 1918", "medium", "GMT+02:00", "fr");
+ }
+
+ @Test
+ public void testDateFormatWithFormatStyleDefault() {
+ assertDate("1 déc. 1918", "default", "GMT+02:00", "fr");
+ }
+
+ @Test
+ public void testDateFormatWithFormatStyleLong() {
+ assertDate("1 décembre 1918", "long", "GMT+02:00", "fr");
+ }
+
+ @Test
+ public void testDateFormatWithFormatStyleFull() {
+ assertDate("dimanche 1 décembre 1918", "full", "GMT+02:00", "fr");
+ }
+
+ @Test
+ public void testDateFormatMixedWithReservedCharacters() {
+ assertEquals("#1: 1918 {0}", subject.call(renderContext, "#1: yyyy {0}", new HashMap<String, Object>() {{
+ put(FormatFilterExtension.TYPE_OPTION, FormatFilterExtension.DATE_FORMAT_TYPE);
+ put(FormatFilterExtension.FORMAT_OPTION, testDate);
+ }}));
+ }
+
+ @Test
+ public void testDateFormatNoNarrowForm() {
+ assertDate("December", "MMMMM", "UTC", "en");
+ assertDate("Sunday", "EEEEE", "UTC", "en");
+ assertDate("Sonntag", "eeeee", "UTC", "de");
+ }
+
+ private void assumeJdk8LocaleData() {
+ if(!System.getProperty("java.version").startsWith("1.8")) {
+ assumeThat(System.getProperty("java.locale.providers"), startsWith("COMPAT"));
+ }
+ }
+
+ private void assertDate(String expected, String format, String timezone, String locale) {
+ Map<String, Object> options = new HashMap<>();
+ options.put(FormatFilterExtension.FORMAT, testDate);
+ if (timezone != null) {
+ options.put(FormatFilterExtension.TIMEZONE_OPTION, timezone);
+ }
+ if (locale != null) {
+ options.put(FormatFilterExtension.LOCALE_OPTION, locale);
+ }
+ assertEquals(expected, subject.call(renderContext, format, options));
+ }
-}
+
+ @Test
+ public void testSimpleFormat() {
+ Object result = subject.call(renderContext,
- "This {0} a {1} format", ImmutableMap.of("format", Arrays.asList("is", "simple")));
++ "This {0} a {1} format", Collections.singletonMap("format", Arrays.asList("is", "simple")));
+ assertEquals("This is a simple format", result);
+ }
+
+ @Test
+ public void testComplexFormatNoSimplePlaceholderWithLocale() {
+ Object result = subject.call(renderContext,
+ "This query has {0,plural,zero {# results} one {# result} other {# results}}",
+ new HashMap<String, Object>() {{
- put("format", Arrays.asList(7));
++ put("format", Collections.singletonList(7));
+ put("locale", "en_US");
+ }});
+ assertEquals("This query has 7 results", result);
+ }
+
+ @Test
+ public void testComplexFormatWithSimplePlaceholderNoLocale() {
+ Object result = subject.call(renderContext,
+ "This {0} has {1,plural,zero {# results} one {# result} other {# results}}",
- ImmutableMap.of("format", Arrays.asList("query", 7)));
++ Collections.singletonMap("format", Arrays.asList("query", 7)));
+ assertEquals("This query has 7 results", result);
+ }
+}