001: package xdoclet.modules.ojb.model;
002:
003: /* Copyright 2004-2005 The Apache Software Foundation
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: import java.util.*;
019:
020: import xdoclet.modules.ojb.CommaListIterator;
021:
022: /**
023: * Represents the model used for generating the torque database schema.
024: */
025: public class TorqueModelDef extends DefBase {
026: /** The tables keyed by their names*/
027: private SortedMap _tableDefs = new TreeMap();
028:
029: /**
030: * Generates a new torque database model from the given ojb model.
031: *
032: * @param dbName The name of the database
033: * @param ojbModel The ojb model
034: * @return The torque model
035: */
036: public TorqueModelDef(String dbName, ModelDef ojbModel) {
037: super (dbName);
038:
039: ClassDescriptorDef classDef;
040: TableDef tableDef;
041: FieldDescriptorDef fieldDef;
042: ColumnDef columnDef;
043: String name;
044:
045: for (Iterator classIt = ojbModel.getClasses(); classIt
046: .hasNext();) {
047: classDef = (ClassDescriptorDef) classIt.next();
048: if (classDef.getBooleanProperty(
049: PropertyHelper.OJB_PROPERTY_OJB_PERSISTENT, false)
050: && classDef
051: .getBooleanProperty(
052: PropertyHelper.OJB_PROPERTY_GENERATE_TABLE_INFO,
053: true)) {
054: addTableFor(classDef);
055: }
056: }
057: }
058:
059: // The conversion algorithm
060: // Note that the complete algorithm is here rather than splitting in onto the
061: // various torque model elements because maintaining it is easier this way
062:
063: /**
064: * Adds a table for the given class descriptor (if necessary).
065: *
066: * @param classDef The class descriptor
067: */
068: private void addTableFor(ClassDescriptorDef classDef) {
069: String name = classDef
070: .getProperty(PropertyHelper.OJB_PROPERTY_TABLE);
071: TableDef tableDef = getTable(name);
072: FieldDescriptorDef fieldDef;
073: ReferenceDescriptorDef refDef;
074: CollectionDescriptorDef collDef;
075: ColumnDef columnDef;
076: IndexDef indexDef;
077:
078: if (tableDef == null) {
079: tableDef = new TableDef(name);
080: addTable(tableDef);
081: }
082: if (classDef
083: .hasProperty(PropertyHelper.OJB_PROPERTY_DOCUMENTATION)) {
084: tableDef
085: .setProperty(
086: PropertyHelper.OJB_PROPERTY_DOCUMENTATION,
087: classDef
088: .getProperty(PropertyHelper.OJB_PROPERTY_DOCUMENTATION));
089: }
090: if (classDef
091: .hasProperty(PropertyHelper.OJB_PROPERTY_TABLE_DOCUMENTATION)) {
092: tableDef
093: .setProperty(
094: PropertyHelper.OJB_PROPERTY_TABLE_DOCUMENTATION,
095: classDef
096: .getProperty(PropertyHelper.OJB_PROPERTY_TABLE_DOCUMENTATION));
097: }
098: for (Iterator fieldIt = classDef.getFields(); fieldIt.hasNext();) {
099: fieldDef = (FieldDescriptorDef) fieldIt.next();
100: if (fieldDef.getBooleanProperty(
101: PropertyHelper.OJB_PROPERTY_IGNORE, false)
102: || fieldDef.getBooleanProperty(
103: PropertyHelper.OJB_PROPERTY_VIRTUAL_FIELD,
104: false)) {
105: continue;
106: }
107: columnDef = addColumnFor(fieldDef, tableDef);
108: if (fieldDef.getBooleanProperty(
109: PropertyHelper.OJB_PROPERTY_INDEXED, false)) {
110: // add the field to the default index
111: indexDef = tableDef.getIndex(null);
112: if (indexDef == null) {
113: indexDef = new IndexDef(null, false);
114: tableDef.addIndex(indexDef);
115: }
116: indexDef.addColumn(columnDef.getName());
117: }
118: }
119: for (Iterator refIt = classDef.getReferences(); refIt.hasNext();) {
120: refDef = (ReferenceDescriptorDef) refIt.next();
121: if (!refDef.getBooleanProperty(
122: PropertyHelper.OJB_PROPERTY_IGNORE, false)) {
123: addForeignkeys(refDef, tableDef);
124: }
125: }
126: for (Iterator collIt = classDef.getCollections(); collIt
127: .hasNext();) {
128: collDef = (CollectionDescriptorDef) collIt.next();
129: if (!collDef.getBooleanProperty(
130: PropertyHelper.OJB_PROPERTY_IGNORE, false)) {
131: if (collDef
132: .hasProperty(PropertyHelper.OJB_PROPERTY_INDIRECTION_TABLE)) {
133: addIndirectionTable(collDef);
134: } else {
135: addForeignkeys(collDef, tableDef);
136: }
137: }
138: }
139: for (Iterator indexIt = classDef.getIndexDescriptors(); indexIt
140: .hasNext();) {
141: addIndex((IndexDescriptorDef) indexIt.next(), tableDef);
142: }
143: }
144:
145: /**
146: * Generates a column for the given field and adds it to the table.
147: *
148: * @param fieldDef The field
149: * @param tableDef The table
150: * @return The column def
151: */
152: private ColumnDef addColumnFor(FieldDescriptorDef fieldDef,
153: TableDef tableDef) {
154: String name = fieldDef
155: .getProperty(PropertyHelper.OJB_PROPERTY_COLUMN);
156: ColumnDef columnDef = tableDef.getColumn(name);
157:
158: if (columnDef == null) {
159: columnDef = new ColumnDef(name);
160: tableDef.addColumn(columnDef);
161: }
162: if (!fieldDef.isNested()) {
163: columnDef.setProperty(
164: PropertyHelper.TORQUE_PROPERTY_JAVANAME, fieldDef
165: .getName());
166: }
167: columnDef
168: .setProperty(
169: PropertyHelper.TORQUE_PROPERTY_TYPE,
170: fieldDef
171: .getProperty(PropertyHelper.OJB_PROPERTY_JDBC_TYPE));
172: columnDef.setProperty(PropertyHelper.TORQUE_PROPERTY_ID,
173: fieldDef.getProperty(PropertyHelper.OJB_PROPERTY_ID));
174: if (fieldDef.getBooleanProperty(
175: PropertyHelper.OJB_PROPERTY_PRIMARYKEY, false)) {
176: columnDef.setProperty(
177: PropertyHelper.TORQUE_PROPERTY_PRIMARYKEY, "true");
178: columnDef.setProperty(
179: PropertyHelper.TORQUE_PROPERTY_REQUIRED, "true");
180: } else if (!fieldDef.getBooleanProperty(
181: PropertyHelper.OJB_PROPERTY_NULLABLE, true)) {
182: columnDef.setProperty(
183: PropertyHelper.TORQUE_PROPERTY_REQUIRED, "true");
184: }
185: if ("database"
186: .equals(fieldDef
187: .getProperty(PropertyHelper.OJB_PROPERTY_AUTOINCREMENT))) {
188: columnDef.setProperty(
189: PropertyHelper.TORQUE_PROPERTY_AUTOINCREMENT,
190: "true");
191: }
192: columnDef.setProperty(PropertyHelper.TORQUE_PROPERTY_SIZE,
193: fieldDef.getSizeConstraint());
194: if (fieldDef
195: .hasProperty(PropertyHelper.OJB_PROPERTY_DOCUMENTATION)) {
196: columnDef
197: .setProperty(
198: PropertyHelper.OJB_PROPERTY_DOCUMENTATION,
199: fieldDef
200: .getProperty(PropertyHelper.OJB_PROPERTY_DOCUMENTATION));
201: }
202: if (fieldDef
203: .hasProperty(PropertyHelper.OJB_PROPERTY_COLUMN_DOCUMENTATION)) {
204: columnDef
205: .setProperty(
206: PropertyHelper.OJB_PROPERTY_COLUMN_DOCUMENTATION,
207: fieldDef
208: .getProperty(PropertyHelper.OJB_PROPERTY_COLUMN_DOCUMENTATION));
209: }
210: return columnDef;
211: }
212:
213: /**
214: * Adds foreignkey(s) for the reference to the corresponding table(s).
215: *
216: * @param refDef The reference
217: * @param tableDef The table of the class owning the reference
218: */
219: private void addForeignkeys(ReferenceDescriptorDef refDef,
220: TableDef tableDef) {
221: if (!refDef.getBooleanProperty(
222: PropertyHelper.OJB_PROPERTY_DATABASE_FOREIGNKEY, true)) {
223: // we shall not generate a database foreignkey
224: return;
225: }
226:
227: // a foreignkey is added to the table schema if
228: // the referenced table exists (i.e. the referenced type has an associated table)
229: // then the foreignkey consists of:
230: // remote table = table of referenced type
231: // local fields = foreignkey fields of the reference
232: // remote fields = primarykeys of the referenced type
233: ClassDescriptorDef ownerClassDef = (ClassDescriptorDef) refDef
234: .getOwner();
235: String targetClassName = refDef
236: .getProperty(PropertyHelper.OJB_PROPERTY_CLASS_REF);
237: ClassDescriptorDef referencedClassDef = ((ModelDef) ownerClassDef
238: .getOwner()).getClass(targetClassName);
239:
240: // we can add a foreignkey only if the target type and all its subtypes either
241: // map to the same table or do not map to a table at all
242: String tableName = getHierarchyTable(referencedClassDef);
243:
244: if (tableName == null) {
245: return;
246: }
247:
248: try {
249: String name = refDef.getName();
250: ArrayList localFields = ownerClassDef
251: .getFields(refDef
252: .getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY));
253: ArrayList remoteFields = referencedClassDef
254: .getPrimaryKeys();
255:
256: tableDef.addForeignkey(name, tableName,
257: getColumns(localFields), getColumns(remoteFields));
258: } catch (NoSuchFieldException ex) {
259: // won't happen if we already checked the constraints
260: }
261: }
262:
263: /**
264: * Adds foreignkey(s) for the collection to the corresponding table(s).
265: *
266: * @param collDef The collection
267: * @param tableDef The table
268: */
269: private void addForeignkeys(CollectionDescriptorDef collDef,
270: TableDef tableDef) {
271: if (!collDef.getBooleanProperty(
272: PropertyHelper.OJB_PROPERTY_DATABASE_FOREIGNKEY, true)) {
273: // we shall not generate a database foreignkey
274: return;
275: }
276:
277: // a foreignkey is added to the table schema if for both ends of the collection
278: // a table exists
279: // then the foreignkey consists of:
280: // remote table = table of collection owner
281: // local fields = foreignkey fields in the element type
282: // remote fields = primarykeys of the collection owner type
283: ClassDescriptorDef ownerClassDef = (ClassDescriptorDef) collDef
284: .getOwner();
285: String elementClassName = collDef
286: .getProperty(PropertyHelper.OJB_PROPERTY_ELEMENT_CLASS_REF);
287: ClassDescriptorDef elementClassDef = ((ModelDef) ownerClassDef
288: .getOwner()).getClass(elementClassName);
289:
290: // we can only generate foreignkeys if the collection itself is not shared by
291: // several classes in the hierarchy
292: for (Iterator it = ownerClassDef.getAllBaseTypes(); it
293: .hasNext();) {
294: if (containsCollectionAndMapsToDifferentTable(collDef,
295: tableDef, (ClassDescriptorDef) it.next())) {
296: return;
297: }
298: }
299: for (Iterator it = ownerClassDef.getAllExtentClasses(); it
300: .hasNext();) {
301: if (containsCollectionAndMapsToDifferentTable(collDef,
302: tableDef, (ClassDescriptorDef) it.next())) {
303: return;
304: }
305: }
306:
307: // We add a foreignkey to all classes in the subtype hierarchy of the element type
308: // that map to a table (we're silently assuming that they contain the fk fields)
309: ArrayList candidates = new ArrayList();
310:
311: if (elementClassDef.getBooleanProperty(
312: PropertyHelper.OJB_PROPERTY_GENERATE_TABLE_INFO, true)) {
313: candidates.add(elementClassDef);
314: }
315: for (Iterator it = elementClassDef.getAllExtentClasses(); it
316: .hasNext();) {
317: ClassDescriptorDef curSubTypeDef = (ClassDescriptorDef) it
318: .next();
319:
320: if (curSubTypeDef.getBooleanProperty(
321: PropertyHelper.OJB_PROPERTY_GENERATE_TABLE_INFO,
322: true)) {
323: candidates.add(curSubTypeDef);
324: }
325: }
326:
327: String name = collDef.getName();
328: ArrayList remoteFields = ownerClassDef.getPrimaryKeys();
329: HashMap processedTables = new HashMap();
330:
331: for (Iterator it = candidates.iterator(); it.hasNext();) {
332: elementClassDef = (ClassDescriptorDef) it.next();
333: try {
334: // for the element class and its subclasses
335: String elementTableName = elementClassDef
336: .getProperty(PropertyHelper.OJB_PROPERTY_TABLE);
337:
338: // ensure that tables are only processed once
339: if (!processedTables.containsKey(elementTableName)) {
340: ArrayList localFields = elementClassDef
341: .getFields(collDef
342: .getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY));
343: TableDef elementTableDef = getTable(elementTableName);
344:
345: if (elementTableDef == null) {
346: elementTableDef = new TableDef(elementTableName);
347: addTable(elementTableDef);
348: }
349: elementTableDef.addForeignkey(name, tableDef
350: .getName(), getColumns(localFields),
351: getColumns(remoteFields));
352: processedTables.put(elementTableName, null);
353: }
354: } catch (NoSuchFieldException ex) {
355: // Shouldn't happen, but even if, then we're ignoring it and simply don't add the fk
356: }
357: }
358: }
359:
360: /**
361: * Extracts the list of columns from the given field list.
362: *
363: * @param fields The fields
364: * @return The corresponding columns
365: */
366: private List getColumns(List fields) {
367: ArrayList columns = new ArrayList();
368:
369: for (Iterator it = fields.iterator(); it.hasNext();) {
370: FieldDescriptorDef fieldDef = (FieldDescriptorDef) it
371: .next();
372:
373: columns.add(fieldDef
374: .getProperty(PropertyHelper.OJB_PROPERTY_COLUMN));
375: }
376: return columns;
377: }
378:
379: /**
380: * Checks whether the given class maps to a different table but also has the given collection.
381: *
382: * @param origCollDef The original collection to search for
383: * @param origTableDef The original table
384: * @param classDef The class descriptor to test
385: * @return <code>true</code> if the class maps to a different table and has the collection
386: */
387: private boolean containsCollectionAndMapsToDifferentTable(
388: CollectionDescriptorDef origCollDef, TableDef origTableDef,
389: ClassDescriptorDef classDef) {
390: if (classDef.getBooleanProperty(
391: PropertyHelper.OJB_PROPERTY_GENERATE_TABLE_INFO, true)
392: && !origTableDef
393: .getName()
394: .equals(
395: classDef
396: .getProperty(PropertyHelper.OJB_PROPERTY_TABLE))) {
397: CollectionDescriptorDef curCollDef = classDef
398: .getCollection(origCollDef.getName());
399:
400: if ((curCollDef != null)
401: && !curCollDef.getBooleanProperty(
402: PropertyHelper.OJB_PROPERTY_IGNORE, false)) {
403: return true;
404: }
405: }
406: return false;
407: }
408:
409: /**
410: * Tries to return the single target table to which the given foreign key columns map in
411: * all m:n collections that target this indirection table.
412: *
413: * @param targetClassDef The original target class
414: * @param indirectionTable The indirection table
415: * @param foreignKeys The foreign keys columns in the indirection table pointing back to the
416: * class' table
417: * @return The table name or <code>null</code> if there is not exactly one table
418: */
419: private String getTargetTable(ClassDescriptorDef targetClassDef,
420: String indirectionTable, String foreignKeys) {
421: ModelDef modelDef = (ModelDef) targetClassDef.getOwner();
422: String tableName = null;
423:
424: for (Iterator classIt = modelDef.getClasses(); classIt
425: .hasNext();) {
426: ClassDescriptorDef curClassDef = (ClassDescriptorDef) classIt
427: .next();
428:
429: if (!curClassDef.getBooleanProperty(
430: PropertyHelper.OJB_PROPERTY_GENERATE_TABLE_INFO,
431: true)) {
432: continue;
433: }
434: for (Iterator collIt = curClassDef.getCollections(); collIt
435: .hasNext();) {
436: CollectionDescriptorDef curCollDef = (CollectionDescriptorDef) collIt
437: .next();
438:
439: if (!indirectionTable
440: .equals(curCollDef
441: .getProperty(PropertyHelper.OJB_PROPERTY_INDIRECTION_TABLE))
442: || !CommaListIterator
443: .sameLists(
444: foreignKeys,
445: curCollDef
446: .getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY))) {
447: continue;
448: }
449: // ok, collection fits
450: if (tableName != null) {
451: if (!tableName
452: .equals(curClassDef
453: .getProperty(PropertyHelper.OJB_PROPERTY_TABLE))) {
454: // maps to a different table
455: return null;
456: }
457: } else {
458: tableName = curClassDef
459: .getProperty(PropertyHelper.OJB_PROPERTY_TABLE);
460: }
461: }
462: }
463: if (tableName == null) {
464: // no fitting collection found -> indirection table with only one collection
465: // we have to check whether the hierarchy of the target class maps to one table only
466: return getHierarchyTable(targetClassDef);
467: } else {
468: return tableName;
469: }
470: }
471:
472: /**
473: * Tries to return the single table to which all classes in the hierarchy with the given
474: * class as the root map.
475: *
476: * @param classDef The root class of the hierarchy
477: * @return The table name or <code>null</code> if the classes map to more than one table
478: * or no class in the hierarchy maps to a table
479: */
480: private String getHierarchyTable(ClassDescriptorDef classDef) {
481: ArrayList queue = new ArrayList();
482: String tableName = null;
483:
484: queue.add(classDef);
485:
486: while (!queue.isEmpty()) {
487: ClassDescriptorDef curClassDef = (ClassDescriptorDef) queue
488: .get(0);
489:
490: queue.remove(0);
491:
492: if (curClassDef.getBooleanProperty(
493: PropertyHelper.OJB_PROPERTY_GENERATE_TABLE_INFO,
494: true)) {
495: if (tableName != null) {
496: if (!tableName
497: .equals(curClassDef
498: .getProperty(PropertyHelper.OJB_PROPERTY_TABLE))) {
499: return null;
500: }
501: } else {
502: tableName = curClassDef
503: .getProperty(PropertyHelper.OJB_PROPERTY_TABLE);
504: }
505: }
506: for (Iterator it = curClassDef.getExtentClasses(); it
507: .hasNext();) {
508: curClassDef = (ClassDescriptorDef) it.next();
509:
510: if (curClassDef.getReference("super") == null) {
511: queue.add(curClassDef);
512: }
513: }
514: }
515: return tableName;
516: }
517:
518: /**
519: * Adds an index to the table for the given index descriptor.
520: *
521: * @param indexDescDef The index descriptor
522: * @param tableDef The table
523: */
524: private void addIndex(IndexDescriptorDef indexDescDef,
525: TableDef tableDef) {
526: IndexDef indexDef = tableDef.getIndex(indexDescDef.getName());
527:
528: if (indexDef == null) {
529: indexDef = new IndexDef(indexDescDef.getName(),
530: indexDescDef.getBooleanProperty(
531: PropertyHelper.OJB_PROPERTY_UNIQUE, false));
532: tableDef.addIndex(indexDef);
533: }
534:
535: try {
536: String fieldNames = indexDescDef
537: .getProperty(PropertyHelper.OJB_PROPERTY_FIELDS);
538: ArrayList fields = ((ClassDescriptorDef) indexDescDef
539: .getOwner()).getFields(fieldNames);
540: FieldDescriptorDef fieldDef;
541:
542: for (Iterator it = fields.iterator(); it.hasNext();) {
543: fieldDef = (FieldDescriptorDef) it.next();
544: indexDef
545: .addColumn(fieldDef
546: .getProperty(PropertyHelper.OJB_PROPERTY_COLUMN));
547: }
548: } catch (NoSuchFieldException ex) {
549: // won't happen if we already checked the constraints
550: }
551: }
552:
553: /**
554: * Adds the indirection table for the given collection descriptor.
555: *
556: * @param collDef The collection descriptor
557: */
558: private void addIndirectionTable(CollectionDescriptorDef collDef) {
559: String tableName = collDef
560: .getProperty(PropertyHelper.OJB_PROPERTY_INDIRECTION_TABLE);
561: TableDef tableDef = getTable(tableName);
562:
563: if (tableDef == null) {
564: tableDef = new TableDef(tableName);
565: addTable(tableDef);
566: }
567: if (collDef
568: .hasProperty(PropertyHelper.OJB_PROPERTY_INDIRECTION_TABLE_DOCUMENTATION)) {
569: tableDef
570: .setProperty(
571: PropertyHelper.OJB_PROPERTY_TABLE_DOCUMENTATION,
572: collDef
573: .getProperty(PropertyHelper.OJB_PROPERTY_INDIRECTION_TABLE_DOCUMENTATION));
574: }
575:
576: // we add columns for every primarykey in this and the element type
577: // collection.foreignkeys <-> ownerclass.primarykeys
578: // collection.remote-foreignkeys <-> elementclass.primarykeys
579: // we also add foreignkeys to the table
580: // name is empty (default foreignkey)
581: // remote table = table of ownerclass/elementclass
582: // local columns = columns in indirection table
583: // remote columns = columns of corresponding primarykeys in ownerclass/elementclass
584: ClassDescriptorDef ownerClassDef = (ClassDescriptorDef) collDef
585: .getOwner();
586: ModelDef modelDef = (ModelDef) ownerClassDef.getOwner();
587: String elementClassName = collDef
588: .getProperty(PropertyHelper.OJB_PROPERTY_ELEMENT_CLASS_REF);
589: ClassDescriptorDef elementClassDef = modelDef
590: .getClass(elementClassName);
591: ArrayList localPrimFields = ownerClassDef.getPrimaryKeys();
592: ArrayList remotePrimFields = elementClassDef.getPrimaryKeys();
593: String localKeyList = collDef
594: .getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY);
595: String remoteKeyList = collDef
596: .getProperty(PropertyHelper.OJB_PROPERTY_REMOTE_FOREIGNKEY);
597: String ownerTable = getTargetTable(ownerClassDef, tableName,
598: localKeyList);
599: String elementTable = getTargetTable(elementClassDef,
600: tableName, remoteKeyList);
601: CommaListIterator localKeys = new CommaListIterator(
602: localKeyList);
603: CommaListIterator localKeyDocs = new CommaListIterator(
604: collDef
605: .getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY_DOCUMENTATION));
606: CommaListIterator remoteKeys = new CommaListIterator(
607: remoteKeyList);
608: CommaListIterator remoteKeyDocs = new CommaListIterator(
609: collDef
610: .getProperty(PropertyHelper.OJB_PROPERTY_REMOTE_FOREIGNKEY_DOCUMENTATION));
611: ArrayList localColumns = new ArrayList();
612: ArrayList remoteColumns = new ArrayList();
613: boolean asPrimarykeys = collDef
614: .getBooleanProperty(
615: PropertyHelper.OJB_PROPERTY_INDIRECTION_TABLE_PRIMARYKEYS,
616: false);
617: FieldDescriptorDef fieldDef;
618: ColumnDef columnDef;
619: String relationName;
620: String name;
621: int idx;
622:
623: for (idx = 0; localKeys.hasNext(); idx++) {
624: fieldDef = (FieldDescriptorDef) localPrimFields.get(idx);
625: name = localKeys.getNext();
626: columnDef = tableDef.getColumn(name);
627: if (columnDef == null) {
628: columnDef = new ColumnDef(name);
629: tableDef.addColumn(columnDef);
630: }
631: columnDef
632: .setProperty(
633: PropertyHelper.TORQUE_PROPERTY_TYPE,
634: fieldDef
635: .getProperty(PropertyHelper.OJB_PROPERTY_JDBC_TYPE));
636: columnDef.setProperty(PropertyHelper.TORQUE_PROPERTY_SIZE,
637: fieldDef.getSizeConstraint());
638: if (asPrimarykeys) {
639: columnDef.setProperty(
640: PropertyHelper.TORQUE_PROPERTY_PRIMARYKEY,
641: "true");
642: }
643: if (localKeyDocs.hasNext()) {
644: columnDef
645: .setProperty(
646: PropertyHelper.OJB_PROPERTY_COLUMN_DOCUMENTATION,
647: localKeyDocs.getNext());
648: }
649: localColumns.add(name);
650: remoteColumns.add(fieldDef
651: .getProperty(PropertyHelper.OJB_PROPERTY_COLUMN));
652: }
653: if (collDef.getBooleanProperty(
654: PropertyHelper.OJB_PROPERTY_DATABASE_FOREIGNKEY, true)) {
655: relationName = collDef
656: .getProperty(PropertyHelper.TORQUE_PROPERTY_RELATION_NAME);
657: if ((relationName != null) && (ownerTable != null)) {
658: tableDef.addForeignkey(relationName, ownerTable,
659: localColumns, remoteColumns);
660: }
661: }
662: localColumns.clear();
663: remoteColumns.clear();
664:
665: for (idx = 0; remoteKeys.hasNext(); idx++) {
666: fieldDef = (FieldDescriptorDef) remotePrimFields.get(idx);
667: name = remoteKeys.getNext();
668:
669: columnDef = tableDef.getColumn(name);
670: if (columnDef == null) {
671: columnDef = new ColumnDef(name);
672: tableDef.addColumn(columnDef);
673: }
674: columnDef
675: .setProperty(
676: PropertyHelper.TORQUE_PROPERTY_TYPE,
677: fieldDef
678: .getProperty(PropertyHelper.OJB_PROPERTY_JDBC_TYPE));
679: columnDef.setProperty(PropertyHelper.TORQUE_PROPERTY_SIZE,
680: fieldDef.getSizeConstraint());
681: if (asPrimarykeys) {
682: columnDef.setProperty(
683: PropertyHelper.TORQUE_PROPERTY_PRIMARYKEY,
684: "true");
685: }
686: if (remoteKeyDocs.hasNext()) {
687: columnDef
688: .setProperty(
689: PropertyHelper.OJB_PROPERTY_COLUMN_DOCUMENTATION,
690: remoteKeyDocs.getNext());
691: }
692: localColumns.add(name);
693: remoteColumns.add(fieldDef
694: .getProperty(PropertyHelper.OJB_PROPERTY_COLUMN));
695: }
696:
697: CollectionDescriptorDef elementCollDef = collDef
698: .getRemoteCollection();
699:
700: if (((elementCollDef != null) && elementCollDef
701: .getBooleanProperty(
702: PropertyHelper.OJB_PROPERTY_DATABASE_FOREIGNKEY,
703: true))
704: || ((elementCollDef == null) && collDef
705: .getBooleanProperty(
706: PropertyHelper.OJB_PROPERTY_DATABASE_FOREIGNKEY,
707: true))) {
708: relationName = collDef
709: .getProperty(PropertyHelper.TORQUE_PROPERTY_INV_RELATION_NAME);
710: if ((relationName != null) && (elementTable != null)) {
711: tableDef.addForeignkey(relationName, elementTable,
712: localColumns, remoteColumns);
713: }
714: }
715: }
716:
717: // Access methods
718:
719: /**
720: * Returns an iterator of the tables.
721: *
722: * @return The tables
723: */
724: public Iterator getTables() {
725: return _tableDefs.values().iterator();
726: }
727:
728: /**
729: * Returns the table of the given name if it exists.
730: *
731: * @param name The table name
732: * @return The table def or <code>null</code> if there is no such table
733: */
734: public TableDef getTable(String name) {
735: return (TableDef) _tableDefs.get(name);
736: }
737:
738: /**
739: * Adds a table to this model.
740: *
741: * @param table The table
742: */
743: private void addTable(TableDef table) {
744: table.setOwner(this);
745: _tableDefs.put(table.getName(), table);
746: }
747: }
|