View Javadoc

1   package org.apache.torque.engine.database.model;
2   
3   /*
4    * Copyright 2001-2005 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.util.ArrayList;
20  import java.util.Iterator;
21  import java.util.List;
22  
23  import org.apache.commons.lang.StringUtils;
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.torque.engine.EngineException;
27  import org.apache.torque.engine.platform.Platform;
28  import org.apache.torque.engine.platform.PlatformDefaultImpl;
29  import org.xml.sax.Attributes;
30  
31  /***
32   * A Class for holding data about a column used in an Application.
33   *
34   * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
35   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
36   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
37   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
38   * @author <a href="mailto:byron_foster@byron_foster@yahoo.com>Byron Foster</a>
39   * @author <a href="mailto:mpoeschl@marmot.at>Martin Poeschl</a>
40   * @version $Id: Column.java 326224 2005-10-18 20:35:33Z tfischer $
41   */
42  public class Column
43  {
44      private static final SchemaType DEFAULT_TYPE = SchemaType.VARCHAR;
45      /*** Logging class from commons.logging */
46      private static Log log = LogFactory.getLog(Column.class);
47      private String name;
48      private String description;
49      private Domain domain = new Domain();
50      private String javaName = null;
51      private String javaNamingMethod;
52      private boolean isNotNull = false;
53      private boolean isProtected = false;
54      private String javaType;
55      private Table parentTable;
56      private int position;
57      private boolean isPrimaryKey = false;
58      private boolean isUnique = false;
59      private boolean isAutoIncrement = false;
60      private List referrers;
61      // only one type is supported currently, which assumes the
62      // column either contains the classnames or a key to
63      // classnames specified in the schema.  Others may be
64      // supported later.
65      private String inheritanceType;
66      private boolean isInheritance;
67      private boolean isEnumeratedClasses;
68      private List inheritanceList;
69      private boolean needsTransactionInPostgres;
70  
71      /*** generate is... setters for boolean columns if true */
72      private boolean correctGetters = false;
73  
74      /*** class name to do input validation on this column */
75      private String inputValidator = null;
76  
77      /***
78       * Creates a new instance with a <code>null</code> name.
79       */
80      public Column()
81      {
82          this(null);
83      }
84  
85      /***
86       * Creates a new column and set the name
87       *
88       * @param name column name
89       */
90      public Column(String name)
91      {
92          this.name = name;
93      }
94  
95      /***
96       * Return a comma delimited string listing the specified columns.
97       *
98       * @param columns Either a list of <code>Column</code> objects, or
99       * a list of <code>String</code> objects with column names.
100      */
101     public static String makeList(List columns)
102     {
103         Object obj = columns.get(0);
104         boolean isColumnList = (obj instanceof Column);
105         if (isColumnList)
106         {
107             obj = ((Column) obj).getName();
108         }
109         StringBuffer buf = new StringBuffer((String) obj);
110         for (int i = 1; i < columns.size(); i++)
111         {
112             obj = columns.get(i);
113             if (isColumnList)
114             {
115                 obj = ((Column) obj).getName();
116             }
117             buf.append(", ").append(obj);
118         }
119         return buf.toString();
120     }
121 
122     /***
123      * Imports a column from an XML specification
124      */
125     public void loadFromXML(Attributes attrib)
126     {
127         String dom = attrib.getValue("domain");
128         if (StringUtils.isNotEmpty(dom))
129         {
130             domain = new Domain(getTable().getDatabase().getDomain(dom));
131         }
132         else
133         {
134             domain = new Domain(getPlatform().getDomainForSchemaType(DEFAULT_TYPE));
135             setType(attrib.getValue("type"));
136         }
137         //Name
138         name = attrib.getValue("name");
139 
140         javaName = attrib.getValue("javaName");
141         javaType = attrib.getValue("javaType");
142         if (javaType != null && javaType.length() == 0)
143         {
144             javaType = null;
145         }
146 
147         // retrieves the method for converting from specified name to
148         // a java name.
149         javaNamingMethod = attrib.getValue("javaNamingMethod");
150         if (javaNamingMethod == null)
151         {
152             javaNamingMethod
153                     = parentTable.getDatabase().getDefaultJavaNamingMethod();
154         }
155 
156         //Primary Key
157         String primaryKey = attrib.getValue("primaryKey");
158         //Avoid NullPointerExceptions on string comparisons.
159         isPrimaryKey = ("true".equals(primaryKey));
160 
161         // If this column is a primary key then it can't be null.
162         if ("true".equals(primaryKey))
163         {
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)
180                 || (isPrimaryKey()
181                     && IDMethod.NATIVE.equals(getTable().getIdMethod())
182                     && Platform.IDENTITY.equals(
183                             getPlatform().getNativeIdMethod())
184                     && (!"false".equals(autoIncrement))));
185         //Default column value.
186         domain.replaceDefaultValue(attrib.getValue("default"));
187 
188         domain.replaceSize(attrib.getValue("size"));
189         domain.replaceScale(attrib.getValue("scale"));
190 
191         inheritanceType = attrib.getValue("inheritance");
192         isInheritance = (inheritanceType != null
193                 && !inheritanceType.equals("false"));
194 
195         this.inputValidator = attrib.getValue("inputValidator");
196         description = attrib.getValue("description");
197 
198         isProtected = ("true".equals(attrib.getValue("protected")));
199     }
200 
201     /***
202      * Returns table.column
203      */
204     public String getFullyQualifiedName()
205     {
206         return (parentTable.getName() + '.' + name);
207     }
208 
209     /***
210      * Get the name of the column
211      */
212     public String getName()
213     {
214         return name;
215     }
216 
217     /***
218      * Set the name of the column
219      */
220     public void setName(String newName)
221     {
222         name = newName;
223     }
224 
225     /***
226      * Get the description for the Table
227      */
228     public String getDescription()
229     {
230         return description;
231     }
232 
233     /***
234      * Set the description for the Table
235      *
236      * @param newDescription description for the Table
237      */
238     public void setDescription(String newDescription)
239     {
240         description = newDescription;
241     }
242 
243     /***
244      * Get name to use in Java sources to build method names.
245      *
246      * @return the capitalised javaName
247      */
248     public String getJavaName()
249     {
250         if (javaName == null)
251         {
252             List inputs = new ArrayList(2);
253             inputs.add(name);
254             inputs.add(javaNamingMethod);
255             try
256             {
257                 javaName = NameFactory.generateName(NameFactory.JAVA_GENERATOR,
258                                                     inputs);
259             }
260             catch (EngineException e)
261             {
262                 log.error(e, e);
263             }
264         }
265         return StringUtils.capitalize(javaName);
266     }
267 
268     /***
269      * Returns the name for the getter method to retrieve the value of this
270      * column
271      *
272      * @return A getter method name for this column.
273      * @since 3.2
274      */
275     public String getGetterName()
276     {
277         if (("boolean".equalsIgnoreCase(getJavaNative()) && isCorrectGetters()))
278         {
279             return "is" + StringUtils.capitalize(getJavaName());
280         }
281         else
282         {
283             return "get" + StringUtils.capitalize(getJavaName());
284         }
285     }
286 
287     /***
288      * Returns the name for the setter method to set the value of this
289      * column
290      *
291      * @return A setter method name for this column.
292      * @since 3.2
293      */
294     public String getSetterName()
295     {
296         return "set" + StringUtils.capitalize(getJavaName());
297     }
298 
299     /***
300      * Get variable name to use in Java sources (= uncapitalised java name)
301      */
302     public String getUncapitalisedJavaName()
303     {
304         return StringUtils.uncapitalize(getJavaName());
305     }
306 
307     /***
308      * Set name to use in Java sources
309      */
310     public void setJavaName(String javaName)
311     {
312         this.javaName = javaName;
313     }
314 
315     /***
316      * Get type to use in Java sources
317      */
318     public String getJavaType()
319     {
320         return javaType;
321     }
322 
323     /***
324      * Get the location of this column within the table (one-based).
325      * @return value of position.
326      */
327     public int getPosition()
328     {
329         return position;
330     }
331 
332     /***
333      * Get the location of this column within the table (one-based).
334      * @param v  Value to assign to position.
335      */
336     public void setPosition(int  v)
337     {
338         this.position = v;
339     }
340 
341     /***
342      * Set the parent Table of the column
343      */
344     public void setTable(Table parent)
345     {
346         parentTable = parent;
347     }
348 
349     /***
350      * Get the parent Table of the column
351      */
352     public Table getTable()
353     {
354         return parentTable;
355     }
356 
357     /***
358      * Returns the Name of the table the column is in
359      */
360     public String getTableName()
361     {
362         return parentTable.getName();
363     }
364 
365     /***
366      * A utility function to create a new column
367      * from attrib and add it to this table.
368      */
369     public Inheritance addInheritance(Attributes attrib)
370     {
371         Inheritance inh = new Inheritance();
372         inh.loadFromXML (attrib);
373         addInheritance(inh);
374 
375         return inh;
376     }
377 
378     /***
379      * Adds a new inheritance definition to the inheritance list and set the
380      * parent column of the inheritance to the current column
381      */
382     public void addInheritance(Inheritance inh)
383     {
384         inh.setColumn(this);
385         if (inheritanceList == null)
386         {
387             inheritanceList = new ArrayList();
388             isEnumeratedClasses = true;
389         }
390         inheritanceList.add(inh);
391     }
392 
393     /***
394      * Get the inheritance definitions.
395      */
396     public List getChildren()
397     {
398         return inheritanceList;
399     }
400 
401     /***
402      * Determine if this column is a normal property or specifies a
403      * the classes that are represented in the table containing this column.
404      */
405     public boolean isInheritance()
406     {
407         return isInheritance;
408     }
409 
410     /***
411      * Determine if possible classes have been enumerated in the xml file.
412      */
413     public boolean isEnumeratedClasses()
414     {
415         return isEnumeratedClasses;
416     }
417 
418     /***
419      * Return the isNotNull property of the column
420      */
421     public boolean isNotNull()
422     {
423         return isNotNull;
424     }
425 
426     /***
427      * Set the isNotNull property of the column
428      */
429     public void setNotNull(boolean status)
430     {
431         isNotNull = status;
432     }
433 
434     /***
435      * Return NOT NULL String for this column
436      *
437      * @return "NOT NULL" if null values are not allowed or an empty String.
438      */
439     public String getNotNullString()
440     {
441         return getTable().getDatabase().getPlatform()
442                 .getNullString(this.isNotNull());
443     }
444 
445     /***
446      * Return the isProtected property of the column
447      */
448     public boolean isProtected()
449     {
450         return isProtected;
451     }
452 
453     /***
454      * Set the isProtected property of the Column
455      */
456     public void setProtected(boolean prot)
457     {
458         isProtected = prot;
459     }
460 
461     /***
462      * Set if the column is a primary key or not
463      */
464     public void setPrimaryKey(boolean pk)
465     {
466         isPrimaryKey = pk;
467     }
468 
469     /***
470      * Return true if the column is a primary key
471      */
472     public boolean isPrimaryKey()
473     {
474         return isPrimaryKey;
475     }
476 
477     /***
478      * Set true if the column is UNIQUE
479      */
480     public void setUnique (boolean u)
481     {
482         isUnique = u;
483     }
484 
485     /***
486      * Get the UNIQUE property
487      */
488     public boolean isUnique()
489     {
490         return isUnique;
491     }
492 
493     /***
494      * Return true if the column requires a transaction in Postgres
495      */
496     public boolean requiresTransactionInPostgres()
497     {
498         return needsTransactionInPostgres;
499     }
500 
501     /***
502      * Utility method to determine if this column is a foreign key.
503      */
504     public boolean isForeignKey()
505     {
506         return (getForeignKey() != null);
507     }
508 
509     /***
510      * Determine if this column is a foreign key that refers to the
511      * same table as another foreign key column in this table.
512      */
513     public boolean isMultipleFK()
514     {
515         ForeignKey fk = getForeignKey();
516         if (fk != null)
517         {
518             Iterator fks = parentTable.getForeignKeys().iterator();
519             while (fks.hasNext())
520             {
521                 ForeignKey key = (ForeignKey) fks.next();
522                 if (key.getForeignTableName().equals(fk.getForeignTableName())
523                         && !key.getLocalColumns().contains(this.name))
524                 {
525                     return true;
526                 }
527             }
528         }
529 
530         // No multiple foreign keys.
531         return false;
532     }
533 
534     /***
535      * get the foreign key object for this column
536      * if it is a foreign key or part of a foreign key
537      */
538     public ForeignKey getForeignKey()
539     {
540         return parentTable.getForeignKey(this.name);
541     }
542 
543     /***
544      * Utility method to get the related table of this column if it is a foreign
545      * key or part of a foreign key
546      */
547     public String getRelatedTableName()
548     {
549         ForeignKey fk = getForeignKey();
550         return (fk == null ? null : fk.getForeignTableName());
551     }
552 
553     /***
554      * Utility method to get the related column of this local column if this
555      * column is a foreign key or part of a foreign key.
556      */
557     public String getRelatedColumnName()
558     {
559         ForeignKey fk = getForeignKey();
560         if (fk == null)
561         {
562             return null;
563         }
564         else
565         {
566             return fk.getLocalForeignMapping().get(this.name).toString();
567         }
568     }
569 
570     /***
571      * Adds the foreign key from another table that refers to this column.
572      */
573     public void addReferrer(ForeignKey fk)
574     {
575         if (referrers == null)
576         {
577             referrers = new ArrayList(5);
578         }
579         referrers.add(fk);
580     }
581 
582     /***
583      * Get list of references to this column.
584      */
585     public List getReferrers()
586     {
587         if (referrers == null)
588         {
589             referrers = new ArrayList(5);
590         }
591         return referrers;
592     }
593 
594     /***
595      * Sets the colunm type
596      */
597     public void setType(String torqueType)
598     {
599         SchemaType type = SchemaType.getEnum(torqueType);
600         if (type == null)
601         {
602             log.warn("SchemaType " + torqueType + " does not exist");
603             type = Column.DEFAULT_TYPE;
604         }
605         setType(type);
606     }
607 
608     /***
609      * Sets the colunm type
610      */
611     public void setType(SchemaType torqueType)
612     {
613         domain = new Domain(getPlatform().getDomainForSchemaType(torqueType));
614         if (torqueType.equals(SchemaType.VARBINARY)
615                 || torqueType.equals(SchemaType.BLOB))
616         {
617             needsTransactionInPostgres = true;
618         }
619     }
620 
621     /***
622      * Returns the column jdbc type as an object
623      *
624      * @deprecated the type conversion is handled by the platform package
625      *             (since torque 3.2)
626      */
627     public Object getType()
628     {
629         return TypeMap.getJdbcType(domain.getType()).getName();
630     }
631 
632     /***
633      * Returns the column type as given in the schema as an object
634      */
635     public Object getTorqueType()
636     {
637         return domain.getType().getName();
638     }
639 
640     /***
641      * Utility method to see if the column is a string
642      *
643      * @deprecated will be removed after the 3.2 release
644      */
645     public boolean isString()
646     {
647         return (domain.getType().getName().indexOf ("CHAR") != -1);
648     }
649 
650     /***
651      * Utility method to return the value as an element to be usable
652      * in an SQL insert statement. This is used from the SQL loader task
653      */
654     public boolean needEscapedValue()
655     {
656         String torqueType = domain.getType().getName();
657         return (torqueType != null) && (torqueType.equals("VARCHAR")
658                         || torqueType.equals("LONGVARCHAR")
659                         || torqueType.equals("DATE")
660                         || torqueType.equals("DATETIME")
661                         || torqueType.equals("TIMESTAMP")
662                         || torqueType.equals("TIME")
663                         || torqueType.equals("CHAR")
664                         || torqueType.equals("CLOB"));
665     }
666 
667     /***
668      * String representation of the column. This is an xml representation.
669      *
670      * @return string representation in xml
671      */
672     public String toString()
673     {
674         StringBuffer result = new StringBuffer();
675         result.append("    <column name=\"").append(name).append('"');
676 
677         if (javaName != null)
678         {
679             result.append(" javaName=\"").append(javaName).append('"');
680         }
681 
682         if (isPrimaryKey)
683         {
684             result.append(" primaryKey=\"").append(isPrimaryKey).append('"');
685         }
686 
687         if (isNotNull)
688         {
689             result.append(" required=\"true\"");
690         }
691         else
692         {
693             result.append(" required=\"false\"");
694         }
695 
696         result.append(" type=\"").append(domain.getType().getName()).append('"');
697 
698         if (domain.getSize() != null)
699         {
700             result.append(" size=\"").append(domain.getSize()).append('"');
701         }
702 
703         if (domain.getScale() != null)
704         {
705             result.append(" scale=\"").append(domain.getScale()).append('"');
706         }
707 
708         if (domain.getDefaultValue() != null)
709         {
710             result.append(" default=\"").append(domain.getDefaultValue()).append('"');
711         }
712 
713         if (isInheritance())
714         {
715             result.append(" inheritance=\"").append(inheritanceType)
716                 .append('"');
717         }
718 
719         // Close the column.
720         result.append(" />\n");
721 
722         return result.toString();
723     }
724 
725     /***
726      * Returns the size of the column
727      */
728     public String getSize()
729     {
730         return domain.getSize();
731     }
732 
733     /***
734      * Set the size of the column
735      */
736     public void setSize(String newSize)
737     {
738         domain.setSize(newSize);
739     }
740 
741     /***
742      * Try to determine the precision of the field from the size attribute.
743      * If size attribute is an integer number, it will be returned.
744      * If size attribute is of the format "Precision,Scale", then Precision
745      * will be returned.
746      * If size is null or the size value is not an valid integer, 
747      * null is returned.
748      * <p>
749      * Note: Unparseable values will be logged as a warning.
750      * 
751      * @return The precision portion of the size attribute.  
752      */
753     public String getPrecision()
754     {
755         String size = getSize();
756         if ( size == null )
757         {
758             return size;
759         }
760         int cLoc = size.indexOf(',');
761         if ( cLoc > 0 )
762         {
763             size = size.substring(0, cLoc);
764         }
765         try 
766         {
767             Integer.parseInt(size);
768         } 
769         catch ( NumberFormatException e  ) 
770         {
771             log.warn("getPrecision(): Size attribute found ("
772                     + getSize()
773                     + ") was not an integer number, using default of null!");
774             size = null;
775         }
776         return size;
777     }
778 
779     /***
780      * Try to determine the scale of the field from the scale and size 
781      * attribute.
782      * If scale attribute is an integer number, it will be returned.
783      * If size attribute is of the format "Precision,Scale", then Scale
784      * will be returned.
785      * If scale and size attributes are null or the scale value found 
786      * is not an valid integer, a null value is returned.
787      * <p>
788      * Note: Unparseable values will be logged as a warning.
789      * 
790      * @return The precision portion of the size attribute.  
791      */
792     public String getScale()
793     {
794         String scale = domain.getScale();
795         // Check for scale on size attribute if no scale attribute
796         if ( scale == null )
797         {
798             scale = getSize();
799             if ( scale == null )   // No scale or size attribute set.
800             {
801                 return scale;
802             }
803             int cLoc = scale.indexOf(',');
804             if ( cLoc < 0 )        // Size did not have "P,S" format
805             {
806                 return null;
807             }
808             scale = scale.substring(cLoc + 1 );
809         }
810 
811         // Validate that scale string found is integer.
812         try 
813         {
814             Integer.parseInt(scale);
815         }
816         catch ( NumberFormatException e  ) 
817         {
818             log.warn("getScale(): Scale (or size=\"p,s\") attribute found ("
819                     + scale
820                     + ") was not an integer number, using default of null.");
821             scale = null;
822         }
823         return scale;
824     }
825 
826     /***
827      * Set the scale of the column
828      */
829     public void setScale(String newScale)
830     {
831         domain.setScale(newScale);
832     }
833 
834     /***
835      * Return the size and scale in brackets for use in an sql schema.
836      *
837      * @return size and scale or an empty String if there are no values
838      *         available.
839      */
840     public String printSize()
841     {
842         return domain.printSize();
843     }
844 
845     /***
846      * Return a string that will give this column a default value.
847      * @deprecated
848      */
849      public String getDefaultSetting()
850      {
851          return domain.getDefaultSetting();
852      }
853 
854     /***
855      * Set a string that will give this column a default value.
856      */
857     public void setDefaultValue(String def)
858     {
859         domain.setDefaultValue(def);
860     }
861 
862     /***
863      * Get a string that will give this column a default value.
864      */
865     public String getDefaultValue()
866     {
867         return domain.getDefaultValue();
868     }
869 
870     /***
871      * Returns the class name to do input validation
872      */
873     public String getInputValidator()
874     {
875        return this.inputValidator;
876     }
877 
878     /***
879      * Return auto increment/sequence string for the target database. We need to
880      * pass in the props for the target database!
881      */
882     public boolean isAutoIncrement()
883     {
884         return isAutoIncrement;
885     }
886 
887     /***
888      * Set the auto increment value.
889      * Use isAutoIncrement() to find out if it is set or not.
890      */
891     public void setAutoIncrement(boolean value)
892     {
893         isAutoIncrement = value;
894     }
895 
896     public String getAutoIncrementString()
897     {
898         if (isAutoIncrement()
899                 && IDMethod.NATIVE.equals(getTable().getIdMethod()))
900         {
901             return getPlatform().getAutoIncrement();
902         }
903         return "";
904     }
905 
906     /***
907      * Set the column type from a string property
908      * (normally a string from an sql input file)
909      */
910     public void setTypeFromString(String typeName, String size)
911     {
912         String tn = typeName.toUpperCase();
913         setType(tn);
914 
915         if (size != null)
916         {
917             domain.setSize(size);
918         }
919 
920         if (tn.indexOf("CHAR") != -1)
921         {
922             domain.setType(SchemaType.VARCHAR);
923         }
924         else if (tn.indexOf("INT") != -1)
925         {
926             domain.setType(SchemaType.INTEGER);
927         }
928         else if (tn.indexOf("FLOAT") != -1)
929         {
930             domain.setType(SchemaType.FLOAT);
931         }
932         else if (tn.indexOf("DATE") != -1)
933         {
934             domain.setType(SchemaType.DATE);
935         }
936         else if (tn.indexOf("TIME") != -1)
937         {
938             domain.setType(SchemaType.TIMESTAMP);
939         }
940         else if (tn.indexOf("BINARY") != -1)
941         {
942             domain.setType(SchemaType.LONGVARBINARY);
943         }
944         else
945         {
946             domain.setType(SchemaType.VARCHAR);
947         }
948     }
949 
950     /***
951      * Return a string representation of the
952      * Java object which corresponds to the JDBC
953      * type of this column. Use in the generation
954      * of MapBuilders.
955      */
956     public String getJavaObject()
957     {
958         return TypeMap.getJavaObject(domain.getType());
959     }
960 
961     /***
962      * Return a string representation of the primitive java type which
963      * corresponds to the JDBC type of this column.
964      *
965      * @return string representation of the primitive java type
966      */
967     public String getJavaPrimitive()
968     {
969         return TypeMap.getJavaNative(domain.getType());
970     }
971 
972     /***
973      * Return a string representation of the native java type which corresponds
974      * to the JDBC type of this column. Use in the generation of Base objects.
975      * This method is used by torque, so it returns Key types for primaryKey and
976      * foreignKey columns
977      *
978      * @return java datatype used by torque
979      */
980     public String getJavaNative()
981     {
982         String jtype = TypeMap.getJavaNativeObject(domain.getType());
983         if (isUsePrimitive())
984         {
985             jtype = TypeMap.getJavaNative(domain.getType());
986         }
987 
988         return jtype;
989     }
990 
991     /***
992      * Return Village asX() method which corresponds to the JDBC type
993      * which represents this column.
994      */
995     public String getVillageMethod()
996     {
997         String vmethod = TypeMap.getVillageObjectMethod(domain.getType());
998         if (isUsePrimitive())
999         {
1000             vmethod = TypeMap.getVillageMethod(domain.getType());
1001         }
1002 
1003         return vmethod;
1004     }
1005 
1006     /***
1007      * Return ParameterParser getX() method which
1008      * corresponds to the JDBC type which represents this column.
1009      */
1010     public String getParameterParserMethod()
1011     {
1012         return TypeMap.getPPMethod(domain.getType());
1013     }
1014 
1015     /***
1016      * Returns true if the column type is boolean in the
1017      * java object and a numeric (1 or 0) in the db.
1018      */
1019     public boolean isBooleanInt()
1020     {
1021         return TypeMap.isBooleanInt(domain.getType());
1022     }
1023 
1024     /***
1025      * Returns true if the column type is boolean in the
1026      * java object and a String ("Y" or "N") in the db.
1027      */
1028     public boolean isBooleanChar()
1029     {
1030         return TypeMap.isBooleanChar(domain.getType());
1031     }
1032 
1033     /***
1034      * Returns true if the column type is boolean in the
1035      * java object and a Bit ("1" or "0") in the db.
1036      */
1037     public boolean isBit()
1038     {
1039         return TypeMap.isBit(domain.getType());
1040     }
1041 
1042     /***
1043      * returns true, if the columns java native type is an
1044      * boolean, byte, short, int, long, float, double, char
1045      */
1046     public boolean isPrimitive()
1047     {
1048         String t = getJavaNative();
1049         return "boolean".equals(t)
1050             || "byte".equals(t)
1051             || "short".equals(t)
1052             || "int".equals(t)
1053             || "long".equals(t)
1054             || "float".equals(t)
1055             || "double".equals(t)
1056             || "char".equals(t);
1057     }
1058 
1059     public boolean isUsePrimitive()
1060     {
1061         String s = getJavaType();
1062         return (s != null && s.equals("primitive"))
1063             || (s == null && !"object".equals(
1064                getTable().getDatabase().getDefaultJavaType()));
1065     }
1066 
1067     /***
1068      * @return Returns the domain.
1069      */
1070     public Domain getDomain()
1071     {
1072         return domain;
1073     }
1074 
1075     /***
1076      * @param domain The domain to set.
1077      */
1078     public void setDomain(Domain domain)
1079     {
1080         this.domain = domain;
1081     }
1082 
1083     private Platform getPlatform()
1084     {
1085         try
1086         {
1087             return getTable().getDatabase().getPlatform();
1088         }
1089         catch (Exception ex)
1090         {
1091             log.warn("could not load platform implementation");
1092         }
1093         return new PlatformDefaultImpl();
1094     }
1095 
1096     public String getSqlString()
1097     {
1098         List resultList = new ArrayList();
1099         resultList.add(getName());
1100 
1101         String type = getDomain().getSqlType();
1102 
1103         if (getPlatform().hasSize(getDomain().getSqlType()))
1104         {
1105             type += getDomain().printSize();
1106         }
1107 
1108         resultList.add(type);
1109 
1110         if (StringUtils.isNotEmpty(getDomain().getDefaultValue()))
1111         {
1112             resultList.add("default");
1113 
1114             if (TypeMap.isTextType(getDomain().getType()))
1115             {
1116                 // TODO: Properly SQL-escape the text.
1117                 resultList.add(
1118                         new StringBuffer()
1119                         .append('\'')
1120                         .append(getDefaultValue())
1121                         .append('\''));
1122             }
1123             else
1124             {
1125                 resultList.add(getDefaultValue());
1126             }
1127         }
1128         if (StringUtils.isNotEmpty(getNotNullString()))
1129         {
1130             resultList.add(getNotNullString());
1131         }
1132         if (StringUtils.isNotEmpty(getAutoIncrementString()))
1133         {
1134             resultList.add(getAutoIncrementString());
1135         }
1136         return StringUtils.join(resultList.iterator(), ' ');
1137     }
1138 
1139     /***
1140      * Return the correctGetters property of the column
1141      *
1142      * @return The currentValue of the correctGetters property.
1143      * @since 3.2
1144      */
1145     public boolean isCorrectGetters()
1146     {
1147         return correctGetters;
1148     }
1149 
1150     /***
1151      * Set the correctGetters property of the column. If set to true, the
1152      * column returns is&lt;xxx&gt; as the getter name which is correct for the
1153      * Bean Specs but incompatible to pre-3.2 releases.
1154      *
1155      * @param correctGetters The new value of the correctGetters property.
1156      * @since 3.2
1157      */
1158     public void setCorrectGetters(boolean correctGetters)
1159     {
1160         this.correctGetters = correctGetters;
1161     }
1162 }