1 21 package oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors; 23 24 import static oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.EmbeddedAccessor.AccessType.MIXED; 25 import static oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.EmbeddedAccessor.AccessType.PROPERTY; 26 import static oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.EmbeddedAccessor.AccessType.FIELD; 27 import static oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.EmbeddedAccessor.AccessType.UNDEFINED; 28 29 import javax.persistence.*; 30 31 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.objects.MetadataAccessibleObject; 32 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.objects.MetadataClass; 33 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.columns.MetadataColumn; 34 35 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataDescriptor; 36 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataHelper; 37 import oracle.toplink.essentials.internal.ejb.cmp3.xml.XMLHelper; 38 import oracle.toplink.essentials.internal.ejb.cmp3.xml.XMLConstants; 39 import oracle.toplink.essentials.internal.ejb.cmp3.xml.accessors.XMLClassAccessor; 40 import oracle.toplink.essentials.internal.helper.DatabaseField; 41 42 import oracle.toplink.essentials.mappings.AggregateObjectMapping; 43 import oracle.toplink.essentials.mappings.DatabaseMapping; 44 import oracle.toplink.essentials.mappings.OneToOneMapping; 45 import oracle.toplink.essentials.exceptions.ValidationException; 46 import org.w3c.dom.Node ; 47 48 54 public class EmbeddedAccessor extends BasicAccessor { 55 enum AccessType {FIELD, PROPERTY, UNDEFINED, MIXED}; 56 57 protected boolean m_isEmbeddedId; 58 59 62 public EmbeddedAccessor(MetadataAccessibleObject accessibleObject, ClassAccessor classAccessor, boolean isEmbeddedId) { 63 super(accessibleObject, classAccessor); 64 65 m_isEmbeddedId = isEmbeddedId; 66 } 67 68 71 public boolean isEmbedded() { 72 return true; 73 } 74 75 78 public boolean isEmbeddedId() { 79 return m_isEmbeddedId; 80 } 81 82 87 public void process() { 88 if (isEmbeddedId()) { 90 processEmbeddedId(); 91 } 92 93 MetadataDescriptor referenceDescriptor = processEmbeddableClass(); 95 96 m_descriptor.addAggregateDescriptor(referenceDescriptor); 99 100 if (m_descriptor.hasMappingForAttributeName(getAttributeName())) { 101 m_logger.logWarningMessage(m_logger.IGNORE_MAPPING, m_descriptor, this); 103 } else { 104 AggregateObjectMapping mapping = new AggregateObjectMapping(); 106 mapping.setIsReadOnly(false); 107 mapping.setIsNullAllowed(true); 108 mapping.setReferenceClassName(getReferenceClassName()); 109 mapping.setAttributeName(getAttributeName()); 110 111 setAccessorMethods(mapping); 113 114 processAttributeOverrides(mapping); 116 117 processAssociationOverrides(mapping); 119 120 m_descriptor.addMapping(mapping); 122 } 123 } 124 125 137 protected void processAssociationOverride(AssociationOverride associationOverride, AggregateObjectMapping aggregateMapping) { 138 MetadataDescriptor aggregateDescriptor = getReferenceDescriptor(); 139 140 String name = associationOverride.name(); 143 DatabaseMapping mapping = aggregateDescriptor.getMappingForAttributeName(name); 144 145 if (mapping == null) { 146 } 149 150 if (mapping.isOneToOneMapping()) { 151 int index = 0; 152 153 for (JoinColumn joinColumn : associationOverride.joinColumns()) { 154 DatabaseField fkField = (DatabaseField) ((OneToOneMapping) mapping).getForeignKeyFields().elementAt(index++); 164 aggregateMapping.addFieldNameTranslation(joinColumn.name(), fkField.getName()); 165 } 166 } else { 167 } 169 } 170 171 178 protected void processAssociationOverrides(AggregateObjectMapping mapping) { 179 AssociationOverrides associationOverrides = getAnnotation(AssociationOverrides.class); 181 if (associationOverrides != null) { 182 for (AssociationOverride associationOverride : associationOverrides.value()) { 183 processAssociationOverride(associationOverride, mapping); 184 } 185 } 186 187 AssociationOverride associationOverride = getAnnotation(AssociationOverride.class); 189 if (associationOverride != null) { 190 processAssociationOverride(associationOverride, mapping); 191 } 192 } 193 194 199 protected void processAttributeOverride(AggregateObjectMapping mapping, MetadataColumn column) { 200 String attributeName = column.getAttributeName(); 201 202 DatabaseMapping aggregateMapping = getReferenceDescriptor().getMappingForAttributeName(attributeName); 204 205 if (aggregateMapping == null) { 206 m_validator.throwInvalidEmbeddableAttribute(getJavaClass(), mapping.getAttributeName(), getReferenceDescriptor().getJavaClass(), attributeName); 207 } 208 209 DatabaseField field; 211 if (m_descriptor.hasAttributeOverrideFor(attributeName)) { 212 field = m_descriptor.getAttributeOverrideFor(attributeName).getDatabaseField(); 213 } else { 214 field = column.getDatabaseField(); 215 } 216 217 mapping.addFieldNameTranslation(field.getQualifiedName(), aggregateMapping.getField().getName()); 218 } 219 220 227 protected void processAttributeOverrides(AggregateObjectMapping mapping) { 228 AttributeOverrides attributeOverrides = getAnnotation(AttributeOverrides.class); 230 231 if (attributeOverrides != null) { 232 for (AttributeOverride attributeOverride : attributeOverrides.value()) { 233 processAttributeOverride(mapping, new MetadataColumn(attributeOverride.column(), attributeOverride.name(), getAnnotatedElement())); 234 } 235 } 236 237 AttributeOverride attributeOverride = getAnnotation(AttributeOverride.class); 239 if (attributeOverride != null) { 240 processAttributeOverride(mapping, new MetadataColumn(attributeOverride.column(), attributeOverride.name(), getAnnotatedElement())); 241 } 242 } 243 244 256 protected MetadataDescriptor processEmbeddableClass() { 257 final Class embeddableClass = getReferenceClass(); 258 MetadataDescriptor embeddableDescriptor = null; 259 try { 260 embeddableDescriptor = m_project.getDescriptor(embeddableClass); 261 } catch (ValidationException ve) { 262 } 264 if (embeddableDescriptor == null) { 265 embeddableDescriptor = new MetadataDescriptor(embeddableClass); 267 m_project.addDescriptor(embeddableDescriptor); 269 embeddableDescriptor.setIgnoreAnnotations( 270 isMetadataComplete(embeddableDescriptor)); 271 AccessType accessType = 272 determineAccessTypeOfEmbedded(embeddableDescriptor); 273 embeddableDescriptor.setUsesPropertyAccess( 274 accessType == PROPERTY ? true : false); 275 ClassAccessor embeddableAccessor = 276 makeAccessorFor(embeddableDescriptor); 277 embeddableAccessor.process(); 278 embeddableAccessor.setIsProcessed(); 279 } else { 280 if(!isMetadataPresent(embeddableDescriptor)) { 285 boolean embeddableUsesPropertyAccess = 286 embeddableDescriptor.usesPropertyAccess(); 287 boolean entityUsesPropertyAccess = m_descriptor.usesPropertyAccess(); 288 if (embeddableUsesPropertyAccess != entityUsesPropertyAccess) { 289 m_validator.throwConflictingAccessTypeInEmbeddable( 290 embeddableClass); 291 } 292 293 } 294 } 295 296 if (isEmbeddedId() && ! m_descriptor.ignoreIDs()) { 299 for (DatabaseMapping mapping : embeddableDescriptor.getMappings()) { 300 DatabaseField field = (DatabaseField) mapping.getField().clone(); 301 field.setTableName(m_descriptor.getPrimaryTableName()); 302 m_descriptor.addPrimaryKeyField(field); 303 } 304 } 305 306 return embeddableDescriptor; 307 } 308 309 315 private boolean isMetadataComplete(MetadataDescriptor emDesc) { 316 final Class emClass = emDesc.getJavaClass(); 317 boolean metadataComplete = 318 m_project.getPersistenceUnit()!= null ? 319 m_project.getPersistenceUnit().isMetadataComplete() : false; 320 if (!metadataComplete) { 321 if (m_project.hasEmbeddable(emClass)) { 323 XMLHelper helper = m_project.getEmbeddableHelper(emClass); 324 Node node = m_project.getEmbeddableNode(emClass); 325 metadataComplete = helper.getNodeValue( 327 node, 328 XMLConstants.ATT_METADATA_COMPLETE, 329 false); 330 } 331 } 332 return metadataComplete; 333 } 334 335 340 private boolean isMetadataPresent(MetadataDescriptor desc) { 341 AccessType annotAccessType = computeAccessTypeFromAnnotation(desc); 342 AccessType xmlAccessType = computeAccessTypeFromXML(desc); 343 return annotAccessType!=UNDEFINED || xmlAccessType!=UNDEFINED; 344 345 } 346 352 private AccessType computeAccessTypeFromAnnotation(MetadataDescriptor desc) { 353 final Class javaClass = desc.getJavaClass(); 354 boolean fieldAccess = MetadataHelper.havePersistenceAnnotationsDefined( 355 MetadataHelper.getFields(javaClass)); 356 boolean propAccess = MetadataHelper.havePersistenceAnnotationsDefined( 357 MetadataHelper.getMethods(javaClass)); 358 AccessType accessType = UNDEFINED; 359 if (fieldAccess && propAccess) { 360 accessType = MIXED; 361 } else if(fieldAccess) { 362 accessType = FIELD; 363 } else if(propAccess) { 364 accessType = PROPERTY; 365 } 366 return accessType; 367 } 368 369 379 private AccessType computeAccessTypeFromXML(MetadataDescriptor desc) { 380 String access = m_project.getPersistenceUnit() != null ? 382 m_project.getPersistenceUnit().getAccess():null; 383 final Class javaClass = desc.getJavaClass(); 385 if (m_project.hasEmbeddable(javaClass)) { 386 XMLHelper helper = m_project.getEmbeddableHelper(javaClass); 387 Node node = m_project.getEmbeddableNode(javaClass); 388 access = helper.getNodeValue( 391 node, 392 XMLConstants.ATT_ACCESS, 393 access); 394 } 395 AccessType accessType = UNDEFINED; 396 if(access!=null && access.length()!=0) { 397 accessType = AccessType.valueOf(access); 398 } 399 return accessType; 400 } 401 427 private AccessType determineAccessTypeOfEmbedded( 428 MetadataDescriptor emDesc) { 429 final AccessType entityAccessType = m_descriptor.usesPropertyAccess() ? 430 PROPERTY : FIELD; 431 AccessType accessType = UNDEFINED; 432 final boolean metadataComplete =emDesc.ignoreAnnotations(); 433 final AccessType accessTypeUsingAnnotation = 434 computeAccessTypeFromAnnotation(emDesc); 435 final AccessType accessTypeUsingXML = 436 computeAccessTypeFromXML(emDesc); 437 if (metadataComplete) { 438 accessType = accessTypeUsingXML != UNDEFINED ? 441 accessTypeUsingXML : entityAccessType; 442 } else { if (accessTypeUsingAnnotation == UNDEFINED 444 && accessTypeUsingAnnotation == UNDEFINED) { 445 accessType = entityAccessType; 447 } else if (accessTypeUsingXML == UNDEFINED 448 && accessTypeUsingAnnotation != UNDEFINED) { 449 accessType = accessTypeUsingAnnotation; 451 if (accessType == MIXED) { 452 m_validator.throwBothFieldsAndPropertiesAnnotatedException(emDesc.getJavaClass()); 453 } 454 } else if (accessTypeUsingAnnotation == UNDEFINED 455 && accessTypeUsingXML != UNDEFINED) { 456 accessType = accessTypeUsingXML; 458 } else if (accessTypeUsingAnnotation == accessTypeUsingXML) { 459 accessType = accessTypeUsingAnnotation; 462 } else { 463 m_validator.throwIncorrectOverridingOfAccessType( 466 emDesc.getJavaClass(), 467 accessTypeUsingXML.toString(), 468 accessTypeUsingAnnotation.toString()); 469 } 470 } 471 assert(accessType != UNDEFINED && accessType != MIXED); 475 return accessType; 476 } 477 478 489 private ClassAccessor makeAccessorFor( 490 MetadataDescriptor embeddableDescriptor) { 491 ClassAccessor embeddableAccessor; 492 final Class embeddableClass = embeddableDescriptor.getJavaClass(); 493 if (m_project.hasEmbeddable(embeddableClass)) { 494 Node node = m_project.getEmbeddableNode(embeddableClass); 495 XMLHelper helper = m_project.getEmbeddableHelper(embeddableClass); 496 embeddableAccessor = new XMLClassAccessor( 497 new MetadataClass(embeddableClass), 498 node, 499 helper, 500 m_processor, 501 embeddableDescriptor); 502 } else if (MetadataHelper.isAnnotationPresent( 503 Embeddable.class, embeddableClass, embeddableDescriptor)) { 504 embeddableAccessor = new ClassAccessor( 505 new MetadataClass(embeddableClass), 506 m_processor, 507 embeddableDescriptor); 508 } else { 509 m_validator.throwInvalidEmbeddedAttribute( 510 m_descriptor.getDescriptor().getJavaClass(), 511 m_accessibleObject.getName(), 512 embeddableClass); 513 throw new RuntimeException ("Will never reach here"); } 516 embeddableDescriptor.setClassAccessor(embeddableAccessor); 518 return embeddableAccessor; 519 } 520 521 527 public void processEmbeddedId() { 528 if (m_descriptor.ignoreIDs()) { 529 m_logger.logWarningMessage(m_logger.IGNORE_EMBEDDED_ID, this); 531 } else { 532 if (m_descriptor.hasEmbeddedIdAttribute()) { 534 m_validator.throwMultipleEmbeddedIdsFound(getJavaClass(), getAttributeName(), m_descriptor.getEmbeddedIdAttributeName()); 535 } 536 537 if (m_descriptor.hasPrimaryKeyFields()) { 539 m_validator.throwEmbeddedIdAndIdFound(getJavaClass(), getAttributeName(), m_descriptor.getIdAttributeName()); 540 } 541 542 m_descriptor.setPKClass(getReferenceClass()); 544 545 m_descriptor.setEmbeddedIdAttributeName(getAttributeName()); 547 } 548 } 549 } 550 | Popular Tags |