1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.common.model;
18
19 import com.fasterxml.jackson.annotation.JsonIgnore;
20 import com.fasterxml.jackson.annotation.JsonProperty;
21 import io.swagger.v3.oas.annotations.media.Schema;
22 import java.io.Serializable;
23 import java.util.Arrays;
24 import java.util.Locale;
25 import java.util.MissingResourceException;
26 import java.util.regex.Pattern;
27 import lombok.Builder;
28 import lombok.EqualsAndHashCode;
29 import lombok.NoArgsConstructor;
30 import org.springframework.util.StringUtils;
31
32
33
34
35
36
37 @Schema(description = "A locale representation.")
38 @EqualsAndHashCode
39 @NoArgsConstructor
40 public class JavaLocale implements Serializable {
41
42 private static final long serialVersionUID = 1L;
43
44 @JsonIgnore
45 private String language;
46
47 @JsonIgnore
48 private String country;
49
50
51
52
53
54
55 protected JavaLocale(String value) {
56 if (value == null || value.trim().length() < 2) {
57 setLanguage(null);
58 setCountry(null);
59 } else {
60 String source = value.trim().replace("-", "_");
61 String[] parts = source.split(Pattern.quote("_"));
62 setLanguage(parts[0]);
63 if (parts.length > 1) {
64 setCountry(parts[1]);
65 }
66 }
67 }
68
69
70
71
72
73
74
75 @Builder(toBuilder = true)
76 public JavaLocale(String language, String country) {
77 setLanguage(language);
78 setCountry(country);
79 }
80
81
82
83
84
85
86
87 public JavaLocale(TwoLetterLanguageCode language, TwoLetterCountryCode country) {
88 this.language = language != null ? language.toString() : null;
89 this.country = country != null ? country.toString() : null;
90 }
91
92
93
94
95
96
97
98 public JavaLocale(ThreeLetterLanguageCode language, ThreeLetterCountryCode country) {
99 this.language = language != null ? language.toLocale().getLanguage() : null;
100 this.country = country != null ? country.toLocale().getCountry() : null;
101 }
102
103
104
105
106
107
108 @Schema(description = "The two letter language code.", example = "de")
109 @JsonProperty("language")
110 public String getLanguage() {
111 return language;
112 }
113
114
115
116
117
118
119 @JsonProperty("language")
120 public void setLanguage(String language) {
121 if (StringUtils.hasText(language)) {
122 for (Locale l : Locale.getAvailableLocales()) {
123 try {
124 if (l.getLanguage().equalsIgnoreCase(language)
125 || (l.getISO3Language() != null && l.getISO3Language().equalsIgnoreCase(language))) {
126 this.language = l.getLanguage();
127 return;
128 }
129 } catch (MissingResourceException ignored) {
130
131 }
132 }
133 if (Arrays.stream(Locale.getISOLanguages()).anyMatch(iso -> iso.equalsIgnoreCase(language))) {
134 this.language = language.toLowerCase();
135 return;
136 }
137 }
138 this.language = null;
139 }
140
141
142
143
144
145
146 @Schema(description = "The two letter country code.", example = "DE")
147 @JsonProperty("country")
148 public String getCountry() {
149 return country;
150 }
151
152
153
154
155
156
157 @JsonProperty("country")
158 public void setCountry(String country) {
159 if (StringUtils.hasText(country)) {
160 for (Locale l : Locale.getAvailableLocales()) {
161 try {
162 if (l.getCountry().equalsIgnoreCase(country)
163 || (l.getISO3Country() != null && l.getISO3Country().equalsIgnoreCase(country))) {
164 this.country = l.getCountry();
165 return;
166 }
167 } catch (MissingResourceException ignored) {
168
169 }
170 }
171 if (Arrays.stream(Locale.getISOCountries()).anyMatch(iso -> iso.equalsIgnoreCase(country))) {
172 this.country = country.toUpperCase();
173 return;
174 }
175 }
176 this.country = null;
177 }
178
179 @Override
180 public String toString() {
181 return toString(Separator.HYPHEN);
182 }
183
184
185
186
187
188
189
190 public String toString(Separator separator) {
191 StringBuilder sb = new StringBuilder();
192 if (StringUtils.hasText(getLanguage())) {
193 sb.append(getLanguage());
194 if (StringUtils.hasText(getCountry())) {
195 sb.append(Separator.fromNullable(separator).toString());
196 sb.append(getCountry());
197 }
198 }
199 return sb.toString();
200 }
201
202
203
204
205
206
207 public Locale toLocale() {
208 return toLocale(null);
209 }
210
211
212
213
214
215
216
217 public Locale toLocale(Locale defaultLocale) {
218 if (!StringUtils.hasText(getLanguage()) && !StringUtils.hasText(getCountry())) {
219 return defaultLocale;
220 }
221 String language = getLanguage() == null ? "" : getLanguage();
222 String country = getCountry() == null ? "" : getCountry();
223 return new Locale(language, country);
224 }
225
226
227
228
229
230
231
232 public static JavaLocale fromValue(String value) {
233 return new JavaLocale(value);
234 }
235
236
237
238
239
240
241
242 public static JavaLocale fromLocale(Locale locale) {
243 return locale == null ? null : fromValue(locale.toString());
244 }
245
246
247
248
249 public enum Separator {
250
251
252
253
254 HYPHEN("-"),
255
256
257
258
259 UNDERSCORE("_");
260
261 private String value;
262
263 Separator(String value) {
264 this.value = value;
265 }
266
267 @Override
268 public String toString() {
269 return value;
270 }
271
272
273
274
275
276
277
278 public static Separator fromNullable(Separator separator) {
279 return separator == null ? HYPHEN : separator;
280 }
281 }
282
283 }
284