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.benerator.factory;
28
29 import com.rapiddweller.benerator.Generator;
30 import com.rapiddweller.benerator.GeneratorProvider;
31 import com.rapiddweller.benerator.NonNullGenerator;
32 import com.rapiddweller.benerator.distribution.Distribution;
33 import com.rapiddweller.benerator.distribution.SequenceManager;
34 import com.rapiddweller.benerator.primitive.CharacterGenerator;
35 import com.rapiddweller.benerator.primitive.datetime.DateGenerator;
36 import com.rapiddweller.benerator.sample.AttachedWeightSampleGenerator;
37 import com.rapiddweller.benerator.sample.ConstantGenerator;
38 import com.rapiddweller.benerator.sample.SequenceGenerator;
39 import com.rapiddweller.benerator.wrapper.WrapperFactory;
40 import com.rapiddweller.common.Assert;
41 import com.rapiddweller.common.ConfigurationError;
42 import com.rapiddweller.common.TimeUtil;
43 import com.rapiddweller.common.validator.StringLengthValidator;
44 import com.rapiddweller.format.regex.RegexParser;
45 import com.rapiddweller.format.regex.RegexPart;
46 import com.rapiddweller.model.data.Uniqueness;
47 import com.rapiddweller.script.WeightedSample;
48
49 import java.util.Calendar;
50 import java.util.Collection;
51 import java.util.Date;
52 import java.util.Locale;
53 import java.util.Objects;
54 import java.util.Set;
55
56
57
58
59
60
61
62
63
64 public abstract class GeneratorFactory {
65
66
67
68
69 protected DefaultsProvider defaultsProvider;
70
71
72
73
74 protected GeneratorFactory() {
75 this(null);
76 }
77
78
79
80
81
82
83 protected GeneratorFactory(DefaultsProvider defaultsProvider) {
84 this.defaultsProvider = defaultsProvider;
85 }
86
87
88
89
90
91
92 public DefaultsProvider getDefaultsProvider() {
93 return defaultsProvider;
94 }
95
96
97
98
99
100
101 public void setDefaultsProvider(DefaultsProvider defaultsProvider) {
102 this.defaultsProvider = defaultsProvider;
103 }
104
105
106
107
108
109
110
111
112
113
114
115 public abstract <T> Generator<T> createAlternativeGenerator(Class<T> targetType, Generator<T>[] sources,
116 Uniqueness uniqueness);
117
118
119
120
121
122
123
124
125
126 public Generator<Boolean> createBooleanGenerator(Double trueQuota) {
127 SequenceGenerator<Boolean> generator = new SequenceGenerator<>(Boolean.class);
128 if (trueQuota == null || trueQuota < 1) {
129 generator.addValue(false);
130 }
131 if (trueQuota == null || trueQuota > 0) {
132 generator.addValue(true);
133 }
134 return generator;
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 public <T extends Number> NonNullGenerator<T> createNumberGenerator(
154 Class<T> numberType, T min, Boolean minInclusive, T max, Boolean maxInclusive, T granularity,
155 Distribution distribution, Uniqueness uniqueness) {
156 Assert.notNull(numberType, "numberType");
157 if (min != null && min.equals(max)) {
158 return WrapperFactory.asNonNullGenerator(new ConstantGenerator<>(min));
159 }
160 if (min == null) {
161 min = defaultsProvider.defaultMin(numberType);
162 }
163 if (granularity == null) {
164 granularity = defaultsProvider.defaultGranularity(numberType);
165 }
166 if (distribution == null) {
167 if (Uniqueness.ORDERED == uniqueness) {
168 distribution = SequenceManager.STEP_SEQUENCE;
169 } else {
170 distribution = defaultDistribution(uniqueness);
171 }
172 }
173 return distribution.createNumberGenerator(numberType, min, max, granularity, uniqueness.isUnique());
174 }
175
176
177
178
179
180
181
182
183
184
185
186
187
188 public abstract <T> Generator<T> createFromWeightedLiteralList(String valueSpec, Class<T> targetType,
189 Distribution distribution, boolean unique);
190
191
192
193
194
195
196
197
198
199
200 public abstract <T> Generator<T> createSampleGenerator(Collection<T> values, Class<T> generatedType, boolean unique);
201
202
203
204
205
206
207
208
209
210 public <T> Generator<T> createWeightedSampleGenerator(Collection<WeightedSample<T>> samples, Class<T> targetType) {
211 AttachedWeightSampleGenerator<T> generator = new AttachedWeightSampleGenerator<>(targetType);
212 for (WeightedSample<T> sample : samples) {
213 generator.addSample(sample.getValue(), sample.getWeight());
214 }
215 return generator;
216 }
217
218
219
220
221
222
223
224
225
226
227
228
229 public Generator<Date> createDateGenerator(
230 Date min, Date max, long granularity, Distribution distribution) {
231 if (min == null) {
232 if (max == null) {
233 min = TimeUtil.date(1970, 0, 1);
234 max = new Date();
235 } else {
236 min = TimeUtil.add(max, Calendar.DATE, -365);
237 }
238 } else if (max == null) {
239 max = TimeUtil.add(min, Calendar.DATE, 365);
240 }
241 return new DateGenerator(min, max, granularity, distribution);
242 }
243
244
245
246
247
248
249
250
251
252
253
254 public Generator<Character> createCharacterGenerator(String pattern, Locale locale, boolean unique) {
255 Set<Character> chars = FactoryUtil.fullLocaleCharSet(pattern, locale);
256 if (unique) {
257 return new SequenceGenerator<>(Character.class, chars);
258 } else {
259 return new CharacterGenerator(chars);
260 }
261 }
262
263
264
265
266
267
268
269 public NonNullGenerator<Character> createCharacterGenerator(Set<Character> characters) {
270 return new CharacterGenerator(defaultSubSet(characters));
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285 public Generator<String> createStringGenerator(String pattern,
286 Locale locale, Integer minLength, Integer maxLength, int lengthGranularity,
287 Distribution lengthDistribution, Uniqueness uniqueness) {
288 if (pattern != null) {
289 RegexPart regex = new RegexParser().parseRegex(pattern);
290 int regexMinLength = regex.minLength();
291 Integer regexMaxLength = regex.maxLength();
292 if (maxLength == null) {
293 maxLength = Objects.requireNonNullElseGet(regexMaxLength, () -> Math.max(regexMinLength * 2, defaultsProvider.defaultMaxLength()));
294 }
295
296 if (minLength == null) {
297 minLength = regexMinLength;
298 }
299 } else {
300 pattern = "[A-Z]*";
301 if (maxLength == null) {
302 maxLength = defaultsProvider.defaultMaxLength();
303 }
304 if (minLength == null) {
305 minLength = defaultsProvider.defaultMinLength();
306 }
307 }
308 if (lengthDistribution != null) {
309 Set<Character> chars = new RegexParser(locale).parseSingleChar(pattern).getCharSet().getSet();
310 return createStringGenerator(
311 chars, minLength, maxLength, lengthGranularity, lengthDistribution, uniqueness);
312 }
313 if (locale == null) {
314 locale = FactoryUtil.defaultLocale();
315 }
316 return createRegexStringGenerator(pattern, minLength, maxLength, uniqueness);
317 }
318
319
320
321
322
323
324
325
326
327
328
329
330 public abstract NonNullGenerator<String> createStringGenerator(Set<Character> chars,
331 Integer minLength, Integer maxLength, int lengthGranularity,
332 Distribution lengthDistribution,
333 Uniqueness uniqueness);
334
335
336
337
338
339
340
341
342
343
344 public abstract NonNullGenerator<String> createCompositeStringGenerator(
345 GeneratorProvider<?> partGeneratorProvider, int minParts, int maxParts, Uniqueness uniqueness);
346
347
348
349
350
351
352
353
354
355
356
357 public NonNullGenerator<String> createRegexStringGenerator(String pattern, int minLength, Integer maxLength,
358 Uniqueness uniqueness) throws ConfigurationError {
359 NonNullGenerator<String> generator = RegexGeneratorFactory.create(pattern, minLength, maxLength, uniqueness, this);
360 StringLengthValidator validator = new StringLengthValidator(minLength, maxLength);
361 return WrapperFactory.asNonNullGenerator(WrapperFactory.applyValidator(validator, generator));
362 }
363
364
365
366
367
368
369
370
371
372
373
374
375 public abstract <T> Generator<T[]> createCompositeArrayGenerator(
376 Class<T> componentType, Generator<T>[] sources, Uniqueness uniqueness);
377
378
379
380
381
382
383
384
385
386
387
388 public abstract <T> Generator<T> createSingleValueGenerator(T value, boolean unique);
389
390
391
392
393
394
395
396
397
398 public abstract Generator<?> applyNullSettings(Generator<?> source, Boolean nullable, Double nullQuota);
399
400
401
402
403
404
405
406
407 public abstract <T> Generator<T> createNullGenerator(Class<T> generatedType);
408
409
410
411
412
413
414
415
416
417
418 public Set<Character> defaultSubSet(Set<Character> characters) {
419 return characters;
420 }
421
422
423
424
425
426
427 protected abstract boolean defaultUnique();
428
429
430
431
432
433
434 protected abstract double defaultTrueQuota();
435
436
437
438
439
440
441
442 public abstract Distribution defaultDistribution(Uniqueness uniqueness);
443
444
445
446
447
448
449
450
451 protected abstract Distribution defaultLengthDistribution(Uniqueness uniqueness, boolean required);
452
453 }