ISIS-903: plural unit tests for PoReader now passing
Project: http://git-wip-us.apache.org/repos/asf/isis/repo Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/f690db38 Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/f690db38 Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/f690db38 Branch: refs/heads/master Commit: f690db38054a6d210f8d3fc9671e0a49b4fc1aa9 Parents: e083008 Author: Dan Haywood <[email protected]> Authored: Tue Feb 17 13:24:09 2015 +0000 Committer: Dan Haywood <[email protected]> Committed: Wed Feb 18 14:07:40 2015 +0000 ---------------------------------------------------------------------- .../services/i18n/TranslatableString.java | 150 +++++++++++-------- .../services/i18n/TranslationService.java | 1 - .../isis/applib/services/i18n/TrStringTest.java | 6 +- .../core/metamodel/services/i18n/po/Block.java | 14 +- .../services/i18n/po/ContextAndMsgId.java | 70 +++++++++ .../services/i18n/po/MsgIdAndContext.java | 70 --------- .../metamodel/services/i18n/po/PoReader.java | 14 +- 7 files changed, 173 insertions(+), 152 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/isis/blob/f690db38/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslatableString.java ---------------------------------------------------------------------- diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslatableString.java b/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslatableString.java index 75b1a6e..08870a4 100644 --- a/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslatableString.java +++ b/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslatableString.java @@ -28,7 +28,7 @@ import com.google.common.collect.Lists; public final class TranslatableString { - //region > tr, trn (factory methods) + //region > tr, trn (factory methods); constructor /** * A translatable string supporting both singular and plural forms. @@ -84,14 +84,44 @@ public final class TranslatableString { } return map; } + + private TranslatableString( + final Type type, + final String singularText, + final String pluralText, + final int number, + final Map<String, Object> argumentsByParameterName) { + + this.type = type; + this.singularText = singularText; + this.pluralText = pluralText; + this.number = number; + this.argumentsByParameterName = argumentsByParameterName; + } + //endregion + //region > singularText, pluralText, pluralForm - private final Type type; - private final String singularPattern; - private final String pluralPattern; - private final int number; - private final Map<String, Object> argumentsByParameterName; + private final String singularText; + private final String pluralText; + + /** + * The text as provided in (either of the {@link #tr(String, Object...) factory} {@link #trn(String, String, int, Object...) method}s, + * with placeholders rather than substituted arguments; if {@link #isPluralForm()} is <code>true</code> then used only + * for the singular form. + */ + String getSingularText() { + return singularText; + } + + /** + * The plural text as provided in the {@link #trn(String, String, int, Object...) factory method}, with placeholders + * rather than substituted arguments; but will be <code>null</code> if {@link #isPluralForm()} is <code>false</code>. + */ + String getPluralText() { + return pluralText; + } private enum Type { /** @@ -100,7 +130,7 @@ public final class TranslatableString { TR { @Override public String toString(final TranslatableString trString) { - return "tr: " + trString.singularPattern; + return "tr: " + trString.singularText; } }, /** @@ -109,44 +139,24 @@ public final class TranslatableString { TRN { @Override public String toString(final TranslatableString trString) { - return "trn: " + trString.pluralPattern; + return "trn: " + trString.pluralText; } }; public abstract String toString(final TranslatableString trString); } - private TranslatableString( - final Type type, - final String singularPattern, - final String pluralPattern, - final int number, - final Map<String, Object> argumentsByParameterName) { - - this.type = type; - this.singularPattern = singularPattern; - this.pluralPattern = pluralPattern; - this.number = number; - this.argumentsByParameterName = argumentsByParameterName; - } - /** - * The pattern (or the singular pattern if {@link #isPluralForm()} is <code>true</code>). - */ - String getSingularPattern() { - return singularPattern; - } - - /** - * The plural pattern (but will be <code>null</code> if {@link #isPluralForm()} is <code>false</code>). - */ - String getPluralPattern() { - return pluralPattern; - } + private final Type type; + private final int number; boolean isPluralForm() { return type == Type.TRN; } + //endregion + + //region > argumentsByParameterName + private final Map<String, Object> argumentsByParameterName; /** * The arguments; excluded from {@link #equals(Object)} comparison. @@ -154,40 +164,20 @@ public final class TranslatableString { Map<String, Object> getArgumentsByParameterName() { return argumentsByParameterName; } - - //region > equals, hashCode - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final TranslatableString that = (TranslatableString) o; - - if (pluralPattern != null ? !pluralPattern.equals(that.pluralPattern) : that.pluralPattern != null) - return false; - if (singularPattern != null ? !singularPattern.equals(that.singularPattern) : that.singularPattern != null) - return false; - if (type != that.type) return false; - - return true; - } - - @Override - public int hashCode() { - int result = type != null ? type.hashCode() : 0; - result = 31 * result + (singularPattern != null ? singularPattern.hashCode() : 0); - result = 31 * result + (pluralPattern != null ? pluralPattern.hashCode() : 0); - return result; - } - //endregion - //region > translate + /** + * Translates this string using the provided {@link org.apache.isis.applib.services.i18n.TranslationService}, selecting + * either the single or plural form as per {@link #getPattern()}. + * @param translationService + * @param context + * @param locale + * @return + */ public String translate(final TranslationService translationService, final String context, final Locale locale) { - final String translatedText = translationService.translate(context, getText(), locale); + final String translatedText = translationService.translate(context, getPattern(), locale); return translated(translatedText); } @@ -195,11 +185,11 @@ public final class TranslatableString { * The text to be translated; depends on whether {@link #isPluralForm()} and whether to be translated. * * <p> - * May or may not hold placeholders. + * Any placeholders will <i>not</i> have been replaced. * </p> */ - String getText() { - return !isPluralForm() || number == 1 ? getSingularPattern() : getPluralPattern(); + public String getPattern() { + return !isPluralForm() || number == 1 ? getSingularText() : getPluralText(); } String translated(final String translatedText) { @@ -232,9 +222,37 @@ public final class TranslatableString { //endregion + //region > equals, hashCode, toString + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final TranslatableString that = (TranslatableString) o; + + if (pluralText != null ? !pluralText.equals(that.pluralText) : that.pluralText != null) + return false; + if (singularText != null ? !singularText.equals(that.singularText) : that.singularText != null) + return false; + if (type != that.type) return false; + + return true; + } + + @Override + public int hashCode() { + int result = type != null ? type.hashCode() : 0; + result = 31 * result + (singularText != null ? singularText.hashCode() : 0); + result = 31 * result + (pluralText != null ? pluralText.hashCode() : 0); + return result; + } @Override public String toString() { return type.toString(this); } + + //endregion + } http://git-wip-us.apache.org/repos/asf/isis/blob/f690db38/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationService.java ---------------------------------------------------------------------- diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationService.java b/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationService.java index df182ad..dfad5ca 100644 --- a/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationService.java +++ b/core/applib/src/main/java/org/apache/isis/applib/services/i18n/TranslationService.java @@ -26,5 +26,4 @@ public interface TranslationService { @Programmatic public String translate(final String context, final String originalText, final Locale targetLocale); - } http://git-wip-us.apache.org/repos/asf/isis/blob/f690db38/core/applib/src/test/java/org/apache/isis/applib/services/i18n/TrStringTest.java ---------------------------------------------------------------------- diff --git a/core/applib/src/test/java/org/apache/isis/applib/services/i18n/TrStringTest.java b/core/applib/src/test/java/org/apache/isis/applib/services/i18n/TrStringTest.java index 3b801ad..953b6a5 100644 --- a/core/applib/src/test/java/org/apache/isis/applib/services/i18n/TrStringTest.java +++ b/core/applib/src/test/java/org/apache/isis/applib/services/i18n/TrStringTest.java @@ -17,21 +17,21 @@ public class TrStringTest { public void singularForm() throws Exception { final TranslatableString ts = TranslatableString.tr("No, you can't do that!"); - assertThat(ts.getText(), is("No, you can't do that!")); + assertThat(ts.getPattern(), is("No, you can't do that!")); } @Test public void pluralFormOne() throws Exception { final TranslatableString ts = TranslatableString.trn("You can't do that because there is a dependent object", "You can't do that because there are dependent objects", 1); - assertThat(ts.getText(), is("You can't do that because there is a dependent object")); + assertThat(ts.getPattern(), is("You can't do that because there is a dependent object")); } @Test public void pluralFormTwo() throws Exception { final TranslatableString ts = TranslatableString.trn("You can't do that because there is a dependent object", "You can't do that because there are dependent objects", 2); - assertThat(ts.getText(), is("You can't do that because there are dependent objects")); + assertThat(ts.getPattern(), is("You can't do that because there are dependent objects")); } } http://git-wip-us.apache.org/repos/asf/isis/blob/f690db38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/Block.java ---------------------------------------------------------------------- diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/Block.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/Block.java index 45af493..cdfbbd4 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/Block.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/Block.java @@ -31,7 +31,7 @@ class Block { String msgstr = null; // either from msgstr or msgstr[0] if there is a plural String msgstr_plural = null; // from msgstr[1] - Block parseLine(final String line, final Map<MsgIdAndContext, String> translationsByKey) { + Block parseLine(final String line, final Map<ContextAndMsgId, String> translationsByKey) { if (state == State.CONTEXT) { final Matcher contextMatcher = state.pattern.matcher(line); if (contextMatcher.matches()) { @@ -98,12 +98,16 @@ class Block { return this; } - void append(final Map<MsgIdAndContext, String> translationsByKey) { - if(msgid != null && msgstr != null) { - for (String context : contextList) { - final MsgIdAndContext mc = new MsgIdAndContext(msgid, context); + void append(final Map<ContextAndMsgId, String> translationsByKey) { + for (String context : contextList) { + if(msgid != null && msgstr != null) { + final ContextAndMsgId mc = new ContextAndMsgId(context, msgid); translationsByKey.put(mc, msgstr); } + if(msgid_plural != null && msgstr_plural != null) { + final ContextAndMsgId mc = new ContextAndMsgId(context, msgid_plural); + translationsByKey.put(mc, msgstr_plural); + } } } http://git-wip-us.apache.org/repos/asf/isis/blob/f690db38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/ContextAndMsgId.java ---------------------------------------------------------------------- diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/ContextAndMsgId.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/ContextAndMsgId.java new file mode 100644 index 0000000..1fbfd02 --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/ContextAndMsgId.java @@ -0,0 +1,70 @@ +package org.apache.isis.core.metamodel.services.i18n.po; + +/** + * The combination of a <tt>msgId</tt> and context (optionally null) that represents a key to a translatable resource. + * + * <p> + * For example, with this <i>.pot</i> file: + * </p> + * <pre> + * #: org.isisaddons.module.sessionlogger.dom.SessionLoggingServiceMenu#activeSessions() + msgid: "Active Sessions" + + #: org.isisaddons.module.audit.dom.AuditingServiceMenu + #: org.isisaddons.module.command.dom.CommandServiceMenu + #: org.isisaddons.module.publishing.dom.PublishingServiceMenu + msgid: "Activity" + + * </pre> + * + * <p> + * the combination of <code>{org.isisaddons.module.sessionlogger.dom.SessionLoggingServiceMenu#activeSessions(), "Active Sessions"}</code> represents such a key, as does <code>{org.isisaddons.module.audit.dom.AuditingServiceMenu, "Activity"}</code> + * </p> + */ +public class ContextAndMsgId implements Comparable<ContextAndMsgId> { + + private final String context; + private final String msgId; + + public ContextAndMsgId(final String context, final String msgId) { + this.msgId = msgId; + this.context = context == null? "": context; + } + + public String getMsgId() { + return msgId; + } + + public String getContext() { + return context; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final ContextAndMsgId that = (ContextAndMsgId) o; + + if (context != null ? !context.equals(that.context) : that.context != null) return false; + if (msgId != null ? !msgId.equals(that.msgId) : that.msgId != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = context != null ? context.hashCode() : 0; + result = 31 * result + (msgId != null ? msgId.hashCode() : 0); + return result; + } + + @Override + public int compareTo(final ContextAndMsgId o) { + final int i = msgId.compareTo(o.msgId); + if(i != 0) { + return i; + } + return context.compareTo(o.context); + } +} http://git-wip-us.apache.org/repos/asf/isis/blob/f690db38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/MsgIdAndContext.java ---------------------------------------------------------------------- diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/MsgIdAndContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/MsgIdAndContext.java deleted file mode 100644 index f7fbd65..0000000 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/MsgIdAndContext.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.apache.isis.core.metamodel.services.i18n.po; - -/** - * The combination of a <tt>msgId</tt> and context (optionally null) that represents a key to a translatable resource. - * - * <p> - * For example, with this <i>.pot</i> file: - * </p> - * <pre> - * #: org.isisaddons.module.sessionlogger.dom.SessionLoggingServiceMenu#activeSessions() - msgid: "Active Sessions" - - #: org.isisaddons.module.audit.dom.AuditingServiceMenu - #: org.isisaddons.module.command.dom.CommandServiceMenu - #: org.isisaddons.module.publishing.dom.PublishingServiceMenu - msgid: "Activity" - - * </pre> - * - * <p> - * the combination of <code>{org.isisaddons.module.sessionlogger.dom.SessionLoggingServiceMenu#activeSessions(), "Active Sessions"}</code> represents such a key, as does <code>{org.isisaddons.module.audit.dom.AuditingServiceMenu, "Activity"}</code> - * </p> - */ -public class MsgIdAndContext implements Comparable<MsgIdAndContext> { - - private final String context; - private final String msgId; - - public MsgIdAndContext(final String msgId, final String context) { - this.msgId = msgId; - this.context = context == null? "": context; - } - - public String getMsgId() { - return msgId; - } - - public String getContext() { - return context; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final MsgIdAndContext that = (MsgIdAndContext) o; - - if (context != null ? !context.equals(that.context) : that.context != null) return false; - if (msgId != null ? !msgId.equals(that.msgId) : that.msgId != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = context != null ? context.hashCode() : 0; - result = 31 * result + (msgId != null ? msgId.hashCode() : 0); - return result; - } - - @Override - public int compareTo(final MsgIdAndContext o) { - final int i = msgId.compareTo(o.msgId); - if(i != 0) { - return i; - } - return context.compareTo(o.context); - } -} http://git-wip-us.apache.org/repos/asf/isis/blob/f690db38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java ---------------------------------------------------------------------- diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java index 83806e6..b6b4ddf 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/i18n/po/PoReader.java @@ -33,7 +33,7 @@ class PoReader extends PoAbstract { public static final String LOCATION_BASE_URL = "isis.services.translation.po.locationBaseUrl"; public static Logger LOG = LoggerFactory.getLogger(PoReader.class); - private final Map<Locale, Map<MsgIdAndContext, String>> translationByKeyByLocale = Maps.newHashMap(); + private final Map<Locale, Map<ContextAndMsgId, String>> translationByKeyByLocale = Maps.newHashMap(); /** * The basename of the translations file, hard-coded to <tt>translations</tt>. @@ -67,15 +67,15 @@ class PoReader extends PoAbstract { public String translate(final String context, final String msgId, final Locale targetLocale) { - final Map<MsgIdAndContext, String> translationsByKey = readAndCacheTranslationsIfRequired(targetLocale); + final Map<ContextAndMsgId, String> translationsByKey = readAndCacheTranslationsIfRequired(targetLocale); - final MsgIdAndContext key = new MsgIdAndContext(msgId, context); + final ContextAndMsgId key = new ContextAndMsgId(context, msgId); final String translation = translationsByKey.get(key); if (translation != null) { return translation; } - final MsgIdAndContext keyNoContext = new MsgIdAndContext(msgId, ""); + final ContextAndMsgId keyNoContext = new ContextAndMsgId("", msgId); final String translationNoContext = translationsByKey.get(keyNoContext); if (translationNoContext != null) { return translationNoContext; @@ -85,8 +85,8 @@ class PoReader extends PoAbstract { return msgId; } - private Map<MsgIdAndContext, String> readAndCacheTranslationsIfRequired(final Locale locale) { - Map<MsgIdAndContext, String> translationsByKey = translationByKeyByLocale.get(locale); + private Map<ContextAndMsgId, String> readAndCacheTranslationsIfRequired(final Locale locale) { + Map<ContextAndMsgId, String> translationsByKey = translationByKeyByLocale.get(locale); if(translationsByKey != null) { return translationsByKey; } @@ -103,7 +103,7 @@ class PoReader extends PoAbstract { * @param locale - the .po file to load * @param translationsByKey - the translations to be populated */ - private void read(final Locale locale, final Map<MsgIdAndContext, String> translationsByKey) { + private void read(final Locale locale, final Map<ContextAndMsgId, String> translationsByKey) { final List<String> contents = readPo(locale); Block block = new Block();
