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 import java.util.Properties; 62 63 import org.apache.torque.engine.EngineException; 64 65 import org.xml.sax.Attributes; 66 67 68 /*** 69 * A class for holding application data structures. 70 * 71 * @author <a href="mailto:leon@opticode.co.za>Leon Messerschmidt</a> 72 * @author <a href="mailto:jmcnally@collab.net>John McNally</a> 73 * @author <a href="mailto:mpoeschl@marmot.at>Martin Poeschl</a> 74 * @author <a href="mailto:dlr@collab.net>Daniel Rall</a> 75 * @author <a href="mailto:byron_foster@byron_foster@yahoo.com>Byron Foster</a> 76 * @version $Id: Database.java,v 1.6 2003/08/04 05:30:29 mpoeschl Exp $ 77 */ 78 public class Database 79 { 80 private String databaseType = null; 81 private List tableList = new ArrayList(100); 82 private String name; 83 private String pkg; 84 private String baseClass; 85 private String basePeer; 86 private String defaultIdMethod; 87 private String defaultJavaType; 88 private String defaultJavaNamingMethod; 89 private AppData dbParent; 90 private Hashtable tablesByName = new Hashtable(); 91 private Hashtable tablesByJavaName = new Hashtable(); 92 private boolean heavyIndexing; 93 94 /*** 95 * Load the database object from an xml tag. 96 * 97 * @param attrib the xml attributes 98 */ 99 public void loadFromXML(Attributes attrib) 100 { 101 setName(attrib.getValue("name")); 102 pkg = attrib.getValue("package"); 103 baseClass = attrib.getValue("baseClass"); 104 basePeer = attrib.getValue("basePeer"); 105 defaultJavaType = attrib.getValue("defaultJavaType"); 106 defaultIdMethod = attrib.getValue("defaultIdMethod"); 107 defaultJavaNamingMethod = attrib.getValue("defaultJavaNamingMethod"); 108 if (defaultJavaNamingMethod == null) 109 { 110 defaultJavaNamingMethod = NameGenerator.CONV_METHOD_UNDERSCORE; 111 } 112 heavyIndexing = "true".equals(attrib.getValue("heavyIndexing")); 113 } 114 115 /*** 116 * Get the name of the Database 117 * 118 * @return name of the Database 119 */ 120 public String getName() 121 { 122 return name; 123 } 124 125 /*** 126 * Set the name of the Database 127 * 128 * @param name name of the Database 129 */ 130 public void setName(String name) 131 { 132 /*** @task check this */ 133 // this.name = (name == null ? Torque.getDefaultDB() : name); 134 this.name = (name == null ? "default" : name); 135 } 136 137 /*** 138 * Get the value of package. 139 * @return value of package. 140 */ 141 public String getPackage() 142 { 143 return pkg; 144 } 145 146 /*** 147 * Set the value of package. 148 * @param v Value to assign to package. 149 */ 150 public void setPackage(String v) 151 { 152 this.pkg = v; 153 } 154 155 /*** 156 * Get the value of baseClass. 157 * @return value of baseClass. 158 */ 159 public String getBaseClass() 160 { 161 if (baseClass == null) 162 { 163 return "BaseObject"; 164 } 165 return baseClass; 166 } 167 168 /*** 169 * Set the value of baseClass. 170 * @param v Value to assign to baseClass. 171 */ 172 public void setBaseClass(String v) 173 { 174 this.baseClass = v; 175 } 176 177 /*** 178 * Get the value of basePeer. 179 * @return value of basePeer. 180 */ 181 public String getBasePeer() 182 { 183 if (basePeer == null) 184 { 185 return "BasePeer"; 186 } 187 return basePeer; 188 } 189 190 /*** 191 * Set the value of basePeer. 192 * @param v Value to assign to basePeer. 193 */ 194 public void setBasePeer(String v) 195 { 196 this.basePeer = v; 197 } 198 199 /*** 200 * Get the value of defaultIdMethod. 201 * @return value of defaultIdMethod. 202 */ 203 public String getDefaultIdMethod() 204 { 205 return defaultIdMethod; 206 } 207 208 /*** 209 * Set the value of defaultIdMethod. 210 * @param v Value to assign to defaultIdMethod. 211 */ 212 public void setDefaultIdMethod(String v) 213 { 214 this.defaultIdMethod = v; 215 } 216 217 /*** 218 * Get type to use in Java sources (primitive || object) 219 * 220 * @return the type to use 221 */ 222 public String getDefaultJavaType() 223 { 224 return defaultJavaType; 225 } 226 227 /*** 228 * Get the value of defaultJavaNamingMethod which specifies the 229 * method for converting schema names for table and column to Java names. 230 * 231 * @return The default naming conversion used by this database. 232 */ 233 public String getDefaultJavaNamingMethod() 234 { 235 return defaultJavaNamingMethod; 236 } 237 238 /*** 239 * Set the value of defaultJavaNamingMethod. 240 * @param v The default naming conversion for this database to use. 241 */ 242 public void setDefaultJavaNamingMethod(String v) 243 { 244 this.defaultJavaNamingMethod = v; 245 } 246 247 /*** 248 * Get the value of heavyIndexing. 249 * @return value of heavyIndexing. 250 */ 251 public boolean isHeavyIndexing() 252 { 253 return heavyIndexing; 254 } 255 256 /*** 257 * Set the value of heavyIndexing. 258 * @param v Value to assign to heavyIndexing. 259 */ 260 public void setHeavyIndexing(boolean v) 261 { 262 this.heavyIndexing = v; 263 } 264 265 /*** 266 * Return an array of all tables 267 * 268 * @return array of all tables 269 */ 270 public Table[] getTables() 271 { 272 int size = tableList.size(); 273 Table[] tbls = new Table[size]; 274 for (int i = 0; i < size; i++) 275 { 276 tbls[i] = (Table) tableList.get(i); 277 } 278 return tbls; 279 } 280 281 /*** 282 * Return the table with the specified name. 283 * 284 * @param name table name 285 * @return A Table object. If it does not exist it returns null 286 */ 287 public Table getTable(String name) 288 { 289 return (Table) tablesByName.get(name); 290 } 291 292 /*** 293 * Return the table with the specified javaName. 294 * 295 * @param javaName name of the java object representing the table 296 * @return A Table object. If it does not exist it returns null 297 */ 298 public Table getTableByJavaName(String javaName) 299 { 300 return (Table) tablesByJavaName.get(javaName); 301 } 302 303 /*** 304 * An utility method to add a new table from an xml attribute. 305 * 306 * @param attrib the xml attributes 307 * @return the created Table 308 */ 309 public Table addTable(Attributes attrib) 310 { 311 Table tbl = new Table(); 312 tbl.setDatabase(this); 313 tbl.loadFromXML(attrib, this.getDefaultIdMethod()); 314 addTable(tbl); 315 return tbl; 316 } 317 318 /*** 319 * Add a table to the list and sets the Database property to this Database 320 * 321 * @param tbl the table to add 322 */ 323 public void addTable(Table tbl) 324 { 325 tbl.setDatabase(this); 326 tableList.add(tbl); 327 tablesByName.put(tbl.getName(), tbl); 328 tablesByJavaName.put(tbl.getJavaName(), tbl); 329 tbl.setPackage(getPackage()); 330 } 331 332 /*** 333 * Set the parent of the database 334 * 335 * @param parent the parent 336 */ 337 public void setAppData(AppData parent) 338 { 339 dbParent = parent; 340 } 341 342 /*** 343 * Get the parent of the table 344 * 345 * @return the parent 346 */ 347 public AppData getAppData() 348 { 349 return dbParent; 350 } 351 352 protected String getDatabaseType() 353 { 354 return databaseType; 355 } 356 357 public void setDatabaseType(String databaseType) 358 { 359 this.databaseType = databaseType; 360 } 361 362 /*** 363 * Returns the value of the named property from this database's 364 * <code>db.props</code> file. 365 * 366 * @param name The name of the property to retrieve the value of. 367 * @return The value of the specified property. 368 * @exception EngineException Couldn't access properties. 369 */ 370 protected String getProperty(String name) 371 throws EngineException 372 { 373 Properties p = getAppData().getIdiosyncrasies(databaseType); 374 return (p == null ? null : p.getProperty(name)); 375 } 376 377 /*** 378 * Determines if this database will be using the 379 * <code>IDMethod.ID_BROKER</code> to create ids for torque OM 380 * objects. 381 * @return true if there is at least one table in this database that 382 * uses the <code>IDMethod.ID_BROKER</code> method of generating 383 * ids. returns false otherwise. 384 */ 385 public boolean requiresIdTable() 386 { 387 Table table[] = getTables(); 388 for (int i = 0; i < table.length; i++) 389 { 390 if (table[i].getIdMethod().equals(IDMethod.ID_BROKER)) 391 { 392 return true; 393 } 394 } 395 return false; 396 } 397 398 public void doFinalInitialization() 399 throws EngineException 400 { 401 Table[] tables = getTables(); 402 for (int i = 0; i < tables.length; i++) 403 { 404 Table currTable = tables[i]; 405 406 // check schema integrity 407 // if idMethod="autoincrement", make sure a column is 408 // specified as autoIncrement="true" 409 // FIXME: Handle idMethod="native" via DB adapter. 410 if (currTable.getIdMethod().equals("autoincrement")) 411 { 412 Column[] columns = currTable.getColumns(); 413 boolean foundOne = false; 414 for (int j = 0; j < columns.length && !foundOne; j++) 415 { 416 foundOne = columns[j].isAutoIncrement(); 417 } 418 419 if (!foundOne) 420 { 421 String errorMessage = "Table '" + currTable.getName() 422 + "' is marked as autoincrement, but it does not " 423 + "have a column which declared as the one to " 424 + "auto increment (i.e. autoIncrement=\"true\")\n"; 425 throw new EngineException("Error in XML schema: " + errorMessage); 426 } 427 } 428 429 currTable.doFinalInitialization(); 430 431 // setup reverse fk relations 432 ForeignKey[] fks = currTable.getForeignKeys(); 433 for (int j = 0; j < fks.length; j++) 434 { 435 ForeignKey currFK = fks[j]; 436 Table foreignTable = getTable(currFK.getForeignTableName()); 437 if (foreignTable == null) 438 { 439 throw new EngineException("Attempt to set foreign" 440 + " key to nonexistent table, " 441 + currFK.getForeignTableName()); 442 } 443 else 444 { 445 List referrers = foreignTable.getReferrers(); 446 if ((referrers == null || !referrers.contains(currFK))) 447 { 448 foreignTable.addReferrer(currFK); 449 } 450 451 // local column references 452 Iterator localColumnNames = currFK.getLocalColumns().iterator(); 453 while (localColumnNames.hasNext()) 454 { 455 Column local = currTable 456 .getColumn((String) localColumnNames.next()); 457 // give notice of a schema inconsistency. 458 // note we do not prevent the npe as there is nothing 459 // that we can do, if it is to occur. 460 if (local == null) 461 { 462 throw new EngineException("Attempt to define foreign" 463 + " key with nonexistent column in table, " 464 + currTable.getName()); 465 } 466 else 467 { 468 //check for foreign pk's 469 if (local.isPrimaryKey()) 470 { 471 currTable.setContainsForeignPK(true); 472 } 473 } 474 } 475 476 // foreign column references 477 Iterator foreignColumnNames 478 = currFK.getForeignColumns().iterator(); 479 while (foreignColumnNames.hasNext()) 480 { 481 String foreignColumnName = (String) foreignColumnNames.next(); 482 Column foreign = foreignTable.getColumn(foreignColumnName); 483 // if the foreign column does not exist, we may have an 484 // external reference or a misspelling 485 if (foreign == null) 486 { 487 throw new EngineException("Attempt to set foreign" 488 + " key to nonexistent column: table=" 489 + currTable.getName() + ", foreign column=" 490 + foreignColumnName); 491 } 492 else 493 { 494 foreign.addReferrer(currFK); 495 } 496 } 497 } 498 } 499 } 500 } 501 502 /*** 503 * Creats a string representation of this Database. 504 * The representation is given in xml format. 505 * 506 * @return string representation in xml 507 */ 508 public String toString() 509 { 510 StringBuffer result = new StringBuffer(); 511 512 result.append("<database name=\"").append(getName()).append('"') 513 .append(" package=\"").append(getPackage()).append('"') 514 .append(" defaultIdMethod=\"").append(getDefaultIdMethod()) 515 .append('"') 516 .append(" baseClass=\"").append(getBaseClass()).append('"') 517 .append(" basePeer=\"").append(getBasePeer()).append('"') 518 .append(">\n"); 519 520 for (Iterator i = tableList.iterator(); i.hasNext();) 521 { 522 result.append(i.next()); 523 } 524 525 result.append("</database>"); 526 return result.toString(); 527 } 528 }

This page was automatically generated by Maven