Coverage Report - org.apache.torque.engine.database.model.Column
 
Classes in this File Line Coverage Branch Coverage Complexity
Column
0%
0/298
0%
0/178
2.081
 
 1  
 package org.apache.torque.engine.database.model;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.util.ArrayList;
 23  
 import java.util.Collections;
 24  
 import java.util.Iterator;
 25  
 import java.util.List;
 26  
 import java.util.Map;
 27  
 
 28  
 import org.apache.commons.collections.map.ListOrderedMap;
 29  
 import org.apache.commons.lang.StringUtils;
 30  
 import org.apache.commons.logging.Log;
 31  
 import org.apache.commons.logging.LogFactory;
 32  
 import org.apache.torque.engine.EngineException;
 33  
 import org.apache.torque.engine.platform.Platform;
 34  
 import org.apache.torque.engine.platform.PlatformDefaultImpl;
 35  
 import org.xml.sax.Attributes;
 36  
 
 37  
 /**
 38  
  * A Class for holding data about a column used in an Application.
 39  
  * 
 40  
  * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
 41  
  * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
 42  
  * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
 43  
  * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
 44  
  * @author <a href="mailto:byron_foster@byron_foster@yahoo.com>Byron Foster</a>
 45  
  * @author <a href="mailto:mpoeschl@marmot.at>Martin Poeschl</a>
 46  
  * @author <a href="mailto:monroe@dukece.com>Greg Monroe</a>
 47  
  * @version $Id: Column.java,v 1.1 2007-10-21 07:57:27 abyrne Exp $
 48  
  */
 49  
 public class Column {
 50  0
         private static final SchemaType DEFAULT_TYPE = SchemaType.VARCHAR;
 51  
         /** Logging class from commons.logging */
 52  0
         private static Log log = LogFactory.getLog(Column.class);
 53  
         private String name;
 54  
         private String description;
 55  0
         private Domain domain = new Domain();
 56  0
         private String javaName = null;
 57  
         private String javaNamingMethod;
 58  0
         private boolean isNotNull = false;
 59  0
         private boolean isProtected = false;
 60  
         private String javaType;
 61  
         private Table parentTable;
 62  
         private int position;
 63  0
         private boolean isPrimaryKey = false;
 64  0
         private boolean isUnique = false;
 65  0
         private boolean isAutoIncrement = false;
 66  
         private List referrers;
 67  
         // only one type is supported currently, which assumes the
 68  
         // column either contains the classnames or a key to
 69  
         // classnames specified in the schema. Others may be
 70  
         // supported later.
 71  
         private String inheritanceType;
 72  
         private boolean isInheritance;
 73  
         private boolean isEnumeratedClasses;
 74  
         private List inheritanceList;
 75  
         private boolean needsTransactionInPostgres;
 76  
         /**
 77  
          * The type from java.sql.Types
 78  
          */
 79  
         private int jdbcType;
 80  
 
 81  
         /** generate is... setters for boolean columns if true */
 82  0
         private boolean correctGetters = false;
 83  
 
 84  
         /** class name to do input validation on this column */
 85  0
         private String inputValidator = null;
 86  
         private Map options;
 87  
 
 88  
         /**
 89  
          * Creates a new instance with a <code>null</code> name.
 90  
          */
 91  
         public Column() {
 92  0
                 this(null);
 93  0
         }
 94  
 
 95  
         /**
 96  
          * Creates a new column and set the name
 97  
          * 
 98  
          * @param name
 99  
          *            column name
 100  
          */
 101  0
         public Column(String name) {
 102  0
                 this.name = name;
 103  0
                 options = Collections.synchronizedMap(new ListOrderedMap());
 104  0
         }
 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  0
                 Object obj = columns.get(0);
 115  0
                 boolean isColumnList = (obj instanceof Column);
 116  0
                 if (isColumnList) {
 117  0
                         obj = ((Column) obj).getName();
 118  
                 }
 119  0
                 StringBuffer buf = new StringBuffer((String) obj);
 120  0
                 for (int i = 1; i < columns.size(); i++) {
 121  0
                         obj = columns.get(i);
 122  0
                         if (isColumnList) {
 123  0
                                 obj = ((Column) obj).getName();
 124  
                         }
 125  0
                         buf.append(", ").append(obj);
 126  
                 }
 127  0
                 return buf.toString();
 128  
         }
 129  
 
 130  
         /**
 131  
          * Imports a column from an XML specification
 132  
          */
 133  
         public void loadFromXML(Attributes attrib) {
 134  0
                 String dom = attrib.getValue("domain");
 135  0
                 if (StringUtils.isNotEmpty(dom)) {
 136  0
                         domain = new Domain(getTable().getDatabase().getDomain(dom));
 137  
                 } else {
 138  0
                         domain = new Domain(getPlatform().getDomainForSchemaType(DEFAULT_TYPE));
 139  0
                         setType(attrib.getValue("type"));
 140  
                 }
 141  
                 // Name
 142  0
                 name = attrib.getValue("name");
 143  
 
 144  0
                 javaName = attrib.getValue("javaName");
 145  0
                 javaType = attrib.getValue("javaType");
 146  0
                 if (javaType != null && javaType.length() == 0) {
 147  0
                         javaType = null;
 148  
                 }
 149  
 
 150  
                 // retrieves the method for converting from specified name to
 151  
                 // a java name.
 152  0
                 javaNamingMethod = attrib.getValue("javaNamingMethod");
 153  0
                 if (javaNamingMethod == null) {
 154  0
                         javaNamingMethod = parentTable.getDatabase().getDefaultJavaNamingMethod();
 155  
                 }
 156  
 
 157  
                 // Primary Key
 158  0
                 String primaryKey = attrib.getValue("primaryKey");
 159  
                 // Avoid NullPointerExceptions on string comparisons.
 160  0
                 isPrimaryKey = ("true".equals(primaryKey));
 161  
 
 162  
                 // If this column is a primary key then it can't be null.
 163  0
                 if ("true".equals(primaryKey)) {
 164  0
                         isNotNull = true;
 165  
                 }
 166  
 
 167  
                 // HELP: Should primary key, index, and/or idMethod="native"
 168  
                 // affect isNotNull? If not, please document why here.
 169  0
                 String notNull = attrib.getValue("required");
 170  0
                 isNotNull = (notNull != null && "true".equals(notNull));
 171  
 
 172  
                 // AutoIncrement/Sequences
 173  0
                 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  0
                 isAutoIncrement = ("true".equals(autoIncrement) || (isPrimaryKey() && IDMethod.NATIVE.equals(getTable().getIdMethod()) && Platform.IDENTITY.equals(getPlatform().getNativeIdMethod()) && (!"false".equals(autoIncrement))));
 180  
                 // Default column value.
 181  0
                 domain.replaceDefaultValue(attrib.getValue("default"));
 182  
 
 183  0
                 domain.replaceSize(attrib.getValue("size"));
 184  0
                 domain.replaceScale(attrib.getValue("scale"));
 185  
 
 186  0
                 inheritanceType = attrib.getValue("inheritance");
 187  0
                 isInheritance = (inheritanceType != null && !inheritanceType.equals("false"));
 188  
 
 189  0
                 this.inputValidator = attrib.getValue("inputValidator");
 190  0
                 description = attrib.getValue("description");
 191  
 
 192  0
                 isProtected = ("true".equals(attrib.getValue("protected")));
 193  0
         }
 194  
 
 195  
         /**
 196  
          * Returns table.column
 197  
          */
 198  
         public String getFullyQualifiedName() {
 199  0
                 return (parentTable.getName() + '.' + name);
 200  
         }
 201  
 
 202  
         /**
 203  
          * Get the name of the column
 204  
          */
 205  
         public String getName() {
 206  0
                 return name;
 207  
         }
 208  
 
 209  
         /**
 210  
          * Set the name of the column
 211  
          */
 212  
         public void setName(String newName) {
 213  0
                 name = newName;
 214  0
         }
 215  
 
 216  
         /**
 217  
          * Get the description for the Table
 218  
          */
 219  
         public String getDescription() {
 220  0
                 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  0
                 description = newDescription;
 231  0
         }
 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  0
                 if (javaName == null) {
 240  0
                         List inputs = new ArrayList(2);
 241  0
                         inputs.add(name);
 242  0
                         inputs.add(javaNamingMethod);
 243  
                         try {
 244  0
                                 javaName = NameFactory.generateName(NameFactory.JAVA_GENERATOR, inputs);
 245  0
                         } catch (EngineException e) {
 246  0
                                 log.error(e, e);
 247  0
                         }
 248  
                 }
 249  0
                 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  0
                 if (("boolean".equalsIgnoreCase(getJavaNative()) && isCorrectGetters())) {
 260  0
                         return "is" + StringUtils.capitalize(getJavaName());
 261  
                 } else {
 262  0
                         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  0
                 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  0
                 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  0
                 String peerName = name.toUpperCase();
 294  0
                 if (peerName.equals("TABLE_NAME") || peerName.equals("DATABASE_NAME")) {
 295  0
                         peerName = "_" + peerName;
 296  
                 }
 297  0
                 return peerName;
 298  
         }
 299  
 
 300  
         /**
 301  
          * Set the name to use in Java sources.
 302  
          */
 303  
         public void setJavaName(String javaName) {
 304  0
                 this.javaName = javaName;
 305  0
         }
 306  
 
 307  
         /**
 308  
          * Returns whether the type in the java object should be an object or primitive.
 309  
          */
 310  
         public String getJavaType() {
 311  0
                 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  0
                 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  0
                 this.position = v;
 331  0
         }
 332  
 
 333  
         /**
 334  
          * Set the parent Table of the column
 335  
          */
 336  
         public void setTable(Table parent) {
 337  0
                 parentTable = parent;
 338  0
         }
 339  
 
 340  
         /**
 341  
          * Get the parent Table of the column
 342  
          */
 343  
         public Table getTable() {
 344  0
                 return parentTable;
 345  
         }
 346  
 
 347  
         /**
 348  
          * Returns the Name of the table the column is in
 349  
          */
 350  
         public String getTableName() {
 351  0
                 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  0
                 Inheritance inh = new Inheritance();
 359  0
                 inh.loadFromXML(attrib);
 360  0
                 addInheritance(inh);
 361  
 
 362  0
                 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  0
                 inh.setColumn(this);
 371  0
                 if (inheritanceList == null) {
 372  0
                         inheritanceList = new ArrayList();
 373  0
                         isEnumeratedClasses = true;
 374  
                 }
 375  0
                 inheritanceList.add(inh);
 376  0
         }
 377  
 
 378  
         /**
 379  
          * Get the inheritance definitions.
 380  
          */
 381  
         public List getChildren() {
 382  0
                 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  0
                 return isInheritance;
 391  
         }
 392  
 
 393  
         /**
 394  
          * Determine if possible classes have been enumerated in the xml file.
 395  
          */
 396  
         public boolean isEnumeratedClasses() {
 397  0
                 return isEnumeratedClasses;
 398  
         }
 399  
 
 400  
         /**
 401  
          * Return the isNotNull property of the column
 402  
          */
 403  
         public boolean isNotNull() {
 404  0
                 return isNotNull;
 405  
         }
 406  
 
 407  
         /**
 408  
          * Set the isNotNull property of the column
 409  
          */
 410  
         public void setNotNull(boolean status) {
 411  0
                 isNotNull = status;
 412  0
         }
 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  0
                 return getTable().getDatabase().getPlatform().getNullString(this.isNotNull());
 421  
         }
 422  
 
 423  
         /**
 424  
          * Return the isProtected property of the column
 425  
          */
 426  
         public boolean isProtected() {
 427  0
                 return isProtected;
 428  
         }
 429  
 
 430  
         /**
 431  
          * Set the isProtected property of the Column
 432  
          */
 433  
         public void setProtected(boolean prot) {
 434  0
                 isProtected = prot;
 435  0
         }
 436  
 
 437  
         /**
 438  
          * Set if the column is a primary key or not
 439  
          */
 440  
         public void setPrimaryKey(boolean pk) {
 441  0
                 isPrimaryKey = pk;
 442  0
         }
 443  
 
 444  
         /**
 445  
          * Return true if the column is a primary key
 446  
          */
 447  
         public boolean isPrimaryKey() {
 448  0
                 return isPrimaryKey;
 449  
         }
 450  
 
 451  
         /**
 452  
          * Set true if the column is UNIQUE
 453  
          */
 454  
         public void setUnique(boolean u) {
 455  0
                 isUnique = u;
 456  0
         }
 457  
 
 458  
         /**
 459  
          * Get the UNIQUE property
 460  
          */
 461  
         public boolean isUnique() {
 462  0
                 return isUnique;
 463  
         }
 464  
 
 465  
         /**
 466  
          * Return true if the column requires a transaction in Postgres
 467  
          */
 468  
         public boolean requiresTransactionInPostgres() {
 469  0
                 return needsTransactionInPostgres;
 470  
         }
 471  
 
 472  
         /**
 473  
          * Utility method to determine if this column is a foreign key.
 474  
          */
 475  
         public boolean isForeignKey() {
 476  0
                 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  0
                 ForeignKey fk = getForeignKey();
 485  0
                 if (fk != null) {
 486  0
                         Iterator fks = parentTable.getForeignKeys().iterator();
 487  0
                         while (fks.hasNext()) {
 488  0
                                 ForeignKey key = (ForeignKey) fks.next();
 489  0
                                 if (key.getForeignTableName().equals(fk.getForeignTableName()) && !key.getLocalColumns().contains(this.name)) {
 490  0
                                         return true;
 491  
                                 }
 492  0
                         }
 493  
                 }
 494  
 
 495  
                 // No multiple foreign keys.
 496  0
                 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  0
                 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  0
                 ForeignKey fk = getForeignKey();
 511  0
                 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  0
                 ForeignKey fk = getForeignKey();
 520  0
                 if (fk == null) {
 521  0
                         return null;
 522  
                 } else {
 523  0
                         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  0
                 if (referrers == null) {
 532  0
                         referrers = new ArrayList(5);
 533  
                 }
 534  0
                 referrers.add(fk);
 535  0
         }
 536  
 
 537  
         /**
 538  
          * Get list of references to this column.
 539  
          */
 540  
         public List getReferrers() {
 541  0
                 if (referrers == null) {
 542  0
                         referrers = new ArrayList(5);
 543  
                 }
 544  0
                 return referrers;
 545  
         }
 546  
 
 547  
         /**
 548  
          * Sets the colunm type
 549  
          */
 550  
         public void setType(String torqueType) {
 551  0
                 SchemaType type = SchemaType.getEnum(torqueType);
 552  0
                 if (type == null) {
 553  0
                         log.warn("SchemaType " + torqueType + " does not exist");
 554  0
                         type = Column.DEFAULT_TYPE;
 555  
                 }
 556  0
                 setType(type);
 557  0
         }
 558  
 
 559  
         /**
 560  
          * Sets the colunm type
 561  
          */
 562  
         public void setType(SchemaType torqueType) {
 563  0
                 domain = new Domain(getPlatform().getDomainForSchemaType(torqueType));
 564  0
                 if (torqueType.equals(SchemaType.VARBINARY) || torqueType.equals(SchemaType.BLOB)) {
 565  0
                         needsTransactionInPostgres = true;
 566  
                 }
 567  0
         }
 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  0
                 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  0
                 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  0
                 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  0
                 String torqueType = domain.getType().getName();
 600  0
                 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  0
                 StringBuffer result = new StringBuffer();
 610  0
                 result.append("    <column name=\"").append(name).append('"');
 611  
 
 612  0
                 if (javaName != null) {
 613  0
                         result.append(" javaName=\"").append(javaName).append('"');
 614  
                 }
 615  
 
 616  0
                 if (isPrimaryKey) {
 617  0
                         result.append(" primaryKey=\"").append(isPrimaryKey).append('"');
 618  
                 }
 619  
 
 620  0
                 if (isNotNull) {
 621  0
                         result.append(" required=\"true\"");
 622  
                 } else {
 623  0
                         result.append(" required=\"false\"");
 624  
                 }
 625  
 
 626  0
                 result.append(" type=\"").append(domain.getType().getName()).append('"');
 627  
 
 628  0
                 if (domain.getSize() != null) {
 629  0
                         result.append(" size=\"").append(domain.getSize()).append('"');
 630  
                 }
 631  
 
 632  0
                 if (domain.getScale() != null) {
 633  0
                         result.append(" scale=\"").append(domain.getScale()).append('"');
 634  
                 }
 635  
 
 636  0
                 if (domain.getDefaultValue() != null) {
 637  0
                         result.append(" default=\"").append(domain.getDefaultValue()).append('"');
 638  
                 }
 639  
 
 640  0
                 if (isInheritance()) {
 641  0
                         result.append(" inheritance=\"").append(inheritanceType).append('"');
 642  
                 }
 643  
 
 644  
                 // Close the column.
 645  0
                 result.append(" />\n");
 646  
 
 647  0
                 return result.toString();
 648  
         }
 649  
 
 650  
         /**
 651  
          * Returns the size of the column
 652  
          */
 653  
         public String getSize() {
 654  0
                 return domain.getSize();
 655  
         }
 656  
 
 657  
         /**
 658  
          * Set the size of the column
 659  
          */
 660  
         public void setSize(String newSize) {
 661  0
                 domain.setSize(newSize);
 662  0
         }
 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  0
                 String size = getSize();
 675  0
                 if (size == null) {
 676  0
                         return size;
 677  
                 }
 678  0
                 int cLoc = size.indexOf(',');
 679  0
                 if (cLoc > 0) {
 680  0
                         size = size.substring(0, cLoc);
 681  
                 }
 682  
                 try {
 683  0
                         Integer.parseInt(size);
 684  0
                 } catch (NumberFormatException e) {
 685  0
                         log.warn("getPrecision(): Size attribute found (" + getSize() + ") was not an integer number, using default of null!");
 686  0
                         size = null;
 687  0
                 }
 688  0
                 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  0
                 String scale = domain.getScale();
 702  
                 // Check for scale on size attribute if no scale attribute
 703  0
                 if (scale == null) {
 704  0
                         scale = getSize();
 705  0
                         if (scale == null) // No scale or size attribute set.
 706  
                         {
 707  0
                                 return scale;
 708  
                         }
 709  0
                         int cLoc = scale.indexOf(',');
 710  0
                         if (cLoc < 0) // Size did not have "P,S" format
 711  
                         {
 712  0
                                 return null;
 713  
                         }
 714  0
                         scale = scale.substring(cLoc + 1);
 715  
                 }
 716  
 
 717  
                 // Validate that scale string found is integer.
 718  
                 try {
 719  0
                         Integer.parseInt(scale);
 720  0
                 } catch (NumberFormatException e) {
 721  0
                         log.warn("getScale(): Scale (or size=\"p,s\") attribute found (" + scale + ") was not an integer number, using default of null.");
 722  0
                         scale = null;
 723  0
                 }
 724  0
                 return scale;
 725  
         }
 726  
 
 727  
         /**
 728  
          * Set the scale of the column
 729  
          */
 730  
         public void setScale(String newScale) {
 731  0
                 domain.setScale(newScale);
 732  0
         }
 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  0
                 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  0
                 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  0
                 domain.setDefaultValue(def);
 757  0
         }
 758  
 
 759  
         /**
 760  
          * Get a string that will give this column a default value.
 761  
          */
 762  
         public String getDefaultValue() {
 763  0
                 return domain.getDefaultValue();
 764  
         }
 765  
 
 766  
         /**
 767  
          * Returns the class name to do input validation
 768  
          */
 769  
         public String getInputValidator() {
 770  0
                 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  0
                 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  0
                 isAutoIncrement = value;
 786  0
         }
 787  
 
 788  
         public String getAutoIncrementString() {
 789  0
                 if (isAutoIncrement() && IDMethod.NATIVE.equals(getTable().getIdMethod())) {
 790  0
                         return getPlatform().getAutoIncrement();
 791  
                 }
 792  0
                 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  0
                 String tn = typeName.toUpperCase();
 800  0
                 setType(tn);
 801  
 
 802  0
                 if (size != null) {
 803  0
                         domain.setSize(size);
 804  
                 }
 805  
 
 806  0
                 if (tn.indexOf("CHAR") != -1) {
 807  0
                         domain.setType(SchemaType.VARCHAR);
 808  0
                 } else if (tn.indexOf("INT") != -1) {
 809  0
                         domain.setType(SchemaType.INTEGER);
 810  0
                 } else if (tn.indexOf("FLOAT") != -1) {
 811  0
                         domain.setType(SchemaType.FLOAT);
 812  0
                 } else if (tn.indexOf("DATE") != -1) {
 813  0
                         domain.setType(SchemaType.DATE);
 814  0
                 } else if (tn.indexOf("TIME") != -1) {
 815  0
                         domain.setType(SchemaType.TIMESTAMP);
 816  0
                 } else if (tn.indexOf("BINARY") != -1) {
 817  0
                         domain.setType(SchemaType.LONGVARBINARY);
 818  
                 } else {
 819  0
                         domain.setType(SchemaType.VARCHAR);
 820  
                 }
 821  0
         }
 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  0
                 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  0
                 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  0
                 String jtype = TypeMap.getJavaNativeObject(domain.getType());
 849  0
                 if (isUsePrimitive()) {
 850  0
                         jtype = TypeMap.getJavaNative(domain.getType());
 851  
                 }
 852  
 
 853  0
                 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  0
                 String vmethod = TypeMap.getVillageObjectMethod(domain.getType());
 861  0
                 if (isUsePrimitive()) {
 862  0
                         vmethod = TypeMap.getVillageMethod(domain.getType());
 863  
                 }
 864  
 
 865  0
                 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  0
                 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  0
                 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  0
                 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  0
                 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  0
                 String t = getJavaNative();
 901  0
                 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  0
                 String s = getJavaType();
 906  0
                 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  0
                 return domain;
 914  
         }
 915  
 
 916  
         /**
 917  
          * @param domain
 918  
          *            The domain to set.
 919  
          */
 920  
         public void setDomain(Domain domain) {
 921  0
                 this.domain = domain;
 922  0
         }
 923  
 
 924  
         private Platform getPlatform() {
 925  
                 try {
 926  0
                         return getTable().getDatabase().getPlatform();
 927  0
                 } catch (Exception ex) {
 928  0
                         log.warn("could not load platform implementation");
 929  
                 }
 930  0
                 return new PlatformDefaultImpl();
 931  
         }
 932  
 
 933  
         public String getSqlString() {
 934  0
                 List resultList = new ArrayList();
 935  0
                 resultList.add(getName());
 936  
 
 937  0
                 String type = getDomain().getSqlType();
 938  
 
 939  0
                 if (getPlatform().hasSize(getDomain().getSqlType())) {
 940  0
                         type += getDomain().printSize();
 941  
                 }
 942  
 
 943  0
                 resultList.add(type);
 944  
 
 945  0
                 String defaultStr = getPlatform().filterInvalidDefaultValues(getDomain().getDefaultValue());
 946  0
                 if (StringUtils.isNotEmpty(defaultStr)) {
 947  
 
 948  0
                         resultList.add("default");
 949  
 
 950  0
                         if (TypeMap.isTextType(getDomain().getType()) && !getPlatform().isSpecialDefault(defaultStr)) {
 951  
                                 // TODO: Properly SQL-escape the text.
 952  0
                                 resultList.add(new StringBuffer().append('\'').append(getDefaultValue()).append('\''));
 953  
                         } else {
 954  0
                                 resultList.add(getDefaultValue());
 955  
                         }
 956  
                 }
 957  0
                 if (getPlatform().createNotNullBeforeAutoincrement()) {
 958  0
                         if (StringUtils.isNotEmpty(getNotNullString())) {
 959  0
                                 resultList.add(getNotNullString());
 960  
                         }
 961  
                 }
 962  0
                 if (StringUtils.isNotEmpty(getAutoIncrementString())) {
 963  0
                         resultList.add(getAutoIncrementString());
 964  
                 }
 965  0
                 if (!getPlatform().createNotNullBeforeAutoincrement()) {
 966  0
                         if (StringUtils.isNotEmpty(getNotNullString())) {
 967  0
                                 resultList.add(getNotNullString());
 968  
                         }
 969  
                 }
 970  0
                 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  0
                 return correctGetters;
 981  
         }
 982  
 
 983  
         /**
 984  
          * Set the correctGetters property of the column. If set to true, the column returns is&lt;xxx&gt; 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  0
                 this.correctGetters = correctGetters;
 993  0
         }
 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  0
                 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  0
                 options.put(key, value);
 1014  0
         }
 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  0
                 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  0
                 return options;
 1038  
         }
 1039  
 
 1040  
         public int getJdbcType() {
 1041  0
                 return jdbcType;
 1042  
         }
 1043  
 
 1044  
         public void setJdbcType(int jdbcType) {
 1045  0
                 this.jdbcType = jdbcType;
 1046  0
         }
 1047  
 }