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
36
37
38
39
40
41
42
43
44
45
46 package org.exolab.castor.builder;
47
48
49 import java.io.File;
50 import java.io.FileInputStream;
51 import java.io.IOException;
52 import java.io.InputStream;
53 import java.util.ArrayList;
54 import java.util.Enumeration;
55 import java.util.Hashtable;
56 import java.util.List;
57 import java.util.Properties;
58 import java.util.StringTokenizer;
59
60 import org.apache.commons.logging.Log;
61 import org.apache.commons.logging.LogFactory;
62 import org.castor.core.util.AbstractProperties;
63 import org.castor.core.util.Messages;
64 import org.castor.xml.JavaNaming;
65 import org.castor.xml.JavaNamingImpl;
66 import org.castor.xml.XMLProperties;
67
68
69
70
71
72
73
74
75
76
77 public class BuilderConfiguration {
78
79
80
81
82 private static final Log LOG = LogFactory.getLog(BuilderConfiguration.class);
83
84
85 private static final String SELF_DIRECTORY = "./";
86
87
88 private static final int SELF_DIRECTORY_LENGTH = SELF_DIRECTORY.length();
89
90
91 private static final String PARENT_DIRECTORY = "../";
92
93
94 private static final int PARENT_DIRECTORY_LENGTH = PARENT_DIRECTORY.length();
95
96
97
98
99 public static class Property {
100
101
102
103
104
105
106
107
108
109
110 public static final String BOUND_PROPERTIES =
111 "org.exolab.castor.builder.boundproperties";
112
113
114
115
116
117
118
119
120
121 public static final String ENUM_TYPE_ACCESS_INTERFACE =
122 "org.exolab.castor.builder.enumTypeAccessInterface";
123
124
125
126
127
128
129
130
131
132 public static final String EXTRA_COLLECTION_METHODS =
133 "org.exolab.castor.builder.extraCollectionMethods";
134
135
136
137
138
139
140
141
142 public static final String SUPER_CLASS =
143 "org.exolab.castor.builder.superclass";
144
145
146
147
148
149
150
151
152
153
154
155
156
157 public static final String JAVA_CLASS_MAPPING =
158 "org.exolab.castor.builder.javaclassmapping";
159
160
161
162
163 public static final String NAMESPACE_PACKAGES_OLD =
164 "org.exolab.castor.builder.nspackages";
165
166
167
168
169 public static final String NAMESPACE_PACKAGES =
170 "org.exolab.castor.xml.nspackages";
171
172
173
174
175
176 public static final String EQUALS_METHOD =
177 "org.exolab.castor.builder.equalsmethod";
178
179
180
181
182
183 public static final String WRAPPER =
184 "org.exolab.castor.builder.primitivetowrapper";
185
186
187
188
189
190
191 public static final String CLASS_DESC_FIELD_NAMES =
192 "org.exolab.castor.builder.classdescfieldnames";
193
194
195
196
197
198 public static final String JAVA_VERSION =
199 "org.exolab.castor.builder.javaVersion";
200
201
202
203
204
205 public static final String FORCE_JAVA4_ENUMS =
206 "org.exolab.castor.builder.forceJava4Enums";
207
208
209
210
211
212
213
214
215 public static final String CONFIG_FILENAME_PROPERTY =
216 "castorbuilder.properties";
217
218
219
220
221
222
223
224
225
226
227
228
229 public static final String MAX_CONSTANTS_PROPERTY =
230 "org.exolab.castor.builder.maxNumberOfConstants";
231
232
233
234
235 static final String RESOURCE_NAME =
236 "/org/exolab/castor/builder/castorbuilder.properties";
237
238
239
240
241
242
243
244
245 public static final String NAME_CONFLICT_STRATEGIES =
246 "org.exolab.castor.builder.nameConflictStrategies";
247
248
249
250
251
252
253
254
255
256 public static final String AUTOMATIC_CONFLICT_RESOLUTION =
257 "org.exolab.castor.builder.automaticConflictResolution";
258
259
260
261
262
263
264
265
266
267
268 public static final String AUTOMATIC_CONFLICT_RESOLUTION_TYPE_SUFFIX =
269 "org.exolab.castor.builder.automaticConflictResolutionTypeSuffix";
270
271
272
273
274
275 public static final String JCLASSPRINTER_FACTORIES =
276 "org.exolab.castor.builder.jclassPrinterFactories";
277
278
279
280
281
282
283
284
285 public static final String EXTRA_DOCUMENTATION_METHODS =
286 "org.exolab.castor.builder.extraDocumentationMethods";
287
288
289
290
291
292
293
294
295
296 public static final String USE_CYCLE_BREAKER = "org.exolab.castor.builder.useCycleBreaker";
297
298
299
300
301
302
303
304
305
306 public static final String USE_OLD_FIELD_NAMING = "org.exolab.castor.builder.field-naming.old";
307
308 }
309
310
311
312
313 private static final String FALSE = "false";
314
315
316
317
318 private static final String TRUE = "true";
319
320
321
322
323 private static final String ELEMENT_VALUE = "element";
324
325
326
327
328 private static final String TYPE_VALUE = "type";
329
330
331
332
333 private Properties _defaultProps = null;
334
335
336
337
338 private Properties _localProps = null;
339
340
341
342
343 private Hashtable<String, String> _nspackages = new Hashtable<String, String>();
344
345
346
347
348 private Hashtable<String, String> _locpackages = new Hashtable<String, String>();
349
350
351 private JavaNaming _javaNaming;
352
353
354
355
356
357
358 private List<AnnotationBuilder> _annotationBuilders = new ArrayList<AnnotationBuilder>();
359
360
361
362
363
364
365 public BuilderConfiguration() {
366 super();
367 getDefault();
368 _localProps = new Properties(_defaultProps);
369 }
370
371
372
373
374
375
376
377
378 public final synchronized Properties getDefault() {
379 if (_defaultProps == null) {
380 load();
381 }
382 return _defaultProps;
383 }
384
385
386
387
388
389
390
391
392
393
394
395 public final String getProperty(final String name, final String defValue) {
396 return _localProps.getProperty(name, defValue);
397 }
398
399
400
401
402
403
404
405
406
407
408 public final boolean boundPropertiesEnabled() {
409 return TRUE.equalsIgnoreCase(_localProps.getProperty(Property.BOUND_PROPERTIES));
410 }
411
412
413
414
415
416
417
418
419
420
421 public final boolean equalsMethod() {
422 return TRUE.equalsIgnoreCase(_localProps.getProperty(Property.EQUALS_METHOD));
423 }
424
425
426
427
428
429
430 public final void setEqualsMethod(final boolean equals) {
431 String value = (equals) ? TRUE : FALSE;
432 _localProps.setProperty(Property.EQUALS_METHOD, value);
433 }
434
435
436
437
438
439
440
441
442
443
444
445 public final boolean classDescFieldNames() {
446 return _localProps.getProperty(Property.CLASS_DESC_FIELD_NAMES, "").equalsIgnoreCase(TRUE);
447 }
448
449
450
451
452
453
454
455
456
457
458
459
460 public final boolean generateExtraCollectionMethods() {
461 return _localProps.getProperty(Property.EXTRA_COLLECTION_METHODS, "")
462 .equalsIgnoreCase(TRUE);
463 }
464
465
466
467
468
469
470
471 public final void setClassDescFieldNames(final boolean classDescFieldNames) {
472 String value = (classDescFieldNames) ? TRUE : FALSE;
473 _localProps.setProperty(Property.CLASS_DESC_FIELD_NAMES, value);
474 }
475
476
477
478
479
480
481 public final boolean usePrimitiveWrapper() {
482 return _localProps.getProperty(Property.WRAPPER, "").equalsIgnoreCase(TRUE);
483 }
484
485
486
487
488
489
490 public final void setPrimitiveWrapper(final boolean wrapper) {
491 String value = (wrapper) ? TRUE : FALSE;
492 _localProps.setProperty(Property.WRAPPER, value);
493 }
494
495
496
497
498
499
500
501 public final boolean useEnumeratedTypeInterface() {
502 return TRUE.equalsIgnoreCase(_localProps.getProperty(Property.ENUM_TYPE_ACCESS_INTERFACE));
503 }
504
505
506
507
508
509
510
511 public final boolean useJava50() {
512 return "5.0".equalsIgnoreCase(_localProps.getProperty(Property.JAVA_VERSION, "1.4"));
513 }
514
515
516
517
518
519
520
521 public final boolean useJava5Enums() {
522 return useJava50() && FALSE.equalsIgnoreCase(
523 _localProps.getProperty(Property.FORCE_JAVA4_ENUMS, FALSE));
524 }
525
526
527
528
529 public final void forceUseJava50() {
530 _localProps.setProperty(Property.JAVA_VERSION, "5.0");
531 }
532
533
534
535
536
537
538
539 public final boolean generateExtraDocumentationMethods() {
540 String extraDocumentationMethods =
541 _localProps.getProperty(Property.EXTRA_DOCUMENTATION_METHODS, "false");
542 return new Boolean(extraDocumentationMethods).booleanValue();
543 }
544
545
546
547
548
549
550
551 public final boolean useCycleBreaker() {
552 return Boolean.valueOf(_localProps.getProperty(Property.USE_CYCLE_BREAKER, "true"));
553 }
554
555
556
557
558
559
560
561
562 public final int getMaximumNumberOfConstants() {
563 String property = _localProps.getProperty(Property.MAX_CONSTANTS_PROPERTY, "1000");
564 return Integer.valueOf(property).intValue();
565 }
566
567
568
569
570
571
572 public final void setUseEnumeratedTypeInterface(final boolean flag) {
573 String value = (flag) ? TRUE : FALSE;
574 _localProps.setProperty(Property.ENUM_TYPE_ACCESS_INTERFACE, value);
575 }
576
577
578
579
580
581
582
583
584 public boolean mappingSchemaElement2Java() {
585 String value = _localProps.getProperty(Property.JAVA_CLASS_MAPPING, "");
586 return ELEMENT_VALUE.equalsIgnoreCase(value);
587 }
588
589
590
591
592
593
594 public boolean mappingSchemaType2Java() {
595 String value = _localProps.getProperty(Property.JAVA_CLASS_MAPPING, "");
596 return TYPE_VALUE.equalsIgnoreCase(value);
597 }
598
599
600
601
602
603
604
605
606
607 public final void setDefaultProperties(final Properties properties) {
608 Properties defaults = null;
609 if (properties == null) {
610 defaults = _defaultProps;
611 } else {
612 defaults = new Properties(_defaultProps);
613 Enumeration<?> enumeration = properties.keys();
614 while (enumeration.hasMoreElements()) {
615 String name = (String) enumeration.nextElement();
616 defaults.setProperty(name, properties.getProperty(name));
617 }
618 }
619 _localProps = new Properties(defaults);
620 processNamespacePackageMappings(
621 _localProps.getProperty(Property.NAMESPACE_PACKAGES_OLD, ""));
622 processNamespacePackageMappings(
623 _localProps.getProperty(Property.NAMESPACE_PACKAGES, ""));
624 }
625
626
627
628
629
630
631
632 public final void setNamespacePackageMapping(final String ns, final String packageName) {
633 _nspackages.put(ns, packageName);
634 }
635
636
637
638
639
640
641
642 public final void setLocationPackageMapping(
643 final String schemaLocation, final String packageName) {
644 _locpackages.put(schemaLocation, packageName);
645 }
646
647
648
649
650
651
652 public final String getJClassPrinterFactories() {
653 return _localProps.getProperty(Property.JCLASSPRINTER_FACTORIES);
654 }
655
656
657
658
659
660
661
662
663 protected final synchronized void load() {
664 if (_defaultProps == null) {
665
666 _defaultProps = loadProperties(
667 Property.RESOURCE_NAME, Property.CONFIG_FILENAME_PROPERTY);
668
669
670
671 boolean found = false;
672
673
674
675 try {
676 InputStream is = SourceGenerator.class.getResourceAsStream(
677 "/" + Property.CONFIG_FILENAME_PROPERTY);
678 if (is != null) {
679 found = true;
680 _defaultProps.load(is);
681 is.close();
682 }
683 } catch (Exception except) {
684
685 }
686
687
688
689 if (!found) {
690 try {
691 File file = new File(Property.CONFIG_FILENAME_PROPERTY);
692 if (file.exists() && file.canRead()) {
693 InputStream is = new FileInputStream(file);
694 _defaultProps.load(is);
695 is.close();
696 }
697 } catch (Exception except) {
698
699 }
700 }
701 }
702
703 AbstractProperties rtconf = XMLProperties.newInstance();
704
705
706
707 processNamespacePackageMappings(rtconf.getString(Property.NAMESPACE_PACKAGES_OLD, ""));
708 processNamespacePackageMappings(rtconf.getString(Property.NAMESPACE_PACKAGES, ""));
709 processNamespacePackageMappings(_defaultProps.getProperty(
710 Property.NAMESPACE_PACKAGES_OLD, ""));
711 processNamespacePackageMappings(_defaultProps.getProperty(
712 Property.NAMESPACE_PACKAGES, ""));
713
714
715 String prop = _defaultProps.getProperty(
716 JavaNamingImpl.UPPER_CASE_AFTER_UNDERSCORE_PROPERTY, null);
717 if (prop != null) {
718
719
720
721
722
723
724 JavaNamingImpl._upperCaseAfterUnderscore = Boolean.valueOf(prop).booleanValue();
725 }
726 }
727
728
729
730
731
732
733 public final String lookupPackageByNamespace(final String nsURL) {
734 String namespaceURL = (nsURL == null) ? "" : nsURL;
735
736
737 String javaPackage = _nspackages.get(namespaceURL);
738 if (javaPackage == null) {
739 return "";
740 }
741 return javaPackage;
742 }
743
744
745
746
747
748
749
750
751 public final String lookupPackageByLocation(final String schemaLocation) {
752 if (schemaLocation == null) {
753 return "";
754 }
755
756
757
758 String javaPackage = _locpackages.get(schemaLocation);
759 if (javaPackage == null) {
760 String cleanedSchemaLocation = schemaLocation;
761
762 while (schemaLocation.startsWith(".")) {
763 if (schemaLocation.startsWith(SELF_DIRECTORY)) {
764 cleanedSchemaLocation = schemaLocation.substring(SELF_DIRECTORY_LENGTH);
765 } else if (schemaLocation.startsWith(PARENT_DIRECTORY)) {
766 cleanedSchemaLocation = schemaLocation.substring(PARENT_DIRECTORY_LENGTH);
767 }
768 }
769 Enumeration<String> keys = _locpackages.keys();
770 boolean found = false;
771 while (keys.hasMoreElements() && !found) {
772 String key = keys.nextElement();
773 if (cleanedSchemaLocation.endsWith(key)) {
774 javaPackage = _locpackages.get(key);
775 found = true;
776 }
777 }
778 if (javaPackage == null) {
779 javaPackage = "";
780 }
781 }
782
783 return javaPackage;
784 }
785
786
787
788
789
790
791 protected final void processNamespacePackageMappings(final String mappings) {
792 if (mappings == null) {
793 return;
794 }
795
796 StringTokenizer tokens = new StringTokenizer(mappings, ",");
797 while (tokens.hasMoreTokens()) {
798 String token = tokens.nextToken();
799 int sepIdx = token.indexOf('=');
800 if (sepIdx < 0) {
801 continue;
802 }
803
804 String ns = token.substring(0, sepIdx).trim();
805 String javaPackage = token.substring(sepIdx + 1).trim();
806 _nspackages.put(ns, javaPackage);
807 }
808 }
809
810
811
812
813
814
815 public boolean isAutomaticConflictResolution() {
816 String automaticConflictResolutionProperty =
817 _localProps.getProperty(Property.AUTOMATIC_CONFLICT_RESOLUTION, "false");
818 return "true".equalsIgnoreCase(automaticConflictResolutionProperty);
819 }
820
821
822
823
824
825
826 public String getAutomaticConflictResolutionTypeSuffix() {
827 return _localProps.getProperty(Property.AUTOMATIC_CONFLICT_RESOLUTION_TYPE_SUFFIX, "");
828 }
829
830
831
832
833
834
835 public void setJavaNaming(final JavaNaming javaNaming) {
836 _javaNaming = javaNaming;
837 }
838
839
840
841
842
843
844 public JavaNaming getJavaNaming() {
845 return _javaNaming;
846 }
847
848
849
850
851
852 public void addAnnotationBuilder(final AnnotationBuilder annotationBuilder) {
853 this._annotationBuilders.add(annotationBuilder);
854 }
855
856
857
858
859
860 public AnnotationBuilder[] getAnnotationBuilders() {
861 return
862 this._annotationBuilders.toArray(
863 new AnnotationBuilder[this._annotationBuilders.size()]);
864 }
865
866
867
868
869
870
871
872
873
874
875
876 public static Properties loadProperties(final String resourceName, final String fileName) {
877 File file;
878 Properties properties = new Properties();
879
880 boolean found = false;
881
882
883
884 InputStream resourceStream = null;
885 try {
886 resourceStream = AbstractProperties.class.getResourceAsStream(resourceName);
887 properties.load(resourceStream);
888
889
890
891
892
893
894 found = true;
895 } catch (Exception except) {
896
897
898 } finally {
899 if (resourceStream != null) {
900 try {
901 resourceStream.close();
902 } catch (IOException e) {
903 LOG.warn("Problem closing stream for " + resourceName);
904 }
905 }
906 }
907
908
909
910
911 String javaHome = null;
912 try {
913 javaHome = System.getProperty("java.home");
914 } catch (SecurityException e) {
915
916
917 LOG.warn(Messages.format("conf.privilegesError", e));
918 } catch (Exception e) {
919
920
921 LOG.warn(Messages.format("conf.nonCriticalError", e));
922 }
923
924 if (javaHome != null) {
925 InputStream fileStream = null;
926 try {
927 file = new File(javaHome, "lib");
928 file = new File(file, fileName);
929 if (file.exists()) {
930 properties = new Properties(properties);
931 fileStream = new FileInputStream(file);
932 properties.load(fileStream);
933 found = true;
934 }
935 } catch (SecurityException e) {
936
937
938 LOG.warn(Messages.format("conf.privilegesError", e));
939 } catch (IOException e) {
940
941 LOG.warn(Messages.format("conf.nonCriticalError", e));
942 } finally {
943 if (fileStream != null) {
944 try {
945 fileStream.close();
946 } catch (IOException e) {
947 LOG.warn("Problem closing stream for " + fileName);
948 }
949 }
950 }
951 }
952
953
954
955 if (!found) {
956 throw new RuntimeException(Messages.format("conf.noDefaultConfigurationFile",
957 fileName));
958 }
959
960 return properties;
961 }
962
963 public boolean useOldFieldNaming() {
964 return "true".equalsIgnoreCase(_localProps.getProperty(Property.USE_OLD_FIELD_NAMING, FALSE));
965 }
966 }