%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.torque.map.DatabaseMap |
|
|
1 | package org.apache.torque.map; |
|
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.lang.reflect.Method; |
|
23 | import java.text.MessageFormat; |
|
24 | import java.util.Collections; |
|
25 | import java.util.HashMap; |
|
26 | import java.util.Iterator; |
|
27 | import java.util.Map; |
|
28 | import java.util.StringTokenizer; |
|
29 | ||
30 | import org.apache.commons.collections.map.ListOrderedMap; |
|
31 | import org.apache.commons.lang.StringUtils; |
|
32 | import org.apache.torque.TorqueException; |
|
33 | import org.apache.torque.adapter.IDMethod; |
|
34 | import org.apache.torque.oid.IDBroker; |
|
35 | import org.apache.torque.oid.IdGenerator; |
|
36 | ||
37 | /** |
|
38 | * DatabaseMap is used to model a database. |
|
39 | * |
|
40 | * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a> |
|
41 | * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> |
|
42 | * @author <a href="mailto:greg.monroe@dukece.com">Greg Monroe</a> |
|
43 | * @version $Id: DatabaseMap.java 476550 2006-11-18 16:08:37Z tfischer $ |
|
44 | */ |
|
45 | public class DatabaseMap implements java.io.Serializable |
|
46 | { |
|
47 | /** |
|
48 | * The character used by most implementations as the separator |
|
49 | * between name elements. |
|
50 | */ |
|
51 | public static final char STD_SEPARATOR_CHAR = '_'; |
|
52 | ||
53 | /** |
|
54 | * The character which separates the schema name from the table name. |
|
55 | */ |
|
56 | public static final char SCHEMA_SEPARATOR_CHAR = '.'; |
|
57 | ||
58 | /** |
|
59 | * Format used to create create the class name for initializing a DB |
|
60 | * specific map |
|
61 | */ |
|
62 | public static final String INIT_CLASS_NAME_FORMAT = |
|
63 | "org.apache.torque.linkage.{0}MapInit"; |
|
64 | ||
65 | /** |
|
66 | * Error Messages for initialisation. |
|
67 | */ |
|
68 | 30 | protected static final String[] ERROR_MESSAGES_INIT = { |
69 | "Invalid Torque OM setup for Database \"{0}\".\n" |
|
70 | + "Database Map initialization class, \"{1}\"," + " " |
|
71 | + "could not be found in your classpath.", |
|
72 | "Invalid Torque OM setup for Database \"{0}\".\n" |
|
73 | + "A class that the Database Map initialization class, \"{1}\", " |
|
74 | + "depends on could not be found.", |
|
75 | "Invalid Torque OM setup for Database \"{0}\".\n" |
|
76 | + "Something unexpected happened doing Class.forName(\"{1}\"). " |
|
77 | + "See the nested exception for details.", |
|
78 | "Invalid Torque OM setup for Database \"{0}\".\n" |
|
79 | + "An error occured invoking the init() method in class, \"{1}\"" |
|
80 | }; |
|
81 | ||
82 | /** The serialVersionUID for this class. */ |
|
83 | private static final long serialVersionUID = 955251837095032274L; |
|
84 | ||
85 | /** The initial size of the Id-Generators map. */ |
|
86 | private static final int ID_GENERATORS_INITIAL_SIZE = 6; |
|
87 | ||
88 | /** Name of the database. */ |
|
89 | private String name; |
|
90 | ||
91 | /** Name of the tables in the database. */ |
|
92 | private Map tables; |
|
93 | ||
94 | /** |
|
95 | * A special table used to generate primary keys for the other |
|
96 | * tables. |
|
97 | */ |
|
98 | 30 | private TableMap idTable = null; |
99 | ||
100 | /** The IDBroker that goes with the idTable. */ |
|
101 | 30 | private IDBroker idBroker = null; |
102 | ||
103 | /** The IdGenerators, keyed by type of idMethod. */ |
|
104 | private HashMap idGenerators; |
|
105 | ||
106 | /** Flag indicating that all tables have been loaded via initialize() */ |
|
107 | 30 | private boolean isInitialized = false; |
108 | ||
109 | /** |
|
110 | * Constructs a new DatabaseMap. |
|
111 | */ |
|
112 | public DatabaseMap() |
|
113 | 0 | { |
114 | 0 | tables = Collections.synchronizedMap(new ListOrderedMap()); |
115 | 0 | idGenerators = new HashMap(ID_GENERATORS_INITIAL_SIZE); |
116 | 0 | } |
117 | ||
118 | /** |
|
119 | * Constructor. |
|
120 | * |
|
121 | * @param name Name of the database. |
|
122 | * @param numberOfTables Number of tables in the database. |
|
123 | * @deprecated use DatabaseMap() instead. Will be removed |
|
124 | * in a future version of Torque. |
|
125 | */ |
|
126 | public DatabaseMap(String name, int numberOfTables) |
|
127 | 0 | { |
128 | 0 | this.name = name; |
129 | 0 | tables = Collections.synchronizedMap(new ListOrderedMap()); |
130 | 0 | idGenerators = new HashMap(ID_GENERATORS_INITIAL_SIZE); |
131 | 0 | } |
132 | ||
133 | /** |
|
134 | * Constructor. |
|
135 | * |
|
136 | * @param name Name of the database. |
|
137 | * @deprecated use DatabaseMap() instead. Will be removed |
|
138 | * in a future version of Torque. |
|
139 | */ |
|
140 | public DatabaseMap(String name) |
|
141 | 30 | { |
142 | 30 | this.name = name; |
143 | 30 | tables = Collections.synchronizedMap(new ListOrderedMap()); |
144 | 30 | idGenerators = new HashMap(ID_GENERATORS_INITIAL_SIZE); |
145 | 30 | } |
146 | ||
147 | /** |
|
148 | * Does this database contain this specific table? |
|
149 | * |
|
150 | * @param table The TableMap representation of the table. |
|
151 | * @return True if the database contains the table. |
|
152 | */ |
|
153 | public boolean containsTable(TableMap table) |
|
154 | { |
|
155 | 0 | return containsTable(table.getName()); |
156 | } |
|
157 | ||
158 | /** |
|
159 | * Does this database contain this specific table? |
|
160 | * |
|
161 | * @param name The String representation of the table. |
|
162 | * @return True if the database contains the table. |
|
163 | */ |
|
164 | public boolean containsTable(String name) |
|
165 | { |
|
166 | 0 | if (name.indexOf('.') > 0) |
167 | { |
|
168 | 0 | name = name.substring(0, name.indexOf('.')); |
169 | } |
|
170 | 0 | return tables.containsKey(name); |
171 | } |
|
172 | ||
173 | /** |
|
174 | * Get the ID table for this database. |
|
175 | * |
|
176 | * @return A TableMap. |
|
177 | */ |
|
178 | public TableMap getIdTable() |
|
179 | { |
|
180 | 0 | return idTable; |
181 | } |
|
182 | ||
183 | /** |
|
184 | * Get the IDBroker for this database. |
|
185 | * |
|
186 | * @return An IDBroker. |
|
187 | * @deprecated Will be removed in a future version of Torque. |
|
188 | * Use DatabaseInfo#getIdBroker() instead |
|
189 | * to access the IDBroker. |
|
190 | */ |
|
191 | public IDBroker getIDBroker() |
|
192 | { |
|
193 | 12 | return idBroker; |
194 | } |
|
195 | ||
196 | /** |
|
197 | * Get the name of this database. |
|
198 | * |
|
199 | * @return A String. |
|
200 | * @deprecated Will be removed in a future version of Torque. |
|
201 | * Use the name of the corresponding database instead. |
|
202 | */ |
|
203 | public String getName() |
|
204 | { |
|
205 | 0 | return name; |
206 | } |
|
207 | ||
208 | /** |
|
209 | * Get a TableMap for the table by name. <p> |
|
210 | * |
|
211 | * Note that by default Torque uses lazy initialization to minimize |
|
212 | * memory usage and startup time. However, if an OM or PEER class |
|
213 | * has not called the table's MapBuilder class, it will not be here. |
|
214 | * See the optional initialize method if you need full OM Mapping.<p> |
|
215 | * |
|
216 | * @param name Name of the table. |
|
217 | * @return A TableMap, null if the table was not found. |
|
218 | */ |
|
219 | public TableMap getTable(String name) |
|
220 | { |
|
221 | 30 | return (TableMap) tables.get(name); |
222 | } |
|
223 | ||
224 | /** |
|
225 | * Get a TableMap[] of all of the tables in the database.<P> |
|
226 | * |
|
227 | * Note that by default Torque uses lazy initialization to minimize |
|
228 | * memory usage and startup time. However, if an OM or PEER class |
|
229 | * has not called the table's MapBuilder class, it will not be here. |
|
230 | * See the optional initialize method if you need full OM Mapping.<p> |
|
231 | * |
|
232 | * @return A TableMap[]. |
|
233 | */ |
|
234 | public TableMap[] getTables() |
|
235 | { |
|
236 | 0 | TableMap[] dbTables = new TableMap[tables.size()]; |
237 | 0 | synchronized (tables) |
238 | { |
|
239 | 0 | Iterator it = tables.values().iterator(); |
240 | 0 | int i = 0; |
241 | 0 | while (it.hasNext()) |
242 | { |
|
243 | 0 | dbTables[i++] = (TableMap) it.next(); |
244 | } |
|
245 | 0 | } |
246 | 0 | return dbTables; |
247 | } |
|
248 | ||
249 | /** |
|
250 | * Add a new table to the database by name. It creates an empty |
|
251 | * TableMap that you need to populate. |
|
252 | * |
|
253 | * @param tableName The name of the table. |
|
254 | */ |
|
255 | public void addTable(String tableName) |
|
256 | { |
|
257 | 12 | TableMap tmap = new TableMap(tableName, this); |
258 | 12 | tables.put(tableName, tmap); |
259 | 12 | } |
260 | ||
261 | /** |
|
262 | * Add a new table to the database by name. It creates an empty |
|
263 | * TableMap that you need to populate. |
|
264 | * |
|
265 | * @param tableName The name of the table. |
|
266 | * @param numberOfColumns The number of columns in the table. |
|
267 | */ |
|
268 | public void addTable(String tableName, int numberOfColumns) |
|
269 | { |
|
270 | 0 | TableMap tmap = new TableMap(tableName, numberOfColumns, this); |
271 | 0 | tables.put(tableName, tmap); |
272 | 0 | } |
273 | ||
274 | /** |
|
275 | * Add a new TableMap to the database. |
|
276 | * |
|
277 | * @param map The TableMap representation. |
|
278 | */ |
|
279 | public void addTable(TableMap map) |
|
280 | { |
|
281 | 6 | tables.put(map.getName(), map); |
282 | 6 | } |
283 | ||
284 | /** |
|
285 | * Set the ID table for this database. |
|
286 | * |
|
287 | * @param idTable The TableMap representation for the ID table. |
|
288 | */ |
|
289 | public void setIdTable(TableMap idTable) |
|
290 | { |
|
291 | 0 | this.idTable = idTable; |
292 | 0 | addTable(idTable); |
293 | 0 | } |
294 | ||
295 | /** |
|
296 | * Set the ID table for this database. |
|
297 | * |
|
298 | * @param tableName The name for the ID table. |
|
299 | */ |
|
300 | public void setIdTable(String tableName) |
|
301 | { |
|
302 | 0 | TableMap tmap = new TableMap(tableName, this); |
303 | 0 | setIdTable(tmap); |
304 | 0 | } |
305 | ||
306 | /** |
|
307 | * Add a type of id generator for access by a TableMap. |
|
308 | * |
|
309 | * @param type a <code>String</code> value |
|
310 | * @param idGen an <code>IdGenerator</code> value |
|
311 | * @deprecated use DatabaseInfo.addGenerator() instead. |
|
312 | * Will be removed in a future version of Torque. |
|
313 | */ |
|
314 | public void addIdGenerator(String type, IdGenerator idGen) |
|
315 | { |
|
316 | 90 | idGenerators.put(type, idGen); |
317 | 90 | } |
318 | ||
319 | /** |
|
320 | * Get a type of id generator. Valid values are listed in the |
|
321 | * {@link org.apache.torque.adapter.IDMethod} interface. |
|
322 | * |
|
323 | * @param type a <code>String</code> value |
|
324 | * @return an <code>IdGenerator</code> value |
|
325 | * @deprecated use DatabaseInfo.getIdGenerator() instead. |
|
326 | * Will be removed in a future version of Torque. |
|
327 | */ |
|
328 | public IdGenerator getIdGenerator(String type) |
|
329 | { |
|
330 | 0 | return (IdGenerator) idGenerators.get(type); |
331 | } |
|
332 | ||
333 | /** |
|
334 | * Creates the Idbroker for this DatabaseMap. |
|
335 | * If an IDBroker already exists for the DatabaseMap, the method |
|
336 | * does nothing. |
|
337 | * @return true if a new IdBroker was created, false otherwise. |
|
338 | * @deprecated Will be removed in a future version of Torque. |
|
339 | * Use DatabaseInfo.startIdBroker() instead. |
|
340 | */ |
|
341 | public synchronized boolean startIdBroker() |
|
342 | { |
|
343 | 0 | if (idBroker == null) |
344 | { |
|
345 | 0 | setIdTable("ID_TABLE"); |
346 | 0 | TableMap tMap = getIdTable(); |
347 | 0 | tMap.addPrimaryKey("ID_TABLE_ID", new Integer(0)); |
348 | 0 | tMap.addColumn("TABLE_NAME", ""); |
349 | 0 | tMap.addColumn("NEXT_ID", new Integer(0)); |
350 | 0 | tMap.addColumn("QUANTITY", new Integer(0)); |
351 | 0 | idBroker = new IDBroker(idTable); |
352 | 0 | addIdGenerator(IDMethod.ID_BROKER, idBroker); |
353 | 0 | return true; |
354 | } |
|
355 | 0 | return false; |
356 | } |
|
357 | ||
358 | /** |
|
359 | * Fully populate this DatabaseMap with all the TablesMaps. This |
|
360 | * is only needed if the application needs to use the complete OM |
|
361 | * mapping information. Otherwise, the OM Mapping information |
|
362 | * will be populated as needed by OM and Peer classes. An example |
|
363 | * of how to initialize the map info from the application:<p> |
|
364 | * |
|
365 | * <code> |
|
366 | * DatabaseMap dbMap = Torque.getDatabaseMap( dbName ); |
|
367 | * try { |
|
368 | * dbMap.initialize(); |
|
369 | * } catch ( TorqueException e ) { |
|
370 | * ... error handling |
|
371 | * } |
|
372 | * </code> |
|
373 | * |
|
374 | * Note that Torque database names are case sensitive and this DB |
|
375 | * map must be retrieved with the exact name used in the XML schema.<p> |
|
376 | * |
|
377 | * This uses Java reflection methods to locate and run the |
|
378 | * init() method of a class generated in the org.apache.torque.linkage |
|
379 | * package with a name based on the XML Database name value, e.g. |
|
380 | * org.apache.torque.linkage.DefaultMapInit<p> |
|
381 | * |
|
382 | * Some misconfiguration situations that could cause this method to fail |
|
383 | * are:<p> |
|
384 | * |
|
385 | * It was used with a Torque OM set of classes generated by V3.2 or older; |
|
386 | * <br> |
|
387 | * The class(es) in the org.apache.torque.linkage package were not included |
|
388 | * with the other generated class files (e.g. the jar file creation process |
|
389 | * only included com.* and not org.* files).<p> |
|
390 | * |
|
391 | * @throws TorqueException If an error is encountered locating and calling |
|
392 | * the init method. |
|
393 | */ |
|
394 | public synchronized void initialize() throws TorqueException |
|
395 | { |
|
396 | 0 | if (isInitialized) |
397 | { |
|
398 | 0 | return; |
399 | } |
|
400 | 0 | String initClassName = MessageFormat.format(INIT_CLASS_NAME_FORMAT, |
401 | new Object[] { |
|
402 | javanameMethod(getName()) |
|
403 | }); |
|
404 | ||
405 | 0 | Class initClass = null; |
406 | try |
|
407 | { |
|
408 | 0 | initClass = Class.forName(initClassName); |
409 | } |
|
410 | 0 | catch (ClassNotFoundException e) |
411 | { |
|
412 | 0 | throw new TorqueException(MessageFormat.format( |
413 | ERROR_MESSAGES_INIT[0], |
|
414 | new Object[] { |
|
415 | getName(), |
|
416 | initClassName |
|
417 | }), |
|
418 | e); |
|
419 | } |
|
420 | 0 | catch (LinkageError e) |
421 | { |
|
422 | 0 | throw new TorqueException(MessageFormat.format( |
423 | ERROR_MESSAGES_INIT[1], |
|
424 | new Object[] { |
|
425 | getName(), initClassName |
|
426 | }), |
|
427 | e); |
|
428 | } |
|
429 | 0 | catch (Throwable e) |
430 | { |
|
431 | 0 | throw new TorqueException(MessageFormat.format( |
432 | ERROR_MESSAGES_INIT[2], |
|
433 | new Object[] { |
|
434 | getName(), initClassName |
|
435 | }), |
|
436 | e); |
|
437 | 0 | } |
438 | try |
|
439 | { |
|
440 | 0 | Method initMethod = initClass.getMethod("init", (Class []) null); |
441 | 0 | initMethod.invoke(null, (Object []) class="keyword">null); |
442 | } |
|
443 | 0 | catch (Exception e) |
444 | { |
|
445 | 0 | throw new TorqueException(MessageFormat.format( |
446 | ERROR_MESSAGES_INIT[3], |
|
447 | new Object[] { |
|
448 | getName(), initClassName |
|
449 | }), |
|
450 | e); |
|
451 | 0 | } |
452 | 0 | isInitialized = true; |
453 | 0 | } |
454 | ||
455 | /** |
|
456 | * Converts a database schema name to java object name. Operates |
|
457 | * same as underscoreMethod but does not convert anything to |
|
458 | * lowercase. This must match the javaNameMethod in the |
|
459 | * JavaNameGenerator class in Generator code. |
|
460 | * |
|
461 | * @param schemaName name to be converted. |
|
462 | * @return converted name. |
|
463 | * |
|
464 | * @see org.apache.torque.engine.database.model.NameGenerator |
|
465 | */ |
|
466 | protected String javanameMethod(String schemaName) |
|
467 | { |
|
468 | 0 | StringBuffer result = new StringBuffer(); |
469 | 0 | StringTokenizer tok = new StringTokenizer |
470 | (schemaName, String.valueOf(STD_SEPARATOR_CHAR)); |
|
471 | 0 | while (tok.hasMoreTokens()) |
472 | { |
|
473 | 0 | String namePart = (String) tok.nextElement(); |
474 | 0 | result.append(StringUtils.capitalize(namePart)); |
475 | } |
|
476 | ||
477 | // remove the SCHEMA_SEPARATOR_CHARs and capitalize |
|
478 | // the tokens |
|
479 | 0 | schemaName = result.toString(); |
480 | 0 | result = new StringBuffer(); |
481 | ||
482 | 0 | tok = new StringTokenizer |
483 | (schemaName, String.valueOf(SCHEMA_SEPARATOR_CHAR)); |
|
484 | 0 | while (tok.hasMoreTokens()) |
485 | { |
|
486 | 0 | String namePart = (String) tok.nextElement(); |
487 | 0 | result.append(StringUtils.capitalize(namePart)); |
488 | } |
|
489 | 0 | return result.toString(); |
490 | } |
|
491 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |