1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.nuiton.eugene.writer;
24
25 import com.google.common.base.Preconditions;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.codehaus.plexus.component.annotations.Component;
29 import org.nuiton.eugene.models.extension.tagvalue.provider.TagValueMetadatasProvider;
30
31 import java.io.File;
32 import java.io.IOException;
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.HashSet;
36 import java.util.LinkedHashSet;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Set;
40 import java.util.regex.Matcher;
41 import java.util.regex.Pattern;
42
43
44
45
46
47
48
49
50
51 @Component(role = ChainedWriterEngine.class, hint = "default")
52 public class DefaultChainedWriterEngine implements ChainedWriterEngine {
53
54
55 private static final Log log = LogFactory.getLog(DefaultChainedWriterEngine.class);
56
57
58 protected ChainedFileWriterConfiguration configuration;
59
60
61 protected Set<ChainedFileWriter> availableWriters;
62
63
64 protected List<ChainedFileWriter> selectedWriters;
65
66 private FileGrabberFromDirectory fileGrabberFromDirectory;
67
68 private FileGrabberFromClassPath fileGrabberFromClassPath;
69
70 public ChainedFileWriterConfiguration getConfiguration() {
71 return configuration;
72 }
73
74 @Override
75 public List<ChainedFileWriter> getSelectedWriters() {
76 if (selectedWriters == null) {
77 checkInit("getSelectedWriters");
78 selectedWriters = new ArrayList<>();
79 }
80 return selectedWriters;
81 }
82
83 @Override
84 public boolean containsWriter(String inputProtocol) {
85 for (ChainedFileWriter w : getSelectedWriters()) {
86 if (inputProtocol.equals(w.getInputProtocol())) {
87 return true;
88 }
89 }
90 return false;
91 }
92
93 @Override
94 public Set<ChainedFileWriter> getAvailableWriters() {
95 if (availableWriters == null) {
96 checkInit("getAvailableWriters");
97 availableWriters = filterWriterForModelType(
98 getConfiguration().getWriters(),
99 getConfiguration().getModelType()
100 );
101 }
102 return availableWriters;
103 }
104
105 @Override
106 public void registerInclude(String include) {
107 checkInit("registerInclude");
108
109 List<ChainedFileWriter> selectedWriters = getSelectedWriters();
110
111 if (log.isDebugEnabled()) {
112 log.debug(">>>>>>>>>>>>>>>>> [" + include + "]");
113 log.debug("Will register include " + "[" + include + "]");
114 log.debug("actual selected writers : " + selectedWriters);
115 }
116 ModelFileWriterEntryType selectedType = null;
117 Matcher matcher = null;
118
119
120
121 for (ModelFileWriterEntryType type :
122 ModelFileWriterEntryType.values()) {
123 matcher = type.getMatcher(include);
124 if (matcher != null) {
125
126 selectedType = type;
127 break;
128 }
129 }
130
131 if (selectedType == null) {
132
133 throw new IllegalArgumentException("could not find a writer for include pattern : " + include);
134 }
135
136
137 ChainedFileWriter writer =
138 selectedType.getWriter(this, include, matcher);
139
140
141
142 ChainedFileWriterEntry writerEntry =
143 selectedType.newEntry(this, include, matcher, writer);
144
145
146
147 writer.addEntry(writerEntry);
148 if (!selectedWriters.contains(writer)) {
149
150 if (log.isDebugEnabled()) {
151 log.debug("[" + include + "] Associated with writer " + writer);
152 }
153 selectedWriters.add(writer);
154 }
155
156 ChainedFileWriterConfiguration configuration = getConfiguration();
157
158 String modelType = configuration.getModelType();
159
160 String outpoutProtocol = writer.getOutputProtocol(modelType);
161
162 if (outpoutProtocol == null) {
163
164 if (log.isDebugEnabled()) {
165 log.debug("<<<<<<<<<<<<<<<<< [" + include + "]");
166 }
167 return;
168 }
169
170
171
172 if (log.isDebugEnabled()) {
173 log.debug("[" + include + "]" + " writer " +
174 writer.getClass().getSimpleName() +
175 " require a next writer of protocol " + outpoutProtocol);
176 }
177
178 ChainedFileWriter nextWriter =
179 ((AbstractChainedFileWriter) writer).getNextWriter();
180 if (nextWriter == null) {
181
182
183 nextWriter = getWriterForInputProtocol(
184 getAvailableWriters(),
185 outpoutProtocol,
186 modelType
187 );
188
189 if (nextWriter == null) {
190 throw new IllegalArgumentException(
191 "could not find a writer for protocole " +
192 outpoutProtocol + " on model " + modelType);
193 }
194
195 ((AbstractChainedFileWriter) writer).setNextWriter(nextWriter);
196 }
197
198
199
200 String basedirpath = configuration.getBasedir().getAbsolutePath();
201
202 String outputpath = writer.getOutputDirectory(
203 configuration.getOutputDirectory(),
204 configuration.isTestPhase()).getAbsolutePath();
205
206 String path = outputpath.substring(basedirpath.length() + 1);
207
208 String newInclude = outpoutProtocol + ":" + path + ":" +
209 nextWriter.getDefaultIncludes();
210
211 registerInclude(newInclude);
212
213 if (log.isDebugEnabled()) {
214 log.debug("<<<<<<<<<<<<<<<<< [" + include + "]");
215 }
216 }
217
218 @Override
219 public void clear() {
220
221 if (selectedWriters != null) {
222 selectedWriters.clear();
223 selectedWriters = null;
224 }
225 if (availableWriters != null) {
226 for (ChainedFileWriter writer : availableWriters) {
227 writer.clear();
228 }
229 availableWriters.clear();
230 availableWriters = null;
231 }
232 configuration = null;
233
234 fileGrabberFromDirectory = null;
235 fileGrabberFromClassPath = null;
236
237 }
238
239 @Override
240 public void init(ChainedFileWriterConfiguration configuration) {
241
242 Preconditions.checkNotNull(configuration, "Configuration can not be null");
243
244 this.configuration = configuration;
245 fileGrabberFromDirectory = new FileGrabberFromDirectory(configuration);
246 fileGrabberFromClassPath = new FileGrabberFromClassPath(configuration);
247
248 }
249
250 @Override
251 public Set<ChainedFileWriter> filterWriterForModelType(
252 Map<String, ChainedFileWriter> universe, String modelType) {
253 Set<ChainedFileWriter> result = new HashSet<>();
254 for (ChainedFileWriter w : universe.values()) {
255 if (w.acceptModel(modelType)) {
256 if (log.isDebugEnabled()) {
257 log.debug("writer [" + w + "] accept model " + modelType);
258 }
259 result.add(w);
260 }
261 }
262 return result;
263 }
264
265 @Override
266 public ChainedFileWriter getWriterForInputProtocol(
267 Set<ChainedFileWriter> universe,
268 String inputProtocol,
269 String modelType) {
270 for (ChainedFileWriter writer : universe) {
271 if (inputProtocol.equals(writer.getInputProtocol(modelType))) {
272 return writer;
273 }
274 }
275 return null;
276 }
277
278 @Override
279 public ChainedFileWriter getWriterForInclude(
280 Set<ChainedFileWriter> universe,
281 String include,
282 String modelType) {
283 for (ChainedFileWriter w : universe) {
284 if (w.acceptInclude(include)) {
285 return w;
286 }
287 }
288 return null;
289 }
290
291 @Override
292 public ChainedFileWriterData getData(ChainedFileWriter writer) throws IOException {
293
294 checkInit("getData");
295 File outputDir = writer.getOutputDirectory(configuration.getOutputDirectory(), configuration.isTestPhase());
296
297 if (!outputDir.exists()) {
298 if (log.isDebugEnabled()) {
299 log.debug("[" + writer.getInputProtocol() + "] Create output directory " + outputDir);
300 }
301 boolean b = outputDir.mkdirs();
302 if (!b) {
303 throw new IOException("Could not create directory " + outputDir);
304 }
305 }
306
307
308 Map<String, Set<String>> directoryEntries = new HashMap<>();
309 Map<String, Set<String>> classpathEntries = new HashMap<>();
310
311 for (ChainedFileWriterEntry e : writer.getEntries()) {
312
313 Map<String, Set<String>> currentMap;
314
315 if (e.isUseClassPath()) {
316 currentMap = classpathEntries;
317 } else {
318 currentMap = directoryEntries;
319 }
320
321 String input = e.getInputPath();
322 Set<String> includes = currentMap.get(input);
323 if (includes == null) {
324 currentMap.put(input, includes = new LinkedHashSet<>());
325 }
326 includes.add(e.getIncludePattern());
327
328 }
329
330 ChainedFileWriterData result = new ChainedFileWriterData();
331 result.setFilesByRoot(new HashMap<File, List<File>>());
332 result.setResourcesByFile(new HashMap<File, List<File>>());
333 result.setOutputDirectory(outputDir);
334
335 File extractDirectory = writer.getExtractDirectory(configuration.getExtractDirectory(),
336 configuration.isTestPhase());
337
338
339 grabFiles(extractDirectory, fileGrabberFromDirectory, directoryEntries, result);
340
341
342 grabFiles(extractDirectory, fileGrabberFromClassPath, classpathEntries, result);
343
344 return result;
345
346 }
347
348 protected void grabFiles(File extractDirectory, FileGrabber grabber,
349 Map<String, Set<String>> entries,
350 ChainedFileWriterData result) throws IOException {
351
352 for (Map.Entry<String, Set<String>> entry : entries.entrySet()) {
353
354 String inputDirectory = entry.getKey();
355 Set<String> includePatterns = entry.getValue();
356 grabber.addFilesToTreate(extractDirectory, inputDirectory, includePatterns, result);
357
358 }
359
360 }
361
362 protected void checkInit(String method) throws IllegalStateException {
363 if (configuration == null) {
364 throw new IllegalStateException("Engine was not initialized! Can not access to " + method +
365 " before the init method was invoked!");
366 }
367 }
368
369 public enum ModelFileWriterEntryType {
370
371 ONLY_PROTOCOL_PATTERN("^([a-zA-Z]+)$") {
372 @Override
373 public ChainedFileWriter getWriter(DefaultChainedWriterEngine engine,
374 String include,
375 Matcher matcher) {
376 ChainedFileWriterConfiguration conf = engine.getConfiguration();
377 Set<ChainedFileWriter> universe = engine.getAvailableWriters();
378
379 String protocol = matcher.group(1).toLowerCase();
380 ChainedFileWriter writer = engine.getWriterForInputProtocol(
381 universe,
382 protocol,
383 conf.getModelType()
384 );
385 if (writer == null) {
386 throw new IllegalArgumentException(
387 "could not find the writer named '" + protocol + "', use one of " + universe);
388 }
389 if (log.isDebugEnabled()) {
390 log.debug("[" + include + "] " + "writer = (" + writer + ")");
391 }
392 return writer;
393 }
394
395 @Override
396 public ChainedFileWriterEntry newEntry(
397 DefaultChainedWriterEngine engine,
398 String include,
399 Matcher matcher,
400 ChainedFileWriter writer) {
401 ChainedFileWriterConfiguration conf = engine.getConfiguration();
402 if (log.isDebugEnabled()) {
403 log.debug("[" + include + "] " + "detected pattern (" + name() + ")");
404 }
405
406 ChainedFileWriterEntry writerEntry = new ChainedFileWriterEntry(
407 new File(conf.getBasedir(),
408 conf.isTestPhase() ?
409 writer.getDefaultTestInputDirectory() :
410 writer.getDefaultInputDirectory()
411 ).getAbsolutePath(),
412 writer.getDefaultIncludes()
413 );
414 return writerEntry;
415 }
416 },
417
418 NO_PROTOCOL_PATTERN_WITH_CLASSPATH("^classpath:([^:]+):([^:]+)$") {
419 @Override
420 public ChainedFileWriter getWriter(DefaultChainedWriterEngine engine,
421 String include,
422 Matcher matcher) {
423 ChainedFileWriterConfiguration conf = engine.getConfiguration();
424 Set<ChainedFileWriter> universe = engine.getAvailableWriters();
425
426 String modelType = conf.getModelType();
427
428
429
430
431 ChainedFileWriter writer = engine.getWriterForInclude(universe, include, modelType);
432 if (writer == null) {
433 throw new IllegalArgumentException("could not find a writer for include " + include);
434 }
435 if (log.isDebugEnabled()) {
436 log.debug("[" + include + "] " + "writer = (" + writer + ")");
437 }
438 return writer;
439 }
440
441 @Override
442 public ChainedFileWriterEntry newEntry(DefaultChainedWriterEngine engine,
443 String include,
444 Matcher matcher,
445 ChainedFileWriter writer) {
446
447
448
449 if (log.isDebugEnabled()) {
450 log.debug("[" + include + "] " + "detected pattern (" + name() + ")");
451 }
452
453 String inputPath = matcher.group(1);
454 String includes = matcher.group(2);
455
456 ChainedFileWriterEntry writerEntry = new ChainedFileWriterEntry(inputPath, includes, true);
457 return writerEntry;
458 }
459 },
460
461 NO_PROTOCOL_PATTERN("^([^:]+):([^:]+)$") {
462 @Override
463 public ChainedFileWriter getWriter(DefaultChainedWriterEngine engine,
464 String include,
465 Matcher matcher) {
466 ChainedFileWriterConfiguration conf = engine.getConfiguration();
467 Set<ChainedFileWriter> universe = engine.getAvailableWriters();
468
469 String modelType = conf.getModelType();
470
471
472
473
474 ChainedFileWriter writer = engine.getWriterForInclude(universe, include, modelType);
475 if (writer == null) {
476 throw new IllegalArgumentException("could not find a writer for include " + include);
477 }
478 if (log.isDebugEnabled()) {
479 log.debug("[" + include + "] " + "writer = (" + writer + ")");
480 }
481 return writer;
482 }
483
484 @Override
485 public ChainedFileWriterEntry newEntry(DefaultChainedWriterEngine engine,
486 String include,
487 Matcher matcher,
488 ChainedFileWriter writer) {
489 ChainedFileWriterConfiguration conf = engine.getConfiguration();
490
491
492 if (log.isDebugEnabled()) {
493 log.debug("[" + include + "] " + "detected pattern (" + name() + ")");
494 }
495
496 String inputPath = matcher.group(1);
497 String includes = matcher.group(2);
498
499 ChainedFileWriterEntry writerEntry = new ChainedFileWriterEntry(
500 new File(conf.getBasedir(), inputPath).getAbsolutePath(),
501 includes
502 );
503 return writerEntry;
504 }
505 },
506
507 FULL_PATTERN_WITH_CLASSPATH("^classpath:(\\w+):([^:]+):([^:]+)$") {
508 @Override
509 public ChainedFileWriter getWriter(DefaultChainedWriterEngine engine,
510 String include,
511 Matcher matcher) {
512
513
514 ChainedFileWriterConfiguration conf = engine.getConfiguration();
515 Set<ChainedFileWriter> universe = engine.getAvailableWriters();
516
517 String protocol = matcher.group(1).toLowerCase();
518 ChainedFileWriter writer = engine.getWriterForInputProtocol(universe, protocol, conf.getModelType());
519
520 if (writer == null) {
521 throw new IllegalArgumentException(
522 "could not find the writer named '" + protocol + "', use one of " + universe);
523 }
524 if (log.isDebugEnabled()) {
525 log.debug("[" + include + "] " + "writer = (" + writer + ")");
526 }
527 return writer;
528 }
529
530 @Override
531 public ChainedFileWriterEntry newEntry(DefaultChainedWriterEngine engine,
532 String include,
533 Matcher matcher,
534 ChainedFileWriter writer) {
535
536
537 if (log.isDebugEnabled()) {
538 log.debug("[" + include + "] " + "detected pattern (" + name() + ")");
539 }
540
541 String inputPath = matcher.group(2);
542 String includes = matcher.group(3);
543
544
545 ChainedFileWriterEntry writerEntry = new ChainedFileWriterEntry(
546 inputPath,
547 includes,
548 true
549 );
550 return writerEntry;
551 }
552 },
553 FULL_PATTERN("^(\\w+):([^:]+):([^:]+)$") {
554 @Override
555 public ChainedFileWriter getWriter(DefaultChainedWriterEngine engine,
556 String include,
557 Matcher matcher) {
558
559
560 ChainedFileWriterConfiguration conf = engine.getConfiguration();
561 Set<ChainedFileWriter> universe = engine.getAvailableWriters();
562
563 String protocol = matcher.group(1).toLowerCase();
564 ChainedFileWriter writer = engine.getWriterForInputProtocol(universe, protocol, conf.getModelType());
565
566 if (writer == null) {
567 throw new IllegalArgumentException(
568 "could not find the writer named '" + protocol + "', use one of " + universe);
569 }
570 if (log.isDebugEnabled()) {
571 log.debug("[" + include + "] " + "writer = (" + writer + ")");
572 }
573 return writer;
574 }
575
576 @Override
577 public ChainedFileWriterEntry newEntry(DefaultChainedWriterEngine engine,
578 String include,
579 Matcher matcher,
580 ChainedFileWriter writer) {
581 ChainedFileWriterConfiguration conf = engine.getConfiguration();
582
583
584 if (log.isDebugEnabled()) {
585 log.debug("[" + include + "] " + "detected pattern (" + name() + ")");
586 }
587
588 String inputPath = matcher.group(2);
589 String includes = matcher.group(3);
590 ChainedFileWriterEntry writerEntry = new ChainedFileWriterEntry(
591 new File(conf.getBasedir(), inputPath).getAbsolutePath(),
592 includes
593 );
594 return writerEntry;
595 }
596 };
597
598 private final Pattern pattern;
599
600 ModelFileWriterEntryType(String pattern) {
601 this.pattern = Pattern.compile(pattern);
602 }
603
604 public Pattern getPattern() {
605 return pattern;
606 }
607
608 public Matcher getMatcher(String include) {
609 Matcher matcher = getPattern().matcher(include);
610 return matcher.matches() ? matcher : null;
611 }
612
613 public abstract ChainedFileWriterEntry newEntry(
614 DefaultChainedWriterEngine engine,
615 String include,
616 Matcher matcher, ChainedFileWriter writer);
617
618 public abstract ChainedFileWriter getWriter(
619 DefaultChainedWriterEngine engine,
620 String include,
621 Matcher matcher);
622 }
623
624 }