in config/ogdl/src/main/java/org/apache/shiro/config/ogdl/ReflectionBuilder.java [636:702]
protected void applyProperty(Object object, String propertyPath, Object value) {
int mapBegin = propertyPath.indexOf(MAP_PROPERTY_BEGIN_TOKEN);
int mapEnd = -1;
String mapPropertyPath = null;
String keyString = null;
String remaining = null;
if (mapBegin >= 0) {
//a map is being referenced in the overall property path. Find just the map's path:
mapPropertyPath = propertyPath.substring(0, mapBegin);
//find the end of the map reference:
mapEnd = propertyPath.indexOf(MAP_PROPERTY_END_TOKEN, mapBegin);
//find the token in between the [ and the ] (the map/array key or index):
keyString = propertyPath.substring(mapBegin + 1, mapEnd);
//find out if there is more path reference to follow. If not, we're at a terminal of the OGNL expression
if (propertyPath.length() > (mapEnd + 1)) {
remaining = propertyPath.substring(mapEnd + 1);
if (remaining.startsWith(".")) {
remaining = StringUtils.clean(remaining.substring(1));
}
}
}
if (remaining == null) {
//we've terminated the OGNL expression. Check to see if we're assigning a property or a map entry:
if (keyString == null) {
//not a map or array value assignment - assign the property directly:
setProperty(object, propertyPath, value);
} else {
//we're assigning a map or array entry. Check to see which we should call:
if (isTypedProperty(object, mapPropertyPath, Map.class)) {
@SuppressWarnings("unchecked")
var map = (Map<Object, Object>) getProperty(object, mapPropertyPath);
Object mapKey = resolveValue(keyString);
//noinspection unchecked
map.put(mapKey, value);
} else {
//must be an array property. Convert the key string to an index:
int index = Integer.valueOf(keyString);
setIndexedProperty(object, mapPropertyPath, index, value);
}
}
} else {
//property is being referenced as part of a nested path. Find the referenced map/array entry and
//recursively call this method with the remaining property path
Object referencedValue = null;
if (isTypedProperty(object, mapPropertyPath, Map.class)) {
Map map = (Map) getProperty(object, mapPropertyPath);
Object mapKey = resolveValue(keyString);
referencedValue = map.get(mapKey);
} else {
//must be an array property:
int index = Integer.valueOf(keyString);
referencedValue = getIndexedProperty(object, mapPropertyPath, index);
}
if (referencedValue == null) {
throw new ConfigurationException("Referenced map/array value '" + mapPropertyPath + "["
+ keyString + "]' does not exist.");
}
applyProperty(referencedValue, remaining, value);
}
}