1 21 package oracle.toplink.essentials.tools.schemaframework; 22 23 import java.sql.DatabaseMetaData ; 24 import java.sql.ResultSet ; 25 import java.sql.SQLException ; 26 import java.util.HashMap ; 27 import java.util.Hashtable ; 28 import java.util.Iterator ; 29 import java.util.Map ; 30 import java.util.Vector ; 31 32 import oracle.toplink.essentials.exceptions.DatabaseException; 33 import oracle.toplink.essentials.internal.helper.ClassConstants; 34 import oracle.toplink.essentials.internal.helper.ConversionManager; 35 import oracle.toplink.essentials.internal.helper.DatabaseField; 36 import oracle.toplink.essentials.internal.helper.DatabaseTable; 37 import oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl; 38 import oracle.toplink.essentials.logging.AbstractSessionLog; 39 import oracle.toplink.essentials.logging.SessionLog; 40 import oracle.toplink.essentials.mappings.AggregateCollectionMapping; 41 import oracle.toplink.essentials.mappings.DatabaseMapping; 42 import oracle.toplink.essentials.mappings.DirectCollectionMapping; 43 import oracle.toplink.essentials.mappings.DirectMapMapping; 44 import oracle.toplink.essentials.mappings.ManyToManyMapping; 45 46 import oracle.toplink.essentials.descriptors.ClassDescriptor; 47 import oracle.toplink.essentials.internal.sessions.AbstractSession; 48 import oracle.toplink.essentials.mappings.OneToManyMapping; 49 import oracle.toplink.essentials.mappings.OneToOneMapping; 50 import oracle.toplink.essentials.sessions.Project; 51 import oracle.toplink.essentials.sessions.DatabaseLogin; 52 import oracle.toplink.essentials.threetier.ServerSession; 53 import oracle.toplink.essentials.sequencing.Sequence; 54 import oracle.toplink.essentials.sequencing.DefaultSequence; 55 import oracle.toplink.essentials.sequencing.NativeSequence; 56 57 58 92 public class DefaultTableGenerator { 93 Project project = null; 95 96 private Map tableMap = null; 99 100 private Map fieldMap = null; 103 104 107 public DefaultTableGenerator(Project project) { 108 this.project = project; 109 tableMap = new HashMap (); 110 fieldMap = new HashMap (); 111 } 112 113 116 public TableCreator generateDefaultTableCreator() { 117 TableCreator tblCreator = new TableCreator(); 118 119 Iterator descIter = project.getDescriptors().values().iterator(); 121 122 while (descIter.hasNext()) { 123 ClassDescriptor desc = (ClassDescriptor)descIter.next(); 124 125 if (!desc.isAggregateDescriptor()) { 127 initTableSchema((ClassDescriptor)desc); 128 } 129 } 130 131 descIter = project.getOrderedDescriptors().iterator(); 133 134 while (descIter.hasNext()) { 135 ClassDescriptor desc = (ClassDescriptor)descIter.next(); 136 137 if (!desc.isAggregateDescriptor()) { 138 postInitTableSchema(desc); 139 } 140 } 141 142 tblCreator.addTableDefinitions(tableMap.values()); 143 144 return tblCreator; 145 } 146 147 152 public TableCreator generateFilteredDefaultTableCreator(AbstractSession session) throws DatabaseException { 153 TableCreator tblCreator = generateDefaultTableCreator(); 154 155 try { 156 java.sql.Connection conn = null; 158 if (session.isServerSession()) { 159 conn = ((ServerSession)session).getDefaultConnectionPool().acquireConnection().getConnection(); 161 } else if (session.isDatabaseSession()) { 162 conn = ((DatabaseSessionImpl)session).getAccessor().getConnection(); 163 } 164 if (conn == null) { 165 return tblCreator; 167 } 168 DatabaseMetaData dbMetaData = conn.getMetaData(); 169 ResultSet resultSet = dbMetaData.getTables(null, dbMetaData.getUserName(), null, new String [] { "TABLE" }); 170 java.util.List tablesInDatabase = new java.util.ArrayList (); 171 172 while (resultSet.next()) { 173 tablesInDatabase.add(resultSet.getString("TABLE_NAME")); 175 } 176 177 resultSet.close(); 178 179 java.util.List existedTables = new java.util.ArrayList (); 180 java.util.List existedTableNames = new java.util.ArrayList (); 181 Iterator tblDefIter = tblCreator.getTableDefinitions().iterator(); 182 183 while (tblDefIter.hasNext()) { 184 TableDefinition tblDef = (TableDefinition) tblDefIter.next(); 185 186 if (tablesInDatabase.contains(tblDef.getFullName())) { 188 existedTables.add(tblDef); 189 existedTableNames.add(tblDef.getFullName()); 190 } 191 } 192 193 if (!existedTableNames.isEmpty()) { 194 session.getSessionLog().log(SessionLog.FINEST, "skip_create_existing_tables", existedTableNames); 195 196 tblCreator.getTableDefinitions().removeAll(existedTables); 198 } 199 } catch (SQLException sqlEx) { 200 throw DatabaseException.errorRetrieveDbMetadataThroughJDBCConnection(); 201 } 202 203 return tblCreator; 204 } 205 206 211 protected void initTableSchema(ClassDescriptor desc) { 212 TableDefinition tblDef = null; 213 DatabaseTable dbTbl = null; 214 Iterator dbTblIter = desc.getTables().iterator(); 215 216 while (dbTblIter.hasNext()) { 218 dbTbl = (DatabaseTable) dbTblIter.next(); 219 tblDef = getTableDefFromDBTable(dbTbl); 220 } 221 222 Iterator fieldIter = desc.getFields().iterator(); 224 DatabaseField dbField = null; 225 226 while (fieldIter.hasNext()) { 227 dbField = (DatabaseField) fieldIter.next(); 228 229 boolean isPKField = false; 230 231 isPKField = desc.getPrimaryKeyFields().contains(dbField); 233 234 Map secondaryKeyMap = (Map ) desc.getAdditionalTablePrimaryKeyFields().get(dbField.getTable()); 236 237 if (secondaryKeyMap != null) { 238 isPKField = isPKField || secondaryKeyMap.containsValue(dbField); 239 } 240 241 FieldDefinition fieldDef = getFieldDefFromDBField(dbField, isPKField); 243 if (isPKField) { 244 String sequenceName = desc.getSequenceNumberName(); 246 DatabaseLogin login = project.getLogin(); 247 Sequence seq = login.getSequence(sequenceName); 248 if(seq instanceof DefaultSequence) { 249 seq = login.getDefaultSequence(); 250 } 251 boolean isIdentity = seq instanceof NativeSequence && seq.shouldAcquireValueAfterInsert(); 253 fieldDef.setIsIdentity(isIdentity); 254 } 255 256 tblDef = (TableDefinition) tableMap.get(dbField.getTableName()); 258 259 if (!tblDef.getFields().contains(fieldDef)) { 260 tblDef.addField(fieldDef); 261 } 262 } 263 } 264 265 270 private void postInitTableSchema(ClassDescriptor desc) { 271 Iterator mappingIter = desc.getMappings().iterator(); 272 273 while (mappingIter.hasNext()) { 274 DatabaseMapping mapping = (DatabaseMapping) mappingIter.next(); 275 276 if (mapping.isManyToManyMapping()) { 277 buildRelationTableDefinition((ManyToManyMapping) mapping); 278 } else if (mapping.isDirectCollectionMapping()) { 279 buildDirectCollectionTableDefinition((DirectCollectionMapping) mapping, desc); 280 } else if (mapping.isAggregateCollectionMapping()) { 281 addForeignkeyFieldToAggregateTargetTable((AggregateCollectionMapping) mapping); 283 } else if (mapping.isForeignReferenceMapping()) { 284 if (mapping.isOneToOneMapping()) 285 addForeignKeyFieldToSourceTargetTable((OneToOneMapping) mapping); 286 else if (mapping.isOneToManyMapping()) 287 addForeignKeyFieldToSourceTargetTable((OneToManyMapping) mapping); 288 } 289 } 290 processAdditionalTablePkFields(desc); 291 } 292 293 296 private void buildRelationTableDefinition(ManyToManyMapping mapping) { 297 TableDefinition tblDef = getTableDefFromDBTable(mapping.getRelationTable()); 299 300 DatabaseField dbField = null; 301 DatabaseField parentDBField = null; 302 FieldDefinition fldDef = null; 303 304 Vector srcFkFields = mapping.getSourceRelationKeyFields(); 306 307 for (int index = 0; index < srcFkFields.size(); index++) { 308 parentDBField = (DatabaseField) mapping.getSourceKeyFields().get(index); 309 dbField = resolveDatabaseField((DatabaseField) srcFkFields.get(index), parentDBField); 310 setFieldToRelationTable(dbField, tblDef); 311 setForeignKeyForRelationTable(dbField, parentDBField); 312 } 313 314 Vector targFkFields = mapping.getTargetRelationKeyFields(); 316 317 for (int index = 0; index < targFkFields.size(); index++) { 318 parentDBField = (DatabaseField) mapping.getTargetKeyFields().get(index); 319 dbField = resolveDatabaseField((DatabaseField) targFkFields.get(index), parentDBField); 320 setFieldToRelationTable(dbField, tblDef); 321 setForeignKeyForRelationTable(dbField, parentDBField); 322 } 323 } 324 325 private void setForeignKeyForRelationTable(final DatabaseField dbField, final DatabaseField parentDBField) { 326 FieldDefinition fldDef; 327 fldDef = getFieldDefFromDBField(dbField, false); 328 fldDef.setForeignKeyFieldName(parentDBField.getTable().getName() + "." + parentDBField.getName()); 329 return; 330 } 331 332 335 private void buildDirectCollectionTableDefinition(DirectCollectionMapping mapping, ClassDescriptor desc) { 336 TableDefinition tblDef = getTableDefFromDBTable(mapping.getReferenceTable()); 338 339 DatabaseField dbField = null; 340 341 Vector refPkFields = mapping.getReferenceKeyFields(); 343 344 for (int index = 0; index < refPkFields.size(); index++) { 345 dbField = resolveDatabaseField((DatabaseField) refPkFields.get(index), (DatabaseField) mapping.getSourceKeyFields().get(index)); 346 tblDef.addField(getDirectCollectionReferenceKeyFieldDefFromDBField(dbField)); 347 } 348 349 tblDef.addField(getFieldDefFromDBField(mapping.getDirectField(), false)); 351 352 if (mapping.isDirectMapMapping()) { 354 dbField = ((DirectMapMapping) mapping).getDirectKeyField(); 355 tblDef.addField(getFieldDefFromDBField(dbField, false)); 356 } 357 } 358 359 362 private void addForeignkeyFieldToAggregateTargetTable(AggregateCollectionMapping mapping) { 363 Iterator targFKIter = mapping.getTargetForeignKeyFields().iterator(); 366 367 while (targFKIter.hasNext()) { 368 DatabaseField dbField = (DatabaseField) targFKIter.next(); 369 370 TableDefinition targTblDef = getTableDefFromDBTable(dbField.getTable()); 372 373 targTblDef.addField(getFieldDefFromDBField(dbField, false)); 375 } 376 } 377 378 private void addForeignKeyFieldToSourceTargetTable(OneToOneMapping mapping) { 379 if (!mapping.isForeignKeyRelationship()) { 380 return; 381 } 382 383 Map srcFields = mapping.getSourceToTargetKeyFields(); 384 addForeignKeyFieldToFieldDefinition(srcFields); 385 } 386 387 private void addForeignKeyFieldToSourceTargetTable(OneToManyMapping mapping) { 388 Map srcFields = mapping.getTargetForeignKeysToSourceKeys(); 389 addForeignKeyFieldToFieldDefinition(srcFields); 390 } 391 392 private void addForeignKeyFieldToFieldDefinition(final Map srcFields) { 393 DatabaseField dbSrcField = null; 394 DatabaseField dbTrgField = null; 395 396 for (Iterator srcFkFields = srcFields.keySet().iterator(); srcFkFields.hasNext();) { 398 dbSrcField = (DatabaseField)srcFkFields.next(); 399 dbTrgField = (DatabaseField)srcFields.get(dbSrcField); 400 401 FieldDefinition srcFldDef = (FieldDefinition)fieldMap.get(dbSrcField); 402 FieldDefinition trgFldDef = (FieldDefinition)fieldMap.get(dbTrgField); 403 404 srcFldDef.setForeignKeyFieldName( 405 dbTrgField.getTable().getQualifiedName() + "." + dbTrgField.getName()); 406 407 srcFldDef.setType(trgFldDef.getType()); 410 srcFldDef.setSize(trgFldDef.getSize()); 411 srcFldDef.setSubSize(trgFldDef.getSubSize()); 412 } 413 } 414 415 418 private TableDefinition getTableDefFromDBTable(DatabaseTable dbTbl) { 419 TableDefinition tblDef = (TableDefinition) this.tableMap.get(dbTbl.getName()); 420 421 if (tblDef == null) { 422 tblDef = new TableDefinition(); 424 tblDef.setName(dbTbl.getName()); 425 tblDef.setQualifier(dbTbl.getTableQualifier()); 426 tblDef.setUniqueKeys(dbTbl.getUniqueConstraints()); 427 tableMap.put(dbTbl.getName(), tblDef); 428 } 429 430 return tblDef; 431 } 432 433 437 private DatabaseField resolveDatabaseField(DatabaseField childField, DatabaseField parentField) { 438 DatabaseField reslovedDatabaseField = new DatabaseField(); 440 reslovedDatabaseField.setName(childField.getName()); 441 reslovedDatabaseField.setType(getFieldDefFromDBField(parentField, true).getType()); 442 443 return reslovedDatabaseField; 444 } 445 446 449 private FieldDefinition getFieldDefFromDBField(DatabaseField dbField, boolean isPrimaryKey) { 450 FieldDefinition fieldDef = (FieldDefinition) this.fieldMap.get(dbField); 451 452 if (fieldDef == null) { 453 fieldDef = new FieldDefinition(); 455 fieldDef.setName(dbField.getName()); 456 457 if (dbField.getColumnDefinition().length() > 0) { 458 fieldDef.setTypeName(dbField.getColumnDefinition()); 461 } else { 462 Class fieldType = dbField.getType(); 463 464 if ((fieldType != null)) { 467 if (fieldType.equals(ClassConstants.STRING) || 468 fieldType.equals(ClassConstants.APCHAR) || 469 fieldType.equals(ClassConstants.ACHAR)) { 470 fieldDef.setSize(dbField.getLength()); 472 } else { 473 if (dbField.getPrecision() > 0) { 474 fieldDef.setSize(dbField.getPrecision()); 475 fieldDef.setSubSize(dbField.getScale()); 476 } 477 } 478 } 479 480 if ((fieldType == null) || (!fieldType.isPrimitive() && 481 (new DatabaseSessionImpl(project).getPlatform().getFieldTypeDefinition(fieldType) == null))) { 482 AbstractSessionLog.getLog().log(SessionLog.FINEST, "field_type_set_to_java_lang_string", dbField.getQualifiedName(), fieldType); 484 485 fieldDef.setType(ClassConstants.STRING); 488 } else { 489 fieldDef.setType(ConversionManager.getObjectClass(fieldType)); 491 } 492 493 fieldDef.setShouldAllowNull(dbField.isNullable()); 494 fieldDef.setUnique(dbField.isUnique()); 495 } 496 497 fieldDef.setIsPrimaryKey(isPrimaryKey); 498 fieldMap.put(dbField, fieldDef); 499 } 500 501 return fieldDef; 502 } 503 504 507 private FieldDefinition getDirectCollectionReferenceKeyFieldDefFromDBField(DatabaseField dbField) { 508 FieldDefinition fieldDef = (FieldDefinition)getFieldDefFromDBField(dbField, true).clone(); 509 fieldDef.setIsPrimaryKey(false); 511 return fieldDef; 512 } 513 514 517 private void setFieldToRelationTable(DatabaseField dbField, TableDefinition tblDef) { 518 FieldDefinition fieldDef = getFieldDefFromDBField(dbField, false); 519 520 if (!tblDef.getFields().contains(fieldDef)) { 521 tblDef.addField(getFieldDefFromDBField(dbField, false)); 523 fieldDef.setIsPrimaryKey(true); 524 } 525 } 526 527 private void processAdditionalTablePkFields(ClassDescriptor desc) { 528 DatabaseTable dbTbl = null; 529 Iterator dbTblIter = desc.getTables().iterator(); 530 while (dbTblIter.hasNext()) { 531 dbTbl = (DatabaseTable) dbTblIter.next(); 532 Map srcFields = (HashMap )desc.getAdditionalTablePrimaryKeyFields().get(dbTbl); 533 if (null != srcFields) { 534 addJoinColumnsFkFieldToFieldDefinition(srcFields); 535 } 536 } 537 } 538 539 private void addJoinColumnsFkFieldToFieldDefinition(final Map srcFields) { 540 DatabaseField dbSrcField = null; 541 DatabaseField dbTrgField = null; 542 543 for (Iterator srcFkFields = srcFields.keySet().iterator(); srcFkFields.hasNext();) { 545 dbSrcField = (DatabaseField)srcFkFields.next(); 546 dbTrgField = (DatabaseField)srcFields.get(dbSrcField); 547 FieldDefinition srcFldDef = (FieldDefinition)fieldMap.get(dbSrcField); 548 FieldDefinition trgFldDef = (FieldDefinition)fieldMap.get(dbTrgField); 549 trgFldDef.setForeignKeyFieldName( 550 dbSrcField.getTable().getQualifiedName() + "." + dbSrcField.getName()); 551 } 552 } 553 } 554 | Popular Tags |