goja-core/src/main/java/goja/core/kits/StrTemplateKit.java
public String parse(String template, MacroResolver macroResolver) {
        StringBuilder result = new StringBuilder(template.length());

        int i = 0;
        int len = template.length();

        int startLen = macroStart.length();
        int endLen = macroEnd.length();

        while (i < len) {
            int ndx = template.indexOf(macroStart, i);
            if (ndx == -1) {
                result.append(i == 0 ? template : template.substring(i));
                break;
            }

            // check escaped
            int j = ndx - 1;
            boolean escape = false;
            int count = 0;

            while ((j >= 0) && (template.charAt(j) == escapeChar)) {
                escape = !escape;
                if (escape) {
                    count++;
                }
                j--;
            }
            if (resolveEscapes) {
                result.append(template.substring(i, ndx - count));
            } else {
                result.append(template.substring(i, ndx));
            }
            if (escape) {
                result.append(macroStart);
                i = ndx + startLen;
                continue;
            }

            // find macros end
            ndx += startLen;
            int ndx2 = template.indexOf(macroEnd, ndx);
            if (ndx2 == -1) {
                throw new IllegalArgumentException(
                        "Invalid template, unclosed macro at: " + (ndx - startLen));
            }

            // detect inner macros, there is no escaping
            int ndx1 = ndx;
            while (ndx1 < ndx2) {
                int n = indexOf(template, macroStart, ndx1, ndx2);
                if (n == -1) {
                    break;
                }
                ndx1 = n + startLen;
            }

            String name = template.substring(ndx1, ndx2);

            // find value and append
            Object value;
            if (missingKeyReplacement != null || !replaceMissingKey) {
                try {
                    value = macroResolver.resolve(name);
                } catch (Exception ignore) {
                    value = null;
                }

                if (value == null) {
                    if (replaceMissingKey) {
                        value = missingKeyReplacement;
                    } else {
                        value = template.substring(ndx1 - startLen, ndx2 + 1);
                    }
                }
            } else {
                value = macroResolver.resolve(name);
                if (value == null) {
                    value = StringPool.EMPTY;
                }
            }

            if (ndx == ndx1) {
                String stringValue = value.toString();
                if (parseValues) {
                    if (stringValue.contains(macroStart)) {
                        stringValue = parse(stringValue, macroResolver);
                    }
                }
                result.append(stringValue);
                i = ndx2 + endLen;
            } else {
                // inner macro
                template = template.substring(0, ndx1 - startLen) + value.toString() + template.substring(
                        ndx2 + endLen);
                len = template.length();
                i = ndx - startLen;
            }
        }
        return result.toString();
    }
public String parse(String template, MacroResolver macroResolver) {
        StringBuilder result = new StringBuilder(template.length());

        int i = 0;
        int len = template.length();

        int startLen = macroStart.length();
        int endLen = macroEnd.length();

        while (i < len) {
            int ndx = template.indexOf(macroStart, i);
            if (ndx == -1) {
                result.append(i == 0 ? template : template.substring(i));
                break;
            }

            // check escaped
            int j = ndx - 1;
            boolean escape = false;
            int count = 0;

            while ((j >= 0) && (template.charAt(j) == escapeChar)) {
                escape = !escape;
                if (escape) {
                    count++;
                }
                j--;
            }
            if (resolveEscapes) {
                result.append(template.substring(i, ndx - count));
            } else {
                result.append(template.substring(i, ndx));
            }
            if (escape) {
                result.append(macroStart);
                i = ndx + startLen;
                continue;
            }

            // find macros end
            ndx += startLen;
            int ndx2 = template.indexOf(macroEnd, ndx);
            if (ndx2 == -1) {
                throw new IllegalArgumentException(
                        "Invalid template, unclosed macro at: " + (ndx - startLen));
            }

            // detect inner macros, there is no escaping
            int ndx1 = ndx;
            while (ndx1 < ndx2) {
                int n = indexOf(template, macroStart, ndx1, ndx2);
                if (n == -1) {
                    break;
                }
                ndx1 = n + startLen;
            }

            String name = template.substring(ndx1, ndx2);

            // find value and append
            Object value;
            if (missingKeyReplacement != null || !replaceMissingKey) {
                try {
                    value = macroResolver.resolve(name);
                } catch (Exception ignore) {
                    value = null;
                }

                if (value == null) {
                    if (replaceMissingKey) {
                        value = missingKeyReplacement;
                    } else {
                        value = template.substring(ndx1 - startLen, ndx2 + 1);
                    }
                }
            } else {
                value = macroResolver.resolve(name);
                if (value == null) {
                    value = StringPool.EMPTY;
                }
            }

            if (ndx == ndx1) {
                String stringValue = value.toString();
                if (parseValues) {
                    if (stringValue.contains(macroStart)) {
                        stringValue = parse(stringValue, macroResolver);
                    }
                }
                result.append(stringValue);
                i = ndx2 + endLen;
            } else {
                // inner macro
                template = template.substring(0, ndx1 - startLen) + value.toString() + template.substring(
                        ndx2 + endLen);
                len = template.length();
                i = ndx - startLen;
            }
        }
        return result.toString();
    }
public String parse ( String template , MacroResolver macroResolver ) { StringBuilder result = new StringBuilder ( template . length ( ) ) ; int i = 0 ; int len = template . length ( ) ; int startLen = macroStart . length ( ) ; int endLen = macroEnd . length ( ) ; while ( i < len ) { int ndx = template . indexOf ( macroStart , i ) ; if ( ndx == - 1 ) { result . append ( i == 0 ? template : template . substring ( i ) ) ; break ; } // check escaped int j = ndx - 1 ; boolean escape = false ; int count = 0 ; while ( ( j >= 0 ) && ( template . charAt ( j ) == escapeChar ) ) { escape = ! escape ; if ( escape ) { count ++ ; } j -- ; } if ( resolveEscapes ) { result . append ( template . substring ( i , ndx - count ) ) ; } else { result . append ( template . substring ( i , ndx ) ) ; } if ( escape ) { result . append ( macroStart ) ; i = ndx + startLen ; continue ; } // find macros end ndx += startLen ; int ndx2 = template . indexOf ( macroEnd , ndx ) ; if ( ndx2 == - 1 ) { throw new IllegalArgumentException ( "Invalid template, unclosed macro at: " + ( ndx - startLen ) ) ; } // detect inner macros, there is no escaping int ndx1 = ndx ; while ( ndx1 < ndx2 ) { int n = indexOf ( template , macroStart , ndx1 , ndx2 ) ; if ( n == - 1 ) { break ; } ndx1 = n + startLen ; } String name = template . substring ( ndx1 , ndx2 ) ; // find value and append Object value ; if ( missingKeyReplacement != null || ! replaceMissingKey ) { try { value = macroResolver . resolve ( name ) ; } catch ( Exception ignore ) { value = null ; } if ( value == null ) { if ( replaceMissingKey ) { value = missingKeyReplacement ; } else { value = template . substring ( ndx1 - startLen , ndx2 + 1 ) ; } } } else { value = macroResolver . resolve ( name ) ; if ( value == null ) { value = StringPool . EMPTY ; } } if ( ndx == ndx1 ) { String stringValue = value . toString ( ) ; if ( parseValues ) { if ( stringValue . contains ( macroStart ) ) { stringValue = parse ( stringValue , macroResolver ) ; } } result . append ( stringValue ) ; i = ndx2 + endLen ; } else { // inner macro template = template . substring ( 0 , ndx1 - startLen ) + value . toString ( ) + template . substring ( ndx2 + endLen ) ; len = template . length ( ) ; i = ndx - startLen ; } } return result . toString ( ) ; }
Parses string template and replaces macros with resolved values.
Parses string template and replaces macros with resolved values .