Skip to content

Commit fbf04d9

Browse files
elPeirettijavier-godoy
authored andcommitted
feat: add country code converter to support more locales
1 parent e8c83c1 commit fbf04d9

File tree

2 files changed

+142
-1
lines changed

2 files changed

+142
-1
lines changed

src/main/java/com/flowingcode/vaadin/addons/localecombobox/LocaleComboBox.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.vaadin.flow.data.renderer.LitRenderer;
2828
import java.util.Arrays;
2929
import java.util.Locale;
30+
import java.util.Optional;
3031

3132
/**
3233
* Vaadin ComboBox extension that allows to choose between multiple locales.
@@ -41,6 +42,7 @@ public class LocaleComboBox extends ComboBox<Locale> {
4142

4243
private static final String ITEM_LAYOUT_CLASS_NAME = "fc-locale-combo-box-item-layout";
4344
private static final String ITEM_FLAG_CLASS_NAME = "fc-locale-combo-box-item-flag";
45+
private static final String DEFAULT_FLAG_CODE = "un";
4446

4547
/**
4648
* Display mode representing the built-in display modes in LocaleComboBox
@@ -73,6 +75,7 @@ public enum DisplayMode {
7375
*/
7476
CUSTOM;
7577
}
78+
7679
private DisplayMode displayMode = DisplayMode.DEFAULT;
7780
private Locale customDisplayLocale = Locale.getDefault();
7881

@@ -123,7 +126,7 @@ private LitRenderer<Locale> getLocaleRenderer() {
123126
</vaadin-horizontal-layout>""")
124127
.withProperty("layoutClass", loc -> ITEM_LAYOUT_CLASS_NAME)
125128
.withProperty("flagClass", loc -> ITEM_FLAG_CLASS_NAME)
126-
.withProperty("countryCode", loc -> loc.getCountry().toLowerCase())
129+
.withProperty("countryCode", this::getFlagCode)
127130
.withProperty("countryName", loc -> loc.getDisplayCountry(getLocaleForDisplay()))
128131
.withProperty("displayName", loc -> loc.getDisplayName(getLocaleForDisplay()));
129132
}
@@ -143,6 +146,16 @@ private Locale getLocaleForDisplay() {
143146
}
144147
}
145148

149+
private String getFlagCode(Locale locale) {
150+
String countryCode = locale.getCountry();
151+
Optional<String> isoCode = LocaleCountryConverter.convertToISO3166Code(countryCode);
152+
153+
if (isoCode.isPresent())
154+
return isoCode.get().toLowerCase();
155+
156+
return DEFAULT_FLAG_CODE;
157+
}
158+
146159
private void onValueChange(ComponentValueChangeEvent<ComboBox<Locale>, Locale> event) {
147160
Locale newValue = event.getValue();
148161
if (newValue == null) {
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*-
2+
* #%L
3+
* LocaleComboBox Add-on
4+
* %%
5+
* Copyright (C) 2024 Flowing Code
6+
* %%
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* #L%
19+
*/
20+
package com.flowingcode.vaadin.addons.localecombobox;
21+
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.Optional;
26+
27+
/**
28+
* Utility class for converting between different formats of country codes.
29+
*
30+
* <p>
31+
* The {@code LocaleCountryConverter} class provides methods to convert country codes from ISO
32+
* 3166-1 alpha-2, alpha-3, and numeric-3 formats to the 3166-1 alpha-2 format. The class uses
33+
* static methods, so no instances are needed.
34+
*
35+
* <p>
36+
* Example usage:
37+
*
38+
* <pre>
39+
* String alpha2Code = LocaleCountryConverter.convertToISO3166Code("ARG").orElse("Unknown");
40+
* </pre>
41+
*
42+
* @see #convertToISO3166Code(String)
43+
*/
44+
public class LocaleCountryConverter {
45+
46+
private static final int TOTAL_COUNTRIES = 249;
47+
private static final List<String> alpha2codes =
48+
List.of("AF", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT",
49+
"AZ", "BS", "BH", "BD", "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW",
50+
"BV", "BR", "IO", "BN", "BG", "BF", "BI", "CV", "KH", "CM", "CA", "KY", "CF", "TD", "CL",
51+
"CN", "CX", "CC", "CO", "KM", "CD", "CG", "CK", "CR", "HR", "CU", "CW", "CY", "CZ", "CI",
52+
"DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", "ER", "EE", "SZ", "ET", "FK", "FO", "FJ",
53+
"FI", "FR", "GF", "PF", "TF", "GA", "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD", "GP",
54+
"GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU", "IS", "IN", "ID",
55+
"IR", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR",
56+
"KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MG", "MW", "MY",
57+
"MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME", "MS",
58+
"MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MK",
59+
"MP", "NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR",
60+
"QA", "RO", "RU", "RW", "RE", "BL", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST",
61+
"SA", "SN", "RS", "SC", "SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES",
62+
"LK", "SD", "SR", "SJ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO",
63+
"TT", "TN", "TM", "TC", "TV", "TR", "UG", "UA", "AE", "GB", "UM", "US", "UY", "UZ", "VU",
64+
"VE", "VN", "VG", "VI", "WF", "EH", "YE", "ZM", "ZW", "AX");
65+
private static final List<String> alpha3codes = List.of("AFG", "ALB", "DZA", "ASM", "AND", "AGO",
66+
"AIA", "ATA", "ATG", "ARG", "ARM", "ABW", "AUS", "AUT", "AZE", "BHS", "BHR", "BGD", "BRB",
67+
"BLR", "BEL", "BLZ", "BEN", "BMU", "BTN", "BOL", "BES", "BIH", "BWA", "BVT", "BRA", "IOT",
68+
"BRN", "BGR", "BFA", "BDI", "CPV", "KHM", "CMR", "CAN", "CYM", "CAF", "TCD", "CHL", "CHN",
69+
"CXR", "CCK", "COL", "COM", "COD", "COG", "COK", "CRI", "HRV", "CUB", "CUW", "CYP", "CZE",
70+
"CIV", "DNK", "DJI", "DMA", "DOM", "ECU", "EGY", "SLV", "GNQ", "ERI", "EST", "SWZ", "ETH",
71+
"FLK", "FRO", "FJI", "FIN", "FRA", "GUF", "PYF", "ATF", "GAB", "GMB", "GEO", "DEU", "GHA",
72+
"GIB", "GRC", "GRL", "GRD", "GLP", "GUM", "GTM", "GGY", "GIN", "GNB", "GUY", "HTI", "HMD",
73+
"VAT", "HND", "HKG", "HUN", "ISL", "IND", "IDN", "IRN", "IRQ", "IRL", "IMN", "ISR", "ITA",
74+
"JAM", "JPN", "JEY", "JOR", "KAZ", "KEN", "KIR", "PRK", "KOR", "KWT", "KGZ", "LAO", "LVA",
75+
"LBN", "LSO", "LBR", "LBY", "LIE", "LTU", "LUX", "MAC", "MDG", "MWI", "MYS", "MDV", "MLI",
76+
"MLT", "MHL", "MTQ", "MRT", "MUS", "MYT", "MEX", "FSM", "MDA", "MCO", "MNG", "MNE", "MSR",
77+
"MAR", "MOZ", "MMR", "NAM", "NRU", "NPL", "NLD", "NCL", "NZL", "NIC", "NER", "NGA", "NIU",
78+
"NFK", "MKD", "MNP", "NOR", "OMN", "PAK", "PLW", "PSE", "PAN", "PNG", "PRY", "PER", "PHL",
79+
"PCN", "POL", "PRT", "PRI", "QAT", "ROU", "RUS", "RWA", "REU", "BLM", "SHN", "KNA", "LCA",
80+
"MAF", "SPM", "VCT", "WSM", "SMR", "STP", "SAU", "SEN", "SRB", "SYC", "SLE", "SGP", "SXM",
81+
"SVK", "SVN", "SLB", "SOM", "ZAF", "SGS", "SSD", "ESP", "LKA", "SDN", "SUR", "SJM", "SWE",
82+
"CHE", "SYR", "TWN", "TJK", "TZA", "THA", "TLS", "TGO", "TKL", "TON", "TTO", "TUN", "TKM",
83+
"TCA", "TUV", "TUR", "UGA", "UKR", "ARE", "GBR", "UMI", "USA", "URY", "UZB", "VUT", "VEN",
84+
"VNM", "VGB", "VIR", "WLF", "ESH", "YEM", "ZMB", "ZWE", "ALA");
85+
private static final List<Integer> numericCodes = List.of(4, 8, 12, 16, 20, 24, 660, 10, 28, 32,
86+
51, 533, 36, 40, 31, 44, 48, 50, 52, 112, 56, 84, 204, 60, 64, 68, 535, 70, 72, 74, 76, 86,
87+
96, 100, 854, 108, 132, 116, 120, 124, 136, 140, 148, 152, 156, 162, 166, 170, 174, 180, 178,
88+
184, 188, 191, 192, 531, 196, 203, 384, 208, 262, 212, 214, 218, 818, 222, 226, 232, 233, 748,
89+
231, 238, 234, 242, 246, 250, 254, 258, 260, 266, 270, 268, 276, 288, 292, 300, 304, 308, 312,
90+
316, 320, 831, 324, 624, 328, 332, 334, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 833,
91+
376, 380, 388, 392, 832, 400, 398, 404, 296, 408, 410, 414, 417, 418, 428, 422, 426, 430, 434,
92+
438, 440, 442, 446, 450, 454, 458, 462, 466, 470, 584, 474, 478, 480, 175, 484, 583, 498, 492,
93+
496, 499, 500, 504, 508, 104, 516, 520, 524, 528, 540, 554, 558, 562, 566, 570, 574, 807, 580,
94+
578, 512, 586, 585, 275, 591, 598, 600, 604, 608, 612, 616, 620, 630, 634, 642, 643, 646, 638,
95+
652, 654, 659, 662, 663, 666, 670, 882, 674, 678, 682, 686, 688, 690, 694, 702, 534, 703, 705,
96+
90, 706, 710, 239, 728, 724, 144, 729, 740, 744, 752, 756, 760, 158, 762, 834, 764, 626, 768,
97+
772, 776, 780, 788, 795, 796, 798, 792, 800, 804, 784, 826, 581, 840, 858, 860, 548, 862, 704,
98+
92, 850, 876, 732, 887, 894, 716, 248);
99+
100+
private static final Map<String, String> conversions = getConversionsMap();
101+
102+
/**
103+
* Converts a country code to its corresponding ISO 3166-1 alpha-2 code.
104+
*
105+
* @param countryCode The country code to be converted. This can be in ISO 3166-1 alpha-2 format
106+
* (e.g., "AR"), ISO 3166-1 alpha-3 format (e.g., "ARG"), or numeric-3 format (e.g.,
107+
* "032").
108+
* @return An {@link Optional} containing the ISO 3166-1 alpha-2 code if the conversion is
109+
* successful.
110+
*/
111+
public static Optional<String> convertToISO3166Code(String countryCode) {
112+
return Optional.ofNullable(conversions.get(countryCode.toUpperCase()));
113+
}
114+
115+
private static Map<String, String> getConversionsMap() {
116+
var conversions = new HashMap<String, String>();
117+
118+
for (int i = 0; i < TOTAL_COUNTRIES; i++) {
119+
String alpha2 = alpha2codes.get(i);
120+
conversions.put(alpha2, alpha2);
121+
conversions.put(alpha3codes.get(i), alpha2);
122+
conversions.put(numericCodes.get(i).toString(), alpha2);
123+
}
124+
125+
return conversions;
126+
}
127+
128+
}

0 commit comments

Comments
 (0)