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.StorageSystem;
31 import com.rapiddweller.benerator.composite.ArrayElementTypeConverter;
32 import com.rapiddweller.benerator.composite.BlankArrayGenerator;
33 import com.rapiddweller.benerator.distribution.DistributingGenerator;
34 import com.rapiddweller.benerator.distribution.Distribution;
35 import com.rapiddweller.benerator.engine.BeneratorContext;
36 import com.rapiddweller.benerator.engine.expression.ScriptExpression;
37 import com.rapiddweller.benerator.util.FilteringGenerator;
38 import com.rapiddweller.benerator.wrapper.DataSourceGenerator;
39 import com.rapiddweller.benerator.wrapper.WrapperFactory;
40 import com.rapiddweller.common.ConfigurationError;
41 import com.rapiddweller.common.StringUtil;
42 import com.rapiddweller.common.context.ContextAware;
43 import com.rapiddweller.format.script.ScriptConverterForObjects;
44 import com.rapiddweller.format.script.ScriptConverterForStrings;
45 import com.rapiddweller.format.script.ScriptUtil;
46 import com.rapiddweller.format.util.DataFileUtil;
47 import com.rapiddweller.model.data.ArrayElementDescriptor;
48 import com.rapiddweller.model.data.ArrayTypeDescriptor;
49 import com.rapiddweller.model.data.Entity;
50 import com.rapiddweller.model.data.EntitySource;
51 import com.rapiddweller.model.data.Mode;
52 import com.rapiddweller.model.data.Uniqueness;
53 import com.rapiddweller.platform.array.Entity2ArrayConverter;
54 import com.rapiddweller.platform.csv.CSVArraySourceProvider;
55 import com.rapiddweller.platform.xls.XLSArraySourceProvider;
56 import com.rapiddweller.script.BeanSpec;
57 import com.rapiddweller.script.DatabeneScriptParser;
58 import com.rapiddweller.script.Expression;
59
60
61
62
63
64
65
66
67 public class ArrayTypeGeneratorFactory extends TypeGeneratorFactory<ArrayTypeDescriptor> {
68
69 @Override
70 protected Generator<Object[]> createSourceGenerator(
71 ArrayTypeDescriptor descriptor, Uniqueness uniqueness, BeneratorContext context) {
72
73 String sourceName = descriptor.getSource();
74 if (sourceName == null) {
75 return null;
76 }
77
78 Generator<Object[]> generator = null;
79 Object contextSourceObject = context.get(sourceName);
80 if (contextSourceObject != null) {
81 generator = createSourceGeneratorFromObject(descriptor, context, contextSourceObject);
82 } else {
83 if (DataFileUtil.isCsvDocument(sourceName)) {
84 generator = createCSVSourceGenerator(descriptor, context, sourceName);
85 } else if (DataFileUtil.isExcelDocument(sourceName)) {
86 generator = createXLSSourceGenerator(descriptor, context, sourceName);
87 } else {
88 try {
89 BeanSpec sourceBeanSpec = DatabeneScriptParser.resolveBeanSpec(sourceName, context);
90 Object sourceObject = sourceBeanSpec.getBean();
91 if (!sourceBeanSpec.isReference() && sourceObject instanceof ContextAware) {
92 ((ContextAware) sourceObject).setContext(context);
93 }
94 generator = createSourceGeneratorFromObject(descriptor, context, sourceObject);
95 if (sourceBeanSpec.isReference()) {
96 generator = WrapperFactory.preventClosing(generator);
97 }
98 return generator;
99 } catch (Exception e) {
100 throw new UnsupportedOperationException("Unknown source type: " + sourceName);
101 }
102 }
103 }
104 if (descriptor.getFilter() != null) {
105 Expression<Boolean> filter
106 = new ScriptExpression<>(ScriptUtil.parseScriptText(descriptor.getFilter()));
107 generator = new FilteringGenerator<>(generator, filter);
108 }
109 Distribution distribution = FactoryUtil.getDistribution(descriptor.getDistribution(), uniqueness, false, context);
110 if (distribution != null) {
111 generator = new DistributingGenerator<>(generator, distribution, uniqueness.isUnique());
112 }
113 return generator;
114 }
115
116 @Override
117 protected Generator<?> createSpecificGenerator(ArrayTypeDescriptor descriptor, String instanceName,
118 boolean nullable, Uniqueness uniqueness, BeneratorContext context) {
119 return null;
120 }
121
122 @Override
123 protected Generator<?> createHeuristicGenerator(
124 ArrayTypeDescriptor descriptor, String instanceName,
125 Uniqueness uniqueness, BeneratorContext context) {
126 return new BlankArrayGenerator(descriptor.getElementCount());
127 }
128
129 @SuppressWarnings({"rawtypes", "unchecked"})
130 @Override
131 protected Generator<?> applyComponentBuilders(Generator<?> generator, ArrayTypeDescriptor descriptor, String instanceName,
132 Uniqueness uniqueness, BeneratorContext context) {
133 Generator[] generators;
134
135 if (generator instanceof BlankArrayGenerator) {
136 generators = createSyntheticElementGenerators(descriptor, uniqueness, context);
137 generator = context.getGeneratorFactory().createCompositeArrayGenerator(
138 Object.class, generators, uniqueness);
139 }
140
141 generator = super.applyComponentBuilders(generator, descriptor, instanceName, uniqueness, context);
142 return generator;
143 }
144
145 @Override
146 protected Class<?> getGeneratedType(ArrayTypeDescriptor descriptor) {
147 return Object[].class;
148 }
149
150
151
152 private Generator<Object[]> createCSVSourceGenerator(ArrayTypeDescriptor arrayType, BeneratorContext context,
153 String sourceName) {
154 logger.debug("createCSVSourceGenerator({})", arrayType);
155 String encoding = arrayType.getEncoding();
156 if (encoding == null) {
157 encoding = context.getDefaultEncoding();
158 }
159 char separator = DescriptorUtil.getSeparator(arrayType, context);
160 boolean rowBased = (arrayType.isRowBased() != null ? arrayType.isRowBased() : true);
161 DataSourceProvider<Object[]> factory =
162 new CSVArraySourceProvider(arrayType.getName(), new ScriptConverterForStrings(context), rowBased, separator, encoding);
163 Generator<Object[]> generator =
164 SourceFactory.createRawSourceGenerator(arrayType.getNesting(), arrayType.getDataset(), sourceName, factory, Object[].class, context);
165 return WrapperFactory.applyConverter(generator, new ArrayElementTypeConverter(arrayType));
166 }
167
168 private Generator<Object[]> createXLSSourceGenerator(
169 ArrayTypeDescriptor arrayType, BeneratorContext context, String sourceName) {
170 logger.debug("createXLSSourceGenerator({})", arrayType);
171 boolean rowBased = (arrayType.isRowBased() != null ? arrayType.isRowBased() : true);
172 String emptyMarker = arrayType.getEmptyMarker();
173 String nullMarker = arrayType.getNullMarker();
174 boolean formatted = isFormatted(arrayType);
175 DataSourceProvider<Object[]> factory = new XLSArraySourceProvider(formatted,
176 new ScriptConverterForObjects(context), emptyMarker, nullMarker, rowBased);
177 Generator<Object[]> generator =
178 SourceFactory.createRawSourceGenerator(arrayType.getNesting(), arrayType.getDataset(), sourceName, factory, Object[].class, context);
179 generator = WrapperFactory.applyConverter(generator, new ArrayElementTypeConverter(arrayType));
180 return generator;
181 }
182
183 @SuppressWarnings({"unchecked", "rawtypes"})
184 private static Generator<Object[]> createSourceGeneratorFromObject(ArrayTypeDescriptor descriptor,
185 BeneratorContext context, Object sourceObject) {
186 Generator<Object[]> generator;
187 if (sourceObject instanceof StorageSystem) {
188 StorageSystem/../com/rapiddweller/benerator/StorageSystem.html#StorageSystem">StorageSystem storage = (StorageSystem) sourceObject;
189 String selector = descriptor.getSelector();
190 String subSelector = descriptor.getSubSelector();
191 if (!StringUtil.isEmpty(subSelector)) {
192 generator = WrapperFactory.applyHeadCycler(new DataSourceGenerator(storage.query(subSelector, false, context)));
193 } else {
194 generator = new DataSourceGenerator(storage.query(selector, false, context));
195 }
196 } else if (sourceObject instanceof EntitySource) {
197 DataSourceGenerator<Entity> entityGenerator = new DataSourceGenerator<>((EntitySource) sourceObject);
198 generator = WrapperFactory.applyConverter(entityGenerator, new Entity2ArrayConverter());
199 } else if (sourceObject instanceof Generator) {
200 generator = (Generator<Object[]>) sourceObject;
201 } else {
202 throw new ConfigurationError("Source type not supported: " + sourceObject.getClass());
203 }
204 return generator;
205 }
206
207 @SuppressWarnings("rawtypes")
208 private Generator<?>[] createSyntheticElementGenerators(
209 ArrayTypeDescriptor arrayType, Uniqueness uniqueness, BeneratorContext context) {
210 Generatortor.html#Generator">Generator[] result = new Generator[arrayType.getElementCount()];
211 for (int i = 0; i < arrayType.getElementCount(); i++) {
212 ArrayElementDescriptor element = getElementOfTypeOrParents(arrayType, i);
213 if (element.getMode() != Mode.ignored) {
214 Generator<?> generator = InstanceGeneratorFactory.createSingleInstanceGenerator(
215 element, uniqueness, context);
216 result[i] = generator;
217 }
218 }
219 return result;
220 }
221
222
223
224
225
226
227
228
229 protected ArrayElementDescriptor getElementOfTypeOrParents(ArrayTypeDescriptor arrayType, int index) {
230 ArrayTypeDescriptor tmp = arrayType;
231 ArrayElementDescriptor result;
232 while ((result = tmp.getElement(index)) == null && tmp.getParent() != null) {
233 tmp = tmp.getParent();
234 }
235 return result;
236 }
237
238 }