/
DataFactory.java
370 lines (328 loc) · 10.2 KB
/
DataFactory.java
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
package org.datafactory;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import org.datafactory.values.NameDataValues;
import org.datafactory.values.AddressDataValues;
import org.datafactory.values.ContentDataValues;
import org.datafactory.values.impl.RBAddressDataValues;
import org.datafactory.values.impl.RBContentDataValues;
public class DataFactory {
private static Random random = new Random(93285);
private Locale locale;
private NameDataValues nameDataValues;
private AddressDataValues addressDataValues;
private ContentDataValues contentDataValues;
public DataFactory(Locale locale) {
this.locale = locale;
}
public DataFactory(String locale) {
this.locale = new Locale(locale);
}
public DataFactory() {
this.locale = Locale.getDefault();
}
/**
* Returns a random item from a list of items.
*
* @param <T>
* Item type in the list and to return
* @param items
* List of items to choose from
* @return Item from the list
*/
public <T> T getItem(List<T> items) {
return getItem(items, 100, null);
}
/**
* Returns a random item from a list of items or the null depending on the
* probability parameter. The probability determines the chance (in %) of
* returning an item off the list versus null.
*
* @param <T>
* Item type in the list and to return
* @param items
* List of items to choose from
* @param probability
* chance (in %, 100 being guaranteed) of returning an item from
* the list
* @return Item from the list or null if the probability test fails.
*/
public <T> T getItem(List<T> items, int probability) {
return getItem(items, probability, null);
}
/**
* Returns a random item from a list of items or the defaultItem depending
* on the probability parameter. The probability determines the chance (in
* %) of returning an item off the list versus the default value.
*
* @param <T>
* Item type in the list and to return
* @param items
* List of items to choose from
* @param probability
* chance (in %, 100 being guaranteed) of returning an item from
* the list
* @param defaultItem
* value to return if the probability test fails
* @return Item from the list or the default value
*/
public <T> T getItem(List<T> items, int probability, T defaultItem) {
if (items == null) {
throw new IllegalArgumentException("Item list cannot be null");
}
if (items.isEmpty()) {
throw new IllegalArgumentException("Item list cannot be empty");
}
return chance(probability) ? items.get(random.nextInt(items.size()))
: defaultItem;
}
/**
* Returns a random item from an array of items
*
* @param <T>
* Array item type and the type to return
* @param items
* Array of items to choose from
* @return Item from the array
*/
public <T> T getItem(T[] items) {
return getItem(items, 100, null);
}
/**
* Returns a random item from an array of items or null depending on the
* probability parameter. The probability determines the chance (in %) of
* returning an item from the array versus null.
*
* @param <T>
* Array item type and the type to return
* @param items
* Array of items to choose from
* @param probability
* chance (in %, 100 being guaranteed) of returning an item from
* the array
* @return Item from the array or the default value
*/
public <T> T getItem(T[] items, int probability) {
return getItem(items, probability, null);
}
/**
* Returns a random item from an array of items or the defaultItem depending
* on the probability parameter. The probability determines the chance (in
* %) of returning an item from the array versus the default value.
*
* @param <T>
* Array item type and the type to return
* @param items
* Array of items to choose from
* @param probability
* chance (in %, 100 being guaranteed) of returning an item from
* the array
* @param defaultItem
* value to return if the probability test fails
* @return Item from the array or the default value
*/
public <T> T getItem(T[] items, int probability, T defaultItem) {
if (items == null) {
throw new IllegalArgumentException("Item array cannot be null");
}
if (items.length == 0) {
throw new IllegalArgumentException("Item array cannot be empty");
}
return chance(probability) ? items[random.nextInt(items.length)]
: defaultItem;
}
/**
* Gives you a true/false based on a probability with a random number
* generator. Can be used to optionally add elements.
*
* <pre>
* if (DataFactory.chance(70)) {
* // 70% chance of this code being executed
* }
* </pre>
*
* @param chance
* % chance of returning true
* @return
*/
public boolean chance(int chance) {
return random.nextInt(100) < chance;
}
/**
* Call randomize with a seed value to reset the random number generator. By
* using the same seed over different tests, you will should get the same
* results out for the same data generation calls.
*
* @param seed
* Seed value to use to generate random numbers
*/
public void randomize(int seed) {
random = new Random(seed);
}
// address data
public AddressDataValues getAddressDataValues() {
initAddressDataValues();
return addressDataValues;
}
public String getStreetName() {
return getItem(getAddressDataValues().getStreetNames());
}
public String getStreetSuffix() {
return getItem(getAddressDataValues().getAddressSuffixes());
}
public String getCity() {
return getItem(getAddressDataValues().getCities());
}
// content data
/**
* @return a random character
*/
public char getRandomChar() {
return (char) (random.nextInt(26) + 'a');
}
/**
* Return a string containing <code>length</code> random characters
*
* @param length
* number of characters to use in the string
* @return A string containing <code>length</code> random characters
*/
public String getRandomChars(int length) {
return getRandomChars(length, length);
}
/**
* Return a string containing between <code>length</code> random characters
*
* @param length
* number of characters to use in the string
* @return A string containing <code>length</code> random characters
*/
public String getRandomChars(int minLength, int maxLength) {
validateMinMaxParams(minLength, maxLength);
StringBuilder sb = new StringBuilder(maxLength);
int length = minLength;
if (maxLength != minLength) {
length = length + random.nextInt(maxLength - minLength);
}
while (length > 0) {
sb.append(getRandomChar());
length--;
}
return sb.toString();
}
public String getRandomUnicode() {
byte[] str = new byte[2];
int chr = random.nextInt(0x51A5) + 0x4E00;
str[1] = (byte) ((chr & 0xFF00) >> 8);
str[0] = (byte) (chr & 0xFF);
try {
return new String(str, "UTF-16LE");
} catch (UnsupportedEncodingException e) {
return null;
}
}
public String getRandomUnicodes(int length) {
return getRandomUnicodes(length, length);
}
public String getRandomUnicodes(int minLength, int maxLength) {
validateMinMaxParams(minLength, maxLength);
StringBuilder sb = new StringBuilder(maxLength);
int length = minLength;
if (maxLength != minLength) {
length = length + random.nextInt(maxLength - minLength);
}
while (length > 0) {
sb.append(getRandomUnicode());
length--;
}
return sb.toString();
}
public ContentDataValues getContentDataValues() {
initContentDataValues();
return contentDataValues;
}
// date data
/**
* Builds a date from the year, month, day values passed in
*
*/
public Date getDate(int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, month - 1, day, 0, 0, 0);
return cal.getTime();
}
/**
* Returns a random date which is in the range <code>baseData</code> +
* <code>minDaysFromData</code> to <code>baseData</code> +
* <code>maxDaysFromData</code>. This method does not alter the time
* component and the time is set to the time value of the base date.
*
*/
public Date getDate(Date baseDate, int minDaysFromDate, int maxDaysFromDate) {
Calendar cal = Calendar.getInstance();
cal.setTime(baseDate);
int diff = minDaysFromDate
+ (random.nextInt(maxDaysFromDate - minDaysFromDate));
cal.add(Calendar.DATE, diff);
return cal.getTime();
}
/**
* Returns a random date between two dates. This method will alter the time
* component of the dates
*
*/
public Date getDateBetween(Date minDate, Date maxDate) {
// this can break if seconds is an int
long seconds = (maxDate.getTime() - minDate.getTime()) / 1000;
seconds = (long) (random.nextDouble() * seconds);
Date result = new Date();
result.setTime(minDate.getTime() + (seconds * 1000));
return result;
}
public Date getBirthDate() {
Date base = new Date(0);
return getDate(base, -365 * 15, 365 * 15);
}
// private methods
private void initAddressDataValues() {
if (addressDataValues == null) {
addressDataValues = new RBAddressDataValues(locale);
}
}
private void initContentDataValues() {
if (contentDataValues == null) {
contentDataValues = new RBContentDataValues(locale);
}
}
private void validateMinMaxParams(int minLength, int maxLength) {
if (minLength < 0) {
throw new IllegalArgumentException(
"Minimum length must be a non-negative number");
}
if (maxLength < 0) {
throw new IllegalArgumentException(
"Maximum length must be a non-negative number");
}
if (maxLength < minLength) {
throw new IllegalArgumentException(
String.format(
"Minimum length must be less than maximum length (min=%d, max=%d)",
minLength, maxLength));
}
}
public static void main(String[] args) {
DataFactory df = new DataFactory(new Locale("zh", "CN"));
for (int i = 0; i < 50; i++) {
// System.out.println(df.getCity() + df.getStreetSuffix()
// + df.getStreetName());
System.out.println(df.getRandomChars(2, 50));
System.out.println(df.getRandomUnicodes(2, 50));
System.out.println(df.getBirthDate());
}
}
}