public static Object replace()

in src/main/java/org/apache/sling/resourceresolver/impl/mapping/Interpolator.java [61:160]


    public static Object replace(final String value, final Provider provider) {
        String result = value;
        int start = -1;
        while (start < result.length()) {
            start = result.indexOf(START, start);
            if (start == -1) {
                // no placeholder found -> end
                LOGGER.trace("No Start ({}) found in: '{}'", START, result);
                start = result.length();
                continue;
            }

            boolean replace = true;
            if (start > 0 && result.charAt(start - 1) == ESCAPE) {
                if (start == 1 || result.charAt(start - 2) != ESCAPE) {
                    LOGGER.trace("Escape ({}) found in: '{}'", ESCAPE, result);
                    replace = false;
                }
            }

            if (!replace) {
                // placeholder is escaped -> remove placeholder and continue
                result = result.substring(0, start - 1).concat(result.substring(start));
                start = start + START.length();
                continue;
            }

            int count = 1;
            int index = start + START.length();
            while (index < result.length() && count > 0) {
                if (result.charAt(index) == START.charAt(1) && result.charAt(index - 1) == START.charAt(0)) {
                    count++;
                } else if (result.charAt(index) == END) {
                    count--;
                }
                index++;
            }

            if (count > 0) {
                LOGGER.trace("No End ({}) found in: '{}' (count: '{}')", END, result, count);
                // no matching end found -> end
                start = result.length();
                continue;
            }

            final String key = result.substring(start + START.length(), index - 1);
            final int sep = key.indexOf(NAME_SEPARATOR);
            if (sep == -1) {
                // invalid key
                start = index;
                continue;
            }

            final String type = key.substring(0, sep);
            final String postfix = key.substring(sep + 1);
            LOGGER.trace("Type: '{}', postfix: '{}'", type, postfix);

            final int dirPos = postfix.indexOf(DIRECTIVES_SEPARATOR);
            final Map<String, String> directives;
            final String name;
            if (dirPos == -1) {
                name = postfix;
                directives = Collections.emptyMap();
                LOGGER.trace("No Directives");
            } else {
                name = postfix.substring(0, dirPos);
                directives = new HashMap<>();

                for (String dir : postfix.substring(dirPos + 1).split(DIRECTIVES_SEPARATOR + "")) {
                    String[] kv = dir.split(DIRECTIVES_VALUE_SEPARATOR + "");
                    if (kv.length == 2) {
                        directives.put(kv[0], kv[1]);
                    }
                }
                LOGGER.trace("Defaults: '{}'", directives);
            }

            // recursive replacement
            final Object newName = replace(name, provider);

            Object replacement = provider.provide(type, newName.toString(), directives);
            if (replacement == null) {
                // no replacement found -> leave as is and continue
                LOGGER.trace("No Replacements found for: '{}'", newName);
                start = index;
            } else {
                if (!(replacement instanceof String)) {
                    if (start == 0 && index == result.length()) {
                        return replacement;
                    }
                }
                // replace and continue with replacement
                result = result.substring(0, start)
                        .concat(replacement.toString())
                        .concat(result.substring(index));
                LOGGER.trace("Replacements found for: '{}': '{}'", newName, result);
            }
        }
        return result;
    }