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.person;
28
29 import com.rapiddweller.benerator.Generator;
30 import com.rapiddweller.benerator.GeneratorContext;
31 import com.rapiddweller.benerator.NonNullGenerator;
32 import com.rapiddweller.benerator.dataset.DatasetBasedGenerator;
33 import com.rapiddweller.benerator.dataset.DatasetUtil;
34 import com.rapiddweller.benerator.primitive.BooleanGenerator;
35 import com.rapiddweller.benerator.wrapper.CompositeGenerator;
36 import com.rapiddweller.benerator.wrapper.ProductWrapper;
37 import com.rapiddweller.common.Converter;
38 import com.rapiddweller.domain.address.Country;
39
40 import java.util.HashMap;
41 import java.util.Locale;
42 import java.util.Map;
43
44 import static com.rapiddweller.benerator.util.GeneratorUtil.generateNonNull;
45 import static com.rapiddweller.benerator.util.GeneratorUtil.generateNullable;
46
47
48
49
50
51
52
53
54
55 public class PersonGenerator extends CompositeGenerator<Person>
56 implements DatasetBasedGenerator<Person>, NonNullGenerator<Person> {
57
58 private static final String REGION_NESTING =
59 "com/rapiddweller/dataset/region";
60
61 private String datasetName;
62 private Locale locale;
63
64 private final GenderGenerator genderGen;
65 private GivenNameGenerator maleGivenNameGen;
66 private GivenNameGenerator femaleGivenNameGen;
67 private BooleanGenerator secondNameTest;
68 private FamilyNameGenerator familyNameGen;
69 private final Map<String, Converter<String, String>>
70 femaleFamilyNameConverters;
71 private AcademicTitleGenerator acadTitleGen;
72 private NobilityTitleGenerator maleNobilityTitleGen;
73 private NobilityTitleGenerator femaleNobilityTitleGen;
74 private SalutationProvider salutationProvider;
75
76 private final BirthDateGenerator birthDateGenerator;
77 private EMailAddressBuilder emailGenerator;
78
79
80
81
82
83
84 public PersonGenerator() {
85 this(Country.getDefault().getIsoCode(), Locale.getDefault());
86 }
87
88
89
90
91
92
93 public PersonGenerator(String datasetName) {
94 this(datasetName, DatasetUtil.defaultLanguageForRegion(datasetName));
95 }
96
97
98
99
100
101
102
103 public PersonGenerator(String datasetName, Locale locale) {
104 super(Person.class);
105 logger.debug(
106 "Instantiating PersonGenerator with dataset '{}' and locale '{}'",
107 datasetName, locale);
108 this.datasetName = datasetName;
109 this.locale = locale;
110 genderGen = registerComponent(new GenderGenerator(0.5));
111 birthDateGenerator = registerComponent(new BirthDateGenerator(15, 105));
112 this.femaleFamilyNameConverters = new HashMap<>();
113 }
114
115
116
117
118
119
120
121
122 public void setMinAgeYears(int minAgeYears) {
123 birthDateGenerator.setMinAgeYears(minAgeYears);
124 }
125
126
127
128
129
130
131 public void setMaxAgeYears(int maxAgeYears) {
132 birthDateGenerator.setMaxAgeYears(maxAgeYears);
133 }
134
135
136
137
138
139
140 public double getFemaleQuota() {
141 return genderGen.getFemaleQuota();
142 }
143
144
145
146
147
148
149 public void setFemaleQuota(double femaleQuota) {
150 this.genderGen.setFemaleQuota(femaleQuota);
151 }
152
153
154
155
156
157
158 public double getNobleQuota() {
159 return maleNobilityTitleGen.getNobleQuota();
160 }
161
162
163
164
165
166
167 public void setNobleQuota(double nobleQuota) {
168 maleNobilityTitleGen.setNobleQuota(nobleQuota);
169 femaleNobilityTitleGen.setNobleQuota(nobleQuota);
170 }
171
172
173
174
175
176
177 public Locale getLocale() {
178 return acadTitleGen.getLocale();
179 }
180
181
182
183
184
185
186 public void setLocale(Locale locale) {
187 this.locale = locale;
188 }
189
190 @Override
191 public String getDataset() {
192 return datasetName;
193 }
194
195
196
197
198
199
200
201
202 public void setDataset(String datasetName) {
203 this.datasetName = datasetName;
204 }
205
206 @Override
207 public String getNesting() {
208 return REGION_NESTING;
209 }
210
211 @Override
212 public Person generateForDataset(String datasetToUse) {
213 assertInitialized();
214 Personon/Person.html#Person">Person person = new Person(acadTitleGen.getLocale());
215 person.setGender(generateNonNull(genderGen));
216 GivenNameGenerator givenNameGenerator
217 = (Gender.MALE.equals(person.getGender()) ? maleGivenNameGen :
218 femaleGivenNameGen);
219 String givenName = givenNameGenerator.generateForDataset(datasetToUse);
220 person.setGivenName(givenName);
221 if (generateNullable(secondNameTest)) {
222 do {
223 person.setSecondGivenName(
224 givenNameGenerator.generateForDataset(datasetToUse));
225 } while (person.getGivenName().equals(person.getSecondGivenName()));
226 }
227 String familyName = familyNameGen.generateForDataset(datasetToUse);
228 if (Gender.FEMALE.equals(person.getGender())) {
229 familyName = getFemaleFamilyNameConverter(datasetToUse)
230 .convert(familyName);
231 }
232 person.setFamilyName(familyName);
233 person.setSalutation(salutationProvider.salutation(person.getGender()));
234 person.setAcademicTitle(generateNullable(acadTitleGen));
235 NobilityTitleGenerator nobTitleGenerator
236 =
237 (Gender.MALE.equals(person.getGender()) ? maleNobilityTitleGen :
238 femaleNobilityTitleGen);
239 person.setNobilityTitle(generateNullable(nobTitleGenerator));
240 person.setBirthDate(generateNullable(birthDateGenerator));
241 person.setEmail(emailGenerator.generate(givenName, familyName));
242 return person;
243 }
244
245
246
247 @Override
248 public synchronized void init(GeneratorContext context) {
249 secondNameTest = registerAndInitComponent(new BooleanGenerator(0.2));
250 genderGen.init(context);
251 birthDateGenerator.init(context);
252 acadTitleGen =
253 registerAndInitComponent(new AcademicTitleGenerator(locale));
254 acadTitleGen.setLocale(locale);
255 maleNobilityTitleGen = registerAndInitComponent(
256 new NobilityTitleGenerator(Gender.MALE, locale));
257 femaleNobilityTitleGen = registerAndInitComponent(
258 new NobilityTitleGenerator(Gender.FEMALE, locale));
259 salutationProvider = new SalutationProvider(locale);
260
261 try {
262 initMembersWithDataset(context);
263 } catch (RuntimeException e) {
264 Country fallBackCountry = Country.getFallback();
265 if (!fallBackCountry.getIsoCode().equals(datasetName)) {
266 logger.error("Error initializing " + getClass().getSimpleName(),
267 e);
268 logger.error("Cannot generate persons for " + datasetName +
269 ", falling back to " + fallBackCountry);
270 this.datasetName = fallBackCountry.getIsoCode();
271 initMembersWithDataset(context);
272 } else {
273 throw e;
274 }
275 }
276 super.init(context);
277 }
278
279
280
281
282
283
284
285
286
287 protected <T extends Generator<U>, U> T registerAndInitComponent(
288 T generator) {
289 registerComponent(generator);
290 generator.init(context);
291 return generator;
292 }
293
294 @Override
295 public ProductWrapper<Person> generate(ProductWrapper<Person> wrapper) {
296 String usedDataset = randomDataset();
297 Person person = generateForDataset(usedDataset);
298 return wrapper.wrap(person).setTag(REGION_NESTING, usedDataset);
299 }
300
301 @Override
302 public Person generate() {
303 return generateForDataset(randomDataset());
304 }
305
306
307
308 private String randomDataset() {
309 return maleGivenNameGen.generate(new ProductWrapper<>())
310 .getTag(DatasetUtil.REGION_NESTING);
311 }
312
313 private Converter<String, String> getFemaleFamilyNameConverter(
314 String usedDataset) {
315 Converter<String, String> result =
316 femaleFamilyNameConverters.get(usedDataset);
317 if (result == null) {
318 result = new FemaleFamilyNameConverter(datasetName);
319 femaleFamilyNameConverters.put(usedDataset, result);
320 }
321 return result;
322 }
323
324 private void initMembersWithDataset(GeneratorContext context) {
325 maleGivenNameGen = registerAndInitComponent(
326 new GivenNameGenerator(datasetName, Gender.MALE));
327 femaleGivenNameGen = registerAndInitComponent(
328 new GivenNameGenerator(datasetName, Gender.FEMALE));
329 familyNameGen =
330 registerAndInitComponent(new FamilyNameGenerator(datasetName));
331 emailGenerator = new EMailAddressBuilder(datasetName);
332 emailGenerator.init(context);
333 }
334
335
336
337 @Override
338 public String toString() {
339 return getClass().getSimpleName();
340 }
341
342 }