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