protected void applyProperty()

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