// We've run out of options. The given "mappedBy"
// setting is invalid.
boolean isNone = "none".equals(mappingProperty);
if (pd == null && !isNone) {
throw new GrailsDomainException("Non-existent mapping property ["+mappingProperty+"] specified for property ["+property.getName()+"] in class ["+getClazz()+"]");
}
else if (pd != null) {
// Tie the properties together.
relatedClassPropertyType = pd.getPropertyType();
property.setReferencePropertyName(pd.getName());
}
}
else {
if(mappedBy.containsKey(property.getName()) && mappedBy.get(property.getName()) == null) return;
// if the related type has a relationships map it may be a many-to-many
// figure out if there is a many-to-many relationship defined
if (isRelationshipManyToMany(property, relatedClassType, relatedClassRelationships)) {
String relatedClassPropertyName = null;
Map relatedClassMappedBy = GrailsDomainConfigurationUtil.getMappedByMap(relatedClassType);
// retrieve the relationship property
for (Object o : relatedClassRelationships.keySet()) {
String currentKey = (String) o;
String mappedByProperty = (String) relatedClassMappedBy.get(currentKey);
if (mappedByProperty != null && !mappedByProperty.equals(property.getName())) continue;
Class<?> currentClass = (Class<?>)relatedClassRelationships.get(currentKey);
if (currentClass.isAssignableFrom(getClazz())) {
relatedClassPropertyName = currentKey;
break;
}
}
// if there is one defined get the type
if (relatedClassPropertyName != null) {
relatedClassPropertyType = GrailsClassUtils.getPropertyType(relatedClassType, relatedClassPropertyName);
}
}
// otherwise figure out if there is a one-to-many relationship by retrieving any properties that are of the related type
// if there is more than one property then (for the moment) ignore the relationship
if (relatedClassPropertyType == null) {
PropertyDescriptor[] descriptors = GrailsClassUtils.getPropertiesOfType(relatedClassType, getClazz());
if (descriptors.length == 1) {
relatedClassPropertyType = descriptors[0].getPropertyType();
property.setReferencePropertyName(descriptors[0].getName());
}
else if (descriptors.length > 1) {
// try now to use the class name by convention
String classPropertyName = getPropertyName();
PropertyDescriptor pd = findProperty(descriptors, classPropertyName);
if (pd == null) {
throw new GrailsDomainException("Property ["+property.getName()+"] in class ["+getClazz()+"] is a bidirectional one-to-many with two possible properties on the inverse side. "+
"Either name one of the properties on other side of the relationship ["+classPropertyName+"] or use the 'mappedBy' static to define the property " +
"that the relationship is mapped with. Example: static mappedBy = ["+property.getName()+":'myprop']");
}
relatedClassPropertyType = pd.getPropertyType();
property.setReferencePropertyName(pd.getName());