in grails-web-databinding/src/main/groovy/grails/web/databinding/GrailsWebDataBinder.groovy [367:455]
protected processIndexedProperty(obj, MetaProperty metaProperty, IndexedPropertyReferenceDescriptor indexedPropertyReferenceDescriptor, val,
DataBindingSource source, DataBindingListener listener, errors) {
boolean needsBinding = true
if (source.dataSourceAware) {
def propName = indexedPropertyReferenceDescriptor.propertyName
def idValue = getIdentifierValueFrom(val)
if (idValue != null && idValue != "") {
def propertyType = getDomainClassType(obj, propName)
def referencedType = getReferencedTypeForCollection propName, obj
if (referencedType != null && isDomainClass(referencedType)) {
needsBinding = false
if (Set.isAssignableFrom(metaProperty.type)) {
def collection = initializeCollection obj, propName, metaProperty.type
def instance
if (collection != null) {
instance = findAlementWithId((Set)collection, idValue)
}
if (instance == null) {
if ('null' != idValue) {
instance = getPersistentInstance(referencedType, idValue)
}
if (instance == null) {
def message = "Illegal attempt to update element in [${propName}] Set with id [${idValue}]. No such record was found."
Exception e = new IllegalArgumentException(message)
addBindingError(obj, propName, idValue, e, listener, errors)
} else {
addElementToCollectionAt obj, propName, collection, Integer.parseInt(indexedPropertyReferenceDescriptor.index), instance
}
}
if (instance != null) {
if (val instanceof Map) {
bind instance, new SimpleMapDataBindingSource(val), listener
} else if (val instanceof DataBindingSource) {
bind instance, val, listener
}
}
} else if (Collection.isAssignableFrom(metaProperty.type)) {
def collection = initializeCollection obj, propName, metaProperty.type
def idx = Integer.parseInt(indexedPropertyReferenceDescriptor.index)
if('null' == idValue) {
if(idx < collection.size()) {
def element = collection[idx]
if(element != null) {
collection.remove element
}
}
} else {
def instance = getPersistentInstance(referencedType, idValue)
addElementToCollectionAt obj, propName, collection, idx, instance
if (instance != null) {
if (val instanceof Map) {
bind instance, new SimpleMapDataBindingSource(val), listener
} else if (val instanceof DataBindingSource) {
bind instance, val, listener
}
}
}
} else if (Map.isAssignableFrom(metaProperty.type)) {
Map map = (Map)obj[propName]
if (idValue == 'null' || idValue == null || idValue == '') {
if (map != null) {
map.remove indexedPropertyReferenceDescriptor.index
}
} else {
map = initializeMap obj, propName
def persistedInstance = getPersistentInstance referencedType, idValue
if (persistedInstance != null) {
if (map.size() < autoGrowCollectionLimit || map.containsKey(indexedPropertyReferenceDescriptor.index)) {
map[indexedPropertyReferenceDescriptor.index] = persistedInstance
if (val instanceof Map) {
bind persistedInstance, new SimpleMapDataBindingSource(val), listener
} else if (val instanceof DataBindingSource) {
bind persistedInstance, val, listener
}
}
} else {
map.remove indexedPropertyReferenceDescriptor.index
}
}
}
}
}
}
if (needsBinding) {
super.processIndexedProperty obj, metaProperty, indexedPropertyReferenceDescriptor, val, source, listener, errors
}
}