1 package org.apache.torque.engine.database.model;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.commons.collections.map.ListOrderedMap;
29 import org.apache.commons.lang.StringUtils;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.torque.engine.EngineException;
33 import org.apache.torque.engine.platform.Platform;
34 import org.xml.sax.Attributes;
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class Column {
49 private static final SchemaType DEFAULT_TYPE = SchemaType.VARCHAR;
50
51 private static Log log = LogFactory.getLog(Column.class);
52 private String name;
53 private String description;
54 private Domain domain = new Domain();
55 private String javaName = null;
56 private String javaNamingMethod;
57 private boolean isNotNull = false;
58 private boolean isProtected = false;
59 private String javaType;
60 private Table parentTable;
61 private int position;
62 private boolean isPrimaryKey = false;
63 private boolean isUnique = false;
64 private boolean isAutoIncrement = false;
65 private List referrers;
66
67
68
69
70 private String inheritanceType;
71 private boolean isInheritance;
72 private boolean isEnumeratedClasses;
73 private List inheritanceList;
74 private boolean needsTransactionInPostgres;
75
76
77
78 private int jdbcType;
79
80
81 private boolean correctGetters = false;
82
83
84 private String inputValidator = null;
85 private Map options;
86
87
88
89
90 public Column() {
91 this(null);
92 }
93
94
95
96
97
98
99
100 public Column(String name) {
101 this.name = name;
102 options = Collections.synchronizedMap(new ListOrderedMap());
103 }
104
105
106
107
108
109
110
111 public static String makeList(List columns) {
112 Object obj = columns.get(0);
113 boolean isColumnList = (obj instanceof Column);
114 if (isColumnList) {
115 obj = ((Column) obj).getName();
116 }
117 StringBuffer buf = new StringBuffer((String) obj);
118 for (int i = 1; i < columns.size(); i++) {
119 obj = columns.get(i);
120 if (isColumnList) {
121 obj = ((Column) obj).getName();
122 }
123 buf.append(", ").append(obj);
124 }
125 return buf.toString();
126 }
127
128
129
130
131 public void loadFromXML(Attributes attrib) {
132 String dom = attrib.getValue("domain");
133 if (StringUtils.isNotEmpty(dom)) {
134 domain = new Domain(getTable().getDatabase().getDomain(dom));
135 } else {
136 domain = new Domain(getPlatform().getDomainForSchemaType(DEFAULT_TYPE));
137 setType(attrib.getValue("type"));
138 }
139
140 name = attrib.getValue("name");
141
142 javaName = attrib.getValue("javaName");
143 javaType = attrib.getValue("javaType");
144 if (javaType != null && javaType.length() == 0) {
145 javaType = null;
146 }
147
148
149
150 javaNamingMethod = attrib.getValue("javaNamingMethod");
151 if (javaNamingMethod == null) {
152 javaNamingMethod = parentTable.getDatabase().getDefaultJavaNamingMethod();
153 }
154
155
156 String primaryKey = attrib.getValue("primaryKey");
157
158 isPrimaryKey = ("true".equals(primaryKey));
159
160
161 if ("true".equals(primaryKey)) {
162 isNotNull = true;
163 }
164
165
166
167 String notNull = attrib.getValue("required");
168 isNotNull = (notNull != null && "true".equals(notNull));
169
170
171 String autoIncrement = attrib.getValue("autoIncrement");
172
173
174
175
176
177 isAutoIncrement = ("true".equals(autoIncrement) || (isPrimaryKey() && IDMethod.NATIVE.equals(getTable().getIdMethod())
178 && Platform.IDENTITY.equals(getPlatform().getNativeIdMethod()) && (!"false".equals(autoIncrement))));
179
180 domain.replaceDefaultValue(attrib.getValue("default"));
181
182 domain.replaceSize(attrib.getValue("size"));
183 domain.replaceScale(attrib.getValue("scale"));
184
185 inheritanceType = attrib.getValue("inheritance");
186 isInheritance = (inheritanceType != null && !inheritanceType.equals("false"));
187
188 this.inputValidator = attrib.getValue("inputValidator");
189 description = attrib.getValue("description");
190
191 isProtected = ("true".equals(attrib.getValue("protected")));
192 }
193
194
195
196
197 public String getFullyQualifiedName() {
198 return (parentTable.getName() + '.' + name);
199 }
200
201
202
203
204 public String getName() {
205 return name;
206 }
207
208
209
210
211 public void setName(String newName) {
212 name = newName;
213 }
214
215
216
217
218 public String getDescription() {
219 return description;
220 }
221
222
223
224
225
226
227
228 public void setDescription(String newDescription) {
229 description = newDescription;
230 }
231
232
233
234
235
236
237 public String getJavaName() {
238 if (javaName == null) {
239 List inputs = new ArrayList(2);
240 inputs.add(name);
241 inputs.add(javaNamingMethod);
242 try {
243 javaName = NameFactory.generateName(NameFactory.JAVA_GENERATOR, inputs);
244 } catch (EngineException e) {
245 log.error(e, e);
246 }
247 }
248 return StringUtils.capitalize(javaName);
249 }
250
251
252
253
254
255
256
257 public String getGetterName() {
258 if (("boolean".equalsIgnoreCase(getJavaNative()) && isCorrectGetters())) {
259 return "is" + StringUtils.capitalize(getJavaName());
260 } else {
261 return "get" + StringUtils.capitalize(getJavaName());
262 }
263 }
264
265
266
267
268
269
270
271 public String getSetterName() {
272 return "set" + StringUtils.capitalize(getJavaName());
273 }
274
275
276
277
278 public String getUncapitalisedJavaName() {
279 return StringUtils.uncapitalize(getJavaName());
280 }
281
282
283
284
285
286
287
288
289
290
291 public String getPeerJavaName() {
292 String peerName = name.toUpperCase();
293 if (peerName.equals("TABLE_NAME") || peerName.equals("DATABASE_NAME")) {
294 peerName = "_" + peerName;
295 }
296 return peerName;
297 }
298
299
300
301
302 public void setJavaName(String javaName) {
303 this.javaName = javaName;
304 }
305
306
307
308
309 public String getJavaType() {
310 return javaType;
311 }
312
313
314
315
316
317
318 public int getPosition() {
319 return position;
320 }
321
322
323
324
325
326
327
328 public void setPosition(int v) {
329 this.position = v;
330 }
331
332
333
334
335 public void setTable(Table parent) {
336 parentTable = parent;
337 }
338
339
340
341
342 public Table getTable() {
343 return parentTable;
344 }
345
346
347
348
349 public String getTableName() {
350 return parentTable.getName();
351 }
352
353
354
355
356 public Inheritance addInheritance(Attributes attrib) {
357 Inheritance inh = new Inheritance();
358 inh.loadFromXML(attrib);
359 addInheritance(inh);
360
361 return inh;
362 }
363
364
365
366
367 public void addInheritance(Inheritance inh) {
368 inh.setColumn(this);
369 if (inheritanceList == null) {
370 inheritanceList = new ArrayList();
371 isEnumeratedClasses = true;
372 }
373 inheritanceList.add(inh);
374 }
375
376
377
378
379 public List getChildren() {
380 return inheritanceList;
381 }
382
383
384
385
386 public boolean isInheritance() {
387 return isInheritance;
388 }
389
390
391
392
393 public boolean isEnumeratedClasses() {
394 return isEnumeratedClasses;
395 }
396
397
398
399
400 public boolean isNotNull() {
401 return isNotNull;
402 }
403
404
405
406
407 public void setNotNull(boolean status) {
408 isNotNull = status;
409 }
410
411
412
413
414
415
416 public String getNotNullString() {
417 return getTable().getDatabase().getPlatform().getNullString(this.isNotNull());
418 }
419
420
421
422
423 public boolean isProtected() {
424 return isProtected;
425 }
426
427
428
429
430 public void setProtected(boolean prot) {
431 isProtected = prot;
432 }
433
434
435
436
437 public void setPrimaryKey(boolean pk) {
438 isPrimaryKey = pk;
439 }
440
441
442
443
444 public boolean isPrimaryKey() {
445 return isPrimaryKey;
446 }
447
448
449
450
451 public void setUnique(boolean u) {
452 isUnique = u;
453 }
454
455
456
457
458 public boolean isUnique() {
459 return isUnique;
460 }
461
462
463
464
465 public boolean requiresTransactionInPostgres() {
466 return needsTransactionInPostgres;
467 }
468
469
470
471
472 public boolean isForeignKey() {
473 return (getForeignKey() != null);
474 }
475
476
477
478
479 public boolean isMultipleFK() {
480 ForeignKey fk = getForeignKey();
481 if (fk != null) {
482 Iterator fks = parentTable.getForeignKeys().iterator();
483 while (fks.hasNext()) {
484 ForeignKey key = (ForeignKey) fks.next();
485 if (key.getForeignTableName().equals(fk.getForeignTableName()) && !key.getLocalColumns().contains(this.name)) {
486 return true;
487 }
488 }
489 }
490
491
492 return false;
493 }
494
495
496
497
498 public ForeignKey getForeignKey() {
499 return parentTable.getForeignKey(this.name);
500 }
501
502
503
504
505 public String getRelatedTableName() {
506 ForeignKey fk = getForeignKey();
507 return (fk == null ? null : fk.getForeignTableName());
508 }
509
510
511
512
513 public String getRelatedColumnName() {
514 ForeignKey fk = getForeignKey();
515 if (fk == null) {
516 return null;
517 } else {
518 return fk.getLocalForeignMapping().get(this.name).toString();
519 }
520 }
521
522
523
524
525 public void addReferrer(ForeignKey fk) {
526 if (referrers == null) {
527 referrers = new ArrayList(5);
528 }
529 referrers.add(fk);
530 }
531
532
533
534
535 public List getReferrers() {
536 if (referrers == null) {
537 referrers = new ArrayList(5);
538 }
539 return referrers;
540 }
541
542
543
544
545 public void setType(String torqueType) {
546 SchemaType type = SchemaType.getEnum(torqueType);
547 if (type == null) {
548 log.warn("SchemaType " + torqueType + " does not exist");
549 type = Column.DEFAULT_TYPE;
550 }
551 setType(type);
552 }
553
554
555
556
557 public void setType(SchemaType torqueType) {
558 domain = new Domain(getPlatform().getDomainForSchemaType(torqueType));
559 if (torqueType.equals(SchemaType.VARBINARY) || torqueType.equals(SchemaType.BLOB)) {
560 needsTransactionInPostgres = true;
561 }
562 }
563
564
565
566
567
568
569 @Deprecated
570 public Object getType() {
571 return TypeMap.getJdbcType(domain.getType()).getName();
572 }
573
574
575
576
577 public Object getTorqueType() {
578 return domain.getType().getName();
579 }
580
581
582
583
584
585
586 @Deprecated
587 public boolean isString() {
588 return (domain.getType().getName().indexOf("CHAR") != -1);
589 }
590
591
592
593
594 public boolean needEscapedValue() {
595 String torqueType = domain.getType().getName();
596 return (torqueType != null)
597 && (torqueType.equals("VARCHAR") || torqueType.equals("LONGVARCHAR") || torqueType.equals("DATE") || torqueType.equals("DATETIME")
598 || torqueType.equals("TIMESTAMP") || torqueType.equals("TIME") || torqueType.equals("CHAR") || torqueType.equals("CLOB"));
599 }
600
601
602
603
604
605
606 @Override
607 public String toString() {
608 StringBuffer result = new StringBuffer();
609 result.append(" <column name=\"").append(name).append('"');
610
611 if (javaName != null) {
612 result.append(" javaName=\"").append(javaName).append('"');
613 }
614
615 if (isPrimaryKey) {
616 result.append(" primaryKey=\"").append(isPrimaryKey).append('"');
617 }
618
619 if (isNotNull) {
620 result.append(" required=\"true\"");
621 } else {
622 result.append(" required=\"false\"");
623 }
624
625 result.append(" type=\"").append(domain.getType().getName()).append('"');
626
627 if (domain.getSize() != null) {
628 result.append(" size=\"").append(domain.getSize()).append('"');
629 }
630
631 if (domain.getScale() != null) {
632 result.append(" scale=\"").append(domain.getScale()).append('"');
633 }
634
635 if (domain.getDefaultValue() != null) {
636 result.append(" default=\"").append(domain.getDefaultValue()).append('"');
637 }
638
639 if (isInheritance()) {
640 result.append(" inheritance=\"").append(inheritanceType).append('"');
641 }
642
643
644 result.append(" />\n");
645
646 return result.toString();
647 }
648
649
650
651
652 public String getSize() {
653 return domain.getSize();
654 }
655
656
657
658
659 public void setSize(String newSize) {
660 domain.setSize(newSize);
661 }
662
663
664
665
666
667
668
669
670
671
672 public String getPrecision() {
673 String size = getSize();
674 if (size == null) {
675 return size;
676 }
677 int cLoc = size.indexOf(',');
678 if (cLoc > 0) {
679 size = size.substring(0, cLoc);
680 }
681 try {
682 Integer.parseInt(size);
683 } catch (NumberFormatException e) {
684 log.warn("getPrecision(): Size attribute found (" + getSize() + ") was not an integer number, using default of null!");
685 size = null;
686 }
687 return size;
688 }
689
690
691
692
693
694
695
696
697
698
699 public String getScale() {
700 String scale = domain.getScale();
701
702 if (scale == null) {
703 scale = getSize();
704 if (scale == null)
705 {
706 return scale;
707 }
708 int cLoc = scale.indexOf(',');
709 if (cLoc < 0)
710 {
711 return null;
712 }
713 scale = scale.substring(cLoc + 1);
714 }
715
716
717 try {
718 Integer.parseInt(scale);
719 } catch (NumberFormatException e) {
720 log.warn("getScale(): Scale (or size=\"p,s\") attribute found (" + scale + ") was not an integer number, using default of null.");
721 scale = null;
722 }
723 return scale;
724 }
725
726
727
728
729 public void setScale(String newScale) {
730 domain.setScale(newScale);
731 }
732
733
734
735
736
737
738 public String printSize() {
739 return domain.printSize();
740 }
741
742
743
744
745
746
747 @Deprecated
748 public String getDefaultSetting() {
749 return domain.getDefaultSetting();
750 }
751
752
753
754
755 public void setDefaultValue(String def) {
756 domain.setDefaultValue(def);
757 }
758
759
760
761
762 public String getDefaultValue() {
763 return domain.getDefaultValue();
764 }
765
766
767
768
769 public String getInputValidator() {
770 return this.inputValidator;
771 }
772
773
774
775
776 public boolean isAutoIncrement() {
777 return isAutoIncrement;
778 }
779
780
781
782
783 public void setAutoIncrement(boolean value) {
784 isAutoIncrement = value;
785 }
786
787 public String getAutoIncrementString() {
788 if (isAutoIncrement() && IDMethod.NATIVE.equals(getTable().getIdMethod())) {
789 return getPlatform().getAutoIncrement();
790 }
791 return "";
792 }
793
794
795
796
797 public void setTypeFromString(String typeName, String size) {
798 String tn = typeName.toUpperCase();
799 setType(tn);
800
801 if (size != null) {
802 domain.setSize(size);
803 }
804
805 if (tn.indexOf("CHAR") != -1) {
806 domain.setType(SchemaType.VARCHAR);
807 } else if (tn.indexOf("INT") != -1) {
808 domain.setType(SchemaType.INTEGER);
809 } else if (tn.indexOf("FLOAT") != -1) {
810 domain.setType(SchemaType.FLOAT);
811 } else if (tn.indexOf("DATE") != -1) {
812 domain.setType(SchemaType.DATE);
813 } else if (tn.indexOf("TIME") != -1) {
814 domain.setType(SchemaType.TIMESTAMP);
815 } else if (tn.indexOf("BINARY") != -1) {
816 domain.setType(SchemaType.LONGVARBINARY);
817 } else {
818 domain.setType(SchemaType.VARCHAR);
819 }
820 }
821
822
823
824
825
826 public String getJavaObject() {
827 return TypeMap.getJavaObject(domain.getType());
828 }
829
830
831
832
833
834
835 public String getJavaPrimitive() {
836 return TypeMap.getJavaNative(domain.getType());
837 }
838
839
840
841
842
843
844
845 public String getJavaNative() {
846 String jtype = TypeMap.getJavaNativeObject(domain.getType());
847 if (isUsePrimitive()) {
848 jtype = TypeMap.getJavaNative(domain.getType());
849 }
850
851 return jtype;
852 }
853
854
855
856
857 public String getVillageMethod() {
858 String vmethod = TypeMap.getVillageObjectMethod(domain.getType());
859 if (isUsePrimitive()) {
860 vmethod = TypeMap.getVillageMethod(domain.getType());
861 }
862
863 return vmethod;
864 }
865
866
867
868
869 public String getParameterParserMethod() {
870 return TypeMap.getPPMethod(domain.getType());
871 }
872
873
874
875
876 public boolean isBooleanInt() {
877 return TypeMap.isBooleanInt(domain.getType());
878 }
879
880
881
882
883 public boolean isBooleanChar() {
884 return TypeMap.isBooleanChar(domain.getType());
885 }
886
887
888
889
890 public boolean isBit() {
891 return TypeMap.isBit(domain.getType());
892 }
893
894
895
896
897 public boolean isPrimitive() {
898 String t = getJavaNative();
899 return "boolean".equals(t) || "byte".equals(t) || "short".equals(t) || "int".equals(t) || "long".equals(t) || "float".equals(t) || "double".equals(t) || "char".equals(t);
900 }
901
902 public boolean isUsePrimitive() {
903 String s = getJavaType();
904 return (s != null && s.equals("primitive")) || (s == null && !"object".equals(getTable().getDatabase().getDefaultJavaType()));
905 }
906
907
908
909
910 public Domain getDomain() {
911 return domain;
912 }
913
914
915
916
917
918 public void setDomain(Domain domain) {
919 this.domain = domain;
920 }
921
922 private Platform getPlatform() {
923 try {
924 return getTable().getDatabase().getPlatform();
925 } catch (Exception ex) {
926 throw new IllegalStateException(ex);
927 }
928 }
929
930 public String getSqlString() {
931 List resultList = new ArrayList();
932 resultList.add(getName());
933
934 String type = getDomain().getSqlType();
935
936 if (getPlatform().hasSize(getDomain().getSqlType())) {
937 type += getDomain().printSize();
938 }
939
940 resultList.add(type);
941
942 String defaultStr = getPlatform().filterInvalidDefaultValues(getDomain().getDefaultValue());
943 if (StringUtils.isNotEmpty(defaultStr)) {
944
945 resultList.add("default");
946
947 if (TypeMap.isTextType(getDomain().getType()) && !getPlatform().isSpecialDefault(defaultStr)) {
948
949 resultList.add(new StringBuffer().append('\'').append(getDefaultValue()).append('\''));
950 } else {
951 resultList.add(getDefaultValue());
952 }
953 }
954 if (getPlatform().createNotNullBeforeAutoincrement()) {
955 if (StringUtils.isNotEmpty(getNotNullString())) {
956 resultList.add(getNotNullString());
957 }
958 }
959 if (StringUtils.isNotEmpty(getAutoIncrementString())) {
960 resultList.add(getAutoIncrementString());
961 }
962 if (!getPlatform().createNotNullBeforeAutoincrement()) {
963 if (StringUtils.isNotEmpty(getNotNullString())) {
964 resultList.add(getNotNullString());
965 }
966 }
967 return StringUtils.join(resultList.iterator(), ' ');
968 }
969
970
971
972
973
974
975
976 public boolean isCorrectGetters() {
977 return correctGetters;
978 }
979
980
981
982
983
984
985
986
987
988 public void setCorrectGetters(boolean correctGetters) {
989 this.correctGetters = correctGetters;
990 }
991
992
993
994
995
996
997 public String getInheritanceType() {
998 return inheritanceType;
999 }
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009 public void addOption(String key, String value) {
1010 options.put(key, value);
1011 }
1012
1013
1014
1015
1016
1017
1018
1019
1020 public String getOption(String key) {
1021 return (String) options.get(key);
1022 }
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033 public Map getOptions() {
1034 return options;
1035 }
1036
1037 public int getJdbcType() {
1038 return jdbcType;
1039 }
1040
1041 public void setJdbcType(int jdbcType) {
1042 this.jdbcType = jdbcType;
1043 }
1044 }