Browse Source

Correctly parse property name in path "map[key[foo]]"

pull/22596/head
Matthias Kurz 6 years ago committed by Juergen Hoeller
parent
commit
6899624155
  1. 25
      spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java
  2. 7
      spring-beans/src/test/java/org/springframework/beans/AbstractPropertyAccessorTests.java
  3. 2
      spring-beans/src/test/java/org/springframework/tests/sample/beans/IndexedTestBean.java

25
spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java

@ -933,7 +933,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA @@ -933,7 +933,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
int keyStart = propertyName.indexOf(PROPERTY_KEY_PREFIX, searchIndex);
searchIndex = -1;
if (keyStart != -1) {
int keyEnd = propertyName.indexOf(PROPERTY_KEY_SUFFIX, keyStart + PROPERTY_KEY_PREFIX.length());
int keyEnd = getPropertyNameKeyEnd(propertyName, keyStart + PROPERTY_KEY_PREFIX.length());
if (keyEnd != -1) {
if (actualName == null) {
actualName = propertyName.substring(0, keyStart);
@ -958,6 +958,29 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA @@ -958,6 +958,29 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
return tokens;
}
private static int getPropertyNameKeyEnd(String propertyName, int startIndex) {
int unclosedPrefixes = 0;
int length = propertyName.length();
for (int i = startIndex; i < length; i++) {
switch (propertyName.charAt(i)) {
case PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR:
// The property name contains opening prefix(es)
unclosedPrefixes++;
break;
case PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR:
if (unclosedPrefixes == 0) {
// No unclosed prefix(es) in the property name (left), this is the suffix we are looking for
return i;
} else {
// This suffix does not close the initial prefix, but one that occurred within the property name
unclosedPrefixes--;
}
break;
}
}
return -1;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getName());

7
spring-beans/src/test/java/org/springframework/beans/AbstractPropertyAccessorTests.java

@ -1599,6 +1599,7 @@ public abstract class AbstractPropertyAccessorTests { @@ -1599,6 +1599,7 @@ public abstract class AbstractPropertyAccessorTests {
TestBean tb7 = ((TestBean) target.getSet().toArray()[1]);
TestBean tb4 = ((TestBean) target.getMap().get("key1"));
TestBean tb5 = ((TestBean) target.getMap().get("key.3"));
TestBean tb8 = ((TestBean) target.getMap().get("key5[foo]"));
assertEquals("name0", tb0.getName());
assertEquals("name1", tb1.getName());
assertEquals("name2", tb2.getName());
@ -1607,6 +1608,7 @@ public abstract class AbstractPropertyAccessorTests { @@ -1607,6 +1608,7 @@ public abstract class AbstractPropertyAccessorTests {
assertEquals("name7", tb7.getName());
assertEquals("name4", tb4.getName());
assertEquals("name5", tb5.getName());
assertEquals("name8", tb8.getName());
assertEquals("name0", accessor.getPropertyValue("array[0].name"));
assertEquals("name1", accessor.getPropertyValue("array[1].name"));
assertEquals("name2", accessor.getPropertyValue("list[0].name"));
@ -1619,6 +1621,9 @@ public abstract class AbstractPropertyAccessorTests { @@ -1619,6 +1621,9 @@ public abstract class AbstractPropertyAccessorTests {
assertEquals("name5", accessor.getPropertyValue("map[\"key.3\"].name"));
assertEquals("nameX", accessor.getPropertyValue("map[key4][0].name"));
assertEquals("nameY", accessor.getPropertyValue("map[key4][1].name"));
assertEquals("name8", accessor.getPropertyValue("map[key5[foo]].name"));
assertEquals("name8", accessor.getPropertyValue("map['key5[foo]'].name"));
assertEquals("name8", accessor.getPropertyValue("map[\"key5[foo]\"].name"));
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("array[0].name", "name5");
@ -1631,6 +1636,7 @@ public abstract class AbstractPropertyAccessorTests { @@ -1631,6 +1636,7 @@ public abstract class AbstractPropertyAccessorTests {
pvs.add("map['key.3'].name", "name0");
pvs.add("map[key4][0].name", "nameA");
pvs.add("map[key4][1].name", "nameB");
pvs.add("map[key5[foo]].name", "name10");
accessor.setPropertyValues(pvs);
assertEquals("name5", tb0.getName());
assertEquals("name4", tb1.getName());
@ -1648,6 +1654,7 @@ public abstract class AbstractPropertyAccessorTests { @@ -1648,6 +1654,7 @@ public abstract class AbstractPropertyAccessorTests {
assertEquals("name0", accessor.getPropertyValue("map['key.3'].name"));
assertEquals("nameA", accessor.getPropertyValue("map[key4][0].name"));
assertEquals("nameB", accessor.getPropertyValue("map[key4][1].name"));
assertEquals("name10", accessor.getPropertyValue("map[key5[foo]].name"));
}
@Test

2
spring-beans/src/test/java/org/springframework/tests/sample/beans/IndexedTestBean.java

@ -66,6 +66,7 @@ public class IndexedTestBean { @@ -66,6 +66,7 @@ public class IndexedTestBean {
TestBean tb5 = new TestBean("name5", 0);
TestBean tb6 = new TestBean("name6", 0);
TestBean tb7 = new TestBean("name7", 0);
TestBean tb8 = new TestBean("name8", 0);
TestBean tbX = new TestBean("nameX", 0);
TestBean tbY = new TestBean("nameY", 0);
this.array = new TestBean[] {tb0, tb1};
@ -83,6 +84,7 @@ public class IndexedTestBean { @@ -83,6 +84,7 @@ public class IndexedTestBean {
list.add(tbX);
list.add(tbY);
this.map.put("key4", list);
this.map.put("key5[foo]", tb8);
}

Loading…
Cancel
Save