protected processIndexedProperty()

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
        }
    }