View Javadoc
1 package org.apache.torque.engine.database.model; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001-2003 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>. 55 */ 56 57 import java.util.ArrayList; 58 import java.util.Hashtable; 59 import java.util.Iterator; 60 import java.util.List; 61 62 import org.apache.commons.lang.StringUtils; 63 64 import org.apache.commons.logging.Log; 65 import org.apache.commons.logging.LogFactory; 66 67 import org.apache.torque.engine.EngineException; 68 69 import org.xml.sax.Attributes; 70 71 /*** 72 * Data about a table used in an application. 73 * 74 * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a> 75 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> 76 * @author <a href="mailto:mpoeschl@marmot.at>Martin Poeschl</a> 77 * @author <a href="mailto:jmcnally@collab.net>John McNally</a> 78 * @author <a href="mailto:dlr@collab.net>Daniel Rall</a> 79 * @author <a href="mailto:byron_foster@byron_foster@yahoo.com>Byron Foster</a> 80 * @version $Id: Table.java,v 1.3 2003/06/26 22:09:41 dlr Exp $ 81 */ 82 public class Table implements IDMethod 83 { 84 /*** Logging class from commons.logging */ 85 private static Log log = LogFactory.getLog(Table.class); 86 87 //private AttributeListImpl attributes; 88 private List columnList; 89 private List foreignKeys; 90 private List indices; 91 private List unices; 92 private List idMethodParameters; 93 private String name; 94 private String description; 95 private String javaName; 96 private String idMethod; 97 private String javaNamingMethod; 98 private Database tableParent; 99 private List referrers; 100 private List foreignTableNames; 101 private boolean containsForeignPK; 102 private Column inheritanceColumn; 103 private boolean skipSql; 104 private boolean abstractValue; 105 private String alias; 106 private String enterface; 107 private String pkg; 108 private String baseClass; 109 private String basePeer; 110 private Hashtable columnsByName; 111 private Hashtable columnsByJavaName; 112 private boolean needsTransactionInPostgres; 113 private boolean heavyIndexing; 114 private boolean forReferenceOnly; 115 116 117 /*** 118 * Default Constructor 119 */ 120 public Table() 121 { 122 this(null); 123 } 124 125 /*** 126 * Constructs a table object with a name 127 * 128 * @param name table name 129 */ 130 public Table(String name) 131 { 132 this.name = name; 133 columnList = new ArrayList(); 134 foreignKeys = new ArrayList(5); 135 indices = new ArrayList(5); 136 unices = new ArrayList(5); 137 columnsByName = new Hashtable(); 138 columnsByJavaName = new Hashtable(); 139 } 140 141 /*** 142 * Load the table object from an xml tag. 143 * 144 * @param attrib xml attributes 145 * @param defaultIdMethod defined at db level 146 */ 147 public void loadFromXML(Attributes attrib, String defaultIdMethod) 148 { 149 name = attrib.getValue("name"); 150 javaName = attrib.getValue("javaName"); 151 idMethod = attrib.getValue("idMethod"); 152 153 // retrieves the method for converting from specified name to 154 // a java name. 155 javaNamingMethod = attrib.getValue("javaNamingMethod"); 156 if (javaNamingMethod == null) 157 { 158 javaNamingMethod = getDatabase().getDefaultJavaNamingMethod(); 159 } 160 161 if ("null".equals(idMethod)) 162 { 163 idMethod = defaultIdMethod; 164 } 165 if ("autoincrement".equals(idMethod) || "sequence".equals(idMethod)) 166 { 167 log.warn("The value '" + idMethod + "' for Torque's " 168 + "table.idMethod attribute has been deprecated in favor " 169 + "of '" + NATIVE + "'. Please adjust your " 170 + "Torque XML schema accordingly."); 171 idMethod = NATIVE; 172 } 173 skipSql = "true".equals(attrib.getValue("skipSql")); 174 // pkg = attrib.getValue("package"); 175 abstractValue = "true".equals(attrib.getValue("abstract")); 176 baseClass = attrib.getValue("baseClass"); 177 basePeer = attrib.getValue("basePeer"); 178 alias = attrib.getValue("alias"); 179 heavyIndexing = "true".equals(attrib.getValue("heavyIndexing")) 180 || (!"false".equals(attrib.getValue("heavyIndexing")) 181 && getDatabase().isHeavyIndexing()); 182 description = attrib.getValue("description"); 183 enterface = attrib.getValue("interface"); 184 } 185 186 /*** 187 * <p>A hook for the SAX XML parser to call when this table has 188 * been fully loaded from the XML, and all nested elements have 189 * been processed.</p> 190 * 191 * <p>Performs heavy indexing and naming of elements which weren't 192 * provided with a name.</p> 193 */ 194 public void doFinalInitialization() 195 { 196 // Heavy indexing must wait until after all columns composing 197 // a table's primary key have been parsed. 198 if (heavyIndexing) 199 { 200 doHeavyIndexing(); 201 } 202 203 // Name any indices which are missing a name using the 204 // appropriate algorithm. 205 doNaming(); 206 } 207 208 /*** 209 * <p>Adds extra indices for multi-part primary key columns.</p> 210 * 211 * <p>For databases like MySQL, values in a where clause must 212 * match key part order from the left to right. So, in the key 213 * definition <code>PRIMARY KEY (FOO_ID, BAR_ID)</code>, 214 * <code>FOO_ID</code> <i>must</i> be the first element used in 215 * the <code>where</code> clause of the SQL query used against 216 * this table for the primary key index to be used. This feature 217 * could cause problems under MySQL with heavily indexed tables, 218 * as MySQL currently only supports 16 indices per table (i.e. it 219 * might cause too many indices to be created).</p> 220 * 221 * <p>See <a href="http://www.mysql.com/doc/E/X/EXPLAIN.html">the 222 * manual</a> for a better description of why heavy indexing is 223 * useful for quickly searchable database tables.</p> 224 */ 225 private void doHeavyIndexing() 226 { 227 if (log.isDebugEnabled()) 228 { 229 log.debug("doHeavyIndex() called on table " + name); 230 } 231 232 List pk = getPrimaryKey(); 233 int size = pk.size(); 234 235 try 236 { 237 // We start at an offset of 1 because the entire column 238 // list is generally implicitly indexed by the fact that 239 // it's a primary key. 240 for (int i = 1; i < size; i++) 241 { 242 addIndex(new Index(this, pk.subList(i, size))); 243 } 244 } 245 catch (EngineException e) 246 { 247 log.error(e, e); 248 } 249 } 250 251 /*** 252 * Names composing objects which haven't yet been named. This 253 * currently consists of foreign-key and index entities. 254 */ 255 private void doNaming() 256 { 257 int i; 258 int size; 259 String name; 260 261 // Assure names are unique across all databases. 262 try 263 { 264 for (i = 0, size = foreignKeys.size(); i < size; i++) 265 { 266 ForeignKey fk = (ForeignKey) foreignKeys.get(i); 267 name = fk.getName(); 268 if (StringUtils.isEmpty(name)) 269 { 270 name = acquireConstraintName("FK", i + 1); 271 fk.setName(name); 272 } 273 } 274 275 for (i = 0, size = indices.size(); i < size; i++) 276 { 277 Index index = (Index) indices.get(i); 278 name = index.getName(); 279 if (StringUtils.isEmpty(name)) 280 { 281 name = acquireConstraintName("I", i + 1); 282 index.setName(name); 283 } 284 } 285 286 // NOTE: Most RDBMSes can apparently name unique column 287 // constraints/indices themselves (using MySQL and Oracle 288 // as test cases), so we'll assume that we needn't add an 289 // entry to the system name list for these. 290 } 291 catch (EngineException nameAlreadyInUse) 292 { 293 log.error(nameAlreadyInUse, nameAlreadyInUse); 294 } 295 } 296 297 /*** 298 * Macro to a constraint name. 299 * 300 * @param nameType constraint type 301 * @param nbr unique number for this constraint type 302 * @return unique name for constraint 303 * @throws EngineException 304 */ 305 private final String acquireConstraintName(String nameType, int nbr) 306 throws EngineException 307 { 308 List inputs = new ArrayList(4); 309 inputs.add(getDatabase()); 310 inputs.add(getName()); 311 inputs.add(nameType); 312 inputs.add(new Integer(nbr)); 313 return NameFactory.generateName(NameFactory.CONSTRAINT_GENERATOR, 314 inputs); 315 } 316 317 /*** 318 * Gets the value of base class for classes produced from this table. 319 * 320 * @return The base class for classes produced from this table. 321 */ 322 public String getBaseClass() 323 { 324 if (isAlias() && baseClass == null) 325 { 326 return alias; 327 } 328 else if (baseClass == null) 329 { 330 return getDatabase().getBaseClass(); 331 } 332 else 333 { 334 return baseClass; 335 } 336 } 337 338 /*** 339 * Set the value of baseClass. 340 * @param v Value to assign to baseClass. 341 */ 342 public void setBaseClass(String v) 343 { 344 this.baseClass = v; 345 } 346 347 /*** 348 * Get the value of basePeer. 349 * @return value of basePeer. 350 */ 351 public String getBasePeer() 352 { 353 if (isAlias() && basePeer == null) 354 { 355 return alias + "Peer"; 356 } 357 else if (basePeer == null) 358 { 359 return getDatabase().getBasePeer(); 360 } 361 else 362 { 363 return basePeer; 364 } 365 } 366 367 /*** 368 * Set the value of basePeer. 369 * @param v Value to assign to basePeer. 370 */ 371 public void setBasePeer(String v) 372 { 373 this.basePeer = v; 374 } 375 376 /*** 377 * A utility function to create a new column from attrib and add it to this 378 * table. 379 * 380 * @param attrib xml attributes for the column to add 381 * @return the added column 382 */ 383 public Column addColumn(Attributes attrib) 384 { 385 Column col = new Column(); 386 col.setTable(this); 387 col.loadFromXML(attrib); 388 addColumn(col); 389 return col; 390 } 391 392 /*** 393 * Adds a new column to the column list and set the 394 * parent table of the column to the current table 395 * 396 * @param col the column to add 397 */ 398 public void addColumn(Column col) 399 { 400 col.setTable (this); 401 if (col.isInheritance()) 402 { 403 inheritanceColumn = col; 404 } 405 columnList.add(col); 406 columnsByName.put(col.getName(), col); 407 columnsByJavaName.put(col.getJavaName(), col); 408 col.setPosition(columnList.size()); 409 needsTransactionInPostgres |= col.requiresTransactionInPostgres(); 410 } 411 412 /*** 413 * A utility function to create a new foreign key 414 * from attrib and add it to this table. 415 * 416 * @param attrib the xml attributes 417 * @return the created ForeignKey 418 */ 419 public ForeignKey addForeignKey(Attributes attrib) 420 { 421 ForeignKey fk = new ForeignKey(); 422 fk.loadFromXML(attrib); 423 addForeignKey(fk); 424 return fk; 425 } 426 427 /*** 428 * Gets the column that subclasses of the class representing this 429 * table can be produced from. 430 */ 431 public Column getChildrenColumn() 432 { 433 return inheritanceColumn; 434 } 435 436 /*** 437 * Get the objects that can be created from this table. 438 */ 439 public List getChildrenNames() 440 { 441 if (inheritanceColumn == null 442 || !inheritanceColumn.isEnumeratedClasses()) 443 { 444 return null; 445 } 446 List children = inheritanceColumn.getChildren(); 447 List names = new ArrayList(children.size()); 448 for (int i = 0; i < children.size(); i++) 449 { 450 names.add(((Inheritance) children.get(i)).getClassName()); 451 } 452 return names; 453 } 454 455 /*** 456 * Adds the foreign key from another table that refers to this table. 457 * 458 * @param fk A foreign key refering to this table 459 */ 460 public void addReferrer(ForeignKey fk) 461 { 462 if (referrers == null) 463 { 464 referrers = new ArrayList(5); 465 } 466 referrers.add(fk); 467 } 468 469 /*** 470 * Get list of references to this table. 471 * 472 * @return A list of references to this table 473 */ 474 public List getReferrers() 475 { 476 return referrers; 477 } 478 479 /*** 480 * Set whether this table contains a foreign PK 481 * 482 * @param b 483 */ 484 public void setContainsForeignPK(boolean b) 485 { 486 containsForeignPK = b; 487 } 488 489 /*** 490 * Determine if this table contains a foreign PK 491 */ 492 public boolean getContainsForeignPK() 493 { 494 return containsForeignPK; 495 } 496 497 /*** 498 * A list of tables referenced by foreign keys in this table 499 * 500 * @return A list of tables 501 */ 502 public List getForeignTableNames() 503 { 504 if (foreignTableNames == null) 505 { 506 foreignTableNames = new ArrayList(1); 507 } 508 return foreignTableNames; 509 } 510 511 /*** 512 * Adds a new FK to the FK list and set the 513 * parent table of the column to the current table 514 * 515 * @param fk A foreign key 516 */ 517 public void addForeignKey(ForeignKey fk) 518 { 519 fk.setTable (this); 520 foreignKeys.add(fk); 521 522 if (foreignTableNames == null) 523 { 524 foreignTableNames = new ArrayList(5); 525 } 526 if (foreignTableNames.contains(fk.getForeignTableName())) 527 { 528 foreignTableNames.add(fk.getForeignTableName()); 529 } 530 } 531 532 /*** 533 * Return true if the column requires a transaction in Postgres 534 */ 535 public boolean requiresTransactionInPostgres() 536 { 537 return needsTransactionInPostgres; 538 } 539 540 /*** 541 * A utility function to create a new id method parameter 542 * from attrib and add it to this table. 543 */ 544 public IdMethodParameter addIdMethodParameter(Attributes attrib) 545 { 546 IdMethodParameter imp = new IdMethodParameter(); 547 imp.loadFromXML(attrib); 548 addIdMethodParameter(imp); 549 return imp; 550 } 551 552 553 /*** 554 * Adds a new ID method parameter to the list and sets the parent 555 * table of the column associated with the supplied parameter to this table. 556 * 557 * @param imp The column to add as an ID method parameter. 558 */ 559 public void addIdMethodParameter(IdMethodParameter imp) 560 { 561 imp.setTable(this); 562 if (idMethodParameters == null) 563 { 564 idMethodParameters = new ArrayList(2); 565 } 566 idMethodParameters.add(imp); 567 } 568 569 /*** 570 * Adds a new index to the index list and set the 571 * parent table of the column to the current table 572 */ 573 public void addIndex(Index index) 574 { 575 index.setTable (this); 576 indices.add(index); 577 } 578 579 /*** 580 * A utility function to create a new index 581 * from attrib and add it to this table. 582 */ 583 public Index addIndex(Attributes attrib) 584 { 585 Index index = new Index(); 586 index.loadFromXML(attrib); 587 addIndex(index); 588 return index; 589 } 590 591 /*** 592 * Adds a new Unique to the Unique list and set the 593 * parent table of the column to the current table 594 */ 595 public void addUnique(Unique unique) 596 { 597 unique.setTable(this); 598 unices.add(unique); 599 } 600 601 /*** 602 * A utility function to create a new Unique 603 * from attrib and add it to this table. 604 * 605 * @param attrib the xml attributes 606 */ 607 public Unique addUnique(Attributes attrib) 608 { 609 Unique unique = new Unique(); 610 unique.loadFromXML(attrib); 611 addUnique(unique); 612 return unique; 613 } 614 615 /*** 616 * Get the name of the Table 617 */ 618 public String getName() 619 { 620 return name; 621 } 622 623 /*** 624 * Set the name of the Table 625 */ 626 public void setName(String newName) 627 { 628 name = newName; 629 } 630 631 /*** 632 * Get the description for the Table 633 */ 634 public String getDescription() 635 { 636 return description; 637 } 638 639 /*** 640 * Set the description for the Table 641 * 642 * @param newDescription description for the Table 643 */ 644 public void setDescription(String newDescription) 645 { 646 description = newDescription; 647 } 648 649 /*** 650 * Get name to use in Java sources 651 */ 652 public String getJavaName() 653 { 654 if (javaName == null) 655 { 656 List inputs = new ArrayList(2); 657 inputs.add(name); 658 inputs.add(javaNamingMethod); 659 try 660 { 661 javaName = NameFactory.generateName(NameFactory.JAVA_GENERATOR, 662 inputs); 663 } 664 catch (EngineException e) 665 { 666 log.error(e, e); 667 } 668 } 669 return javaName; 670 } 671 672 /*** 673 * Set name to use in Java sources 674 */ 675 public void setJavaName(String javaName) 676 { 677 this.javaName = javaName; 678 } 679 680 /*** 681 * Get the method for generating pk's 682 */ 683 public String getIdMethod() 684 { 685 if (idMethod == null) 686 { 687 return IDMethod.NO_ID_METHOD; 688 } 689 else 690 { 691 return idMethod; 692 } 693 } 694 695 /*** 696 * Set the method for generating pk's 697 */ 698 public void setIdMethod(String idMethod) 699 { 700 this.idMethod = idMethod; 701 } 702 703 /*** 704 * Skip generating sql for this table (in the event it should 705 * not be created from scratch). 706 * @return value of skipSql. 707 */ 708 public boolean isSkipSql() 709 { 710 return (skipSql || isAlias() || isForReferenceOnly()); 711 } 712 713 /*** 714 * Set whether this table should have its creation sql generated. 715 * @param v Value to assign to skipSql. 716 */ 717 public void setSkipSql(boolean v) 718 { 719 this.skipSql = v; 720 } 721 722 /*** 723 * JavaName of om object this entry references. 724 * @return value of external. 725 */ 726 public String getAlias() 727 { 728 return alias; 729 } 730 731 /*** 732 * Is this table specified in the schema or is there just 733 * a foreign key reference to it. 734 * @return value of external. 735 */ 736 public boolean isAlias() 737 { 738 return (alias != null); 739 } 740 741 /*** 742 * Set whether this table specified in the schema or is there just 743 * a foreign key reference to it. 744 * @param v Value to assign to alias. 745 */ 746 public void setAlias(String v) 747 { 748 this.alias = v; 749 } 750 751 752 /*** 753 * Interface which objects for this table will implement 754 * @return value of interface. 755 */ 756 public String getInterface() 757 { 758 return enterface; 759 } 760 761 /*** 762 * Interface which objects for this table will implement 763 * @param v Value to assign to interface. 764 */ 765 public void setInterface(String v) 766 { 767 this.enterface = v; 768 } 769 770 /*** 771 * When a table is abstract, it marks the business object class that is 772 * generated as being abstract. If you have a table called "FOO", then the 773 * Foo BO will be <code>public abstract class Foo</code> 774 * This helps support class hierarchies 775 * 776 * @return value of abstractValue. 777 */ 778 public boolean isAbstract() 779 { 780 return abstractValue; 781 } 782 783 /*** 784 * When a table is abstract, it marks the business object 785 * class that is generated as being abstract. If you have a 786 * table called "FOO", then the Foo BO will be 787 * <code>public abstract class Foo</code> 788 * This helps support class hierarchies 789 * 790 * @param v Value to assign to abstractValue. 791 */ 792 public void setAbstract(boolean v) 793 { 794 this.abstractValue = v; 795 } 796 797 /*** 798 * Get the value of package. 799 * 800 * @return value of package. 801 */ 802 public String getPackage() 803 { 804 if (pkg != null) 805 { 806 return pkg; 807 } 808 else 809 { 810 return this.getDatabase().getPackage(); 811 } 812 } 813 814 /*** 815 * Set the value of package. 816 * 817 * @param v Value to assign to package. 818 */ 819 public void setPackage(String v) 820 { 821 this.pkg = v; 822 } 823 824 /*** 825 * Returns an Array containing all the columns in the table 826 */ 827 public Column[] getColumns() 828 { 829 int size = columnList.size(); 830 Column[] tbls = new Column[size]; 831 for (int i = 0; i < size; i++) 832 { 833 tbls[i] = (Column) columnList.get(i); 834 } 835 return tbls; 836 } 837 838 /*** 839 * Utility method to get the number of columns in this table 840 */ 841 public int getNumColumns() 842 { 843 return columnList.size(); 844 } 845 846 /*** 847 * Returns an Array containing all the FKs in the table 848 */ 849 public ForeignKey[] getForeignKeys() 850 { 851 int size = foreignKeys.size(); 852 ForeignKey[] tbls = new ForeignKey[size]; 853 for (int i = 0; i < size; i++) 854 { 855 tbls[i] = (ForeignKey) foreignKeys.get(i); 856 } 857 return tbls; 858 } 859 860 /*** 861 * Returns a Collection of parameters relevant for the chosen 862 * id generation method. 863 */ 864 public List getIdMethodParameters() 865 { 866 return idMethodParameters; 867 } 868 869 /*** 870 * A name to use for creating a sequence if one is not specified. 871 * 872 * @return name of the sequence 873 */ 874 public String getSequenceName() 875 { 876 String result = null; 877 if (getIdMethod().equals(NATIVE)) 878 { 879 List idMethodParams = getIdMethodParameters(); 880 if (idMethodParams == null) 881 { 882 result = getName() + "_SEQ"; 883 } 884 else 885 { 886 result = ((IdMethodParameter) idMethodParams.get(0)).getValue(); 887 } 888 } 889 return result; 890 } 891 892 /*** 893 * Returns an Array containing all the indices in the table 894 * 895 * @return An array containing all the indices 896 */ 897 public Index[] getIndices() 898 { 899 int size = indices.size(); 900 Index[] tbls = new Index[size]; 901 for (int i = 0; i < size; i++) 902 { 903 tbls[i] = (Index) indices.get(i); 904 } 905 return tbls; 906 } 907 908 /*** 909 * Returns an Array containing all the UKs in the table 910 * 911 * @return An array containing all the UKs 912 */ 913 public Unique[] getUnices() 914 { 915 int size = unices.size(); 916 Unique[] tbls = new Unique[size]; 917 for (int i = 0; i < size; i++) 918 { 919 tbls[i] = (Unique) unices.get(i); 920 } 921 return tbls; 922 } 923 924 /*** 925 * Returns a specified column. 926 * 927 * @param name name of the column 928 * @return Return a Column object or null if it does not exist. 929 */ 930 public Column getColumn(String name) 931 { 932 return (Column) columnsByName.get(name); 933 } 934 935 /*** 936 * Returns a specified column. 937 * 938 * @param javaName java name of the column 939 * @return Return a Column object or null if it does not exist. 940 */ 941 public Column getColumnByJavaName(String javaName) 942 { 943 return (Column) columnsByJavaName.get(javaName); 944 } 945 946 /*** 947 * Return the first foreign key that includes col in it's list 948 * of local columns. Eg. Foreign key (a,b,c) refrences tbl(x,y,z) 949 * will be returned of col is either a,b or c. 950 * 951 * @param col column name included in the key 952 * @return Return a Column object or null if it does not exist. 953 */ 954 public ForeignKey getForeignKey(String col) 955 { 956 ForeignKey firstFK = null; 957 for (Iterator iter = foreignKeys.iterator(); iter.hasNext();) 958 { 959 ForeignKey key = (ForeignKey) iter.next(); 960 if (key.getLocalColumns().contains(col)) 961 { 962 if (firstFK == null) 963 { 964 firstFK = key; 965 } 966 else 967 { 968 //System.out.println(col+" is in multiple FKs. This is not" 969 // + " being handled properly."); 970 //throw new IllegalStateException("Cannot call method if " + 971 // "column is referenced multiple times"); 972 } 973 } 974 } 975 return firstFK; 976 } 977 978 /*** 979 * Returns true if the table contains a specified column 980 * 981 * @param col the column 982 * @return true if the table contains the column 983 */ 984 public boolean containsColumn(Column col) 985 { 986 return columnList.contains(col); 987 } 988 989 /*** 990 * Returns true if the table contains a specified column 991 * 992 * @param name name of the column 993 * @return true if the table contains the column 994 */ 995 public boolean containsColumn(String name) 996 { 997 return (getColumn(name) != null); 998 } 999 1000 /*** 1001 * Set the parent of the table 1002 * 1003 * @param parent the parant database 1004 */ 1005 public void setDatabase(Database parent) 1006 { 1007 tableParent = parent; 1008 } 1009 1010 /*** 1011 * Get the parent of the table 1012 * 1013 * @return the parant database 1014 */ 1015 public Database getDatabase() 1016 { 1017 return tableParent; 1018 } 1019 1020 /*** 1021 * Flag to determine if code/sql gets created for this table. 1022 * Table will be skipped, if return true. 1023 * @return value of forReferenceOnly. 1024 */ 1025 public boolean isForReferenceOnly() 1026 { 1027 return forReferenceOnly; 1028 } 1029 1030 /*** 1031 * Flag to determine if code/sql gets created for this table. 1032 * Table will be skipped, if set to true. 1033 * @param v Value to assign to forReferenceOnly. 1034 */ 1035 public void setForReferenceOnly(boolean v) 1036 { 1037 this.forReferenceOnly = v; 1038 } 1039 1040 /*** 1041 * Returns a XML representation of this table. 1042 * 1043 * @return XML representation of this table 1044 */ 1045 public String toString() 1046 { 1047 StringBuffer result = new StringBuffer(); 1048 1049 result.append ("<table name=\"") 1050 .append(name) 1051 .append('\"'); 1052 1053 if (javaName != null) 1054 { 1055 result.append(" javaName=\"") 1056 .append(javaName) 1057 .append('\"'); 1058 } 1059 1060 if (idMethod != null) 1061 { 1062 result.append(" idMethod=\"") 1063 .append(idMethod) 1064 .append('\"'); 1065 } 1066 1067 if (skipSql) 1068 { 1069 result.append(" skipSql=\"") 1070 .append(new Boolean(skipSql)) 1071 .append('\"'); 1072 } 1073 1074 if (abstractValue) 1075 { 1076 result.append(" abstract=\"") 1077 .append(new Boolean(abstractValue)) 1078 .append('\"'); 1079 } 1080 1081 if (baseClass != null) 1082 { 1083 result.append(" baseClass=\"") 1084 .append(baseClass) 1085 .append('\"'); 1086 } 1087 1088 if (basePeer != null) 1089 { 1090 result.append(" basePeer=\"") 1091 .append(basePeer) 1092 .append('\"'); 1093 } 1094 1095 result.append(">\n"); 1096 1097 if (columnList != null) 1098 { 1099 for (Iterator iter = columnList.iterator(); iter.hasNext();) 1100 { 1101 result.append(iter.next()); 1102 } 1103 } 1104 1105 if (foreignKeys != null) 1106 { 1107 for (Iterator iter = foreignKeys.iterator(); iter.hasNext();) 1108 { 1109 result.append(iter.next()); 1110 } 1111 } 1112 1113 if (idMethodParameters != null) 1114 { 1115 Iterator iter = idMethodParameters.iterator(); 1116 while (iter.hasNext()) 1117 { 1118 result.append(iter.next()); 1119 } 1120 } 1121 1122 result.append ("</table>\n"); 1123 1124 return result.toString(); 1125 } 1126 1127 /*** 1128 * Returns the collection of Columns which make up the single primary 1129 * key for this table. 1130 * 1131 * @return A list of the primary key parts. 1132 */ 1133 public List getPrimaryKey() 1134 { 1135 List pk = new ArrayList(columnList.size()); 1136 1137 Iterator iter = columnList.iterator(); 1138 while (iter.hasNext()) 1139 { 1140 Column col = (Column) iter.next(); 1141 if (col.isPrimaryKey()) 1142 { 1143 pk.add(col); 1144 } 1145 } 1146 return pk; 1147 } 1148 1149 /*** 1150 * Determine whether this table has a primary key. 1151 * 1152 * @return Whether this table has any primary key parts. 1153 */ 1154 public boolean hasPrimaryKey() 1155 { 1156 return (getPrimaryKey().size() > 0); 1157 } 1158 1159 /*** 1160 * Returns all parts of the primary key, separated by commas. 1161 * 1162 * @return A CSV list of primary key parts. 1163 */ 1164 public String printPrimaryKey() 1165 { 1166 return printList(columnList); 1167 } 1168 1169 /*** 1170 * Returns the elements of the list, separated by commas. 1171 * 1172 * @param list a list of Columns 1173 * @return A CSV list. 1174 */ 1175 private String printList(List list) 1176 { 1177 StringBuffer result = new StringBuffer(); 1178 boolean comma = false; 1179 for (Iterator iter = list.iterator(); iter.hasNext();) 1180 { 1181 Column col = (Column) iter.next(); 1182 if (col.isPrimaryKey()) 1183 { 1184 if (comma) 1185 { 1186 result.append(','); 1187 } 1188 else 1189 { 1190 comma = true; 1191 } 1192 result.append(col.getName()); 1193 } 1194 } 1195 return result.toString(); 1196 } 1197 }

This page was automatically generated by Maven