Skip to content

Commit 2d47949

Browse files
GRAILS-9082 - improve Map binding
1 parent eeb67e4 commit 2d47949

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/binding/DataBindingTests.groovy

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,26 @@ class Person {
6666
static constraints = {
6767
birthDate nullable: true
6868
}
69+
}
70+
@Entity
71+
class Pet {
72+
String name
73+
Map detailMap
74+
Person owner
6975
}
7076
''')
7177
}
78+
79+
void testBindingMapValue() {
80+
def petClass = ga.getDomainClass('databindingtests.Pet')
81+
def pet = petClass.newInstance()
82+
pet.properties = [name: 'lemur', detailMap: [first: 'one', second: 'two'], owner: [name: 'Jeff'], foo: 'bar', bar: [a: 'a', b: 'b']]
83+
84+
assert pet.name == 'lemur'
85+
assert pet.detailMap.first == 'one'
86+
assert pet.detailMap.second == 'two'
87+
assert !pet.hasErrors()
88+
}
7289

7390
void testBindingNullToANullableDateThatAlreadyHasAValue() {
7491
def c = ga.getControllerClass('databindingtests.TestController').newInstance()

grails-web/src/main/groovy/org/codehaus/groovy/grails/web/binding/GrailsDataBinder.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import groovy.lang.MissingMethodException;
2727
import groovy.lang.MissingPropertyException;
2828

29+
import java.beans.PropertyDescriptor;
2930
import java.beans.PropertyEditor;
3031
import java.math.BigDecimal;
3132
import java.math.BigInteger;
@@ -71,6 +72,7 @@
7172
import org.codehaus.groovy.runtime.InvokerHelper;
7273
import org.codehaus.groovy.runtime.MetaClassHelper;
7374
import org.codehaus.groovy.runtime.metaclass.ThreadManagedMetaBeanProperty;
75+
import org.springframework.beans.BeanUtils;
7476
import org.springframework.beans.BeanWrapper;
7577
import org.springframework.beans.BeanWrapperImpl;
7678
import org.springframework.beans.ConfigurablePropertyAccessor;
@@ -512,14 +514,29 @@ private void filterNestedParameterMaps(MutablePropertyValues mpvs) {
512514
if (JSONObject.NULL.getClass().isInstance(value)) {
513515
mpvs.removePropertyValue(pv);
514516
}
515-
if (isNotCandidateForBinding(value)) {
517+
if (!isCandidateForBinding(pv)) {
516518
mpvs.removePropertyValue(pv);
517519
}
518520
}
519521
}
520522

521-
private boolean isNotCandidateForBinding(Object value) {
522-
return value instanceof Map;
523+
private boolean isCandidateForBinding(PropertyValue pv) {
524+
boolean isCandidate = true;
525+
final Object value = pv.getValue();
526+
if(value instanceof GrailsParameterMap || value instanceof JSONObject) {
527+
isCandidate = false;
528+
} else if(value instanceof Map) {
529+
isCandidate = false;
530+
final String propertyName = pv.getName();
531+
final PropertyDescriptor property = BeanUtils.getPropertyDescriptor(getTarget().getClass(), propertyName);
532+
if(property != null) {
533+
final Class<?> propertyType = property.getPropertyType();
534+
if(propertyType.isAssignableFrom(value.getClass())) {
535+
isCandidate = true;
536+
}
537+
}
538+
}
539+
return isCandidate;
523540
}
524541

525542
private PropertyValues filterPropertyValues(PropertyValues propertyValues, String prefix) {

0 commit comments

Comments
 (0)