From 89ad3c36cfa0ca6841c4819a75694a0466cf6b67 Mon Sep 17 00:00:00 2001 From: Steve Kashishian Date: Wed, 16 Jan 2019 17:20:36 +0100 Subject: [PATCH 1/2] [localization] initial fallback implementation --- .../localization/LocalizationPlugin.java | 17 ++++++---- .../plugins/localization/MapLocale.java | 33 +++++++++++++++++-- .../localization/LocalizationPluginTest.java | 2 +- .../plugins/localization/MapLocaleTest.java | 13 +++++++- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java index 01fb47a76..6edb731a4 100644 --- a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java +++ b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java @@ -27,8 +27,8 @@ /** * Useful class for quickly adjusting the maps language and the maps camera starting position. - * You can either use {@link #matchMapLanguageWithDeviceDefault()} to match the map language with - * the one being currently used on the device. Using {@link #setMapLanguage(Locale)} and it's + * You can either use {@link #matchMapLanguageWithDeviceDefault(boolean acceptFallback)} to match the map language with + * the one being currently used on the device. Using {@link #setMapLanguage(Locale,boolean acceptFallback)} and it's * variants, you can also change the maps language at anytime to any of the supported languages. *

* The plugin uses a fallback logic in case there are missing resources @@ -139,10 +139,12 @@ public void onStyleLoaded(@NonNull Style style) { * Initializing this class and then calling this method oftentimes will be the only thing you'll * need to quickly adjust the map language to the devices specified language. * + * @param acceptFallback whether a fallback to a language default is desired + * * @since 0.1.0 */ - public void matchMapLanguageWithDeviceDefault() { - setMapLanguage(Locale.getDefault()); + public void matchMapLanguageWithDeviceDefault(boolean acceptFallback) { + setMapLanguage(Locale.getDefault(),acceptFallback); } /** @@ -163,10 +165,11 @@ public void setMapLanguage(@Languages String language) { * locale you are trying to use, has a complementary {@link MapLocale} for it. * * @param locale a {@link Locale} which has a complementary {@link MapLocale} for it + * @param acceptFallback whether a fallback to a language default is desired * @since 0.1.0 */ - public void setMapLanguage(@NonNull Locale locale) { - MapLocale mapLocale = MapLocale.getMapLocale(locale); + public void setMapLanguage(@NonNull Locale locale, boolean acceptFallback) { + MapLocale mapLocale = MapLocale.getMapLocale(locale,acceptFallback); if (mapLocale != null) { setMapLanguage(mapLocale); } else { @@ -289,7 +292,7 @@ public void setCameraToLocaleCountry(int padding) { * @since 0.1.0 */ public void setCameraToLocaleCountry(Locale locale, int padding) { - MapLocale mapLocale = MapLocale.getMapLocale(locale); + MapLocale mapLocale = MapLocale.getMapLocale(locale,false); if (mapLocale != null) { setCameraToLocaleCountry(mapLocale, padding); } else { diff --git a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/MapLocale.java b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/MapLocale.java index b6eb7d859..d16775971 100644 --- a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/MapLocale.java +++ b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/MapLocale.java @@ -3,6 +3,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringDef; +import android.util.Log; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; @@ -364,7 +365,35 @@ public static void addMapLocale(@NonNull Locale locale, @NonNull MapLocale mapLo * @since 0.1.0 */ @Nullable - public static MapLocale getMapLocale(@NonNull Locale locale) { - return LOCALE_SET.get(locale); + public static MapLocale getMapLocale(@NonNull Locale locale, boolean acceptFallback) { + MapLocale foundLocale = LOCALE_SET.get(locale); + if (acceptFallback && foundLocale == null) { + foundLocale = getMapLocaleFallback(locale); + } + return foundLocale; + } + + /** + * Passing in a Locale, you are able to receive the {@link MapLocale} object which it is currently + * paired with as a fallback. If this returns null, there was no matching {@link MapLocale} to go along with the + * passed in Locale. If you expected a non-null result, you should make sure you used + * {@link #addMapLocale(Locale, MapLocale)} before making this call. + * + * @param locale the locale which you'd like to receive its matching {@link MapLocale}(fallback) if one exists + * @return the matching {@link MapLocale} if one exists, otherwise null + * @since 0.1.0 + */ + @Nullable + private static MapLocale getMapLocaleFallback(@NonNull Locale locale) { + String fallbackCode = locale.getLanguage().substring(0,2); + MapLocale foundMapLocale = null; + + for (Locale possibleLocale: LOCALE_SET.keySet()) { + if (possibleLocale.getLanguage().equals(fallbackCode)) { + foundMapLocale = LOCALE_SET.get(possibleLocale); + break; + } + } + return foundMapLocale; } } \ No newline at end of file diff --git a/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.java b/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.java index e5a9ddd6f..2b8422531 100644 --- a/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.java +++ b/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.java @@ -46,6 +46,6 @@ public void setMapLanguage_localePassedInNotValid() throws Exception { thrown.expectMessage(containsString("has no matching MapLocale object. You need to create")); LocalizationPlugin localizationPlugin = new LocalizationPlugin(mock(MapView.class), mock(MapboxMap.class), style); - localizationPlugin.setMapLanguage(new Locale("foo", "bar")); + localizationPlugin.setMapLanguage(new Locale("foo", "bar"),false); } } \ No newline at end of file diff --git a/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/MapLocaleTest.java b/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/MapLocaleTest.java index 93c7d7948..4140cc74d 100644 --- a/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/MapLocaleTest.java +++ b/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/MapLocaleTest.java @@ -22,7 +22,18 @@ public void addMapLocale_doesGetAddedAndReferencedCorrectly() throws Exception { Locale locale = new Locale("foo", "bar"); MapLocale mapLocale = new MapLocale("abc"); MapLocale.addMapLocale(locale, mapLocale); - MapLocale mapLocale1 = MapLocale.getMapLocale(locale); + MapLocale mapLocale1 = MapLocale.getMapLocale(locale,false); Assert.assertThat(mapLocale1.getMapLanguage(), equalTo("abc")); } + + @Test + public void regionalVariantsCanFallbackCorrectly() throws Exception { + Locale localeHN = new Locale("es_HN", "Honduras"); + MapLocale mapLocale1 = MapLocale.getMapLocale(localeHN,true); + assertThat(mapLocale1.getMapLanguage(), equalTo(MapLocale.SPANISH)); + + Locale localeUS = new Locale("es_US", "United States of America"); + MapLocale mapLocale2 = MapLocale.getMapLocale(localeUS,true); + assertThat(mapLocale2.getMapLanguage(), equalTo(MapLocale.SPANISH)); + } } From 79b651f503227008ab631679c434fa775ca82834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 24 Jan 2019 12:33:10 +0100 Subject: [PATCH 2/2] [localization] language fallback - fix formatting, docs and avoid breaking changes --- .../localization/LocalizationPlugin.java | 36 +++++++++++++++---- .../plugins/localization/MapLocale.java | 22 ++++++++++-- .../localization/LocalizationPluginTest.java | 2 +- .../plugins/localization/MapLocaleTest.java | 14 ++++++-- 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java index 6edb731a4..e1fb589a3 100644 --- a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java +++ b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java @@ -28,7 +28,7 @@ /** * Useful class for quickly adjusting the maps language and the maps camera starting position. * You can either use {@link #matchMapLanguageWithDeviceDefault(boolean acceptFallback)} to match the map language with - * the one being currently used on the device. Using {@link #setMapLanguage(Locale,boolean acceptFallback)} and it's + * the one being currently used on the device. Using {@link #setMapLanguage(Locale, boolean acceptFallback)} and it's * variants, you can also change the maps language at anytime to any of the supported languages. *

* The plugin uses a fallback logic in case there are missing resources @@ -139,12 +139,22 @@ public void onStyleLoaded(@NonNull Style style) { * Initializing this class and then calling this method oftentimes will be the only thing you'll * need to quickly adjust the map language to the devices specified language. * - * @param acceptFallback whether a fallback to a language default is desired + * @since 0.1.0 + */ + public void matchMapLanguageWithDeviceDefault() { + setMapLanguage(Locale.getDefault(), false); + } + + /** + * Initializing this class and then calling this method oftentimes will be the only thing you'll + * need to quickly adjust the map language to the devices specified language. * + * @param acceptFallback whether the locale should fallback to the first declared that matches the language, + * the fallback locale can be added with {@link MapLocale#addMapLocale(Locale, MapLocale)} * @since 0.1.0 */ public void matchMapLanguageWithDeviceDefault(boolean acceptFallback) { - setMapLanguage(Locale.getDefault(),acceptFallback); + setMapLanguage(Locale.getDefault(), acceptFallback); } /** @@ -165,11 +175,25 @@ public void setMapLanguage(@Languages String language) { * locale you are trying to use, has a complementary {@link MapLocale} for it. * * @param locale a {@link Locale} which has a complementary {@link MapLocale} for it - * @param acceptFallback whether a fallback to a language default is desired + * @since 0.1.0 + */ + public void setMapLanguage(@NonNull Locale locale) { + setMapLanguage(locale, false); + } + + /** + * If you'd like to set the map language to a specific locale, you can pass it in as a parameter + * and MapLocale will try matching the information with one of the MapLocales found in its map. + * If one isn't found, a null point exception will be thrown. To prevent this, ensure that the + * locale you are trying to use, has a complementary {@link MapLocale} for it. + * + * @param locale a {@link Locale} which has a complementary {@link MapLocale} for it + * @param acceptFallback whether the locale should fallback to the first declared that matches the language, + * the fallback locale can be added with {@link MapLocale#addMapLocale(Locale, MapLocale)} * @since 0.1.0 */ public void setMapLanguage(@NonNull Locale locale, boolean acceptFallback) { - MapLocale mapLocale = MapLocale.getMapLocale(locale,acceptFallback); + MapLocale mapLocale = MapLocale.getMapLocale(locale, acceptFallback); if (mapLocale != null) { setMapLanguage(mapLocale); } else { @@ -292,7 +316,7 @@ public void setCameraToLocaleCountry(int padding) { * @since 0.1.0 */ public void setCameraToLocaleCountry(Locale locale, int padding) { - MapLocale mapLocale = MapLocale.getMapLocale(locale,false); + MapLocale mapLocale = MapLocale.getMapLocale(locale, false); if (mapLocale != null) { setCameraToLocaleCountry(mapLocale, padding); } else { diff --git a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/MapLocale.java b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/MapLocale.java index d16775971..8c0952b0c 100644 --- a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/MapLocale.java +++ b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/MapLocale.java @@ -3,7 +3,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringDef; -import android.util.Log; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; @@ -361,7 +360,24 @@ public static void addMapLocale(@NonNull Locale locale, @NonNull MapLocale mapLo * {@link #addMapLocale(Locale, MapLocale)} before making this call. * * @param locale the locale which you'd like to receive its matching {@link MapLocale} if one exists + * @since 0.1.0 + */ + @Nullable + public static MapLocale getMapLocale(@NonNull Locale locale) { + return getMapLocale(locale, false); + } + + /** + * Passing in a Locale, you are able to receive the {@link MapLocale} object which it is currently + * paired with. If this returns null, there was no matching {@link MapLocale} to go along with the + * passed in Locale. If you expected a non-null result, you should make sure you used + * {@link #addMapLocale(Locale, MapLocale)} before making this call. + * + * @param locale the locale which you'd like to receive its matching {@link MapLocale} if one exists + * @param acceptFallback whether the locale should fallback to the first declared that matches the language, + * the fallback locale can be added with {@link #addMapLocale(Locale, MapLocale)} * @return the matching {@link MapLocale} if one exists, otherwise null + * @see #getMapLocaleFallback(Locale) * @since 0.1.0 */ @Nullable @@ -385,10 +401,10 @@ public static MapLocale getMapLocale(@NonNull Locale locale, boolean acceptFallb */ @Nullable private static MapLocale getMapLocaleFallback(@NonNull Locale locale) { - String fallbackCode = locale.getLanguage().substring(0,2); + String fallbackCode = locale.getLanguage().substring(0, 2); MapLocale foundMapLocale = null; - for (Locale possibleLocale: LOCALE_SET.keySet()) { + for (Locale possibleLocale : LOCALE_SET.keySet()) { if (possibleLocale.getLanguage().equals(fallbackCode)) { foundMapLocale = LOCALE_SET.get(possibleLocale); break; diff --git a/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.java b/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.java index 2b8422531..c5dcd527d 100644 --- a/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.java +++ b/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPluginTest.java @@ -46,6 +46,6 @@ public void setMapLanguage_localePassedInNotValid() throws Exception { thrown.expectMessage(containsString("has no matching MapLocale object. You need to create")); LocalizationPlugin localizationPlugin = new LocalizationPlugin(mock(MapView.class), mock(MapboxMap.class), style); - localizationPlugin.setMapLanguage(new Locale("foo", "bar"),false); + localizationPlugin.setMapLanguage(new Locale("foo", "bar"), false); } } \ No newline at end of file diff --git a/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/MapLocaleTest.java b/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/MapLocaleTest.java index 4140cc74d..f66f8a0a7 100644 --- a/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/MapLocaleTest.java +++ b/plugin-localization/src/test/java/com/mapbox/mapboxsdk/plugins/localization/MapLocaleTest.java @@ -6,6 +6,7 @@ import java.util.Locale; import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; public class MapLocaleTest { @@ -22,18 +23,25 @@ public void addMapLocale_doesGetAddedAndReferencedCorrectly() throws Exception { Locale locale = new Locale("foo", "bar"); MapLocale mapLocale = new MapLocale("abc"); MapLocale.addMapLocale(locale, mapLocale); - MapLocale mapLocale1 = MapLocale.getMapLocale(locale,false); + MapLocale mapLocale1 = MapLocale.getMapLocale(locale, false); Assert.assertThat(mapLocale1.getMapLanguage(), equalTo("abc")); } @Test public void regionalVariantsCanFallbackCorrectly() throws Exception { Locale localeHN = new Locale("es_HN", "Honduras"); - MapLocale mapLocale1 = MapLocale.getMapLocale(localeHN,true); + MapLocale mapLocale1 = MapLocale.getMapLocale(localeHN, true); assertThat(mapLocale1.getMapLanguage(), equalTo(MapLocale.SPANISH)); Locale localeUS = new Locale("es_US", "United States of America"); - MapLocale mapLocale2 = MapLocale.getMapLocale(localeUS,true); + MapLocale mapLocale2 = MapLocale.getMapLocale(localeUS, true); assertThat(mapLocale2.getMapLanguage(), equalTo(MapLocale.SPANISH)); } + + @Test + public void regionalVariantsNoFallbackWhenNotRequested() throws Exception { + Locale localeHN = new Locale("es_HN", "Honduras"); + MapLocale mapLocale = MapLocale.getMapLocale(localeHN, false); + assertNull(mapLocale); + } }