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