Coverage report

  %line %branch
org.apache.torque.engine.database.model.Database
50% 
84% 

 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.HashMap;
 25  
 import java.util.Hashtable;
 26  
 import java.util.Iterator;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 
 30  
 import org.apache.commons.collections.map.ListOrderedMap;
 31  
 import org.apache.commons.logging.Log;
 32  
 import org.apache.commons.logging.LogFactory;
 33  
 import org.apache.torque.engine.EngineException;
 34  
 import org.apache.torque.engine.database.transform.DTDResolver;
 35  
 import org.apache.torque.engine.platform.Platform;
 36  
 import org.apache.torque.engine.platform.PlatformFactory;
 37  
 import org.xml.sax.Attributes;
 38  
 
 39  
 
 40  
 /**
 41  
  * A class for holding application data structures.
 42  
  *
 43  
  * @author <a href="mailto:leon@opticode.co.za>Leon Messerschmidt</a>
 44  
  * @author <a href="mailto:jmcnally@collab.net>John McNally</a>
 45  
  * @author <a href="mailto:mpoeschl@marmot.at>Martin Poeschl</a>
 46  
  * @author <a href="mailto:dlr@collab.net>Daniel Rall</a>
 47  
  * @author <a href="mailto:byron_foster@byron_foster@yahoo.com>Byron Foster</a>
 48  
  * @author <a href="mailto:monroe@dukece.com>Greg Monroe</a>
 49  
  * @version $Id: Database.java 473814 2006-11-11 22:30:30Z tv $
 50  
  */
 51  
 public class Database
 52  
 {
 53  
     /** Logging class from commons.logging */
 54  126
     private static Log log = LogFactory.getLog(Database.class);
 55  
 
 56  364
     private String databaseType = null;
 57  364
     private List tableList = new ArrayList(100);
 58  364
     private Map domainMap = new HashMap();
 59  
     private String name;
 60  
     private String javaName;
 61  
     private String pkg;
 62  
     private String baseClass;
 63  
     private String basePeer;
 64  
     private String defaultIdMethod;
 65  
     private String defaultJavaType;
 66  
     private String defaultJavaNamingMethod;
 67  364
     private Hashtable tablesByName = new Hashtable();
 68  364
     private Hashtable tablesByJavaName = new Hashtable();
 69  
     private boolean heavyIndexing;
 70  
     /** the name of the definition file */
 71  
     private String fileName;
 72  364
     private Map options = Collections.synchronizedMap(new ListOrderedMap());
 73  
 
 74  
 
 75  
     /**
 76  
      * Creates a new instance for the specified database type.
 77  
      *
 78  
      * @param databaseType The default type for this database.
 79  
      */
 80  
     public Database(String databaseType)
 81  364
     {
 82  364
         this.databaseType = databaseType;
 83  364
     }
 84  
 
 85  
     /**
 86  
      * Load the database object from an xml tag.
 87  
      *
 88  
      * @param attrib the xml attributes
 89  
      */
 90  
     public void loadFromXML(Attributes attrib)
 91  
     {
 92  343
         setName(attrib.getValue("name"));
 93  343
         pkg = attrib.getValue("package");
 94  343
         baseClass = attrib.getValue("baseClass");
 95  343
         basePeer = attrib.getValue("basePeer");
 96  343
         defaultJavaType = attrib.getValue("defaultJavaType");
 97  343
         defaultIdMethod = attrib.getValue("defaultIdMethod");
 98  343
         defaultJavaNamingMethod = attrib.getValue("defaultJavaNamingMethod");
 99  343
         if (defaultJavaNamingMethod == null)
 100  
         {
 101  0
             defaultJavaNamingMethod = NameGenerator.CONV_METHOD_UNDERSCORE;
 102  
         }
 103  343
         heavyIndexing = "true".equals(attrib.getValue("heavyIndexing"));
 104  343
     }
 105  
 
 106  
     /**
 107  
      * Get the name of the Database
 108  
      *
 109  
      * @return name of the Database
 110  
      */
 111  
     public String getName()
 112  
     {
 113  0
         return name;
 114  
     }
 115  
 
 116  
     /**
 117  
      * Set the name of the Database
 118  
      *
 119  
      * @param name name of the Database
 120  
      */
 121  
     public void setName(String name)
 122  
     {
 123  
         /** @task check this */
 124  
 //        this.name = (name == null ? Torque.getDefaultDB() : name);
 125  343
         this.name = (name == null ? "default" : name);
 126  343
     }
 127  
 
 128  
     public String getFileName()
 129  
     {
 130  0
         return fileName;
 131  
     }
 132  
 
 133  
     public void setFileName(String name)
 134  
     {
 135  0
         this.fileName = name;
 136  0
     }
 137  
 
 138  
     /**
 139  
      * Get the value of package.
 140  
      * @return value of package.
 141  
      */
 142  
     public String getPackage()
 143  
     {
 144  2009
         return pkg;
 145  
     }
 146  
 
 147  
     /**
 148  
      * Set the value of package.
 149  
      * @param v  Value to assign to package.
 150  
      */
 151  
     public void setPackage(String v)
 152  
     {
 153  336
         this.pkg = v;
 154  336
     }
 155  
 
 156  
     /**
 157  
      * Get the value of baseClass.
 158  
      * @return value of baseClass.
 159  
      */
 160  
     public String getBaseClass()
 161  
     {
 162  0
         if (baseClass == null)
 163  
         {
 164  0
             return "BaseObject";
 165  
         }
 166  0
         return baseClass;
 167  
     }
 168  
 
 169  
     /**
 170  
      * Set the value of baseClass.
 171  
      * @param v  Value to assign to baseClass.
 172  
      */
 173  
     public void setBaseClass(String v)
 174  
     {
 175  0
         this.baseClass = v;
 176  0
     }
 177  
 
 178  
     /**
 179  
      * Get the value of basePeer.
 180  
      * @return value of basePeer.
 181  
      */
 182  
     public String getBasePeer()
 183  
     {
 184  0
         if (basePeer == null)
 185  
         {
 186  0
             return "BasePeer";
 187  
         }
 188  0
         return basePeer;
 189  
     }
 190  
 
 191  
     /**
 192  
      * Set the value of basePeer.
 193  
      * @param v Value to assign to basePeer.
 194  
      */
 195  
     public void setBasePeer(String v)
 196  
     {
 197  0
         this.basePeer = v;
 198  0
     }
 199  
 
 200  
     /**
 201  
      * Get the value of defaultIdMethod.
 202  
      * @return value of defaultIdMethod.
 203  
      */
 204  
     public String getDefaultIdMethod()
 205  
     {
 206  1652
         return defaultIdMethod;
 207  
     }
 208  
 
 209  
     /**
 210  
      * Set the value of defaultIdMethod.
 211  
      * @param v Value to assign to defaultIdMethod.
 212  
      */
 213  
     public void setDefaultIdMethod(String v)
 214  
     {
 215  0
         this.defaultIdMethod = v;
 216  0
     }
 217  
 
 218  
     /**
 219  
      * Get type to use in Java sources (primitive || object)
 220  
      *
 221  
      * @return the type to use
 222  
      */
 223  
     public String getDefaultJavaType()
 224  
     {
 225  0
         return defaultJavaType;
 226  
     }
 227  
 
 228  
     /**
 229  
      * Get the value of defaultJavaNamingMethod which specifies the
 230  
      * method for converting schema names for table and column to Java names.
 231  
      *
 232  
      * @return The default naming conversion used by this database.
 233  
      */
 234  
     public String getDefaultJavaNamingMethod()
 235  
     {
 236  14091
         return defaultJavaNamingMethod;
 237  
     }
 238  
 
 239  
     /**
 240  
      * Set the value of defaultJavaNamingMethod.
 241  
      * @param v The default naming conversion for this database to use.
 242  
      */
 243  
     public void setDefaultJavaNamingMethod(String v)
 244  
     {
 245  0
         this.defaultJavaNamingMethod = v;
 246  0
     }
 247  
 
 248  
     /**
 249  
      * Get the value of heavyIndexing.
 250  
      * @return value of heavyIndexing.
 251  
      */
 252  
     public boolean isHeavyIndexing()
 253  
     {
 254  1645
         return heavyIndexing;
 255  
     }
 256  
 
 257  
     /**
 258  
      * Set the value of heavyIndexing.
 259  
      * @param v  Value to assign to heavyIndexing.
 260  
      */
 261  
     public void setHeavyIndexing(boolean v)
 262  
     {
 263  0
         this.heavyIndexing = v;
 264  0
     }
 265  
 
 266  
     /**
 267  
      * Return an List of all tables
 268  
      *
 269  
      * @return List of all tables
 270  
      */
 271  
     public List getTables()
 272  
     {
 273  350
         return tableList;
 274  
     }
 275  
 
 276  
     /**
 277  
      * Return the table with the specified name.
 278  
      *
 279  
      * @param name table name
 280  
      * @return A Table object.  If it does not exist it returns null
 281  
      */
 282  
     public Table getTable(String name)
 283  
     {
 284  539
         return (Table) tablesByName.get(name);
 285  
     }
 286  
 
 287  
     /**
 288  
      * Return the table with the specified javaName.
 289  
      *
 290  
      * @param javaName name of the java object representing the table
 291  
      * @return A Table object.  If it does not exist it returns null
 292  
      */
 293  
     public Table getTableByJavaName(String javaName)
 294  
     {
 295  0
         return (Table) tablesByJavaName.get(javaName);
 296  
     }
 297  
 
 298  
     /**
 299  
      * An utility method to add a new table from an xml attribute.
 300  
      *
 301  
      * @param attrib the xml attributes
 302  
      * @return the created Table
 303  
      */
 304  
     public Table addTable(Attributes attrib)
 305  
     {
 306  1645
         Table tbl = new Table();
 307  1645
         tbl.setDatabase(this);
 308  1645
         tbl.loadFromXML(attrib, this.getDefaultIdMethod());
 309  1645
         addTable(tbl);
 310  1645
         return tbl;
 311  
     }
 312  
 
 313  
     /**
 314  
      * Add a table to the list and sets the Database property to this Database
 315  
      *
 316  
      * @param tbl the table to add
 317  
      */
 318  
     public void addTable(Table tbl)
 319  
     {
 320  1652
         tbl.setDatabase(this);
 321  1652
         tableList.add(tbl);
 322  1652
         tablesByName.put(tbl.getName(), tbl);
 323  1652
         tablesByJavaName.put(tbl.getJavaName(), tbl);
 324  1652
         tbl.setPackage(getPackage());
 325  1652
     }
 326  
 
 327  
     public void addDomain(Domain domain)
 328  
     {
 329  266
         domainMap.put(domain.getName(), domain);
 330  266
     }
 331  
 
 332  
     public Domain getDomain(String domainName)
 333  
     {
 334  539
         return (Domain) domainMap.get(domainName);
 335  
     }
 336  
 
 337  
     protected String getDatabaseType()
 338  
     {
 339  0
         return databaseType;
 340  
     }
 341  
 
 342  
     public void setDatabaseType(String databaseType)
 343  
     {
 344  14
         this.databaseType = databaseType;
 345  14
     }
 346  
 
 347  
     /**
 348  
      * Returns the Platform implementation for this database.
 349  
      *
 350  
      * @return a Platform implementation
 351  
      */
 352  
     public Platform getPlatform()
 353  
     {
 354  25760
         return PlatformFactory.getPlatformFor(databaseType);
 355  
     }
 356  
 
 357  
     /**
 358  
      * Determines if this database will be using the
 359  
      * <code>IDMethod.ID_BROKER</code> to create ids for torque OM
 360  
      * objects.
 361  
      * @return true if there is at least one table in this database that
 362  
      * uses the <code>IDMethod.ID_BROKER</code> method of generating
 363  
      * ids. returns false otherwise.
 364  
      */
 365  
     public boolean requiresIdTable()
 366  
     {
 367  0
         Iterator iter = getTables().iterator();
 368  0
         while (iter.hasNext())
 369  
         {
 370  0
             Table table = (Table) iter.next();
 371  0
             if (table.getIdMethod().equals(IDMethod.ID_BROKER))
 372  
             {
 373  0
                 return true;
 374  
             }
 375  0
         }
 376  0
         return false;
 377  
     }
 378  
 
 379  
     /**
 380  
      * Initializes the model.
 381  
      *
 382  
      * @throws EngineException
 383  
      */
 384  
     public void doFinalInitialization() throws EngineException
 385  
     {
 386  343
         Iterator iter = getTables().iterator();
 387  1988
         while (iter.hasNext())
 388  
         {
 389  1645
             Table currTable = (Table) iter.next();
 390  
 
 391  
             // check schema integrity
 392  
             // if idMethod="autoincrement", make sure a column is
 393  
             // specified as autoIncrement="true"
 394  
             // FIXME: Handle idMethod="native" via DB adapter.
 395  
             // TODO autoincrement is no longer supported!!!
 396  1645
             if (currTable.getIdMethod().equals("autoincrement"))
 397  
             {
 398  0
                 boolean foundOne = false;
 399  0
                 Iterator colIter = currTable.getColumns().iterator();
 400  0
                 while (colIter.hasNext() && !foundOne)
 401  
                 {
 402  0
                     foundOne = ((Column) colIter.next()).isAutoIncrement();
 403  
                 }
 404  
 
 405  0
                 if (!foundOne)
 406  
                 {
 407  0
                     String errorMessage = "Table '" + currTable.getName()
 408  
                             + "' is marked as autoincrement, but it does not "
 409  
                             + "have a column which declared as the one to "
 410  
                             + "auto increment (i.e. autoIncrement=\"true\")\n";
 411  0
                     throw new EngineException("Error in XML schema: " + errorMessage);
 412  
                 }
 413  
             }
 414  
 
 415  1645
             currTable.doFinalInitialization();
 416  
 
 417  
             // setup reverse fk relations
 418  1645
             Iterator fks = currTable.getForeignKeys().iterator();
 419  1834
             while (fks.hasNext())
 420  
             {
 421  189
                 ForeignKey currFK = (ForeignKey) fks.next();
 422  189
                 Table foreignTable = getTable(currFK.getForeignTableName());
 423  189
                 if (foreignTable == null)
 424  
                 {
 425  0
                     throw new EngineException("Attempt to set foreign"
 426  
                             + " key to nonexistent table, "
 427  
                             + currFK.getForeignTableName());
 428  
                 }
 429  
                 else
 430  
                 {
 431  
                     // TODO check type and size
 432  189
                     List referrers = foreignTable.getReferrers();
 433  189
                     if ((referrers == null || !referrers.contains(currFK)))
 434  
                     {
 435  189
                         foreignTable.addReferrer(currFK);
 436  
                     }
 437  
 
 438  
                     // local column references
 439  189
                     Iterator localColumnNames = currFK.getLocalColumns().iterator();
 440  441
                     while (localColumnNames.hasNext())
 441  
                     {
 442  252
                         Column local = currTable
 443  
                                 .getColumn((String) localColumnNames.next());
 444  
                         // give notice of a schema inconsistency.
 445  
                         // note we do not prevent the npe as there is nothing
 446  
                         // that we can do, if it is to occur.
 447  252
                         if (local == null)
 448  
                         {
 449  0
                             throw new EngineException("Attempt to define foreign"
 450  
                                     + " key with nonexistent column in table, "
 451  
                                     + currTable.getName());
 452  
                         }
 453  
                         else
 454  
                         {
 455  
                             //check for foreign pk's
 456  252
                             if (local.isPrimaryKey())
 457  
                             {
 458  0
                                 currTable.setContainsForeignPK(true);
 459  
                             }
 460  
                         }
 461  144
                     }
 462  
 
 463  
                     // foreign column references
 464  189
                     Iterator foreignColumnNames
 465  
                             = currFK.getForeignColumns().iterator();
 466  441
                     while (foreignColumnNames.hasNext())
 467  
                     {
 468  252
                         String foreignColumnName = (String) foreignColumnNames.next();
 469  252
                         Column foreign = foreignTable.getColumn(foreignColumnName);
 470  
                         // if the foreign column does not exist, we may have an
 471  
                         // external reference or a misspelling
 472  252
                         if (foreign == null)
 473  
                         {
 474  0
                             throw new EngineException("Attempt to set foreign"
 475  
                                     + " key to nonexistent column: table="
 476  
                                     +  currTable.getName() + ", foreign column="
 477  
                                     +  foreignColumnName);
 478  
                         }
 479  
                         else
 480  
                         {
 481  252
                             foreign.addReferrer(currFK);
 482  
                         }
 483  144
                     }
 484  
                 }
 485  108
             }
 486  940
         }
 487  343
     }
 488  
 
 489  
     /**
 490  
      * Get the base name to use when creating related Java Classes.
 491  
      *
 492  
      * @return A Java syntax capatible version of the dbName using the method
 493  
      *         defined by the defaultJavaNamingMethod XML value.
 494  
      */
 495  
     public String getJavaName()
 496  
     {
 497  0
         if (javaName == null)
 498  
         {
 499  0
             List inputs = new ArrayList(2);
 500  0
             inputs.add(name);
 501  0
             inputs.add(defaultJavaNamingMethod);
 502  
             try
 503  
             {
 504  0
                 javaName = NameFactory.generateName(NameFactory.JAVA_GENERATOR,
 505  
                                                     inputs);
 506  
             }
 507  0
             catch (EngineException e)
 508  
             {
 509  0
                 log.error(e, e);
 510  0
             }
 511  
         }
 512  0
         return javaName;
 513  
     }
 514  
 
 515  
     /**
 516  
      * Convert dbName to a Java compatible name by the JavaName method only
 517  
      * (ignores the defaultJavaNamingMethod).
 518  
      *
 519  
      * @return The current dbName converted to a standard format that can
 520  
      *          be used as part of a Java Object name.
 521  
      */
 522  
     public String getStandardJavaName()
 523  
     {
 524  0
         if (javaName == null)
 525  
         {
 526  0
             List inputs = new ArrayList(2);
 527  0
             inputs.add(name);
 528  0
             inputs.add(NameGenerator.CONV_METHOD_JAVANAME);
 529  
             try
 530  
             {
 531  0
                 javaName = NameFactory.generateName(NameFactory.JAVA_GENERATOR,
 532  
                                                     inputs);
 533  
             }
 534  0
             catch (EngineException e)
 535  
             {
 536  0
                 log.error(e, e);
 537  0
             }
 538  
         }
 539  0
         return javaName;
 540  
     }
 541  
 
 542  
     /**
 543  
      * Creats a string representation of this Database.
 544  
      * The representation is given in xml format.
 545  
      *
 546  
      * @return string representation in xml
 547  
      */
 548  
     public String toString()
 549  
     {
 550  0
         StringBuffer result = new StringBuffer();
 551  
 
 552  0
         result.append ("<?xml version=\ŕ.0\"?>\n");
 553  0
         result.append ("<!DOCTYPE database SYSTEM \""
 554  
                 + DTDResolver.WEB_SITE_DTD + "\">\n");
 555  0
         result.append("<!-- Autogenerated by SQLToXMLSchema! -->\n");
 556  0
         result.append("<database name=\"").append(getName()).append('"')
 557  
             .append(" package=\"").append(getPackage()).append('"')
 558  
             .append(" defaultIdMethod=\"").append(getDefaultIdMethod())
 559  
             .append('"')
 560  
             .append(" baseClass=\"").append(getBaseClass()).append('"')
 561  
             .append(" basePeer=\"").append(getBasePeer()).append('"')
 562  
             .append(">\n");
 563  
 
 564  0
         for (Iterator i = tableList.iterator(); i.hasNext();)
 565  
         {
 566  0
             result.append(i.next());
 567  
         }
 568  
 
 569  0
         result.append("</database>");
 570  0
         return result.toString();
 571  
     }
 572  
 
 573  
     /**
 574  
      * Add an XML Specified option key/value pair to this element's option set.
 575  
      *
 576  
      * @param key the key of the option.
 577  
      * @param value the value of the option.
 578  
      */
 579  
     public void addOption(String key, String value)
 580  
     {
 581  0
         options.put(key, value);
 582  0
     }
 583  
 
 584  
     /**
 585  
      * Get the value that was associated with this key in an XML option
 586  
      * element.
 587  
      *
 588  
      * @param key the key of the option.
 589  
      * @return The value for the key or a null.
 590  
      */
 591  
     public String getOption(String key)
 592  
     {
 593  0
         return (String) options.get(key);
 594  
     }
 595  
 
 596  
     /**
 597  
      * Gets the full ordered hashtable array of items specified by XML option
 598  
      * statements under this element.<p>
 599  
      *
 600  
      * Note, this is not thread save but since it's only used for
 601  
      * generation which is single threaded, there should be minimum
 602  
      * danger using this in Velocity.
 603  
      *
 604  
      * @return An Map of all options. Will not be null but may be empty.
 605  
      */
 606  
     public Map getOptions()
 607  
     {
 608  0
         return options;
 609  
     }
 610  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.