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.engine;
28
29 import com.rapiddweller.benerator.BeneratorFactory;
30 import com.rapiddweller.benerator.engine.parser.String2DistributionConverter;
31 import com.rapiddweller.benerator.factory.DefaultsProvider;
32 import com.rapiddweller.benerator.factory.GeneratorFactory;
33 import com.rapiddweller.benerator.factory.StochasticGeneratorFactory;
34 import com.rapiddweller.benerator.script.BeneratorScriptFactory;
35 import com.rapiddweller.benerator.script.graaljs.GraalJsScriptFactory;
36 import com.rapiddweller.benerator.script.graalpy.GraalPyScriptFactory;
37 import com.rapiddweller.benerator.wrapper.ProductWrapper;
38 import com.rapiddweller.common.BeanUtil;
39 import com.rapiddweller.common.ConfigurationError;
40 import com.rapiddweller.common.Context;
41 import com.rapiddweller.common.ErrorHandler;
42 import com.rapiddweller.common.IOUtil;
43 import com.rapiddweller.common.Level;
44 import com.rapiddweller.common.LocaleUtil;
45 import com.rapiddweller.common.NullSafeComparator;
46 import com.rapiddweller.common.SystemInfo;
47 import com.rapiddweller.common.bean.ClassCache;
48 import com.rapiddweller.common.context.ContextStack;
49 import com.rapiddweller.common.context.DefaultContext;
50 import com.rapiddweller.common.context.SimpleContextStack;
51 import com.rapiddweller.common.converter.ConverterManager;
52 import com.rapiddweller.common.file.FileSuffixFilter;
53 import com.rapiddweller.domain.address.Country;
54 import com.rapiddweller.format.script.ScriptUtil;
55 import com.rapiddweller.model.data.ComplexTypeDescriptor;
56 import com.rapiddweller.model.data.ComponentDescriptor;
57 import com.rapiddweller.model.data.DataModel;
58 import com.rapiddweller.model.data.DefaultDescriptorProvider;
59 import com.rapiddweller.model.data.DescriptorProvider;
60 import com.rapiddweller.model.data.TypeDescriptor;
61
62 import java.io.File;
63 import java.util.Locale;
64 import java.util.Map.Entry;
65 import java.util.Objects;
66 import java.util.Set;
67 import java.util.concurrent.ExecutorService;
68 import java.util.concurrent.Executors;
69
70
71
72
73
74
75
76
77 public class DefaultBeneratorContext implements BeneratorContext {
78
79
80
81
82
83
84 public static final String CELL_SEPARATOR_SYSPROP = "cell.separator";
85
86
87
88 public static final char DEFAULT_CELL_SEPARATOR = ',';
89
90
91
92
93 private GeneratorFactory generatorFactory;
94 private final DefaultContext settings;
95 private final ClassCache classCache;
96 private final ContextStack contextStack;
97
98
99
100
101 protected String defaultEncoding = SystemInfo.getFileEncoding();
102
103
104
105 protected String defaultDataset = LocaleUtil.getDefaultCountryCode();
106
107
108
109 protected long defaultPageSize = 1;
110
111
112
113 protected boolean defaultNull = true;
114
115
116
117 protected String contextUri = "./";
118
119
120
121 public Long maxCount = null;
122
123
124
125 public boolean defaultOneToOne = false;
126
127
128
129 public boolean defaultImports = true;
130
131
132
133 public boolean acceptUnknownSimpleTypes = false;
134
135
136
137
138
139 protected ComplexTypeDescriptor defaultComponent;
140
141
142
143 protected ExecutorService executorService;
144
145 private ProductWrapper<?> currentProduct;
146
147 private DataModel dataModel;
148 private final DefaultDescriptorProvider localDescriptorProvider;
149
150
151
152
153 protected String currentProductName;
154
155
156
157
158 static {
159 ScriptUtil.addFactory("js", new GraalJsScriptFactory());
160 ScriptUtil.addFactory("py", new GraalPyScriptFactory());
161 ScriptUtil.addFactory("ben", new BeneratorScriptFactory());
162 ScriptUtil.setDefaultScriptEngine("ben");
163 ConverterManager.getInstance().registerConverterClass(String2DistributionConverter.class);
164 }
165
166
167
168
169 public DefaultBeneratorContext() {
170 this(".");
171 }
172
173
174
175
176
177
178 public DefaultBeneratorContext(String contextUri) {
179 if (contextUri == null) {
180 throw new ConfigurationError("No context URI specified");
181 }
182 this.contextUri = contextUri;
183 this.executorService = createExecutorService();
184 this.dataModel = new DataModel();
185 this.localDescriptorProvider = new DefaultDescriptorProvider("ctx", dataModel);
186 this.defaultComponent = new ComplexTypeDescriptor("benerator:defaultComponent", localDescriptorProvider);
187 this.generatorFactory = new StochasticGeneratorFactory();
188 settings = new DefaultContext();
189 this.contextStack = createContextStack(
190 new DefaultContext(java.lang.System.getenv()),
191 new DefaultContext(java.lang.System.getProperties()),
192 settings,
193 BeneratorFactory.getInstance().createGenerationContext()
194 );
195 set("context", this);
196 if (IOUtil.isFileUri(contextUri)) {
197 addLibFolderToClassLoader();
198 }
199 classCache = new ClassCache();
200 }
201
202
203
204
205 @Override
206 public GeneratorFactory getGeneratorFactory() {
207 return generatorFactory;
208 }
209
210 @Override
211 public void setGeneratorFactory(GeneratorFactory generatorFactory) {
212 this.generatorFactory = generatorFactory;
213 }
214
215 @Override
216 public DescriptorProvider getLocalDescriptorProvider() {
217 return localDescriptorProvider;
218 }
219
220 @Override
221 public void setDefaultsProvider(DefaultsProvider defaultsProvider) {
222 this.generatorFactory.setDefaultsProvider(defaultsProvider);
223 }
224
225 @Override
226 public String getDefaultEncoding() {
227 return defaultEncoding;
228 }
229
230 @Override
231 public void setDefaultEncoding(String defaultEncoding) {
232 SystemInfo.setFileEncoding(defaultEncoding);
233 this.defaultEncoding = defaultEncoding;
234 }
235
236 @Override
237 public String getDefaultLineSeparator() {
238 return SystemInfo.getLineSeparator();
239 }
240
241 @Override
242 public void setDefaultLineSeparator(String defaultLineSeparator) {
243 SystemInfo.setLineSeparator(defaultLineSeparator);
244 }
245
246 @Override
247 public Locale getDefaultLocale() {
248 return Locale.getDefault();
249 }
250
251 @Override
252 public void setDefaultLocale(Locale defaultLocale) {
253 Locale.setDefault(defaultLocale);
254 }
255
256 @Override
257 public String getDefaultDataset() {
258 return defaultDataset;
259 }
260
261 @Override
262 public void setDefaultDataset(String defaultDataset) {
263 this.defaultDataset = defaultDataset;
264 Country country = Country.getInstance(defaultDataset, false);
265 if (country != null) {
266 Country.setDefault(country);
267 }
268 }
269
270 @Override
271 public long getDefaultPageSize() {
272 return defaultPageSize;
273 }
274
275 @Override
276 public void setDefaultPageSize(long defaultPageSize) {
277 this.defaultPageSize = defaultPageSize;
278 }
279
280 @Override
281 public String getDefaultScript() {
282 return ScriptUtil.getDefaultScriptEngine();
283 }
284
285 @Override
286 public void setDefaultScript(String defaultScript) {
287 ScriptUtil.setDefaultScriptEngine(defaultScript);
288 }
289
290 @Override
291 public boolean isDefaultNull() {
292 return defaultNull;
293 }
294
295 @Override
296 public void setDefaultNull(boolean defaultNull) {
297 this.defaultNull = defaultNull;
298 }
299
300 @Override
301 public char getDefaultSeparator() {
302 return getDefaultCellSeparator();
303 }
304
305 @Override
306 public void setDefaultSeparator(char defaultSeparator) {
307 System.setProperty(CELL_SEPARATOR_SYSPROP, String.valueOf(defaultSeparator));
308 }
309
310 @Override
311 public ComponentDescriptor getDefaultComponentConfig(String name) {
312 return defaultComponent.getComponent(name);
313 }
314
315 @Override
316 public void setDefaultComponentConfig(ComponentDescriptor component) {
317 defaultComponent.addComponent(component);
318 }
319
320 @Override
321 public String getDefaultErrorHandler() {
322 return ErrorHandler.getDefaultLevel().name();
323 }
324
325 @Override
326 public void setDefaultErrorHandler(String defaultErrorHandler) {
327 ErrorHandler.setDefaultLevel(Level.valueOf(defaultErrorHandler));
328 }
329
330 @Override
331 public String getContextUri() {
332 return contextUri;
333 }
334
335 @Override
336 public void setContextUri(String contextUri) {
337 this.contextUri = contextUri;
338 }
339
340 @Override
341 public boolean isValidate() {
342 return BeneratorOpts.isValidating();
343 }
344
345 @Override
346 public void setValidate(boolean validate) {
347 BeneratorOpts.setValidating(validate);
348 }
349
350 @Override
351 public Long getMaxCount() {
352 return maxCount;
353 }
354
355 @Override
356 public void setMaxCount(Long maxCount) {
357 this.maxCount = maxCount;
358 }
359
360 @Override
361 public ExecutorService getExecutorService() {
362 return executorService;
363 }
364
365 @Override
366 public boolean isDefaultOneToOne() {
367 return defaultOneToOne;
368 }
369
370 @Override
371 public void setDefaultOneToOne(boolean defaultOneToOne) {
372 this.defaultOneToOne = defaultOneToOne;
373 }
374
375 @Override
376 public boolean isAcceptUnknownSimpleTypes() {
377 return acceptUnknownSimpleTypes;
378 }
379
380 @Override
381 public void setAcceptUnknownSimpleTypes(boolean acceptUnknownSimpleTypes) {
382 this.acceptUnknownSimpleTypes = acceptUnknownSimpleTypes;
383 dataModel.setAcceptUnknownPrimitives(acceptUnknownSimpleTypes);
384 }
385
386
387
388
389
390
391 public static char getDefaultCellSeparator() {
392 String tmp = System.getProperty(CELL_SEPARATOR_SYSPROP);
393 if (tmp == null) {
394 return DEFAULT_CELL_SEPARATOR;
395 }
396 if (tmp.length() != 1) {
397 throw new ConfigurationError("Cell separator has illegal length: '" + tmp + "'");
398 }
399 return tmp.charAt(0);
400 }
401
402 @Override
403 public DefaultsProvider getDefaultsProvider() {
404 return getGeneratorFactory().getDefaultsProvider();
405 }
406
407 @Override
408 public void setDefaultImports(boolean defaultImports) {
409 this.defaultImports = defaultImports;
410 }
411
412 @Override
413 public boolean isDefaultImports() {
414 return defaultImports;
415 }
416
417 @Override
418 public ProductWrapper<?> getCurrentProduct() {
419 return currentProduct;
420 }
421
422 @Override
423 public void setCurrentProduct(ProductWrapper<?> currentProduct) {
424 this.currentProduct = currentProduct;
425 }
426
427 @Override
428 public DataModel getDataModel() {
429 return dataModel;
430 }
431
432 @Override
433 public void setDataModel(DataModel dataModel) {
434 this.dataModel = dataModel;
435 }
436
437
438
439
440 @Override
441 public Object get(String key) {
442 if (contextStack.contains(key)) {
443 return contextStack.get(key);
444 } else if (key.equalsIgnoreCase(currentProductName) || "this".equalsIgnoreCase(key)) {
445 return currentProduct.unwrap();
446 } else {
447 return null;
448 }
449 }
450
451 @Override
452 public void set(String key, Object value) {
453 contextStack.set(key, value);
454 }
455
456 @Override
457 public void remove(String key) {
458 contextStack.remove(key);
459 }
460
461 @Override
462 public Set<String> keySet() {
463 return contextStack.keySet();
464 }
465
466 @Override
467 public Set<Entry<String, Object>> entrySet() {
468 return contextStack.entrySet();
469 }
470
471 @Override
472 public boolean contains(String key) {
473 return (key != null && (key.equalsIgnoreCase(currentProductName) || "this".equalsIgnoreCase(key) || contextStack.contains(key)));
474 }
475
476
477
478
479 @Override
480 public Class<?> forName(String className) {
481 return classCache.forName(className);
482 }
483
484 @Override
485 public void importClass(String className) {
486 classCache.importClass(className);
487 }
488
489 @Override
490 public void importPackage(String packageName) {
491 classCache.importPackage(packageName);
492 }
493
494 @Override
495 public void importDefaults() {
496
497 importPackage("com.rapiddweller.benerator.consumer");
498 importPackage("com.rapiddweller.benerator.primitive");
499 importPackage("com.rapiddweller.benerator.primitive.datetime");
500 importPackage("com.rapiddweller.benerator.distribution.sequence");
501 importPackage("com.rapiddweller.benerator.distribution.function");
502 importPackage("com.rapiddweller.benerator.distribution.cumulative");
503 importPackage("com.rapiddweller.benerator.sample");
504
505 importPackage("com.rapiddweller.model.consumer");
506
507 importPackage("com.rapiddweller.common.converter");
508 importPackage("com.rapiddweller.common.format");
509 importPackage("com.rapiddweller.common.validator");
510
511 importPackage("com.rapiddweller.platform.fixedwidth");
512 importPackage("com.rapiddweller.platform.csv");
513 importPackage("com.rapiddweller.platform.dbunit");
514 importPackage("com.rapiddweller.platform.xls");
515 importPackage("com.rapiddweller.platform.template");
516 }
517
518
519
520
521 @Override
522 public void setGlobal(String name, Object value) {
523 settings.set(name, value);
524 }
525
526 @Override
527 public Object getGlobal(String name) {
528 return settings.get(name);
529 }
530
531 @Override
532 public void close() {
533 executorService.shutdownNow();
534 }
535
536 @Override
537 public void addLocalType(TypeDescriptor type) {
538 localDescriptorProvider.addTypeDescriptor(type);
539 }
540
541 @Override
542 public BeneratorContext createSubContext(String productName) {
543 return new DefaultBeneratorSubContext(productName, this);
544 }
545
546
547
548
549
550
551
552 public void setCurrentProduct(ProductWrapper<?> currentProduct, String currentProductName) {
553 this.currentProductName = currentProductName;
554 setCurrentProduct(currentProduct);
555 }
556
557 @Override
558 public boolean hasProductNameInScope(String productName) {
559 return (NullSafeComparator.equals(this.currentProductName, productName));
560 }
561
562 @Override
563 public String resolveRelativeUri(String relativeUri) {
564 return IOUtil.resolveRelativeUri(relativeUri, contextUri);
565 }
566
567
568
569
570 private void addLibFolderToClassLoader() {
571 File libFolder = new File(contextUri, "lib");
572 if (libFolder.exists()) {
573 Thread.currentThread().setContextClassLoader(BeanUtil.createDirectoryClassLoader(libFolder));
574 for (File jarFile : Objects.requireNonNull(libFolder.listFiles(new FileSuffixFilter("jar", false)))) {
575 ClassLoader classLoader = BeanUtil.createJarClassLoader(jarFile);
576 Thread.currentThread().setContextClassLoader(classLoader);
577 }
578 }
579 }
580
581
582
583
584
585
586 protected ExecutorService createExecutorService() {
587 return Executors.newSingleThreadExecutor();
588 }
589
590
591
592
593
594
595
596 protected ContextStack createContextStack(Context... contexts) {
597 return new SimpleContextStack(contexts);
598 }
599
600
601
602
603 @Override
604 public String toString() {
605 return getClass() + "[" + currentProductName + "]";
606 }
607
608 }