001 package org.apache.torque.engine.database.model; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.util.ArrayList; 023 import java.util.Collections; 024 import java.util.Iterator; 025 import java.util.List; 026 import java.util.Map; 027 028 import org.apache.commons.collections.map.ListOrderedMap; 029 import org.apache.commons.lang.StringUtils; 030 import org.apache.commons.logging.Log; 031 import org.apache.commons.logging.LogFactory; 032 import org.apache.torque.engine.EngineException; 033 import org.apache.torque.engine.platform.Platform; 034 import org.xml.sax.Attributes; 035 036 /** 037 * A Class for holding data about a column used in an Application. 038 * 039 * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a> 040 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> 041 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> 042 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> 043 * @author <a href="mailto:byron_foster@byron_foster@yahoo.com>Byron Foster</a> 044 * @author <a href="mailto:mpoeschl@marmot.at>Martin Poeschl</a> 045 * @author <a href="mailto:monroe@dukece.com>Greg Monroe</a> 046 * @version $Id: Column.java,v 1.1 2007-10-21 07:57:27 abyrne Exp $ 047 */ 048 public class Column { 049 private static final SchemaType DEFAULT_TYPE = SchemaType.VARCHAR; 050 /** Logging class from commons.logging */ 051 private static Log log = LogFactory.getLog(Column.class); 052 private String name; 053 private String description; 054 private Domain domain = new Domain(); 055 private String javaName = null; 056 private String javaNamingMethod; 057 private boolean isNotNull = false; 058 private boolean isProtected = false; 059 private String javaType; 060 private Table parentTable; 061 private int position; 062 private boolean isPrimaryKey = false; 063 private boolean isUnique = false; 064 private boolean isAutoIncrement = false; 065 private List referrers; 066 // only one type is supported currently, which assumes the 067 // column either contains the classnames or a key to 068 // classnames specified in the schema. Others may be 069 // supported later. 070 private String inheritanceType; 071 private boolean isInheritance; 072 private boolean isEnumeratedClasses; 073 private List inheritanceList; 074 private boolean needsTransactionInPostgres; 075 /** 076 * The type from java.sql.Types 077 */ 078 private int jdbcType; 079 080 /** generate is... setters for boolean columns if true */ 081 private boolean correctGetters = false; 082 083 /** class name to do input validation on this column */ 084 private String inputValidator = null; 085 private Map options; 086 087 /** 088 * Creates a new instance with a <code>null</code> name. 089 */ 090 public Column() { 091 this(null); 092 } 093 094 /** 095 * Creates a new column and set the name 096 * 097 * @param name 098 * column name 099 */ 100 public Column(String name) { 101 this.name = name; 102 options = Collections.synchronizedMap(new ListOrderedMap()); 103 } 104 105 /** 106 * Return a comma delimited string listing the specified columns. 107 * 108 * @param columns 109 * Either a list of <code>Column</code> objects, or a list of <code>String</code> objects with column names. 110 */ 111 public static String makeList(List columns) { 112 Object obj = columns.get(0); 113 boolean isColumnList = (obj instanceof Column); 114 if (isColumnList) { 115 obj = ((Column) obj).getName(); 116 } 117 StringBuffer buf = new StringBuffer((String) obj); 118 for (int i = 1; i < columns.size(); i++) { 119 obj = columns.get(i); 120 if (isColumnList) { 121 obj = ((Column) obj).getName(); 122 } 123 buf.append(", ").append(obj); 124 } 125 return buf.toString(); 126 } 127 128 /** 129 * Imports a column from an XML specification 130 */ 131 public void loadFromXML(Attributes attrib) { 132 String dom = attrib.getValue("domain"); 133 if (StringUtils.isNotEmpty(dom)) { 134 domain = new Domain(getTable().getDatabase().getDomain(dom)); 135 } else { 136 domain = new Domain(getPlatform().getDomainForSchemaType(DEFAULT_TYPE)); 137 setType(attrib.getValue("type")); 138 } 139 // Name 140 name = attrib.getValue("name"); 141 142 javaName = attrib.getValue("javaName"); 143 javaType = attrib.getValue("javaType"); 144 if (javaType != null && javaType.length() == 0) { 145 javaType = null; 146 } 147 148 // retrieves the method for converting from specified name to 149 // a java name. 150 javaNamingMethod = attrib.getValue("javaNamingMethod"); 151 if (javaNamingMethod == null) { 152 javaNamingMethod = parentTable.getDatabase().getDefaultJavaNamingMethod(); 153 } 154 155 // Primary Key 156 String primaryKey = attrib.getValue("primaryKey"); 157 // Avoid NullPointerExceptions on string comparisons. 158 isPrimaryKey = ("true".equals(primaryKey)); 159 160 // If this column is a primary key then it can't be null. 161 if ("true".equals(primaryKey)) { 162 isNotNull = true; 163 } 164 165 // HELP: Should primary key, index, and/or idMethod="native" 166 // affect isNotNull? If not, please document why here. 167 String notNull = attrib.getValue("required"); 168 isNotNull = (notNull != null && "true".equals(notNull)); 169 170 // AutoIncrement/Sequences 171 String autoIncrement = attrib.getValue("autoIncrement"); 172 // autoincrement is false per default, 173 // except if the column is a primary key 174 // and the idMethod is native 175 // and the platform's default id Method is identity 176 // and autoIncrement is not excplicitly set to false 177 isAutoIncrement = ("true".equals(autoIncrement) || (isPrimaryKey() && IDMethod.NATIVE.equals(getTable().getIdMethod()) 178 && Platform.IDENTITY.equals(getPlatform().getNativeIdMethod()) && (!"false".equals(autoIncrement)))); 179 // Default column value. 180 domain.replaceDefaultValue(attrib.getValue("default")); 181 182 domain.replaceSize(attrib.getValue("size")); 183 domain.replaceScale(attrib.getValue("scale")); 184 185 inheritanceType = attrib.getValue("inheritance"); 186 isInheritance = (inheritanceType != null && !inheritanceType.equals("false")); 187 188 this.inputValidator = attrib.getValue("inputValidator"); 189 description = attrib.getValue("description"); 190 191 isProtected = ("true".equals(attrib.getValue("protected"))); 192 } 193 194 /** 195 * Returns table.column 196 */ 197 public String getFullyQualifiedName() { 198 return (parentTable.getName() + '.' + name); 199 } 200 201 /** 202 * Get the name of the column 203 */ 204 public String getName() { 205 return name; 206 } 207 208 /** 209 * Set the name of the column 210 */ 211 public void setName(String newName) { 212 name = newName; 213 } 214 215 /** 216 * Get the description for the Table 217 */ 218 public String getDescription() { 219 return description; 220 } 221 222 /** 223 * Set the description for the Table 224 * 225 * @param newDescription 226 * description for the Table 227 */ 228 public void setDescription(String newDescription) { 229 description = newDescription; 230 } 231 232 /** 233 * Get name to use in Java sources to build method names. 234 * 235 * @return the capitalised javaName 236 */ 237 public String getJavaName() { 238 if (javaName == null) { 239 List inputs = new ArrayList(2); 240 inputs.add(name); 241 inputs.add(javaNamingMethod); 242 try { 243 javaName = NameFactory.generateName(NameFactory.JAVA_GENERATOR, inputs); 244 } catch (EngineException e) { 245 log.error(e, e); 246 } 247 } 248 return StringUtils.capitalize(javaName); 249 } 250 251 /** 252 * Returns the name for the getter method to retrieve the value of this column 253 * 254 * @return A getter method name for this column. 255 * @since 3.2 256 */ 257 public String getGetterName() { 258 if (("boolean".equalsIgnoreCase(getJavaNative()) && isCorrectGetters())) { 259 return "is" + StringUtils.capitalize(getJavaName()); 260 } else { 261 return "get" + StringUtils.capitalize(getJavaName()); 262 } 263 } 264 265 /** 266 * Returns the name for the setter method to set the value of this column 267 * 268 * @return A setter method name for this column. 269 * @since 3.2 270 */ 271 public String getSetterName() { 272 return "set" + StringUtils.capitalize(getJavaName()); 273 } 274 275 /** 276 * Get variable name to use in Java sources (= uncapitalised java name) 277 */ 278 public String getUncapitalisedJavaName() { 279 return StringUtils.uncapitalize(getJavaName()); 280 } 281 282 /** 283 * Returns the name of the constant that is used for the column in the Peer class, e.g., RecordPeer.COLVARNAME. Generally this will be a 284 * straight conversion to upper case. But if the column name is equals to TABLE_NAME or DATABASE_NAME (Torque predefined vars), the 285 * column name will have an _ prefixed, e.g. _TABLE_NAME. 286 * <p> 287 * TODO: Handle delimited column names that have non-Java identifier characters in them. 288 * 289 * @return The name to use in defining the Peer class column variable. 290 */ 291 public String getPeerJavaName() { 292 String peerName = name.toUpperCase(); 293 if (peerName.equals("TABLE_NAME") || peerName.equals("DATABASE_NAME")) { 294 peerName = "_" + peerName; 295 } 296 return peerName; 297 } 298 299 /** 300 * Set the name to use in Java sources. 301 */ 302 public void setJavaName(String javaName) { 303 this.javaName = javaName; 304 } 305 306 /** 307 * Returns whether the type in the java object should be an object or primitive. 308 */ 309 public String getJavaType() { 310 return javaType; 311 } 312 313 /** 314 * Get the location of this column within the table (one-based). 315 * 316 * @return value of position. 317 */ 318 public int getPosition() { 319 return position; 320 } 321 322 /** 323 * Get the location of this column within the table (one-based). 324 * 325 * @param v 326 * Value to assign to position. 327 */ 328 public void setPosition(int v) { 329 this.position = v; 330 } 331 332 /** 333 * Set the parent Table of the column 334 */ 335 public void setTable(Table parent) { 336 parentTable = parent; 337 } 338 339 /** 340 * Get the parent Table of the column 341 */ 342 public Table getTable() { 343 return parentTable; 344 } 345 346 /** 347 * Returns the Name of the table the column is in 348 */ 349 public String getTableName() { 350 return parentTable.getName(); 351 } 352 353 /** 354 * A utility function to create a new column from attrib and add it to this table. 355 */ 356 public Inheritance addInheritance(Attributes attrib) { 357 Inheritance inh = new Inheritance(); 358 inh.loadFromXML(attrib); 359 addInheritance(inh); 360 361 return inh; 362 } 363 364 /** 365 * Adds a new inheritance definition to the inheritance list and set the parent column of the inheritance to the current column 366 */ 367 public void addInheritance(Inheritance inh) { 368 inh.setColumn(this); 369 if (inheritanceList == null) { 370 inheritanceList = new ArrayList(); 371 isEnumeratedClasses = true; 372 } 373 inheritanceList.add(inh); 374 } 375 376 /** 377 * Get the inheritance definitions. 378 */ 379 public List getChildren() { 380 return inheritanceList; 381 } 382 383 /** 384 * Determine if this column is a normal property or specifies a the classes that are represented in the table containing this column. 385 */ 386 public boolean isInheritance() { 387 return isInheritance; 388 } 389 390 /** 391 * Determine if possible classes have been enumerated in the xml file. 392 */ 393 public boolean isEnumeratedClasses() { 394 return isEnumeratedClasses; 395 } 396 397 /** 398 * Return the isNotNull property of the column 399 */ 400 public boolean isNotNull() { 401 return isNotNull; 402 } 403 404 /** 405 * Set the isNotNull property of the column 406 */ 407 public void setNotNull(boolean status) { 408 isNotNull = status; 409 } 410 411 /** 412 * Return NOT NULL String for this column 413 * 414 * @return "NOT NULL" if null values are not allowed or an empty String. 415 */ 416 public String getNotNullString() { 417 return getTable().getDatabase().getPlatform().getNullString(this.isNotNull()); 418 } 419 420 /** 421 * Return the isProtected property of the column 422 */ 423 public boolean isProtected() { 424 return isProtected; 425 } 426 427 /** 428 * Set the isProtected property of the Column 429 */ 430 public void setProtected(boolean prot) { 431 isProtected = prot; 432 } 433 434 /** 435 * Set if the column is a primary key or not 436 */ 437 public void setPrimaryKey(boolean pk) { 438 isPrimaryKey = pk; 439 } 440 441 /** 442 * Return true if the column is a primary key 443 */ 444 public boolean isPrimaryKey() { 445 return isPrimaryKey; 446 } 447 448 /** 449 * Set true if the column is UNIQUE 450 */ 451 public void setUnique(boolean u) { 452 isUnique = u; 453 } 454 455 /** 456 * Get the UNIQUE property 457 */ 458 public boolean isUnique() { 459 return isUnique; 460 } 461 462 /** 463 * Return true if the column requires a transaction in Postgres 464 */ 465 public boolean requiresTransactionInPostgres() { 466 return needsTransactionInPostgres; 467 } 468 469 /** 470 * Utility method to determine if this column is a foreign key. 471 */ 472 public boolean isForeignKey() { 473 return (getForeignKey() != null); 474 } 475 476 /** 477 * Determine if this column is a foreign key that refers to the same table as another foreign key column in this table. 478 */ 479 public boolean isMultipleFK() { 480 ForeignKey fk = getForeignKey(); 481 if (fk != null) { 482 Iterator fks = parentTable.getForeignKeys().iterator(); 483 while (fks.hasNext()) { 484 ForeignKey key = (ForeignKey) fks.next(); 485 if (key.getForeignTableName().equals(fk.getForeignTableName()) && !key.getLocalColumns().contains(this.name)) { 486 return true; 487 } 488 } 489 } 490 491 // No multiple foreign keys. 492 return false; 493 } 494 495 /** 496 * get the foreign key object for this column if it is a foreign key or part of a foreign key 497 */ 498 public ForeignKey getForeignKey() { 499 return parentTable.getForeignKey(this.name); 500 } 501 502 /** 503 * Utility method to get the related table of this column if it is a foreign key or part of a foreign key 504 */ 505 public String getRelatedTableName() { 506 ForeignKey fk = getForeignKey(); 507 return (fk == null ? null : fk.getForeignTableName()); 508 } 509 510 /** 511 * Utility method to get the related column of this local column if this column is a foreign key or part of a foreign key. 512 */ 513 public String getRelatedColumnName() { 514 ForeignKey fk = getForeignKey(); 515 if (fk == null) { 516 return null; 517 } else { 518 return fk.getLocalForeignMapping().get(this.name).toString(); 519 } 520 } 521 522 /** 523 * Adds the foreign key from another table that refers to this column. 524 */ 525 public void addReferrer(ForeignKey fk) { 526 if (referrers == null) { 527 referrers = new ArrayList(5); 528 } 529 referrers.add(fk); 530 } 531 532 /** 533 * Get list of references to this column. 534 */ 535 public List getReferrers() { 536 if (referrers == null) { 537 referrers = new ArrayList(5); 538 } 539 return referrers; 540 } 541 542 /** 543 * Sets the colunm type 544 */ 545 public void setType(String torqueType) { 546 SchemaType type = SchemaType.getEnum(torqueType); 547 if (type == null) { 548 log.warn("SchemaType " + torqueType + " does not exist"); 549 type = Column.DEFAULT_TYPE; 550 } 551 setType(type); 552 } 553 554 /** 555 * Sets the colunm type 556 */ 557 public void setType(SchemaType torqueType) { 558 domain = new Domain(getPlatform().getDomainForSchemaType(torqueType)); 559 if (torqueType.equals(SchemaType.VARBINARY) || torqueType.equals(SchemaType.BLOB)) { 560 needsTransactionInPostgres = true; 561 } 562 } 563 564 /** 565 * Returns the column jdbc type as an object 566 * 567 * @deprecated the type conversion is handled by the platform package (since torque 3.2) 568 */ 569 @Deprecated 570 public Object getType() { 571 return TypeMap.getJdbcType(domain.getType()).getName(); 572 } 573 574 /** 575 * Returns the column type as given in the schema as an object 576 */ 577 public Object getTorqueType() { 578 return domain.getType().getName(); 579 } 580 581 /** 582 * Utility method to see if the column is a string 583 * 584 * @deprecated will be removed after the 3.3 release 585 */ 586 @Deprecated 587 public boolean isString() { 588 return (domain.getType().getName().indexOf("CHAR") != -1); 589 } 590 591 /** 592 * Utility method to return the value as an element to be usable in an SQL insert statement. This is used from the SQL loader task 593 */ 594 public boolean needEscapedValue() { 595 String torqueType = domain.getType().getName(); 596 return (torqueType != null) 597 && (torqueType.equals("VARCHAR") || torqueType.equals("LONGVARCHAR") || torqueType.equals("DATE") || torqueType.equals("DATETIME") 598 || torqueType.equals("TIMESTAMP") || torqueType.equals("TIME") || torqueType.equals("CHAR") || torqueType.equals("CLOB")); 599 } 600 601 /** 602 * String representation of the column. This is an xml representation. 603 * 604 * @return string representation in xml 605 */ 606 @Override 607 public String toString() { 608 StringBuffer result = new StringBuffer(); 609 result.append(" <column name=\"").append(name).append('"'); 610 611 if (javaName != null) { 612 result.append(" javaName=\"").append(javaName).append('"'); 613 } 614 615 if (isPrimaryKey) { 616 result.append(" primaryKey=\"").append(isPrimaryKey).append('"'); 617 } 618 619 if (isNotNull) { 620 result.append(" required=\"true\""); 621 } else { 622 result.append(" required=\"false\""); 623 } 624 625 result.append(" type=\"").append(domain.getType().getName()).append('"'); 626 627 if (domain.getSize() != null) { 628 result.append(" size=\"").append(domain.getSize()).append('"'); 629 } 630 631 if (domain.getScale() != null) { 632 result.append(" scale=\"").append(domain.getScale()).append('"'); 633 } 634 635 if (domain.getDefaultValue() != null) { 636 result.append(" default=\"").append(domain.getDefaultValue()).append('"'); 637 } 638 639 if (isInheritance()) { 640 result.append(" inheritance=\"").append(inheritanceType).append('"'); 641 } 642 643 // Close the column. 644 result.append(" />\n"); 645 646 return result.toString(); 647 } 648 649 /** 650 * Returns the size of the column 651 */ 652 public String getSize() { 653 return domain.getSize(); 654 } 655 656 /** 657 * Set the size of the column 658 */ 659 public void setSize(String newSize) { 660 domain.setSize(newSize); 661 } 662 663 /** 664 * Try to determine the precision of the field from the size attribute. If size attribute is an integer number, it will be returned. If 665 * size attribute is of the format "Precision,Scale", then Precision will be returned. If size is null or the size value is not an valid 666 * integer, null is returned. 667 * <p> 668 * Note: Unparseable values will be logged as a warning. 669 * 670 * @return The precision portion of the size attribute. 671 */ 672 public String getPrecision() { 673 String size = getSize(); 674 if (size == null) { 675 return size; 676 } 677 int cLoc = size.indexOf(','); 678 if (cLoc > 0) { 679 size = size.substring(0, cLoc); 680 } 681 try { 682 Integer.parseInt(size); 683 } catch (NumberFormatException e) { 684 log.warn("getPrecision(): Size attribute found (" + getSize() + ") was not an integer number, using default of null!"); 685 size = null; 686 } 687 return size; 688 } 689 690 /** 691 * Try to determine the scale of the field from the scale and size attribute. If scale attribute is an integer number, it will be 692 * returned. If size attribute is of the format "Precision,Scale", then Scale will be returned. If scale and size attributes are null or 693 * the scale value found is not an valid integer, a null value is returned. 694 * <p> 695 * Note: Unparseable values will be logged as a warning. 696 * 697 * @return The precision portion of the size attribute. 698 */ 699 public String getScale() { 700 String scale = domain.getScale(); 701 // Check for scale on size attribute if no scale attribute 702 if (scale == null) { 703 scale = getSize(); 704 if (scale == null) // No scale or size attribute set. 705 { 706 return scale; 707 } 708 int cLoc = scale.indexOf(','); 709 if (cLoc < 0) // Size did not have "P,S" format 710 { 711 return null; 712 } 713 scale = scale.substring(cLoc + 1); 714 } 715 716 // Validate that scale string found is integer. 717 try { 718 Integer.parseInt(scale); 719 } catch (NumberFormatException e) { 720 log.warn("getScale(): Scale (or size=\"p,s\") attribute found (" + scale + ") was not an integer number, using default of null."); 721 scale = null; 722 } 723 return scale; 724 } 725 726 /** 727 * Set the scale of the column 728 */ 729 public void setScale(String newScale) { 730 domain.setScale(newScale); 731 } 732 733 /** 734 * Return the size and scale in brackets for use in an sql schema. 735 * 736 * @return size and scale or an empty String if there are no values available. 737 */ 738 public String printSize() { 739 return domain.printSize(); 740 } 741 742 /** 743 * Return a string that will give this column a default value. 744 * 745 * @deprecated 746 */ 747 @Deprecated 748 public String getDefaultSetting() { 749 return domain.getDefaultSetting(); 750 } 751 752 /** 753 * Set a string that will give this column a default value. 754 */ 755 public void setDefaultValue(String def) { 756 domain.setDefaultValue(def); 757 } 758 759 /** 760 * Get a string that will give this column a default value. 761 */ 762 public String getDefaultValue() { 763 return domain.getDefaultValue(); 764 } 765 766 /** 767 * Returns the class name to do input validation 768 */ 769 public String getInputValidator() { 770 return this.inputValidator; 771 } 772 773 /** 774 * Return auto increment/sequence string for the target database. We need to pass in the props for the target database! 775 */ 776 public boolean isAutoIncrement() { 777 return isAutoIncrement; 778 } 779 780 /** 781 * Set the auto increment value. Use isAutoIncrement() to find out if it is set or not. 782 */ 783 public void setAutoIncrement(boolean value) { 784 isAutoIncrement = value; 785 } 786 787 public String getAutoIncrementString() { 788 if (isAutoIncrement() && IDMethod.NATIVE.equals(getTable().getIdMethod())) { 789 return getPlatform().getAutoIncrement(); 790 } 791 return ""; 792 } 793 794 /** 795 * Set the column type from a string property (normally a string from an sql input file) 796 */ 797 public void setTypeFromString(String typeName, String size) { 798 String tn = typeName.toUpperCase(); 799 setType(tn); 800 801 if (size != null) { 802 domain.setSize(size); 803 } 804 805 if (tn.indexOf("CHAR") != -1) { 806 domain.setType(SchemaType.VARCHAR); 807 } else if (tn.indexOf("INT") != -1) { 808 domain.setType(SchemaType.INTEGER); 809 } else if (tn.indexOf("FLOAT") != -1) { 810 domain.setType(SchemaType.FLOAT); 811 } else if (tn.indexOf("DATE") != -1) { 812 domain.setType(SchemaType.DATE); 813 } else if (tn.indexOf("TIME") != -1) { 814 domain.setType(SchemaType.TIMESTAMP); 815 } else if (tn.indexOf("BINARY") != -1) { 816 domain.setType(SchemaType.LONGVARBINARY); 817 } else { 818 domain.setType(SchemaType.VARCHAR); 819 } 820 } 821 822 /** 823 * Return a string representation of the Java object which corresponds to the JDBC type of this column. Use in the generation of 824 * MapBuilders. 825 */ 826 public String getJavaObject() { 827 return TypeMap.getJavaObject(domain.getType()); 828 } 829 830 /** 831 * Return a string representation of the primitive java type which corresponds to the JDBC type of this column. 832 * 833 * @return string representation of the primitive java type 834 */ 835 public String getJavaPrimitive() { 836 return TypeMap.getJavaNative(domain.getType()); 837 } 838 839 /** 840 * Return a string representation of the native java type which corresponds to the JDBC type of this column. Use in the generation of 841 * Base objects. This method is used by torque, so it returns Key types for primaryKey and foreignKey columns 842 * 843 * @return java datatype used by torque 844 */ 845 public String getJavaNative() { 846 String jtype = TypeMap.getJavaNativeObject(domain.getType()); 847 if (isUsePrimitive()) { 848 jtype = TypeMap.getJavaNative(domain.getType()); 849 } 850 851 return jtype; 852 } 853 854 /** 855 * Return Village asX() method which corresponds to the JDBC type which represents this column. 856 */ 857 public String getVillageMethod() { 858 String vmethod = TypeMap.getVillageObjectMethod(domain.getType()); 859 if (isUsePrimitive()) { 860 vmethod = TypeMap.getVillageMethod(domain.getType()); 861 } 862 863 return vmethod; 864 } 865 866 /** 867 * Return ParameterParser getX() method which corresponds to the JDBC type which represents this column. 868 */ 869 public String getParameterParserMethod() { 870 return TypeMap.getPPMethod(domain.getType()); 871 } 872 873 /** 874 * Returns true if the column type is boolean in the java object and a numeric (1 or 0) in the db. 875 */ 876 public boolean isBooleanInt() { 877 return TypeMap.isBooleanInt(domain.getType()); 878 } 879 880 /** 881 * Returns true if the column type is boolean in the java object and a String ("Y" or "N") in the db. 882 */ 883 public boolean isBooleanChar() { 884 return TypeMap.isBooleanChar(domain.getType()); 885 } 886 887 /** 888 * Returns true if the column type is boolean in the java object and a Bit ("1" or "0") in the db. 889 */ 890 public boolean isBit() { 891 return TypeMap.isBit(domain.getType()); 892 } 893 894 /** 895 * returns true, if the columns java native type is an boolean, byte, short, int, long, float, double, char 896 */ 897 public boolean isPrimitive() { 898 String t = getJavaNative(); 899 return "boolean".equals(t) || "byte".equals(t) || "short".equals(t) || "int".equals(t) || "long".equals(t) || "float".equals(t) || "double".equals(t) || "char".equals(t); 900 } 901 902 public boolean isUsePrimitive() { 903 String s = getJavaType(); 904 return (s != null && s.equals("primitive")) || (s == null && !"object".equals(getTable().getDatabase().getDefaultJavaType())); 905 } 906 907 /** 908 * @return Returns the domain. 909 */ 910 public Domain getDomain() { 911 return domain; 912 } 913 914 /** 915 * @param domain 916 * The domain to set. 917 */ 918 public void setDomain(Domain domain) { 919 this.domain = domain; 920 } 921 922 private Platform getPlatform() { 923 try { 924 return getTable().getDatabase().getPlatform(); 925 } catch (Exception ex) { 926 throw new IllegalStateException(ex); 927 } 928 } 929 930 public String getSqlString() { 931 List resultList = new ArrayList(); 932 resultList.add(getName()); 933 934 String type = getDomain().getSqlType(); 935 936 if (getPlatform().hasSize(getDomain().getSqlType())) { 937 type += getDomain().printSize(); 938 } 939 940 resultList.add(type); 941 942 String defaultStr = getPlatform().filterInvalidDefaultValues(getDomain().getDefaultValue()); 943 if (StringUtils.isNotEmpty(defaultStr)) { 944 945 resultList.add("default"); 946 947 if (TypeMap.isTextType(getDomain().getType()) && !getPlatform().isSpecialDefault(defaultStr)) { 948 // TODO: Properly SQL-escape the text. 949 resultList.add(new StringBuffer().append('\'').append(getDefaultValue()).append('\'')); 950 } else { 951 resultList.add(getDefaultValue()); 952 } 953 } 954 if (getPlatform().createNotNullBeforeAutoincrement()) { 955 if (StringUtils.isNotEmpty(getNotNullString())) { 956 resultList.add(getNotNullString()); 957 } 958 } 959 if (StringUtils.isNotEmpty(getAutoIncrementString())) { 960 resultList.add(getAutoIncrementString()); 961 } 962 if (!getPlatform().createNotNullBeforeAutoincrement()) { 963 if (StringUtils.isNotEmpty(getNotNullString())) { 964 resultList.add(getNotNullString()); 965 } 966 } 967 return StringUtils.join(resultList.iterator(), ' '); 968 } 969 970 /** 971 * Return the correctGetters property of the column 972 * 973 * @return The currentValue of the correctGetters property. 974 * @since 3.2 975 */ 976 public boolean isCorrectGetters() { 977 return correctGetters; 978 } 979 980 /** 981 * Set the correctGetters property of the column. If set to true, the column returns is<xxx> as the getter name which is correct 982 * for the Bean Specs but incompatible to pre-3.2 releases. 983 * 984 * @param correctGetters 985 * The new value of the correctGetters property. 986 * @since 3.2 987 */ 988 public void setCorrectGetters(boolean correctGetters) { 989 this.correctGetters = correctGetters; 990 } 991 992 /** 993 * Get the value of the inheritance attribute defined in the schema XML. 994 * 995 * @return Returns the inheritanceType. 996 */ 997 public String getInheritanceType() { 998 return inheritanceType; 999 } 1000 1001 /** 1002 * Add an XML Specified option key/value pair to this element's option set. 1003 * 1004 * @param key 1005 * the key of the option. 1006 * @param value 1007 * the value of the option. 1008 */ 1009 public void addOption(String key, String value) { 1010 options.put(key, value); 1011 } 1012 1013 /** 1014 * Get the value that was associated with this key in an XML option element. 1015 * 1016 * @param key 1017 * the key of the option. 1018 * @return The value for the key or a null. 1019 */ 1020 public String getOption(String key) { 1021 return (String) options.get(key); 1022 } 1023 1024 /** 1025 * Gets the full ordered hashtable array of items specified by XML option statements under this element. 1026 * <p> 1027 * 1028 * Note, this is not thread save but since it's only used for generation which is single threaded, there should be minimum danger using 1029 * this in Velocity. 1030 * 1031 * @return An Map of all options. Will not be null but may be empty. 1032 */ 1033 public Map getOptions() { 1034 return options; 1035 } 1036 1037 public int getJdbcType() { 1038 return jdbcType; 1039 } 1040 1041 public void setJdbcType(int jdbcType) { 1042 this.jdbcType = jdbcType; 1043 } 1044 }