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.BlankEntityGenerator;
32 import com.rapiddweller.benerator.composite.ComponentTypeConverter;
33 import com.rapiddweller.benerator.composite.GeneratorComponent;
34 import com.rapiddweller.benerator.composite.SimpleTypeEntityGenerator;
35 import com.rapiddweller.benerator.composite.SourceAwareGenerator;
36 import com.rapiddweller.benerator.distribution.DistributingGenerator;
37 import com.rapiddweller.benerator.distribution.Distribution;
38 import com.rapiddweller.benerator.engine.BeneratorContext;
39 import com.rapiddweller.benerator.engine.expression.ScriptExpression;
40 import com.rapiddweller.benerator.util.FilteringGenerator;
41 import com.rapiddweller.benerator.wrapper.DataSourceGenerator;
42 import com.rapiddweller.benerator.wrapper.EntityPartSource;
43 import com.rapiddweller.benerator.wrapper.WrapperFactory;
44 import com.rapiddweller.common.ConfigurationError;
45 import com.rapiddweller.common.Converter;
46 import com.rapiddweller.common.StringUtil;
47 import com.rapiddweller.format.DataSource;
48 import com.rapiddweller.format.fixedwidth.FixedWidthColumnDescriptor;
49 import com.rapiddweller.format.fixedwidth.FixedWidthRowTypeDescriptor;
50 import com.rapiddweller.format.fixedwidth.FixedWidthUtil;
51 import com.rapiddweller.format.script.ScriptConverterForStrings;
52 import com.rapiddweller.format.script.ScriptUtil;
53 import com.rapiddweller.format.util.DataFileUtil;
54 import com.rapiddweller.model.data.ComplexTypeDescriptor;
55 import com.rapiddweller.model.data.ComponentDescriptor;
56 import com.rapiddweller.model.data.Entity;
57 import com.rapiddweller.model.data.EntitySource;
58 import com.rapiddweller.model.data.InstanceDescriptor;
59 import com.rapiddweller.model.data.Mode;
60 import com.rapiddweller.model.data.TypeDescriptor;
61 import com.rapiddweller.model.data.Uniqueness;
62 import com.rapiddweller.platform.csv.CSVEntitySourceProvider;
63 import com.rapiddweller.platform.dbunit.DbUnitEntitySource;
64 import com.rapiddweller.platform.fixedwidth.FixedWidthEntitySource;
65 import com.rapiddweller.platform.xls.XLSEntitySourceProvider;
66 import com.rapiddweller.script.BeanSpec;
67 import com.rapiddweller.script.DatabeneScriptParser;
68 import com.rapiddweller.script.Expression;
69
70 import java.text.ParseException;
71 import java.util.ArrayList;
72 import java.util.List;
73
74
75
76
77
78
79
80
81 public class ComplexTypeGeneratorFactory extends TypeGeneratorFactory<ComplexTypeDescriptor> {
82
83 private static final ComplexTypeGeneratorFactoryatorFactory.html#ComplexTypeGeneratorFactory">ComplexTypeGeneratorFactory INSTANCE = new ComplexTypeGeneratorFactory();
84
85
86
87
88
89
90 public static ComplexTypeGeneratorFactory getInstance() {
91 return INSTANCE;
92 }
93
94
95
96
97 protected ComplexTypeGeneratorFactory() {
98 }
99
100 @Override
101 protected Generator<?> applyComponentBuilders(Generator<?> generator, ComplexTypeDescriptor descriptor,
102 String instanceName, Uniqueness uniqueness, BeneratorContext context) {
103 generator = createMutatingEntityGenerator(instanceName, descriptor, uniqueness, context, generator);
104 return super.applyComponentBuilders(generator, descriptor, instanceName, uniqueness, context);
105 }
106
107 @Override
108 protected Generator<Entity> createSourceGenerator(
109 ComplexTypeDescriptor descriptor, Uniqueness uniqueness, BeneratorContext context) {
110
111 String sourceSpec = descriptor.getSource();
112 if (sourceSpec == null) {
113 return null;
114 }
115 Object sourceObject = null;
116 if (ScriptUtil.isScript(sourceSpec)) {
117 Object tmp = ScriptUtil.evaluate(sourceSpec, context);
118 if (tmp instanceof String) {
119 sourceSpec = (String) tmp;
120 sourceObject = context.get(sourceSpec);
121 } else {
122 sourceObject = tmp;
123 }
124 } else if (context.hasProductNameInScope(sourceSpec)) {
125 String partName = StringUtil.lastToken(descriptor.getName(), '.');
126 sourceObject = new EntityPartSource(sourceSpec, partName, context);
127 } else {
128 sourceObject = context.get(sourceSpec);
129 }
130
131
132
133 Generator<Entity> generator = null;
134 if (sourceObject != null) {
135 generator = createSourceGeneratorFromObject(descriptor, context, sourceObject);
136 } else {
137 String segment = descriptor.getSegment();
138 if (DataFileUtil.isXmlDocument(sourceSpec)) {
139 generator = new DataSourceGenerator<>(new DbUnitEntitySource(sourceSpec, context));
140 } else if (DataFileUtil.isCsvDocument(sourceSpec)) {
141 generator = createCSVSourceGenerator(descriptor, context, sourceSpec);
142 } else if (DataFileUtil.isFixedColumnWidthFile(sourceSpec)) {
143 generator = createFixedColumnWidthSourceGenerator(descriptor, context, sourceSpec);
144 } else if (DataFileUtil.isExcelDocument(sourceSpec)) {
145 generator = createXLSSourceGenerator(descriptor, context, sourceSpec, segment);
146 } else {
147 try {
148 BeanSpec sourceBeanSpec = DatabeneScriptParser.resolveBeanSpec(sourceSpec, context);
149 sourceObject = sourceBeanSpec.getBean();
150 generator = createSourceGeneratorFromObject(descriptor, context, sourceObject);
151 if (sourceBeanSpec.isReference() && !(sourceObject instanceof StorageSystem)) {
152 generator = WrapperFactory.preventClosing(generator);
153 }
154 } catch (Exception e) {
155 throw new UnsupportedOperationException("Error resolving source: " + sourceSpec, e);
156 }
157 }
158 }
159 if (generator.getGeneratedType() != Entity.class) {
160 generator = new SimpleTypeEntityGenerator(generator, descriptor);
161 }
162 if (descriptor.getFilter() != null) {
163 Expression<Boolean> filter
164 = new ScriptExpression<>(ScriptUtil.parseScriptText(descriptor.getFilter()));
165 generator = new FilteringGenerator<>(generator, filter);
166 }
167 Distribution distribution = FactoryUtil.getDistribution(descriptor.getDistribution(), uniqueness, false, context);
168 if (distribution != null) {
169 generator = new DistributingGenerator<>(generator, distribution, uniqueness.isUnique());
170 }
171 return generator;
172 }
173
174 @Override
175 protected Generator<?> createSpecificGenerator(ComplexTypeDescriptor descriptor, String instanceName,
176 boolean nullable, Uniqueness uniqueness, BeneratorContext context) {
177 return null;
178 }
179
180 @Override
181 protected Generator<?> createHeuristicGenerator(ComplexTypeDescriptor type, String instanceName,
182 Uniqueness uniqueness, BeneratorContext context) {
183 if (DescriptorUtil.isWrappedSimpleType(type)) {
184 return createSimpleTypeEntityGenerator(type, uniqueness, context);
185 } else {
186 return new BlankEntityGenerator(type);
187 }
188 }
189
190 @Override
191 protected Class<?> getGeneratedType(ComplexTypeDescriptor descriptor) {
192 return Entity.class;
193 }
194
195
196
197
198
199
200
201
202
203
204
205 @SuppressWarnings("unchecked")
206 public static Generator<?> createMutatingEntityGenerator(String name, ComplexTypeDescriptor descriptor,
207 Uniqueness ownerUniqueness, BeneratorContext context, Generator<?> source) {
208 List<GeneratorComponent<Entity>> generatorComponent =
209 createMutatingGeneratorComponents(descriptor, ownerUniqueness, context);
210 return new SourceAwareGenerator<>(name, (Generator<Entity>) source, generatorComponent, context);
211 }
212
213
214
215 @SuppressWarnings({"unchecked", "rawtypes"})
216 private static Generator<Entity> createSourceGeneratorFromObject(ComplexTypeDescriptor descriptor,
217 BeneratorContext context, Object sourceObject) {
218 Generator<Entity> generator;
219 if (sourceObject instanceof StorageSystem) {
220 StorageSystem/../com/rapiddweller/benerator/StorageSystem.html#StorageSystem">StorageSystem storage = (StorageSystem) sourceObject;
221 String selector = descriptor.getSelector();
222 String subSelector = descriptor.getSubSelector();
223 if (!StringUtil.isEmpty(subSelector)) {
224 DataSource<Entity> dataSource = storage.queryEntities(descriptor.getName(), subSelector, context);
225 generator = WrapperFactory.applyHeadCycler(new DataSourceGenerator<>(dataSource));
226 } else {
227 generator = new DataSourceGenerator<>(storage.queryEntities(descriptor.getName(), selector, context));
228 }
229 } else if (sourceObject instanceof Generator) {
230 generator = (Generator<Entity>) sourceObject;
231 } else if (sourceObject instanceof EntitySource) {
232 generator = new DataSourceGenerator<>((EntitySource) sourceObject);
233 } else if (sourceObject instanceof DataSource) {
234 DataSource dataSource = (DataSource) sourceObject;
235 if (!Entity.class.isAssignableFrom(dataSource.getType())) {
236 throw new UnsupportedOperationException("Not a supported data type to iterate: " + dataSource.getType());
237 }
238 generator = new DataSourceGenerator<Entity>(dataSource);
239 } else {
240 throw new UnsupportedOperationException("Source type not supported: " + sourceObject.getClass());
241 }
242 return generator;
243 }
244
245 private static Generator<Entity> createFixedColumnWidthSourceGenerator(
246 ComplexTypeDescriptor descriptor, BeneratorContext context, String sourceName) {
247 Generator<Entity> generator;
248 String encoding = descriptor.getEncoding();
249 if (encoding == null) {
250 encoding = context.getDefaultEncoding();
251 }
252 String pattern = descriptor.getPattern();
253 if (pattern == null) {
254 throw new ConfigurationError("No pattern specified for FCW file import: " + sourceName);
255 }
256 try {
257 FixedWidthRowTypeDescriptor rowDescriptor = FixedWidthUtil.parseBeanColumnsSpec(
258 pattern, descriptor.getName(), null, context.getDefaultLocale());
259 FixedWidthColumnDescriptor[] ffcd = rowDescriptor.getColumnDescriptors();
260 Converter<String, String> scriptConverter = DescriptorUtil.createStringScriptConverter(context);
261 FixedWidthEntitySourcehEntitySource.html#FixedWidthEntitySource">FixedWidthEntitySource iterable = new FixedWidthEntitySource(sourceName, descriptor, scriptConverter, encoding, null, ffcd);
262 iterable.setContext(context);
263 generator = new DataSourceGenerator<>(iterable);
264 return generator;
265 } catch (ParseException e) {
266 throw new ConfigurationError("Error parsing fixed-width pattern: " + pattern, e);
267 }
268 }
269
270 private static Generator<Entity> createCSVSourceGenerator(
271 ComplexTypeDescriptor complexType, BeneratorContext context, String sourceName) {
272 String encoding = complexType.getEncoding();
273 if (encoding == null) {
274 encoding = context.getDefaultEncoding();
275 }
276 Converter<String, String> scriptConverter = DescriptorUtil.createStringScriptConverter(context);
277 char separator = DescriptorUtil.getSeparator(complexType, context);
278 DataSourceProvider<Entity> fileProvider = new CSVEntitySourceProvider(complexType, scriptConverter,
279 separator, encoding);
280 return createEntitySourceGenerator(complexType, context, sourceName, fileProvider);
281 }
282
283 private static Generator<Entity> createXLSSourceGenerator(
284 ComplexTypeDescriptor complexType, BeneratorContext context, String sourceName, String segment) {
285 ScriptConverterForStrings converter = new ScriptConverterForStrings(context);
286 boolean formatted = isFormatted(complexType);
287 XLSEntitySourceProviderer.html#XLSEntitySourceProvider">XLSEntitySourceProvider fileProvider = new XLSEntitySourceProvider(complexType, formatted, converter);
288 return createEntitySourceGenerator(complexType, context, sourceName, fileProvider);
289 }
290
291 private static Generator<Entity> createSimpleTypeEntityGenerator(ComplexTypeDescriptor complexType,
292 Uniqueness ownerUniqueness, BeneratorContext context) {
293 TypeDescriptor contentType = complexType.getComponent(ComplexTypeDescriptor.__SIMPLE_CONTENT).getTypeDescriptor();
294 Generator<?> generator = MetaGeneratorFactory.createTypeGenerator(
295 contentType, complexType.getName(), false, ownerUniqueness, context);
296 return new SimpleTypeEntityGenerator(generator, complexType);
297 }
298
299
300
301
302
303
304
305
306
307 @SuppressWarnings("unchecked")
308 public static List<GeneratorComponent<Entity>> createMutatingGeneratorComponents(ComplexTypeDescriptor descriptor,
309 Uniqueness ownerUniqueness, BeneratorContext context) {
310 List<GeneratorComponent<Entity>> generatorComponents = new ArrayList<>();
311 for (InstanceDescriptor part : descriptor.getDeclaredParts()) {
312 if (!(part instanceof ComponentDescriptor) ||
313 part.getMode() != Mode.ignored && !ComplexTypeDescriptor.__SIMPLE_CONTENT.equals(part.getName())) {
314 try {
315 GeneratorComponent<Entity> generatorComponent =
316 (GeneratorComponent<Entity>) GeneratorComponentFactory.createGeneratorComponent(part, ownerUniqueness, context);
317 generatorComponents.add(generatorComponent);
318 } catch (Exception e) {
319 throw new ConfigurationError("Error creating component builder for " + part, e);
320 }
321 }
322 }
323 return generatorComponents;
324 }
325
326 private static Generator<Entity> createEntitySourceGenerator(ComplexTypeDescriptor complexType,
327 BeneratorContext context, String sourceName, DataSourceProvider<Entity> factory) {
328 Generator<Entity> generator =
329 SourceFactory.createRawSourceGenerator(complexType.getNesting(), complexType.getDataset(), sourceName, factory, Entity.class, context);
330 generator = WrapperFactory.applyConverter(generator, new ComponentTypeConverter(complexType));
331 return generator;
332 }
333
334 }