*/
// Tie into the collection hierarchy at a lower level
if (mapping instanceof CollectionMapping) {
// Handle 1:m, n:m collection mappings
CollectionMapping colMapping = (CollectionMapping) mapping;
ContainerPolicy collectionContainerPolicy = colMapping.getContainerPolicy();
if (collectionContainerPolicy.isMapPolicy()) {
// Handle the 3 Map type mappings (policy.isMappedKeyMapPolicy()) is handled by isMapPolicy())
member = new MapAttributeImpl(this, colMapping, true);
// check mapping.attributeAcessor.attributeField.type=Collection
} else if (collectionContainerPolicy.isListPolicy()) {
// This seems very over complex...
/**
* Handle lazy Collections and Lists and the fact that both return an IndirectList policy.
* We check the type on the attributeField of the attributeAccessor on the mapping
*/
Class aType = null;
// 325699: AttributeAccessor is subclassed by both IntanceVariableAttributeAccessor (JPA) and ValuesAccessor (Dynamic JPA)
if(colMapping.getAttributeAccessor() instanceof ValuesAccessor) {
member = new ListAttributeImpl(this, colMapping);
} else if(colMapping.getAttributeAccessor() instanceof InstanceVariableAttributeAccessor) {
Field aField = ((InstanceVariableAttributeAccessor)colMapping.getAttributeAccessor()).getAttributeField();
// MappedSuperclasses need special handling to get their type from an inheriting subclass
if(null == aField) { // MappedSuperclass field will not be set
if(this.isMappedSuperclass()) {
// get inheriting subtype member (without handling @override annotations)
MappedSuperclassTypeImpl aMappedSuperclass = ((MappedSuperclassTypeImpl)this);
AttributeImpl inheritingTypeMember = aMappedSuperclass.getMemberFromInheritingType(colMapping.getAttributeName());
// 322166: If attribute is defined on this current ManagedType (and not on a superclass) - do not attempt a reflective call on a superclass
if(null != inheritingTypeMember) {
// Verify we have an attributeAccessor
aField = ((InstanceVariableAttributeAccessor)inheritingTypeMember.getMapping().getAttributeAccessor()).getAttributeField();
}
}
}
// 322166: The attribute may be defined on the current ManagedType - not inherited
if(null == aField) {
// Check attributeName when the field is null
aType = this.getTypeClassFromAttributeOrMethodLevelAccessor(mapping);
} else {
aType = aField.getType();
}
// This attribute is declared as List
if((aType != null) && List.class.isAssignableFrom(aType)) {
member = new ListAttributeImpl(this, colMapping, true);
} else if((aType != null) && Collection.class.isAssignableFrom(aType)) {
// This attribute is therefore declared as Collection
member = new CollectionAttributeImpl(this, colMapping, true);
} else {
member = initializePluralAttributeTypeNotFound(this, colMapping, true);
}
} else {
// handle variations of missing get/set methods - only for Collection vs List
if(colMapping.getAttributeAccessor() instanceof MethodAttributeAccessor) {
/**
* The following call will perform a getMethod call for us.
* If no getMethod exists, we will secondarily check the getMethodName below.
*/
aType = ((MethodAttributeAccessor)colMapping.getAttributeAccessor()).getAttributeClass();
if((aType != null) && List.class.isAssignableFrom(aType)) {
member = new ListAttributeImpl(this, colMapping, true);
} else if((aType != null) && Collection.class.isAssignableFrom(aType)) {
member = new CollectionAttributeImpl(this, colMapping, true);
} else {
/**
* In this block we have the following scenario:
* 1) The access type is "field"
* 2) The get method is not set on the entity
* 3) The get method is named differently than the attribute
*/
// Type may be null when no getMethod exists for the class for a ManyToMany mapping
// Here we check the returnType on the declared method on the class directly
String getMethodName = ((MethodAttributeAccessor)colMapping.getAttributeAccessor()).getGetMethodName();
if(null == getMethodName) {
// Check declaredFields in the case where we have no getMethod or getMethodName
try {
Field field = null;
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try {
field = (Field)AccessController.doPrivileged(new PrivilegedGetDeclaredField(
this.getJavaType(), colMapping.getAttributeName(), false));
} catch (PrivilegedActionException exception) {
member = initializePluralAttributeTypeNotFound(this, colMapping, true);
}
} else {
field = PrivilegedAccessHelper.getDeclaredField(
this.getJavaType(), colMapping.getAttributeName(), false);
}
if(null == field) {
member = initializePluralAttributeTypeNotFound(this, colMapping, true);
} else {
aType = field.getType();
if((aType != null) && List.class.isAssignableFrom(aType)) {
member = new ListAttributeImpl(this, colMapping, true);
} else if((aType != null) && Collection.class.isAssignableFrom(aType)) {
member = new CollectionAttributeImpl(this, colMapping, true);
} else {
member = initializePluralAttributeTypeNotFound(this, colMapping, true);
}
}
} catch (Exception e) {
member = initializePluralAttributeTypeNotFound(this, colMapping, true);
}
} else {
/**
* Field access Handling:
* If a get method name exists, we check the return type on the method directly
* using reflection.
* In all failure cases we default to the List type.
*/
try {
Method aMethod = null;
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
aMethod = (Method) AccessController.doPrivileged(new PrivilegedGetDeclaredMethod(
this.getJavaType(), getMethodName, null));
} else {
aMethod = PrivilegedAccessHelper.getDeclaredMethod(
this.getJavaType(), getMethodName, null);
}
if(null == aMethod) {
member = initializePluralAttributeTypeNotFound(this, colMapping, true);
} else {
aType = aMethod.getReturnType();
if((aType != null) && List.class.isAssignableFrom(aType)) {
member = new ListAttributeImpl(this, colMapping, true);
} else if((aType != null) && Collection.class.isAssignableFrom(aType)) {
member = new CollectionAttributeImpl(this, colMapping, true);
} else {
member = initializePluralAttributeTypeNotFound(this, colMapping, true);
}
}
} catch (Exception e) {
member = initializePluralAttributeTypeNotFound(this, colMapping, true);
}
}
}
}
}
} else {
// Handle non-lazy Collection or Set type mappings (IndirectSet.isAssignableFrom(Set.class) == false)
if ((collectionContainerPolicy.getContainerClass() != null) && Set.class.isAssignableFrom(collectionContainerPolicy.getContainerClass())) {
member = new SetAttributeImpl(this, colMapping, true);
} else {
// Check for non-lazy Collection policy possibly instantiated to a Set or List (both of which is ignored)
if(collectionContainerPolicy.isCollectionPolicy()) {
member = new CollectionAttributeImpl(this, colMapping, true);
} else {
// Handle Collection type mappings as a default (we should never get here)
// TODO: System.out.println("_Warning: defaulting to non-Set specific Collection type on " + colMapping);
member = new CollectionAttributeImpl(this, colMapping);