1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package com.rapiddweller.domain.address;
28
29 import com.rapiddweller.benerator.engine.DefaultBeneratorContext;
30 import com.rapiddweller.benerator.primitive.RandomVarLengthStringGenerator;
31 import com.rapiddweller.benerator.primitive.RegexStringGenerator;
32 import com.rapiddweller.benerator.util.RandomUtil;
33 import com.rapiddweller.common.Assert;
34 import com.rapiddweller.common.BeanUtil;
35 import com.rapiddweller.common.ConfigurationError;
36 import com.rapiddweller.common.Encodings;
37 import com.rapiddweller.common.IOUtil;
38 import com.rapiddweller.common.LocaleUtil;
39 import com.rapiddweller.common.StringUtil;
40 import com.rapiddweller.common.collection.OrderedNameMap;
41 import com.rapiddweller.format.DataContainer;
42 import com.rapiddweller.format.DataIterator;
43 import com.rapiddweller.format.csv.CSVLineIterator;
44 import com.rapiddweller.model.data.ComplexTypeDescriptor;
45 import com.rapiddweller.model.data.Entity;
46 import com.rapiddweller.platform.csv.CSVEntitySource;
47 import com.rapiddweller.platform.java.BeanDescriptorProvider;
48 import org.apache.logging.log4j.LogManager;
49 import org.apache.logging.log4j.Logger;
50
51 import java.io.IOException;
52 import java.util.ArrayList;
53 import java.util.Collection;
54 import java.util.HashMap;
55 import java.util.List;
56 import java.util.Locale;
57 import java.util.Map;
58
59
60
61
62
63
64
65
66
67 public class Country {
68
69 private static final Logger LOGGER = LogManager.getLogger(Country.class);
70 private static final String DEFAULT_PHONE_CODE = "[2-9][0-9][0-9]";
71 private static final String DEFAULT_MOBILE_PHONE_PATTERN =
72 "[1-9][0-9][0-9]";
73 private static final Map<String, Country> instances = new HashMap<>(250);
74
75
76
77 public static final Country GERMANY = getInstance("DE");
78
79
80
81 public static final Country AUSTRIA = getInstance("AT");
82
83
84
85 public static final Country SWITZERLAND = getInstance("CH");
86
87
88
89 public static final Country LIECHTENSTEIN = getInstance("LI");
90
91
92
93
94 public static final Country BELGIUM = getInstance("BE");
95
96
97
98 public static final Country NETHERLANDS = getInstance("NL");
99
100
101
102 public static final Country LUXEMBURG = getInstance("LU");
103
104
105
106 public static final Country DENMARK = getInstance("DK");
107
108
109
110 public static final Country FINLAND = getInstance("FI");
111
112
113
114 public static final Country IRELAND = getInstance("IE");
115
116
117
118 public static final Country ICELAND = getInstance("IS");
119
120
121
122 public static final Country NORWAY = getInstance("NO");
123
124
125
126 public static final Country SWEDEN = getInstance("SE");
127
128
129
130 public static final Country UNITED_KINGDOM = getInstance("GB");
131
132
133
134 public static final Country GREAT_BRITAIN = getInstance("GB");
135
136
137
138 public static final Country ITALY = getInstance("IT");
139
140
141
142 public static final Country SAN_MARINO = getInstance("SM");
143
144
145
146 public static final Country MALTA = getInstance("MT");
147
148
149
150 public static final Country FRANCE = getInstance("FR");
151
152
153
154 public static final Country MONACO = getInstance("MC");
155
156
157
158 public static final Country ANDORRA = getInstance("AD");
159
160
161
162 public static final Country SPAIN = getInstance("ES");
163
164
165
166 public static final Country PORTUGAL = getInstance("PT");
167
168
169
170 public static final Country GREECE = getInstance("GR");
171
172
173
174 public static final Country CYPRUS = getInstance("CY");
175
176
177
178 public static final Country TURKEY = getInstance("TR");
179
180
181
182 public static final Country ALBANIA = getInstance("AL");
183
184
185
186 public static final Country BOSNIA_AND_HERZEGOVINA = getInstance("BA");
187
188
189
190 public static final Country BULGARIA = getInstance("BG");
191
192
193
194 public static final Country BELARUS = getInstance("BY");
195
196
197
198 public static final Country CZECH_REPUBLIC = getInstance("CZ");
199
200
201
202 public static final Country ESTONIA = getInstance("EE");
203
204
205
206 public static final Country CROATIA = getInstance("HR");
207
208
209
210 public static final Country HUNGARY = getInstance("HU");
211
212
213
214 public static final Country LITHUANIA = getInstance("LT");
215
216
217
218
219
220 public static final Country LATVIA = getInstance("LV");
221
222
223
224 public static final Country POLAND = getInstance("PL");
225
226
227
228 public static final Country ROMANIA = getInstance("RO");
229
230
231
232
233
234 public static final Country RUSSIA = getInstance("RU");
235
236
237
238 public static final Country SERBIA = getInstance("RS");
239
240
241
242 public static final Country SLOVENIA = getInstance("SI");
243
244
245
246 public static final Country SLOVAKIA = getInstance("SK");
247
248
249
250 public static final Country UKRAINE = getInstance("UA");
251
252
253
254 public static final Country UNITED_ARAB_EMIRATES = getInstance("AE");
255
256
257
258 public static final Country AFGHANISTAN = getInstance("AF");
259
260
261
262 public static final Country BAHRAIN = getInstance("BH");
263
264
265
266 public static final Country ISRAEL = getInstance("IL");
267
268
269
270 public static final Country IRAN = getInstance("IR");
271
272
273
274 public static final Country IRAQ = getInstance("IQ");
275
276
277
278 public static final Country JORDAN = getInstance("JO");
279
280
281
282 public static final Country KAZAKHSTAN = getInstance("KZ");
283
284
285
286 public static final Country PAKISTAN = getInstance("PK");
287
288
289
290 public static final Country QATAR = getInstance("QA");
291
292
293
294 public static final Country SAUDI_ARABIA = getInstance("SA");
295
296
297
298 public static final Country ALGERIA = getInstance("AL");
299
300
301
302 public static final Country EGYPT = getInstance("EG");
303
304
305
306 public static final Country GHANA = getInstance("GH");
307
308
309
310 public static final Country KENYA = getInstance("KE");
311
312
313
314 public static final Country SOUTH_AFRICA = getInstance("ZA");
315
316
317
318 public static final Country USA = getInstance("US");
319
320
321
322 public static final Country US = USA;
323
324
325
326 public static final Country CANADA = getInstance("CA");
327
328
329
330 public static final Country BAHAMAS = getInstance("BS");
331
332
333
334 public static final Country MEXICO = getInstance("MX");
335
336
337
338 public static final Country ARGENTINA = getInstance("AR");
339
340
341
342 public static final Country BRAZIL = getInstance("BR");
343
344
345
346 public static final Country CHILE = getInstance("CL");
347
348
349
350 public static final Country ECUADOR = getInstance("EC");
351
352
353
354 public static final Country CHINA = getInstance("CN");
355
356
357
358 public static final Country INDONESIA = getInstance("ID");
359
360
361
362 public static final Country INDIA = getInstance("IN");
363
364
365
366 public static final Country JAPAN = getInstance("JP");
367
368
369
370 public static final Country KOREA_PR = getInstance("KP");
371
372
373
374 public static final Country KOREA_R = getInstance("KR");
375
376
377
378 public static final Country MALAYSIA = getInstance("MY");
379
380
381
382 public static final Country SINGAPORE = getInstance("SG");
383
384
385
386 public static final Country THAILAND = getInstance("TH");
387
388
389
390 public static final Country TAIWAN = getInstance("TW");
391
392
393
394 public static final Country VIETNAM = getInstance("VN");
395
396
397
398 public static final Country NEW_ZEALAND = getInstance("NZ");
399
400
401
402 public static final Country AUSTRALIA = getInstance("AU");
403 private static Country defaultCountry;
404
405 static {
406 parseConfigFile();
407 }
408
409 static {
410 defaultCountry =
411 Country.getInstance(LocaleUtil.getDefaultCountryCode());
412 }
413
414 private final String isoCode;
415 private final String name;
416 private final String phoneCode;
417 private final boolean mobilePhoneCityRelated;
418 private final RegexStringGenerator mobilePrefixGenerator;
419 private final RandomVarLengthStringGenerator localNumberGenerator;
420 private final Locale countryLocale;
421 private final Locale defaultLanguageLocale;
422 private final int population;
423 private Map<String, State> states;
424 private CityGenerator cityGenerator;
425 private boolean citiesInitialized = false;
426
427 private Country(String isoCode, String defaultLanguage, int population,
428 String phoneCode, String mobileCodePattern,
429 String name) {
430 this.isoCode = isoCode;
431 this.defaultLanguageLocale = LocaleUtil.getLocale(defaultLanguage);
432 this.phoneCode = phoneCode;
433 this.countryLocale =
434 new Locale(LocaleUtil.getLocale(defaultLanguage).getLanguage(),
435 isoCode);
436 this.mobilePhoneCityRelated = "BR".equalsIgnoreCase(isoCode);
437 this.mobilePrefixGenerator = new RegexStringGenerator(mobileCodePattern);
438 this.mobilePrefixGenerator.init(null);
439 this.localNumberGenerator = new RandomVarLengthStringGenerator("\\d", 7);
440 this.localNumberGenerator.init(null);
441 this.name = (name != null ? name :
442 countryLocale.getDisplayCountry(Locale.US));
443 this.population = population;
444 importStates();
445 instances.put(isoCode, this);
446 }
447
448 private static void mapProperty(String propertyName, Entity source,
449 State target, boolean required) {
450 String propertyValue = String.valueOf(source.get(propertyName));
451 if (required) {
452 Assert.notNull(propertyValue, propertyName);
453 }
454 BeanUtil.setPropertyValue(target, propertyName, propertyValue);
455 }
456
457
458
459
460
461
462 public static Collection<Country> getInstances() {
463 return instances.values();
464 }
465
466
467
468
469
470
471
472
473 public static Country getInstance(String isoCode) {
474 return getInstance(isoCode, true);
475 }
476
477
478
479
480
481
482
483
484
485 public static Country getInstance(String isoCode, boolean create) {
486 Country country = instances.get(isoCode.toUpperCase());
487 if (country == null && create) {
488 country = new Country(isoCode, Locale.getDefault().getLanguage(),
489 1000000, DEFAULT_PHONE_CODE, DEFAULT_MOBILE_PHONE_PATTERN,
490 null);
491 }
492 return country;
493 }
494
495
496
497
498
499
500
501 public static boolean hasInstance(String isoCode) {
502 return (instances.get(isoCode.toUpperCase()) != null);
503 }
504
505
506
507
508
509
510 public static Country getDefault() {
511 return Country.defaultCountry;
512 }
513
514
515
516
517
518
519 public static void setDefault(Country country) {
520 Country.defaultCountry = country;
521 }
522
523
524
525
526
527
528 public static Country getFallback() {
529 return Country.US;
530 }
531
532 private static void parseConfigFile() {
533 CSVLineIterator iterator = null;
534 try {
535 String fileName = "/com/rapiddweller/domain/address/country.csv";
536 iterator = new CSVLineIterator(fileName, ',', true);
537 LOGGER.debug("Parsing country setup file {}", fileName);
538 DataContainer<String[]> container = new DataContainer<>();
539 while ((container = iterator.next(container)) != null) {
540 String[] cells = container.getData();
541 String isoCode = cells[0];
542 String defaultLocale =
543 (cells.length > 1 && !StringUtil.isEmpty(cells[1]) ?
544 cells[1].trim() : "en");
545 String phoneCode =
546 (cells.length > 2 && !StringUtil.isEmpty(cells[2]) ?
547 cells[2].trim() : null);
548 String mobilCodePattern =
549 (cells.length > 3 && !StringUtil.isEmpty(cells[3]) ?
550 cells[3].trim() : DEFAULT_MOBILE_PHONE_PATTERN);
551 String name = (cells.length > 4 ? cells[4].trim() : null);
552 int population =
553 (cells.length > 5 ? Integer.parseInt(cells[5].trim()) :
554 1000000);
555 Country country =
556 new Country(isoCode, defaultLocale, population,
557 phoneCode, mobilCodePattern, name);
558 LOGGER.debug("Parsed country {}", country);
559 }
560 } catch (IOException e) {
561 throw new ConfigurationError(
562 "Country definition file could not be processed. ", e);
563 } finally {
564 if (iterator != null) {
565 iterator.close();
566 }
567 }
568 }
569
570 private void importStates() {
571 this.states = new OrderedNameMap<>();
572 String filename =
573 "/com/rapiddweller/domain/address/state_" + isoCode + ".csv";
574 if (!IOUtil.isURIAvailable(filename)) {
575 LOGGER.debug("No states defined for {}", this);
576 return;
577 }
578 ComplexTypeDescriptor stateDescriptor =
579 (ComplexTypeDescriptor) new BeanDescriptorProvider()
580 .getTypeDescriptor(State.class.getName());
581 CSVEntitySource source =
582 new CSVEntitySource(filename, stateDescriptor, Encodings.UTF_8);
583 source.setContext(new DefaultBeneratorContext());
584 DataIterator<Entity> iterator = source.iterator();
585 DataContainer<Entity> container = new DataContainer<>();
586 while ((container = iterator.next(container)) != null) {
587 Entity entity = container.getData();
588 Statedress/State.html#State">State state = new State();
589 mapProperty("id", entity, state, true);
590 mapProperty("name", entity, state, true);
591 mapProperty("defaultLanguage", entity, state, false);
592 state.setCountry(this);
593 addState(state);
594 }
595 IOUtil.close(iterator);
596 }
597
598
599
600
601
602
603 public String getIsoCode() {
604 return isoCode;
605 }
606
607
608
609
610
611
612 public String getName() {
613 return name;
614 }
615
616
617
618
619
620
621 public String getDisplayName() {
622 return countryLocale.getDisplayCountry(Locale.getDefault());
623 }
624
625
626
627
628
629
630 public String getLocalName() {
631 return countryLocale.getDisplayCountry(
632 new Locale(defaultLanguageLocale.getLanguage()));
633 }
634
635
636
637
638
639
640 public Locale getDefaultLanguageLocale() {
641 return defaultLanguageLocale;
642 }
643
644
645
646
647
648
649 public int getPopulation() {
650 return population;
651 }
652
653
654
655
656
657
658 public String getPhoneCode() {
659 return phoneCode;
660 }
661
662
663
664
665
666
667
668 public State getState(String stateId) {
669 return states.get(stateId);
670 }
671
672
673
674
675
676
677 public Collection<State> getStates() {
678 return states.values();
679 }
680
681
682
683
684
685
686 public void addState(State state) {
687 state.setCountry(this);
688 states.put(state.getId(), state);
689 }
690
691
692
693
694
695
696 public boolean isMobilePhoneCityRelated() {
697 return mobilePhoneCityRelated;
698 }
699
700
701
702
703
704
705 public List<City> getCities() {
706 List<City> cities = new ArrayList<>();
707 for (State state : states.values()) {
708 cities.addAll(state.getCities());
709 }
710 return cities;
711 }
712
713
714
715
716
717
718 public City generateCity() {
719 return getCityGenerator().generate();
720 }
721
722
723
724
725
726
727 public PhoneNumber generatePhoneNumber() {
728 if (RandomUtil.randomInt(0, 2) <
729 2) {
730
731
732 return generateLandlineNumber();
733 } else {
734 return generateMobileNumber();
735 }
736 }
737
738
739
740
741
742
743 public PhoneNumber generateLandlineNumber() {
744 return generateCity().generateLandlineNumber();
745 }
746
747
748
749
750
751
752 public PhoneNumber generateMobileNumber() {
753 if (mobilePhoneCityRelated) {
754 return generateCity().generateMobileNumber();
755 } else {
756 return generateMobileNumber(null);
757 }
758 }
759
760
761
762
763
764
765
766 public PhoneNumber generateMobileNumber(City city) {
767 String localNumber = localNumberGenerator.generate();
768 String mobilePrefix = mobilePrefixGenerator.generate();
769 if (mobilePhoneCityRelated) {
770 return new PhoneNumber(phoneCode,
771 city != null ? city.getAreaCode() : null,
772 mobilePrefix +
773 localNumber.substring(mobilePrefix.length()));
774 } else {
775 return new PhoneNumber(phoneCode,
776 mobilePrefix,
777 localNumber);
778 }
779 }
780
781 private CityGenerator getCityGenerator() {
782 if (cityGenerator == null) {
783 cityGenerator = new CityGenerator(this.getIsoCode());
784 cityGenerator.init(null);
785 }
786 return cityGenerator;
787 }
788
789
790
791 @Override
792 public String toString() {
793 return getName();
794 }
795
796 @Override
797 public int hashCode() {
798 return isoCode.hashCode();
799 }
800
801 @Override
802 public boolean equals(Object obj) {
803 if (this == obj) {
804 return true;
805 }
806 if (obj == null) {
807 return false;
808 }
809 if (getClass() != obj.getClass()) {
810 return false;
811 }
812 final Country../../../../com/rapiddweller/domain/address/Country.html#Country">Country other = (Country) obj;
813 return isoCode.equals(other.isoCode);
814 }
815
816
817
818
819 void checkCities() {
820 if (!citiesInitialized) {
821 synchronized (this) {
822 if (!citiesInitialized) {
823 citiesInitialized = true;
824 CityManager.readCities(this);
825 }
826 }
827 }
828 }
829
830 }