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