From a357f3a8609d93bc0ef7c04485b107676ca128bb Mon Sep 17 00:00:00 2001 From: trydofor Date: Wed, 15 Jan 2025 14:59:09 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20i18nString=20with=20cache=20#48?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pro/fessional/mirana/i18n/I18nAware.java | 22 +++++++++------- .../pro/fessional/mirana/i18n/I18nString.java | 26 ++++++++++++++++--- .../fessional/mirana/i18n/I18nStringTest.java | 12 ++++++--- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/main/java/pro/fessional/mirana/i18n/I18nAware.java b/src/main/java/pro/fessional/mirana/i18n/I18nAware.java index 2c8412b..d1f97e1 100644 --- a/src/main/java/pro/fessional/mirana/i18n/I18nAware.java +++ b/src/main/java/pro/fessional/mirana/i18n/I18nAware.java @@ -59,17 +59,8 @@ default I18nString toI18nString(String hint, Object... args) { return new I18nString(getI18nCode(), hint, args); } - /** - * use Locale.getDefault() if locale is null. - * return the i18nCode if message format get empty. - */ default String toString(Locale locale) { - return toString(locale, (code, args, hint, lang) -> { - if (hint == null || hint.isEmpty() || args == null || args.length == 0) return hint; - - return new MessageFormat(hint, lang == null ? Locale.getDefault() : lang) - .format(args); - }); + return toString(locale, I18nSource.Default); } /** @@ -94,6 +85,17 @@ default String toString(Locale locale, @NotNull I18nSource source) { @FunctionalInterface interface I18nSource { + + /** + * ignore i18nCode, format hint with args by MessageFormat. + */ + I18nSource Default = (ignoreCode, args, hint, lang) -> { + if (hint == null || hint.isEmpty()) return null; + if (args == null || args.length == 0) return hint; + if (lang == null) lang = Locale.getDefault(); + return new MessageFormat(hint, lang).format(args); + }; + /** *
          * should return null or code if template is not found by code.
diff --git a/src/main/java/pro/fessional/mirana/i18n/I18nString.java b/src/main/java/pro/fessional/mirana/i18n/I18nString.java
index 28446cb..b78d535 100644
--- a/src/main/java/pro/fessional/mirana/i18n/I18nString.java
+++ b/src/main/java/pro/fessional/mirana/i18n/I18nString.java
@@ -12,9 +12,10 @@
 /**
  * 
  * String can be used as i18n template (MessageFormat by default)
- * * i18nCode - template id, default empty
- * * i18nArgs - template arguments, default empty
- * * i18nHint - default text or template, not in hash and equals, default empty
+ * - i18nCode - template id, default empty
+ * - i18nArgs - template arguments, default empty
+ * - i18nHint - default text or template, not in hash and equals, default empty
+ * - i18nCache - cached value for performance
  * 
* * @author trydofor @@ -32,6 +33,8 @@ public class I18nString implements I18nAware { @NotNull private String i18nHint; + private transient String i18nCache = null; + public I18nString(String i18nCode) { this(i18nCode, "", EMPTY_ARGS); } @@ -80,12 +83,29 @@ public I18nString setI18nHint(@Nullable Locale locale, @NotNull I18nSource sourc return setI18nHint(toString(locale, source)); } + @Nullable + public String getI18nCache() { + return i18nCache; + } + + @Contract("_->this") + public I18nString setI18nCache(String i18nCache) { + this.i18nCache = i18nCache; + return this; + } + + @Contract("_,_->this") + public I18nString setI18nCache(@Nullable Locale locale, @NotNull I18nSource source) { + return setI18nCache(toString(locale, source)); + } + public boolean isEmpty() { return i18nCode.isEmpty(); } @Override public String toString() { + if (i18nCache != null) return i18nCache; return toString(Locale.getDefault()); } diff --git a/src/test/java/pro/fessional/mirana/i18n/I18nStringTest.java b/src/test/java/pro/fessional/mirana/i18n/I18nStringTest.java index 4b13b0c..cfc4be7 100644 --- a/src/test/java/pro/fessional/mirana/i18n/I18nStringTest.java +++ b/src/test/java/pro/fessional/mirana/i18n/I18nStringTest.java @@ -42,7 +42,7 @@ void testConstructorWithHint() { void testConstructorWithArgs() { I18nString i18nString = new I18nString("testCode", "testHint", "arg1", "arg2"); assertEquals("testCode", i18nString.getI18nCode()); - assertArrayEquals(new Object[]{"arg1", "arg2"}, i18nString.getI18nArgs()); + assertArrayEquals(new Object[]{ "arg1", "arg2" }, i18nString.getI18nArgs()); assertEquals("testHint", i18nString.getI18nHint()); } @@ -126,11 +126,15 @@ void testString() { assertEquals("name is ok", s1.toString(Locale.ENGLISH)); I18nString s2 = new I18nString("200", "{0} is ok", I18nString.of("name")); - final String str2 = s2.toString(Locale.ENGLISH, (code, args, hint, lang) -> { - if(code.equals("name")) return "trydofor"; + I18nAware.I18nSource i18nSource = (code, args, hint, lang) -> { + if (code.equals("name")) return "trydofor"; return new MessageFormat(hint, lang).format(args); - }); + }; + final String str2 = s2.toString(Locale.ENGLISH, i18nSource); assertEquals("trydofor is ok", str2); + s2.setI18nCache(Locale.ENGLISH, i18nSource); + assertEquals(str2, s2.getI18nCache()); + assertEquals(str2, s2.toString()); I18nString s3 = s1.toI18nString(); assertEquals(s1, s3);