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.statement;
28
29 import com.rapiddweller.benerator.Consumer;
30 import com.rapiddweller.benerator.composite.ComponentBuilder;
31 import com.rapiddweller.benerator.engine.BeneratorContext;
32 import com.rapiddweller.benerator.engine.BeneratorMonitor;
33 import com.rapiddweller.benerator.engine.CurrentProductGeneration;
34 import com.rapiddweller.benerator.engine.LifeCycleHolder;
35 import com.rapiddweller.benerator.engine.ResourceManager;
36 import com.rapiddweller.benerator.engine.ResourceManagerSupport;
37 import com.rapiddweller.benerator.engine.ScopedLifeCycleHolder;
38 import com.rapiddweller.benerator.engine.Statement;
39 import com.rapiddweller.benerator.engine.StatementUtil;
40 import com.rapiddweller.benerator.wrapper.ProductWrapper;
41 import com.rapiddweller.common.Context;
42 import com.rapiddweller.common.ErrorHandler;
43 import com.rapiddweller.common.IOUtil;
44 import com.rapiddweller.common.MessageHolder;
45 import com.rapiddweller.common.Resettable;
46 import com.rapiddweller.script.Expression;
47 import com.rapiddweller.script.expression.ExpressionUtil;
48 import com.rapiddweller.task.PageListener;
49 import com.rapiddweller.task.Task;
50 import com.rapiddweller.task.TaskResult;
51
52 import java.io.Closeable;
53 import java.util.ArrayList;
54 import java.util.List;
55 import java.util.concurrent.atomic.AtomicBoolean;
56
57
58
59
60
61
62
63 public class GenerateAndConsumeTask implements Task, PageListener, ResourceManager, MessageHolder {
64
65 private final String taskName;
66 private BeneratorContext context;
67 private final ResourceManager resourceManager;
68
69
70
71
72 protected final List<Statement> statements;
73 private final List<ScopedLifeCycleHolder> scopeds;
74 private Expression<Consumer> consumerExpr;
75
76 private final AtomicBoolean initialized;
77 private Consumer consumer;
78 private String message;
79 private final String productName;
80
81
82
83
84
85
86
87 public GenerateAndConsumeTask(String taskName, String productName) {
88 this.taskName = taskName;
89 this.productName = productName;
90 this.resourceManager = new ResourceManagerSupport();
91 this.initialized = new AtomicBoolean(false);
92 this.statements = new ArrayList<>();
93 this.scopeds = new ArrayList<>();
94 }
95
96
97
98
99
100
101
102
103 public void addStatement(Statement statement) {
104 this.statements.add(statement);
105 }
106
107
108
109
110
111
112 public void setStatements(List<Statement> statements) {
113 this.statements.clear();
114 for (Statement statement : statements) {
115 this.addStatement(statement);
116 }
117 }
118
119
120
121
122
123
124 public ResourceManager getResourceManager() {
125 return resourceManager;
126 }
127
128
129
130
131
132
133 public void setConsumer(Expression<Consumer> consumerExpr) {
134 this.consumerExpr = consumerExpr;
135 }
136
137
138
139
140
141
142 public Consumer getConsumer() {
143 return consumer;
144 }
145
146
147
148
149
150
151 public void init(BeneratorContext context) {
152 synchronized (initialized) {
153 if (!initialized.get()) {
154 this.context = context;
155 this.consumer = ExpressionUtil.evaluate(consumerExpr, context);
156 resourceManager.addResource(consumer);
157 injectConsumptionStart();
158 injectConsumptionEnd();
159 initialized.set(true);
160 initStatements(context);
161 checkScopes(statements, context);
162 }
163 }
164 }
165
166
167
168
169
170
171 public String getProductName() {
172 return productName;
173 }
174
175
176
177
178
179
180 public ProductWrapper<?> getRecentProduct() {
181 return context.getCurrentProduct();
182 }
183
184
185
186 @Override
187 public String getTaskName() {
188 return taskName;
189 }
190
191 @Override
192 public boolean isThreadSafe() {
193 return false;
194 }
195
196 @Override
197 public boolean isParallelizable() {
198 return false;
199 }
200
201 @Override
202 public TaskResult execute(Context ctx, ErrorHandler errorHandler) {
203 message = null;
204 if (!initialized.get()) {
205 init((BeneratorContext) ctx);
206 }
207 try {
208 boolean success = true;
209 for (int i = 0; i < statements.size(); i++) {
210 Statement statement = statements.get(i);
211 success &= statement.execute(context);
212 if (!success && (statement instanceof ValidationStatement)) {
213 i = -1;
214 success = true;
215 continue;
216 }
217 if (!success) {
218 if (statement instanceof MessageHolder) {
219 this.message = ((MessageHolder) statement).getMessage();
220 }
221 break;
222 }
223 }
224 if (success) {
225 BeneratorMonitor.INSTANCE.countGenerations(1);
226 }
227 enqueueResets(statements);
228 Thread.yield();
229 return (success ? TaskResult.EXECUTING : TaskResult.UNAVAILABLE);
230 } catch (Exception e) {
231 errorHandler.handleError("Error in execution of task " + getTaskName(), e);
232 return TaskResult.EXECUTING;
233 }
234 }
235
236
237
238
239 public void reset() {
240 for (Statement statement : statements) {
241 statement = StatementUtil.getRealStatement(statement, context);
242 if (statement instanceof ScopedLifeCycleHolder) {
243 ScopedLifeCycleHoldercom/rapiddweller/benerator/engine/ScopedLifeCycleHolder.html#ScopedLifeCycleHolder">ScopedLifeCycleHolder holder = (ScopedLifeCycleHolder) statement;
244 holder.resetIfNeeded();
245 } else if (statement instanceof Resettable) {
246 ((Resettable) statement).reset();
247 }
248 }
249 }
250
251 @Override
252 public void close() {
253
254 for (Statement statement : statements) {
255 statement = StatementUtil.getRealStatement(statement, context);
256 if (statement instanceof Closeable) {
257 IOUtil.close((Closeable) statement);
258 }
259 }
260
261 resourceManager.close();
262 }
263
264
265
266
267 @Override
268 public void pageStarting() {
269
270 }
271
272 @Override
273 public void pageFinished() {
274 IOUtil.flush(consumer);
275 }
276
277
278
279
280 @Override
281 public boolean addResource(Closeable resource) {
282 return resourceManager.addResource(resource);
283 }
284
285
286
287 @Override
288 public String getMessage() {
289 return message;
290 }
291
292
293
294 @Override
295 public String toString() {
296 return getClass().getSimpleName() + '(' + taskName + ')';
297 }
298
299
300
301 private void injectConsumptionStart() {
302
303 int lastMemberIndex = -1;
304 for (int i = statements.size() - 1; i >= 0; i--) {
305 Statement statement = statements.get(i);
306 if (statement instanceof ComponentBuilder || statement instanceof CurrentProductGeneration
307 || statement instanceof ValidationStatement || statement instanceof ConversionStatement) {
308 lastMemberIndex = i;
309 break;
310 }
311 }
312
313 ConsumptionStatementConsumptionStatement.html#ConsumptionStatement">ConsumptionStatement consumption = new ConsumptionStatement(consumer, true, false);
314 statements.add(lastMemberIndex + 1, consumption);
315 }
316
317 private void injectConsumptionEnd() {
318
319 int lastSubGenIndex = statements.size() - 1;
320 for (int i = statements.size() - 1; i >= 0; i--) {
321 Statement statement = statements.get(i);
322 if (statement instanceof GenerateOrIterateStatement) {
323 lastSubGenIndex = i;
324 break;
325 }
326 }
327
328 ConsumptionStatementConsumptionStatement.html#ConsumptionStatement">ConsumptionStatement consumption = new ConsumptionStatement(consumer, false, true);
329 statements.add(lastSubGenIndex + 1, consumption);
330 }
331
332
333
334
335
336
337 public void initStatements(BeneratorContext context) {
338 for (Statement statement : statements) {
339 statement = StatementUtil.getRealStatement(statement, context);
340 if (statement instanceof LifeCycleHolder) {
341 ((LifeCycleHolder) statement).init(context);
342 }
343 }
344 }
345
346 private void checkScopes(List<Statement> statements, BeneratorContext scopeContext) {
347 for (Statement statement : statements) {
348 statement = StatementUtil.getRealStatement(statement, scopeContext);
349 if (statement instanceof ScopedLifeCycleHolder) {
350 ScopedLifeCycleHoldercom/rapiddweller/benerator/engine/ScopedLifeCycleHolder.html#ScopedLifeCycleHolder">ScopedLifeCycleHolder holder = (ScopedLifeCycleHolder) statement;
351 String scope = holder.getScope();
352 if (scope == null || productName.equals(scope)) {
353 scopeds.add(holder);
354 }
355 } else if (statement instanceof GenerateOrIterateStatement) {
356 GenerateOrIterateStatementweller/benerator/engine/statement/GenerateOrIterateStatement.html#GenerateOrIterateStatement">GenerateOrIterateStatement subGenerate = (GenerateOrIterateStatement) statement;
357 checkScopes(subGenerate.getTask().statements, subGenerate.getChildContext());
358 }
359 }
360 }
361
362 private void enqueueResets(List<Statement> statements) {
363 for (ScopedLifeCycleHolder scoped : scopeds) {
364 scoped.setResetNeeded(true);
365 }
366 }
367
368 }