001 package org.apache.torque.engine.database.model;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import java.util.ArrayList;
023 import java.util.Collections;
024 import java.util.Iterator;
025 import java.util.List;
026 import java.util.Map;
027
028 import org.apache.commons.collections.map.ListOrderedMap;
029 import org.apache.commons.lang.StringUtils;
030 import org.apache.commons.logging.Log;
031 import org.apache.commons.logging.LogFactory;
032 import org.apache.torque.engine.EngineException;
033 import org.apache.torque.engine.platform.Platform;
034 import org.xml.sax.Attributes;
035
036 /**
037 * A Class for holding data about a column used in an Application.
038 *
039 * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
040 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
041 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
042 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
043 * @author <a href="mailto:byron_foster@byron_foster@yahoo.com>Byron Foster</a>
044 * @author <a href="mailto:mpoeschl@marmot.at>Martin Poeschl</a>
045 * @author <a href="mailto:monroe@dukece.com>Greg Monroe</a>
046 * @version $Id: Column.java,v 1.1 2007-10-21 07:57:27 abyrne Exp $
047 */
048 public class Column {
049 private static final SchemaType DEFAULT_TYPE = SchemaType.VARCHAR;
050 /** Logging class from commons.logging */
051 private static Log log = LogFactory.getLog(Column.class);
052 private String name;
053 private String description;
054 private Domain domain = new Domain();
055 private String javaName = null;
056 private String javaNamingMethod;
057 private boolean isNotNull = false;
058 private boolean isProtected = false;
059 private String javaType;
060 private Table parentTable;
061 private int position;
062 private boolean isPrimaryKey = false;
063 private boolean isUnique = false;
064 private boolean isAutoIncrement = false;
065 private List referrers;
066 // only one type is supported currently, which assumes the
067 // column either contains the classnames or a key to
068 // classnames specified in the schema. Others may be
069 // supported later.
070 private String inheritanceType;
071 private boolean isInheritance;
072 private boolean isEnumeratedClasses;
073 private List inheritanceList;
074 private boolean needsTransactionInPostgres;
075 /**
076 * The type from java.sql.Types
077 */
078 private int jdbcType;
079
080 /** generate is... setters for boolean columns if true */
081 private boolean correctGetters = false;
082
083 /** class name to do input validation on this column */
084 private String inputValidator = null;
085 private Map options;
086
087 /**
088 * Creates a new instance with a <code>null</code> name.
089 */
090 public Column() {
091 this(null);
092 }
093
094 /**
095 * Creates a new column and set the name
096 *
097 * @param name
098 * column name
099 */
100 public Column(String name) {
101 this.name = name;
102 options = Collections.synchronizedMap(new ListOrderedMap());
103 }
104
105 /**
106 * Return a comma delimited string listing the specified columns.
107 *
108 * @param columns
109 * Either a list of <code>Column</code> objects, or a list of <code>String</code> objects with column names.
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 * Imports a column from an XML specification
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 // Name
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 // retrieves the method for converting from specified name to
149 // a java name.
150 javaNamingMethod = attrib.getValue("javaNamingMethod");
151 if (javaNamingMethod == null) {
152 javaNamingMethod = parentTable.getDatabase().getDefaultJavaNamingMethod();
153 }
154
155 // Primary Key
156 String primaryKey = attrib.getValue("primaryKey");
157 // Avoid NullPointerExceptions on string comparisons.
158 isPrimaryKey = ("true".equals(primaryKey));
159
160 // If this column is a primary key then it can't be null.
161 if ("true".equals(primaryKey)) {
162 isNotNull = true;
163 }
164
165 // HELP: Should primary key, index, and/or idMethod="native"
166 // affect isNotNull? If not, please document why here.
167 String notNull = attrib.getValue("required");
168 isNotNull = (notNull != null && "true".equals(notNull));
169
170 // AutoIncrement/Sequences
171 String autoIncrement = attrib.getValue("autoIncrement");
172 // autoincrement is false per default,
173 // except if the column is a primary key
174 // and the idMethod is native
175 // and the platform's default id Method is identity
176 // and autoIncrement is not excplicitly set to false
177 isAutoIncrement = ("true".equals(autoIncrement) || (isPrimaryKey() && IDMethod.NATIVE.equals(getTable().getIdMethod())
178 && Platform.IDENTITY.equals(getPlatform().getNativeIdMethod()) && (!"false".equals(autoIncrement))));
179 // Default column value.
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 * Returns table.column
196 */
197 public String getFullyQualifiedName() {
198 return (parentTable.getName() + '.' + name);
199 }
200
201 /**
202 * Get the name of the column
203 */
204 public String getName() {
205 return name;
206 }
207
208 /**
209 * Set the name of the column
210 */
211 public void setName(String newName) {
212 name = newName;
213 }
214
215 /**
216 * Get the description for the Table
217 */
218 public String getDescription() {
219 return description;
220 }
221
222 /**
223 * Set the description for the Table
224 *
225 * @param newDescription
226 * description for the Table
227 */
228 public void setDescription(String newDescription) {
229 description = newDescription;
230 }
231
232 /**
233 * Get name to use in Java sources to build method names.
234 *
235 * @return the capitalised javaName
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 * Returns the name for the getter method to retrieve the value of this column
253 *
254 * @return A getter method name for this column.
255 * @since 3.2
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 * Returns the name for the setter method to set the value of this column
267 *
268 * @return A setter method name for this column.
269 * @since 3.2
270 */
271 public String getSetterName() {
272 return "set" + StringUtils.capitalize(getJavaName());
273 }
274
275 /**
276 * Get variable name to use in Java sources (= uncapitalised java name)
277 */
278 public String getUncapitalisedJavaName() {
279 return StringUtils.uncapitalize(getJavaName());
280 }
281
282 /**
283 * Returns the name of the constant that is used for the column in the Peer class, e.g., RecordPeer.COLVARNAME. Generally this will be a
284 * straight conversion to upper case. But if the column name is equals to TABLE_NAME or DATABASE_NAME (Torque predefined vars), the
285 * column name will have an _ prefixed, e.g. _TABLE_NAME.
286 * <p>
287 * TODO: Handle delimited column names that have non-Java identifier characters in them.
288 *
289 * @return The name to use in defining the Peer class column variable.
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 * Set the name to use in Java sources.
301 */
302 public void setJavaName(String javaName) {
303 this.javaName = javaName;
304 }
305
306 /**
307 * Returns whether the type in the java object should be an object or primitive.
308 */
309 public String getJavaType() {
310 return javaType;
311 }
312
313 /**
314 * Get the location of this column within the table (one-based).
315 *
316 * @return value of position.
317 */
318 public int getPosition() {
319 return position;
320 }
321
322 /**
323 * Get the location of this column within the table (one-based).
324 *
325 * @param v
326 * Value to assign to position.
327 */
328 public void setPosition(int v) {
329 this.position = v;
330 }
331
332 /**
333 * Set the parent Table of the column
334 */
335 public void setTable(Table parent) {
336 parentTable = parent;
337 }
338
339 /**
340 * Get the parent Table of the column
341 */
342 public Table getTable() {
343 return parentTable;
344 }
345
346 /**
347 * Returns the Name of the table the column is in
348 */
349 public String getTableName() {
350 return parentTable.getName();
351 }
352
353 /**
354 * A utility function to create a new column from attrib and add it to this table.
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 * Adds a new inheritance definition to the inheritance list and set the parent column of the inheritance to the current column
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 * Get the inheritance definitions.
378 */
379 public List getChildren() {
380 return inheritanceList;
381 }
382
383 /**
384 * Determine if this column is a normal property or specifies a the classes that are represented in the table containing this column.
385 */
386 public boolean isInheritance() {
387 return isInheritance;
388 }
389
390 /**
391 * Determine if possible classes have been enumerated in the xml file.
392 */
393 public boolean isEnumeratedClasses() {
394 return isEnumeratedClasses;
395 }
396
397 /**
398 * Return the isNotNull property of the column
399 */
400 public boolean isNotNull() {
401 return isNotNull;
402 }
403
404 /**
405 * Set the isNotNull property of the column
406 */
407 public void setNotNull(boolean status) {
408 isNotNull = status;
409 }
410
411 /**
412 * Return NOT NULL String for this column
413 *
414 * @return "NOT NULL" if null values are not allowed or an empty String.
415 */
416 public String getNotNullString() {
417 return getTable().getDatabase().getPlatform().getNullString(this.isNotNull());
418 }
419
420 /**
421 * Return the isProtected property of the column
422 */
423 public boolean isProtected() {
424 return isProtected;
425 }
426
427 /**
428 * Set the isProtected property of the Column
429 */
430 public void setProtected(boolean prot) {
431 isProtected = prot;
432 }
433
434 /**
435 * Set if the column is a primary key or not
436 */
437 public void setPrimaryKey(boolean pk) {
438 isPrimaryKey = pk;
439 }
440
441 /**
442 * Return true if the column is a primary key
443 */
444 public boolean isPrimaryKey() {
445 return isPrimaryKey;
446 }
447
448 /**
449 * Set true if the column is UNIQUE
450 */
451 public void setUnique(boolean u) {
452 isUnique = u;
453 }
454
455 /**
456 * Get the UNIQUE property
457 */
458 public boolean isUnique() {
459 return isUnique;
460 }
461
462 /**
463 * Return true if the column requires a transaction in Postgres
464 */
465 public boolean requiresTransactionInPostgres() {
466 return needsTransactionInPostgres;
467 }
468
469 /**
470 * Utility method to determine if this column is a foreign key.
471 */
472 public boolean isForeignKey() {
473 return (getForeignKey() != null);
474 }
475
476 /**
477 * Determine if this column is a foreign key that refers to the same table as another foreign key column in this table.
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 // No multiple foreign keys.
492 return false;
493 }
494
495 /**
496 * get the foreign key object for this column if it is a foreign key or part of a foreign key
497 */
498 public ForeignKey getForeignKey() {
499 return parentTable.getForeignKey(this.name);
500 }
501
502 /**
503 * Utility method to get the related table of this column if it is a foreign key or part of a foreign key
504 */
505 public String getRelatedTableName() {
506 ForeignKey fk = getForeignKey();
507 return (fk == null ? null : fk.getForeignTableName());
508 }
509
510 /**
511 * Utility method to get the related column of this local column if this column is a foreign key or part of a foreign key.
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 * Adds the foreign key from another table that refers to this column.
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 * Get list of references to this column.
534 */
535 public List getReferrers() {
536 if (referrers == null) {
537 referrers = new ArrayList(5);
538 }
539 return referrers;
540 }
541
542 /**
543 * Sets the colunm type
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 * Sets the colunm type
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 * Returns the column jdbc type as an object
566 *
567 * @deprecated the type conversion is handled by the platform package (since torque 3.2)
568 */
569 @Deprecated
570 public Object getType() {
571 return TypeMap.getJdbcType(domain.getType()).getName();
572 }
573
574 /**
575 * Returns the column type as given in the schema as an object
576 */
577 public Object getTorqueType() {
578 return domain.getType().getName();
579 }
580
581 /**
582 * Utility method to see if the column is a string
583 *
584 * @deprecated will be removed after the 3.3 release
585 */
586 @Deprecated
587 public boolean isString() {
588 return (domain.getType().getName().indexOf("CHAR") != -1);
589 }
590
591 /**
592 * Utility method to return the value as an element to be usable in an SQL insert statement. This is used from the SQL loader task
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 * String representation of the column. This is an xml representation.
603 *
604 * @return string representation in xml
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 // Close the column.
644 result.append(" />\n");
645
646 return result.toString();
647 }
648
649 /**
650 * Returns the size of the column
651 */
652 public String getSize() {
653 return domain.getSize();
654 }
655
656 /**
657 * Set the size of the column
658 */
659 public void setSize(String newSize) {
660 domain.setSize(newSize);
661 }
662
663 /**
664 * Try to determine the precision of the field from the size attribute. If size attribute is an integer number, it will be returned. If
665 * size attribute is of the format "Precision,Scale", then Precision will be returned. If size is null or the size value is not an valid
666 * integer, null is returned.
667 * <p>
668 * Note: Unparseable values will be logged as a warning.
669 *
670 * @return The precision portion of the size attribute.
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 * Try to determine the scale of the field from the scale and size attribute. If scale attribute is an integer number, it will be
692 * returned. If size attribute is of the format "Precision,Scale", then Scale will be returned. If scale and size attributes are null or
693 * the scale value found is not an valid integer, a null value is returned.
694 * <p>
695 * Note: Unparseable values will be logged as a warning.
696 *
697 * @return The precision portion of the size attribute.
698 */
699 public String getScale() {
700 String scale = domain.getScale();
701 // Check for scale on size attribute if no scale attribute
702 if (scale == null) {
703 scale = getSize();
704 if (scale == null) // No scale or size attribute set.
705 {
706 return scale;
707 }
708 int cLoc = scale.indexOf(',');
709 if (cLoc < 0) // Size did not have "P,S" format
710 {
711 return null;
712 }
713 scale = scale.substring(cLoc + 1);
714 }
715
716 // Validate that scale string found is integer.
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 * Set the scale of the column
728 */
729 public void setScale(String newScale) {
730 domain.setScale(newScale);
731 }
732
733 /**
734 * Return the size and scale in brackets for use in an sql schema.
735 *
736 * @return size and scale or an empty String if there are no values available.
737 */
738 public String printSize() {
739 return domain.printSize();
740 }
741
742 /**
743 * Return a string that will give this column a default value.
744 *
745 * @deprecated
746 */
747 @Deprecated
748 public String getDefaultSetting() {
749 return domain.getDefaultSetting();
750 }
751
752 /**
753 * Set a string that will give this column a default value.
754 */
755 public void setDefaultValue(String def) {
756 domain.setDefaultValue(def);
757 }
758
759 /**
760 * Get a string that will give this column a default value.
761 */
762 public String getDefaultValue() {
763 return domain.getDefaultValue();
764 }
765
766 /**
767 * Returns the class name to do input validation
768 */
769 public String getInputValidator() {
770 return this.inputValidator;
771 }
772
773 /**
774 * Return auto increment/sequence string for the target database. We need to pass in the props for the target database!
775 */
776 public boolean isAutoIncrement() {
777 return isAutoIncrement;
778 }
779
780 /**
781 * Set the auto increment value. Use isAutoIncrement() to find out if it is set or not.
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 * Set the column type from a string property (normally a string from an sql input file)
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 * Return a string representation of the Java object which corresponds to the JDBC type of this column. Use in the generation of
824 * MapBuilders.
825 */
826 public String getJavaObject() {
827 return TypeMap.getJavaObject(domain.getType());
828 }
829
830 /**
831 * Return a string representation of the primitive java type which corresponds to the JDBC type of this column.
832 *
833 * @return string representation of the primitive java type
834 */
835 public String getJavaPrimitive() {
836 return TypeMap.getJavaNative(domain.getType());
837 }
838
839 /**
840 * Return a string representation of the native java type which corresponds to the JDBC type of this column. Use in the generation of
841 * Base objects. This method is used by torque, so it returns Key types for primaryKey and foreignKey columns
842 *
843 * @return java datatype used by torque
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 * Return Village asX() method which corresponds to the JDBC type which represents this column.
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 * Return ParameterParser getX() method which corresponds to the JDBC type which represents this column.
868 */
869 public String getParameterParserMethod() {
870 return TypeMap.getPPMethod(domain.getType());
871 }
872
873 /**
874 * Returns true if the column type is boolean in the java object and a numeric (1 or 0) in the db.
875 */
876 public boolean isBooleanInt() {
877 return TypeMap.isBooleanInt(domain.getType());
878 }
879
880 /**
881 * Returns true if the column type is boolean in the java object and a String ("Y" or "N") in the db.
882 */
883 public boolean isBooleanChar() {
884 return TypeMap.isBooleanChar(domain.getType());
885 }
886
887 /**
888 * Returns true if the column type is boolean in the java object and a Bit ("1" or "0") in the db.
889 */
890 public boolean isBit() {
891 return TypeMap.isBit(domain.getType());
892 }
893
894 /**
895 * returns true, if the columns java native type is an boolean, byte, short, int, long, float, double, char
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 * @return Returns the domain.
909 */
910 public Domain getDomain() {
911 return domain;
912 }
913
914 /**
915 * @param domain
916 * The domain to set.
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 // TODO: Properly SQL-escape the text.
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 * Return the correctGetters property of the column
972 *
973 * @return The currentValue of the correctGetters property.
974 * @since 3.2
975 */
976 public boolean isCorrectGetters() {
977 return correctGetters;
978 }
979
980 /**
981 * Set the correctGetters property of the column. If set to true, the column returns is<xxx> as the getter name which is correct
982 * for the Bean Specs but incompatible to pre-3.2 releases.
983 *
984 * @param correctGetters
985 * The new value of the correctGetters property.
986 * @since 3.2
987 */
988 public void setCorrectGetters(boolean correctGetters) {
989 this.correctGetters = correctGetters;
990 }
991
992 /**
993 * Get the value of the inheritance attribute defined in the schema XML.
994 *
995 * @return Returns the inheritanceType.
996 */
997 public String getInheritanceType() {
998 return inheritanceType;
999 }
1000
1001 /**
1002 * Add an XML Specified option key/value pair to this element's option set.
1003 *
1004 * @param key
1005 * the key of the option.
1006 * @param value
1007 * the value of the option.
1008 */
1009 public void addOption(String key, String value) {
1010 options.put(key, value);
1011 }
1012
1013 /**
1014 * Get the value that was associated with this key in an XML option element.
1015 *
1016 * @param key
1017 * the key of the option.
1018 * @return The value for the key or a null.
1019 */
1020 public String getOption(String key) {
1021 return (String) options.get(key);
1022 }
1023
1024 /**
1025 * Gets the full ordered hashtable array of items specified by XML option statements under this element.
1026 * <p>
1027 *
1028 * Note, this is not thread save but since it's only used for generation which is single threaded, there should be minimum danger using
1029 * this in Velocity.
1030 *
1031 * @return An Map of all options. Will not be null but may be empty.
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 }