1 package org.apache.torque.generator.control;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.nio.charset.Charset;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Properties;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.log4j.PropertyConfigurator;
34 import org.apache.torque.generator.GeneratorException;
35 import org.apache.torque.generator.configuration.Configuration;
36 import org.apache.torque.generator.configuration.ConfigurationException;
37 import org.apache.torque.generator.configuration.UnitConfiguration;
38 import org.apache.torque.generator.configuration.UnitDescriptor;
39 import org.apache.torque.generator.configuration.controller.OutletReference;
40 import org.apache.torque.generator.configuration.controller.Output;
41 import org.apache.torque.generator.configuration.outlet.OutletConfiguration;
42 import org.apache.torque.generator.control.existingtargetstrategy.AppendToTargetFileStrategy;
43 import org.apache.torque.generator.control.existingtargetstrategy.ExistingTargetStrategy;
44 import org.apache.torque.generator.control.existingtargetstrategy.MergeTargetFileStrategy;
45 import org.apache.torque.generator.control.existingtargetstrategy.ReplaceTargetFileStrategy;
46 import org.apache.torque.generator.control.existingtargetstrategy.SkipExistingTargetFileStrategy;
47 import org.apache.torque.generator.outlet.Outlet;
48 import org.apache.torque.generator.outlet.OutletResult;
49 import org.apache.torque.generator.source.Source;
50 import org.apache.torque.generator.source.SourceElement;
51 import org.apache.torque.generator.source.SourceException;
52 import org.apache.torque.generator.source.SourcePath;
53 import org.apache.torque.generator.source.SourceProcessConfiguration;
54 import org.apache.torque.generator.source.SourceProvider;
55 import org.apache.torque.generator.source.SourceTransformerDefinition;
56 import org.apache.torque.generator.source.skipDecider.SkipDecider;
57 import org.apache.torque.generator.source.transform.SourceTransformer;
58 import org.apache.torque.generator.source.transform.SourceTransformerException;
59
60
61
62
63 public class Controller
64 {
65
66 private static Log log = LogFactory.getLog(Controller.class);
67
68
69
70
71
72 private static final List<ExistingTargetStrategy>
73 EXISTING_TARGET_STRATEGIES;
74
75 static
76 {
77 List<ExistingTargetStrategy> existingTargetStrategies
78 = new ArrayList<ExistingTargetStrategy>();
79 existingTargetStrategies.add(new ReplaceTargetFileStrategy());
80 existingTargetStrategies.add(new SkipExistingTargetFileStrategy());
81 existingTargetStrategies.add(new MergeTargetFileStrategy());
82 existingTargetStrategies.add(new AppendToTargetFileStrategy());
83 EXISTING_TARGET_STRATEGIES = Collections.unmodifiableList(
84 existingTargetStrategies);
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 public void run(List<UnitDescriptor> unitDescriptors)
101 throws GeneratorException
102 {
103 initLogging();
104 Configuration configuration = readConfiguration(unitDescriptors);
105
106 List<UnitConfiguration> unitConfigurations
107 = configuration.getUnitConfigurations();
108 ControllerState controllerState = new ControllerState();
109 for (UnitConfiguration unitConfiguration : unitConfigurations)
110 {
111 processGenerationUnit(
112 controllerState,
113 unitConfiguration);
114 }
115 controllerState.getVariableStore().endGeneration();
116 }
117
118
119
120
121 protected void initLogging()
122 {
123 InputStream log4jStream
124 = Controller.class.getClassLoader().getResourceAsStream(
125 "org/apache/torque/generator/log4j.properties");
126 Properties log4jProperties = new Properties();
127 try
128 {
129 log4jProperties.load(log4jStream);
130 }
131 catch (IOException e)
132 {
133 throw new RuntimeException(e);
134 }
135 PropertyConfigurator.configure(log4jProperties);
136 }
137
138
139
140
141
142
143
144
145
146
147
148 private Configuration readConfiguration(
149 List<UnitDescriptor> unitDescriptors)
150 throws ConfigurationException
151 {
152 log.info("readConfiguration() : Starting to read configuration files");
153 Configuration configuration = new Configuration();
154 configuration.addUnits(unitDescriptors);
155 configuration.read();
156 log.info("readConfiguration() : Configuration read.");
157 return configuration;
158 }
159
160
161
162
163
164
165
166
167
168
169 protected void processGenerationUnit(
170 ControllerState controllerState,
171 UnitConfiguration unitConfiguration)
172 throws GeneratorException
173 {
174 log.debug("processGenerationUnit() : start");
175 unitConfiguration.getLoglevel().apply();
176 log.debug("processGenerationUnit() : Loglevel applied.");
177 controllerState.setUnitConfiguration(unitConfiguration);
178 List<Output> outputList = unitConfiguration.getOutputList();
179 for (Output output : outputList)
180 {
181 processOutput(
182 output,
183 controllerState,
184 unitConfiguration);
185 }
186 }
187
188
189
190
191
192
193
194
195
196
197
198 private void processOutput(
199 Output output,
200 ControllerState controllerState,
201 UnitConfiguration unitConfiguration)
202 throws GeneratorException
203 {
204 log.info("Processing output " + output.getName());
205 controllerState.setOutput(output);
206
207 SourceProvider sourceProvider = output.getSourceProvider();
208 SourceProvider overrideSourceProvider
209 = unitConfiguration.getOverrideSourceProvider();
210 if (overrideSourceProvider != null)
211 {
212 overrideSourceProvider = overrideSourceProvider.copy();
213 overrideSourceProvider.copyNotSetSettingsFrom(sourceProvider);
214 sourceProvider = overrideSourceProvider;
215 }
216 controllerState.setSourceProvider(sourceProvider);
217 sourceProvider.init(
218 unitConfiguration.getConfigurationHandlers(),
219 controllerState);
220 if (!sourceProvider.hasNext())
221 {
222 log.info("No sources found, skipping output");
223 }
224
225 while (sourceProvider.hasNext())
226 {
227 Source source = sourceProvider.next();
228 processSourceInOutput(
229 source,
230 output,
231 controllerState,
232 unitConfiguration);
233 }
234 controllerState.setSourceProvider(null);
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248 private void processSourceInOutput(
249 Source source,
250 Output output,
251 ControllerState controllerState,
252 UnitConfiguration unitConfiguration)
253 throws GeneratorException
254 {
255 log.info("Processing source " + source.getDescription());
256 SourceElement rootElement = source.getRootElement();
257 controllerState.setSourceFile(source.getSourceFile());
258 SourceProcessConfiguration sourceProcessConfiguration
259 = output.getSourceProcessConfiguration();
260 rootElement = transformSource(
261 rootElement,
262 sourceProcessConfiguration.getTransformerDefinitions(),
263 controllerState);
264 controllerState.setRootElement(rootElement);
265
266 String startElementsPath
267 = sourceProcessConfiguration.getStartElementsPath();
268 List<SourceElement> startElements
269 = SourcePath.getElementsFromRoot(
270 rootElement,
271 startElementsPath);
272 if (startElements.isEmpty())
273 {
274 log.info("No start Elements found for path "
275 + startElementsPath);
276 }
277 for (SourceElement startElement : startElements)
278 {
279 processStartElement(
280 startElement,
281 output,
282 source,
283 unitConfiguration,
284 controllerState);
285 }
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303 protected void createOutputFilename(
304 Output output,
305 ControllerState controllerState)
306 throws GeneratorException
307 {
308 if (output.getFilenameOutlet() == null)
309 {
310 if (output.getFilename() == null)
311 {
312 throw new ConfigurationException(
313 "neither filename nor filenameOutlet are set"
314 + " on output" + output);
315 }
316 }
317 else
318 {
319 if (log.isDebugEnabled())
320 {
321 log.debug("Start generation of Output File path");
322 }
323 controllerState.setOutputFile(null);
324
325 Outlet filenameOutlet = output.getFilenameOutlet();
326 OutletReference contentOutletReference
327 = new OutletReference(
328 filenameOutlet.getName());
329 controllerState.setRootOutletReference(
330 contentOutletReference);
331
332
333
334 controllerState.setOutletNamespace(
335 output.getContentOutlet().getNamespace());
336 filenameOutlet.beforeExecute(controllerState);
337 OutletResult filenameResult
338 = filenameOutlet.execute(controllerState);
339 if (!filenameResult.isStringResult())
340 {
341 throw new GeneratorException(
342 "The result of a filename generation must be a String,"
343 + " not a byte array");
344 }
345 String filename = filenameResult.getStringResult();
346 filenameOutlet.afterExecute(controllerState);
347 if (log.isDebugEnabled())
348 {
349 log.debug("End generation of Output File path, result is "
350 + filename);
351 }
352 output.setFilename(filename);
353 }
354 }
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371 private void processStartElement(
372 SourceElement startElement,
373 Output output,
374 Source source,
375 UnitConfiguration unitConfiguration,
376 ControllerState controllerState)
377 throws GeneratorException
378 {
379 if (startElement == null)
380 {
381 throw new ControllerException(
382 "Null start element found in source "
383 + "for generating the filename "
384 + "of output file "
385 + output);
386 }
387 controllerState.setSourceElement(startElement);
388 log.debug("Processing new startElement "
389 + startElement.getName());
390
391 ExistingTargetStrategy existingTargetStrategy = null;
392 for (ExistingTargetStrategy candidate : EXISTING_TARGET_STRATEGIES)
393 {
394 if (candidate.getStrategyName().equals(
395 output.getExistingTargetStrategy()))
396 {
397 existingTargetStrategy = candidate;
398 break;
399 }
400 }
401 if (existingTargetStrategy == null)
402 {
403 throw new ControllerException("existingTargetStrategy "
404 + output.getExistingTargetStrategy()
405 + " not found");
406 }
407
408 createOutputFilename(output, controllerState);
409 File outputFile = ControllerHelper.getOutputFile(
410 output.getOutputDirKey(),
411 output.getFilename(),
412 unitConfiguration);
413 controllerState.setOutputFile(outputFile);
414
415 if (!existingTargetStrategy.beforeGeneration(
416 output.getOutputDirKey(),
417 output.getFilename(),
418 getOutputEncoding(output, unitConfiguration),
419 unitConfiguration))
420 {
421 log.info("Skipping generation of File "
422 + outputFile.getAbsolutePath()
423 + " because of existingTargetStrategy "
424 + existingTargetStrategy.getStrategyName());
425 return;
426 }
427 if (log.isInfoEnabled())
428 {
429 log.info("Start generation of File "
430 + outputFile.getAbsolutePath());
431 }
432
433 OutletReference contentOutletConfiguration
434 = output.getContentOutlet();
435 controllerState.setOutletNamespace(
436 contentOutletConfiguration.getNamespace());
437 controllerState.setRootOutletReference(
438 contentOutletConfiguration);
439
440 OutletConfiguration outletConfiguration
441 = unitConfiguration.getOutletConfiguration();
442
443 Outlet outlet = outletConfiguration.getOutlet(
444 contentOutletConfiguration.getName());
445 if (outlet == null)
446 {
447 throw new ControllerException(
448 "No outlet configured for outlet name \""
449 + contentOutletConfiguration.getName()
450 + "\"");
451 }
452
453 SkipDecider skipDecider
454 = output.getSourceProcessConfiguration().getSkipDecider();
455 if (skipDecider != null)
456 {
457 if (!skipDecider.proceed(controllerState))
458 {
459 log.debug("SkipDecider " + skipDecider.getClass().getName()
460 + " decided to skip "
461 + "generation of file "
462 + controllerState.getOutputFile());
463 return;
464 }
465 else
466 {
467 log.debug("SkipDecider " + skipDecider.getClass().getName()
468 + " decided to proceed");
469 }
470 }
471
472 {
473 File parentOutputDir
474 = controllerState.getOutputFile().getParentFile();
475 if (parentOutputDir != null
476 && !parentOutputDir.isDirectory())
477 {
478 boolean success = parentOutputDir.mkdirs();
479 if (!success)
480 {
481 throw new ControllerException(
482 "Could not create directory \""
483 + parentOutputDir.getAbsolutePath()
484 + "\"");
485 }
486 }
487 }
488
489 outlet.beforeExecute(controllerState);
490 OutletResult result = outlet.execute(controllerState);
491 outlet.afterExecute(controllerState);
492
493 existingTargetStrategy.afterGeneration(
494 output.getOutputDirKey(),
495 output.getFilename(),
496 getOutputEncoding(output, unitConfiguration),
497 result,
498 unitConfiguration);
499
500 controllerState.getVariableStore().endFile();
501 if (log.isDebugEnabled())
502 {
503 log.debug("End generation of Output File "
504 + controllerState.getOutputFile());
505 }
506 }
507
508
509
510
511
512
513
514
515
516
517
518
519 public SourceElement transformSource(
520 final SourceElement rootElement,
521 final List<SourceTransformerDefinition> transformerDefinitions,
522 final ControllerState controllerState)
523 throws SourceTransformerException, SourceException
524 {
525 SourceElement result = rootElement;
526 for (SourceTransformerDefinition transformerDefinition
527 : transformerDefinitions)
528 {
529 SourceTransformer sourceTransformer
530 = transformerDefinition.getSourceTransformer();
531 String elements = transformerDefinition.getElements();
532 log.debug("Applying source transformer "
533 + sourceTransformer.getClass().getName()
534 + (elements == null
535 ? " to the root element"
536 : " to the elements " + elements));
537
538 List<SourceElement> toTransform
539 = SourcePath.getElementsFromRoot(rootElement, elements);
540 if (toTransform.isEmpty())
541 {
542 log.debug("No element found, nothing transformed");
543 }
544 for (SourceElement sourceElement : toTransform)
545 {
546 log.debug("transforming element " + sourceElement);
547 SourceElement transformedElement = sourceTransformer.transform(
548 sourceElement,
549 controllerState);
550 if (transformedElement == null)
551 {
552 throw new SourceTransformerException("Transformer "
553 + sourceTransformer.getClass().getName()
554 + " returned null for element "
555 + sourceElement.getName());
556 }
557 SourceElement parent = sourceElement.getParent();
558 if (parent == null)
559 {
560 result = transformedElement;
561 }
562 else
563 {
564 List<SourceElement> children = parent.getChildren();
565 int index = children.indexOf(sourceElement);
566 children.set(index, transformedElement);
567 }
568 }
569 log.debug("Transformation ended");
570 }
571 return result;
572 }
573
574
575
576
577
578
579
580
581
582
583 private String getOutputEncoding(
584 Output output,
585 UnitConfiguration unitConfiguration)
586 {
587 if (output.getEncoding() != null)
588 {
589 return output.getEncoding();
590 }
591 if (unitConfiguration.getDefaultOutputEncoding() != null)
592 {
593 return unitConfiguration.getDefaultOutputEncoding();
594 }
595 return Charset.defaultCharset().displayName();
596 }
597
598 }