1 22 package org.jboss.ejb.plugins.cmp.jdbc.metadata; 23 24 import java.util.Collection ; 25 import java.util.Collections ; 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.Map ; 30 31 import org.jboss.deployment.DeploymentException; 32 import org.jboss.metadata.MetaData; 33 import org.jboss.metadata.RelationshipRoleMetaData; 34 import org.w3c.dom.Element ; 35 36 44 public final class JDBCRelationshipRoleMetaData 45 { 46 47 private final JDBCRelationMetaData relationMetaData; 48 49 50 private final String relationshipRoleName; 51 52 53 private final boolean multiplicityOne; 54 55 56 private final boolean foreignKeyConstraint; 57 58 59 private final boolean cascadeDelete; 60 61 62 private final boolean batchCascadeDelete; 63 64 65 private final JDBCEntityMetaData entity; 66 67 68 private final String cmrFieldName; 69 70 71 private final boolean navigable; 72 73 74 private final String cmrFieldType; 75 76 private boolean genIndex; 77 78 79 private final JDBCReadAheadMetaData readAhead; 80 81 82 private JDBCRelationshipRoleMetaData relatedRole; 83 84 85 private Map keyFields; 86 87 public JDBCRelationshipRoleMetaData(JDBCRelationMetaData relationMetaData, 88 JDBCApplicationMetaData application, 89 RelationshipRoleMetaData role) 90 throws DeploymentException 91 { 92 this.relationMetaData = relationMetaData; 93 94 relationshipRoleName = role.getRelationshipRoleName(); 95 multiplicityOne = role.isMultiplicityOne(); 96 cascadeDelete = role.isCascadeDelete(); 97 batchCascadeDelete = false; 98 foreignKeyConstraint = false; 99 readAhead = null; 100 101 String fieldName = loadCMRFieldName(role); 102 if(fieldName == null) 103 { 104 cmrFieldName = generateNonNavigableCMRName(role); 105 navigable = false; 106 } 107 else 108 { 109 cmrFieldName = fieldName; 110 navigable = true; 111 } 112 cmrFieldType = role.getCMRFieldType(); 113 114 entity = application.getBeanByEjbName(role.getEntityName()); 116 if(entity == null) 117 { 118 throw new DeploymentException("Entity: " + role.getEntityName() + 119 " not found for relation: " + role.getRelationMetaData().getRelationName()); 120 } 121 } 122 123 public JDBCRelationshipRoleMetaData(JDBCRelationMetaData relationMetaData, 124 JDBCApplicationMetaData application, 125 Element element, 126 JDBCRelationshipRoleMetaData defaultValues) 127 throws DeploymentException 128 { 129 130 this.relationMetaData = relationMetaData; 131 this.entity = application.getBeanByEjbName(defaultValues.getEntity().getName()); 132 133 relationshipRoleName = defaultValues.getRelationshipRoleName(); 134 multiplicityOne = defaultValues.isMultiplicityOne(); 135 cascadeDelete = defaultValues.isCascadeDelete(); 136 137 cmrFieldName = defaultValues.getCMRFieldName(); 138 navigable = defaultValues.isNavigable(); 139 cmrFieldType = defaultValues.getCMRFieldType(); 140 141 String fkString = MetaData.getOptionalChildContent(element, "fk-constraint"); 143 if(fkString != null) 144 { 145 foreignKeyConstraint = Boolean.valueOf(fkString).booleanValue(); 146 } 147 else 148 { 149 foreignKeyConstraint = defaultValues.hasForeignKeyConstraint(); 150 } 151 152 Element readAheadElement = MetaData.getOptionalChild(element, "read-ahead"); 154 if(readAheadElement != null) 155 { 156 readAhead = new JDBCReadAheadMetaData(readAheadElement, entity.getReadAhead()); 157 } 158 else 159 { 160 readAhead = entity.getReadAhead(); 161 } 162 163 batchCascadeDelete = MetaData.getOptionalChild(element, "batch-cascade-delete") != null; 164 if(batchCascadeDelete) 165 { 166 if(!cascadeDelete) 167 throw new DeploymentException( 168 relationMetaData.getRelationName() + '/' + relationshipRoleName 169 + " has batch-cascade-delete in jbosscmp-jdbc.xml but has no cascade-delete in ejb-jar.xml" 170 ); 171 172 if(relationMetaData.isTableMappingStyle()) 173 { 174 throw new DeploymentException( 175 "Relationship " + relationMetaData.getRelationName() 176 + " with relation-table-mapping style was setup for batch cascade-delete." 177 + " Batch cascade-delete supported only for foreign key mapping style." 178 ); 179 } 180 } 181 } 182 183 public void init(JDBCRelationshipRoleMetaData relatedRole) 184 throws DeploymentException 185 { 186 init(relatedRole, null); 187 } 188 189 public void init(JDBCRelationshipRoleMetaData relatedRole, Element element) 190 throws DeploymentException 191 { 192 this.relatedRole = relatedRole; 193 if(element == null || "defaults".equals(element.getTagName())) 194 { 195 keyFields = loadKeyFields(); 196 } 197 else 198 { 199 keyFields = loadKeyFields(element); 200 } 201 } 202 203 private static String loadCMRFieldName(RelationshipRoleMetaData role) 204 { 205 return role.getCMRFieldName(); 206 } 207 208 private static String generateNonNavigableCMRName(RelationshipRoleMetaData role) 209 { 210 RelationshipRoleMetaData relatedRole = role.getRelatedRoleMetaData(); 211 return relatedRole.getEntityName() + "_" + relatedRole.getCMRFieldName(); 212 } 213 214 217 public JDBCRelationMetaData getRelationMetaData() 218 { 219 return relationMetaData; 220 } 221 222 225 public String getRelationshipRoleName() 226 { 227 return relationshipRoleName; 228 } 229 230 235 public boolean hasForeignKeyConstraint() 236 { 237 return foreignKeyConstraint; 238 } 239 240 243 public boolean isMultiplicityOne() 244 { 245 return multiplicityOne; 246 } 247 248 251 public boolean isMultiplicityMany() 252 { 253 return !multiplicityOne; 254 } 255 256 259 public boolean isCascadeDelete() 260 { 261 return cascadeDelete; 262 } 263 264 public boolean isBatchCascadeDelete() 265 { 266 return batchCascadeDelete; 267 } 268 269 272 public JDBCEntityMetaData getEntity() 273 { 274 return entity; 275 } 276 277 280 public String getCMRFieldName() 281 { 282 return cmrFieldName; 283 } 284 285 private boolean isNavigable() 286 { 287 return navigable; 288 } 289 290 293 private String getCMRFieldType() 294 { 295 return cmrFieldType; 296 } 297 298 301 public JDBCRelationshipRoleMetaData getRelatedRole() 302 { 303 return relationMetaData.getOtherRelationshipRole(this); 304 } 305 306 309 public JDBCReadAheadMetaData getReadAhead() 310 { 311 return readAhead; 312 } 313 314 318 public Collection getKeyFields() 319 { 320 return Collections.unmodifiableCollection(keyFields.values()); 321 } 322 323 public boolean isIndexed() 324 { 325 return genIndex; 326 } 327 328 332 private Map loadKeyFields() 333 { 334 if(relationMetaData.isForeignKeyMappingStyle()) 338 { 339 if(isMultiplicityMany()) 340 return Collections.EMPTY_MAP; 341 else 342 if(getRelatedRole().isMultiplicityOne() && !getRelatedRole().isNavigable()) 343 return Collections.EMPTY_MAP; 344 } 345 346 ArrayList pkFields = new ArrayList (); 348 for(Iterator i = entity.getCMPFields().iterator(); i.hasNext();) 349 { 350 JDBCCMPFieldMetaData cmpField = (JDBCCMPFieldMetaData) i.next(); 351 if(cmpField.isPrimaryKeyMember()) 352 { 353 pkFields.add(cmpField); 354 } 355 } 356 357 Map fields = new HashMap (pkFields.size()); 359 for(Iterator i = pkFields.iterator(); i.hasNext();) 360 { 361 JDBCCMPFieldMetaData cmpField = (JDBCCMPFieldMetaData) i.next(); 362 363 String columnName; 364 if(relationMetaData.isTableMappingStyle()) 365 { 366 if(entity.equals(relatedRole.getEntity())) 367 columnName = getCMRFieldName(); 368 else 369 columnName = entity.getName(); 370 } 371 else 372 { 373 columnName = relatedRole.getCMRFieldName(); 374 } 375 376 if(pkFields.size() > 1) 377 { 378 columnName += "_" + cmpField.getFieldName(); 379 } 380 381 cmpField = new JDBCCMPFieldMetaData( 382 entity, 383 cmpField, 384 columnName, 385 false, 386 relationMetaData.isTableMappingStyle(), 387 relationMetaData.isReadOnly(), 388 relationMetaData.getReadTimeOut(), 389 relationMetaData.isTableMappingStyle()); 390 fields.put(cmpField.getFieldName(), cmpField); 391 } 392 return Collections.unmodifiableMap(fields); 393 } 394 395 399 private Map loadKeyFields(Element element) 400 throws DeploymentException 401 { 402 Element keysElement = MetaData.getOptionalChild(element, "key-fields"); 403 404 if(keysElement == null) 406 { 407 return loadKeyFields(); 408 } 409 410 Iterator iter = MetaData.getChildrenByTagName(keysElement, "key-field"); 412 413 if(!iter.hasNext()) 415 { 416 return Collections.EMPTY_MAP; 417 } 418 else 419 if(relationMetaData.isForeignKeyMappingStyle() && isMultiplicityMany()) 420 { 421 throw new DeploymentException("Role: " + relationshipRoleName + " with multiplicity many using " + 422 "foreign-key mapping is not allowed to have key-fields"); 423 } 424 425 Map defaultFields = getPrimaryKeyFields(); 427 428 Map fields = new HashMap (defaultFields.size()); 430 while(iter.hasNext()) 431 { 432 Element keyElement = (Element ) iter.next(); 433 String fieldName = MetaData.getUniqueChildContent(keyElement, "field-name"); 434 435 JDBCCMPFieldMetaData cmpField = (JDBCCMPFieldMetaData) defaultFields.remove(fieldName); 436 if(cmpField == null) 437 { 438 throw new DeploymentException( 439 "Role '" + relationshipRoleName + "' on Entity Bean '" + 440 entity.getName() + "' : CMP field for key not found: field " + 441 "name='" + fieldName + "'"); 442 } 443 String isIndexedtmp = MetaData.getOptionalChildContent(keyElement, "dbindex"); 444 boolean isIndexed; 445 446 if(isIndexedtmp != null) 447 isIndexed = true; 448 else 449 isIndexed = false; 450 genIndex = isIndexed; 451 452 453 cmpField = new JDBCCMPFieldMetaData( 454 entity, 455 keyElement, 456 cmpField, 457 false, 458 relationMetaData.isTableMappingStyle(), 459 relationMetaData.isReadOnly(), 460 relationMetaData.getReadTimeOut(), 461 relationMetaData.isTableMappingStyle()); 462 fields.put(cmpField.getFieldName(), cmpField); 463 } 464 465 if(!defaultFields.isEmpty()) 467 { 468 throw new DeploymentException("Mappings were not provided for all " + 469 "fields: unmaped fields=" + defaultFields.keySet() + 470 " in role=" + relationshipRoleName); 471 } 472 return Collections.unmodifiableMap(fields); 473 } 474 475 478 private Map getPrimaryKeyFields() 479 { 480 Map pkFields = new HashMap (); 481 for(Iterator cmpFieldsIter = entity.getCMPFields().iterator(); cmpFieldsIter.hasNext();) 482 { 483 JDBCCMPFieldMetaData cmpField = (JDBCCMPFieldMetaData) cmpFieldsIter.next(); 484 if(cmpField.isPrimaryKeyMember()) 485 pkFields.put(cmpField.getFieldName(), cmpField); 486 } 487 return pkFields; 488 } 489 } 490 | Popular Tags |