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
28
29
30
31
32
33
34
35 package org.castor.anttask;
36
37 import java.io.File;
38 import java.io.FileInputStream;
39 import java.io.FileNotFoundException;
40 import java.io.IOException;
41 import java.lang.reflect.InvocationTargetException;
42 import java.lang.reflect.Method;
43 import java.util.Properties;
44 import java.util.Vector;
45
46 import org.apache.tools.ant.BuildException;
47 import org.apache.tools.ant.DirectoryScanner;
48 import org.apache.tools.ant.taskdefs.MatchingTask;
49 import org.apache.tools.ant.types.FileSet;
50 import org.castor.xml.BackwardCompatibilityContext;
51 import org.castor.xml.InternalContext;
52 import org.exolab.castor.builder.SourceGenerator;
53 import org.exolab.castor.builder.binding.ExtendedBinding;
54 import org.exolab.castor.builder.factory.FieldInfoFactory;
55 import org.exolab.castor.xml.XMLException;
56 import org.exolab.castor.xml.schema.Schema;
57 import org.exolab.castor.xml.schema.SchemaContext;
58 import org.exolab.castor.xml.schema.SchemaContextImpl;
59 import org.exolab.castor.xml.schema.reader.Sax2ComponentReader;
60 import org.exolab.castor.xml.schema.reader.SchemaUnmarshaller;
61 import org.exolab.javasource.JClass;
62 import org.xml.sax.InputSource;
63 import org.xml.sax.Parser;
64 import org.xml.sax.SAXException;
65
66
67
68
69
70
71
72
73
74
75 public final class CastorCodeGenTask extends MatchingTask {
76
77
78 private static final String PROBLEM_SETTING_JDO_DESC =
79 "Problem calling SourceGenerator.setJdoDescriptorCreation: ";
80
81
82 private static final String DISABLE_DESCRIPTORS_MSG = "Disabling generation of Class descriptors";
83
84
85 private static final String DISABLE_MARSHAL_MSG =
86 "Disabling generation of Marshaling framework methods (marshal, unmarshal, validate).";
87
88
89 private static final String CASTOR_TESTABLE_MSG =
90 "The generated classes will implement org.exolab.castor.tests.CastorTestable";
91
92
93 private static final String INVALID_LINESEP_MSG =
94 "Invalid value for lineseparator, must be win, unix, or mac.";
95
96
97 private static final String NO_SCHEMA_MSG =
98 "At least one of the file, url or dir attributes, or a fileset element, must be set.";
99
100
101 private InternalContext _internalContext;
102
103
104 private File _schemaFile = null;
105
106
107 private String _schemaURL = null;
108
109
110 private File _schemaDir = null;
111
112
113 private Vector<FileSet> _schemaFilesets = new Vector<>();
114
115
116
117 private String _srcpackage;
118
119
120 private String _todir;
121
122
123 private String _resourcesDirectory;
124
125
126 private String _bindingfile;
127
128
129 private String _types;
130
131
132 private String _lineseparator;
133
134
135 private boolean _verbose;
136
137
138
139
140
141 private boolean _warnings = true;
142
143
144 private boolean _nodesc;
145
146
147 private boolean _nomarshal;
148
149
150 private boolean _useOldFieldNaming = true;
151
152
153
154
155 private boolean _generateMapping;
156
157
158 private boolean _testable;
159
160
161 private boolean _generateImportedSchemas;
162
163
164 private boolean _sax1;
165
166
167 private boolean _caseInsensitive;
168
169
170 private String _properties;
171
172
173 private String _nameConflictStrategy = "warnViaConsoleDialog";
174
175
176 private String _automaticConflictStrategy = "xpath";
177
178
179 private boolean _generateJdoDescriptors;
180
181
182
183
184 private String _jclassPrinterType = "standard";
185
186
187 private SourceGenerator _sgen;
188
189
190
191
192 public CastorCodeGenTask() {
193 super();
194 _internalContext = new BackwardCompatibilityContext();
195 }
196
197
198
199
200
201
202 public void setFile(final File file) {
203 _schemaFile = file;
204 }
205
206
207
208
209
210
211 public void setSchemaURL(final String schemaURL) {
212 _schemaURL = schemaURL;
213 }
214
215
216
217
218
219
220
221 public void setDir(final File dir) {
222 _schemaDir = dir;
223 }
224
225
226
227
228
229
230 public void addFileset(final FileSet set) {
231 _schemaFilesets.add(set);
232 }
233
234
235
236
237
238
239 public void setPackage(final String pack) {
240 _srcpackage = pack;
241 }
242
243
244
245
246
247
248 public void setTodir(final String dest) {
249 _todir = dest;
250 }
251
252
253
254
255
256
257
258 public void setResourcesDirectory(final String destination) {
259 _resourcesDirectory = destination;
260 }
261
262
263
264
265
266
267 public void setBindingfile(final String bindingfile) {
268 _bindingfile = bindingfile;
269 }
270
271
272
273
274
275
276 public void setLineseparator(final String ls) {
277 _lineseparator = ls;
278 }
279
280
281
282
283
284
285 public void setTypes(final String tf) {
286 _types = "j2".equals(tf) ? "arraylist" : tf;
287 }
288
289
290
291
292
293
294 public void setVerbose(final boolean b) {
295 _verbose = b;
296 }
297
298
299
300
301
302
303 public void setNameConflictStrategy(final String nameConflictStrategy) {
304 _nameConflictStrategy = nameConflictStrategy;
305 }
306
307
308
309
310
311
312 public void setAutomaticConflictStrategy(final String automaticConflictStrategy) {
313 _automaticConflictStrategy = automaticConflictStrategy;
314 }
315
316
317
318
319
320
321
322
323 public void setWarnings(final boolean b) {
324 _warnings = b;
325 }
326
327
328
329
330
331
332 public void setUseOldFieldNaming(final boolean useOldFieldNaming) {
333 _useOldFieldNaming = useOldFieldNaming;
334 }
335
336
337
338
339
340
341 public void setNodesc(final boolean b) {
342 _nodesc = b;
343 }
344
345
346
347
348
349
350 public void setNomarshal(final boolean b) {
351 _nomarshal = b;
352 }
353
354
355
356
357
358
359 public void setTestable(final boolean b) {
360 _testable = b;
361 }
362
363
364
365
366
367
368 public void setGenerateImportedSchemas(final boolean generateImportedSchemas) {
369 _generateImportedSchemas = generateImportedSchemas;
370 }
371
372
373
374
375
376
377 public void setGenerateJdoDescriptors(final boolean generateJdoDescriptors) {
378 _generateJdoDescriptors = generateJdoDescriptors;
379 }
380
381
382
383
384
385
386
387 public void setSAX1(final boolean sax1) {
388 _sax1 = sax1;
389 }
390
391
392
393
394
395
396
397 public void setCaseInsensitive(final boolean caseInsensitive) {
398 _caseInsensitive = caseInsensitive;
399 }
400
401
402
403
404
405
406 public void setProperties(final String properties) {
407 _properties = properties;
408 }
409
410
411
412
413
414
415 public void setJClassPrinterType(final String jclassPrinterType) {
416 _jclassPrinterType = jclassPrinterType;
417 }
418
419
420
421
422
423
424 public void setGenerateMapping(final boolean generateMapping) {
425 _generateMapping = generateMapping;
426 }
427
428
429
430
431
432 private void config() {
433
434 if (_types != null) {
435 FieldInfoFactory factory;
436 try {
437 if (_useOldFieldNaming) {
438 factory = new FieldInfoFactory(_types);
439 } else {
440 factory = new FieldInfoFactory(_types, false);
441 }
442
443 _sgen = new CastorSourceGeneratorWrapper(factory);
444 } catch (Exception e) {
445 try {
446 factory = (FieldInfoFactory) Class.forName(_types).newInstance();
447 _sgen = new CastorSourceGeneratorWrapper(factory);
448 } catch (Exception e2) {
449 throw new BuildException("Invalid types \"" + _types + "\": " + e.getMessage());
450 }
451 }
452 } else {
453
454 _sgen = new CastorSourceGeneratorWrapper();
455 }
456
457
458 String lineSep = System.getProperty("line.separator");
459 if (_lineseparator != null) {
460 if ("win".equals(_lineseparator)) {
461 log("Using Windows style line separation.");
462 lineSep = "\r\n";
463 } else if ("unix".equals(_lineseparator)) {
464 log("Using UNIX style line separation.");
465 lineSep = "\n";
466 } else if ("mac".equals(_lineseparator)) {
467 log("Using Macintosh style line separation.");
468 lineSep = "\r";
469 } else {
470 throw new BuildException(INVALID_LINESEP_MSG);
471 }
472 }
473 _sgen.setLineSeparator(lineSep);
474
475 _sgen.setDestDir(_todir);
476
477
478 if (_resourcesDirectory != null && _resourcesDirectory.length() > 0) {
479 _sgen.setResourceDestination(_resourcesDirectory);
480 }
481
482 if (_bindingfile != null) {
483 _sgen.setBinding(_bindingfile);
484 }
485
486 _sgen.setVerbose(_verbose);
487 _sgen.setSuppressNonFatalWarnings(!_warnings);
488
489 _sgen.setDescriptorCreation(!_nodesc);
490 if (_nodesc) {
491 log(DISABLE_DESCRIPTORS_MSG);
492 }
493
494 _sgen.setCreateMarshalMethods(!_nomarshal);
495 if (_nomarshal) {
496 log(DISABLE_MARSHAL_MSG);
497 }
498
499 _sgen.setGenerateImportedSchemas(_generateImportedSchemas);
500
501 _sgen.setSAX1(_sax1);
502
503 _sgen.setCaseInsensitive(_caseInsensitive);
504
505 _sgen.setNameConflictStrategy(_nameConflictStrategy);
506
507 _sgen.setClassNameConflictResolver(_automaticConflictStrategy);
508
509 _sgen.setJClassPrinterType(_jclassPrinterType);
510
511 _sgen.setGenerateMappingFile(_generateMapping);
512
513 if (_generateJdoDescriptors) {
514 callSetterMethodUsingReflection(_sgen, "setJdoDescriptorCreation", boolean.class,
515 Boolean.valueOf(_generateJdoDescriptors));
516 }
517
518 _sgen.setTestable(_testable);
519 if (this._testable) {
520 log(CASTOR_TESTABLE_MSG);
521 }
522
523
524 if (_properties != null) {
525 String filePath = new File(_properties).getAbsolutePath();
526 Properties customProperties = new Properties();
527 try (FileInputStream fis = new FileInputStream(filePath)) {
528 customProperties.load(fis);
529 } catch (FileNotFoundException e) {
530 throw new BuildException("Properties file \"" + filePath + "\" not found");
531 } catch (IOException e) {
532 throw new BuildException("Can't read properties file \"" + filePath + "\": " + e);
533 }
534 _sgen.setDefaultProperties(customProperties);
535 }
536 }
537
538
539
540
541
542
543
544 private void processFile(final String filePath) {
545 log("Processing " + filePath);
546 try {
547 _sgen.generateSource(filePath, _srcpackage);
548 } catch (FileNotFoundException e) {
549 String message = "XML Schema file \"" + _schemaFile.getAbsolutePath() + "\" not found.";
550 log(message);
551 throw new BuildException(message);
552 } catch (Exception iox) {
553 throw new BuildException(iox);
554 }
555 }
556
557
558
559
560
561
562
563 private void processURL(final String schemaURL) {
564 log("Processing " + schemaURL);
565 try {
566 InputSource inputSource = new InputSource(schemaURL);
567 _sgen.generateSource(inputSource, _srcpackage);
568 } catch (FileNotFoundException e) {
569 String message = "XML Schema file \"" + _schemaURL + "\" not found.";
570 log(message);
571 throw new BuildException(message);
572 } catch (Exception iox) {
573 throw new BuildException(iox);
574 }
575 }
576
577
578
579
580
581
582
583
584 public void execute() {
585
586 if (_schemaFile == null && _schemaDir == null && _schemaFilesets.isEmpty()
587 && _schemaURL == null) {
588 throw new BuildException(NO_SCHEMA_MSG);
589 }
590
591 try {
592 config();
593
594
595 if (_schemaFile != null) {
596 processFile(_schemaFile.getAbsolutePath());
597 }
598
599
600 if (_schemaDir != null && _schemaDir.exists() && _schemaDir.isDirectory()) {
601 DirectoryScanner ds = this.getDirectoryScanner(_schemaDir);
602
603 String[] files = ds.getIncludedFiles();
604 for (String file : files) {
605 String filePath = _schemaDir.getAbsolutePath() + File.separator + file;
606 processFile(filePath);
607 }
608 }
609
610
611 for (FileSet fs : _schemaFilesets) {
612 DirectoryScanner ds = fs.getDirectoryScanner(getProject());
613 File subdir = fs.getDir(getProject());
614
615 String[] files = ds.getIncludedFiles();
616 for (String file : files) {
617 String filePath = subdir.getAbsolutePath() + File.separator + file;
618 processFile(filePath);
619 }
620 }
621
622
623 if (_schemaURL != null) {
624 processURL(_schemaURL);
625 }
626 } finally {
627 _sgen = null;
628 }
629 }
630
631
632
633
634
635 private final class CastorSourceGeneratorWrapper extends SourceGenerator {
636
637
638
639 public CastorSourceGeneratorWrapper() {
640 super();
641 }
642
643
644
645
646
647
648 public CastorSourceGeneratorWrapper(final FieldInfoFactory fieldInfoFactory) {
649 super(fieldInfoFactory);
650 }
651
652
653
654
655
656
657
658 public CastorSourceGeneratorWrapper(final FieldInfoFactory fieldInfoFactory,
659 final ExtendedBinding extendedBinding) {
660 super(fieldInfoFactory, extendedBinding);
661 }
662
663
664
665
666
667
668
669
670
671
672
673 public void generateSource(final InputSource source, final String packageName) {
674 Parser parser = null;
675 try {
676 parser = _internalContext.getParser();
677 } catch (RuntimeException e) {
678 throw new BuildException("Unable to create SAX parser.", e);
679 }
680 if (parser == null) {
681 throw new BuildException("Unable to create SAX parser.");
682 }
683
684 SchemaContext schemaContext = new SchemaContextImpl();
685 SchemaUnmarshaller schemaUnmarshaller = null;
686 try {
687 schemaUnmarshaller = new SchemaUnmarshaller(schemaContext);
688 } catch (XMLException e) {
689 throw new BuildException("Unable to create schema unmarshaller.", e);
690 }
691
692 Sax2ComponentReader handler = new Sax2ComponentReader(schemaUnmarshaller);
693 parser.setDocumentHandler(handler);
694 parser.setErrorHandler(handler);
695 try {
696 parser.parse(source);
697 } catch (IOException | SAXException e) {
698 String msg = "Can't read input file " + source.getSystemId() + ".\n" + e;
699 throw new BuildException(msg, e);
700 }
701 Schema schema = schemaUnmarshaller.getSchema();
702 try {
703 generateSource(schema, packageName);
704 } catch (Exception iox) {
705 throw new BuildException(iox);
706 }
707 }
708 }
709
710
711
712
713
714
715
716
717
718
719
720 private void callSetterMethodUsingReflection(final SourceGenerator sgen, final String methodName,
721 final Class parameterType, final Object parameterValue) throws BuildException {
722 try {
723 Method method = sgen.getClass().getMethod(methodName, new Class[] {parameterType});
724 method.invoke(sgen, new Object[] {parameterValue});
725 } catch (NoSuchMethodException e) {
726
727 } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
728 throw new BuildException(PROBLEM_SETTING_JDO_DESC, e);
729 }
730 }
731
732
733
734 }