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