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..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 @@ -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 @@ -142,7 +142,19 @@ public void onStyleLoaded(@NonNull Style style) { * @since 0.1.0 */ public void matchMapLanguageWithDeviceDefault() { - setMapLanguage(Locale.getDefault()); + 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); } /** @@ -166,7 +178,22 @@ public void setMapLanguage(@Languages String language) { * @since 0.1.0 */ public void setMapLanguage(@NonNull Locale locale) { - MapLocale mapLocale = MapLocale.getMapLocale(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); if (mapLocale != null) { setMapLanguage(mapLocale); } else { @@ -289,7 +316,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..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 @@ -360,11 +360,56 @@ 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 - * @return the matching {@link MapLocale} if one exists, otherwise null * @since 0.1.0 */ @Nullable public static MapLocale getMapLocale(@NonNull Locale locale) { - return LOCALE_SET.get(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 + 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..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")); + 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..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,7 +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); + 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)); + } + + @Test + public void regionalVariantsNoFallbackWhenNotRequested() throws Exception { + Locale localeHN = new Locale("es_HN", "Honduras"); + MapLocale mapLocale = MapLocale.getMapLocale(localeHN, false); + assertNull(mapLocale); + } }