jodd-core/src/main/java/jodd/template/StringTemplateParser.java
public String parse(String template, final Function<String, String> macroResolver) {
		StringBuilder result = new StringBuilder(template.length());

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

		// strict flag means that start and end tag are not necessary
		boolean strict;

		if (macroPrefix == null) {
			// when prefix is not specified, make it equals to macro start
			// so we can use the same code
			macroPrefix = macroStart;

			strict = true;
		}
		else {
			strict = false;
		}

		final int prefixLen = macroPrefix.length();
		final int startLen = macroStart.length();
		final int endLen = macroEnd.length();

		while (i < len) {
			int ndx = template.indexOf(macroPrefix, 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(macroPrefix);

				i = ndx + prefixLen;

				continue;
			}

			// macro started, detect strict format

			boolean detectedStrictFormat = strict;

			if (!detectedStrictFormat) {
				if (StringUtil.isSubstringAt(template, macroStart, ndx)) {
					detectedStrictFormat = true;
				}
			}

			int ndx1;
			int ndx2;

			if (!detectedStrictFormat) {
				// not strict format: $foo

				ndx += prefixLen;
				ndx1 = ndx;
				ndx2 = ndx;

				while ((ndx2 < len) && CharUtil.isPropertyNameChar(template.charAt(ndx2))) {
					ndx2++;
				}

				if (ndx2 == len) {
					ndx2--;
				}

				while ((ndx2 > ndx) && !CharUtil.isAlphaOrDigit(template.charAt(ndx2))) {
					ndx2--;
				}

				ndx2++;

				if (ndx2 == ndx1 + 1) {
					// no value, hence no macro
					result.append(macroPrefix);

					i = ndx1;
					continue;
				}
			}
			else {
				// strict format: ${foo}

				// find macros end
				ndx += startLen;
				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
				ndx1 = ndx;
				while (ndx1 < ndx2) {
					int n = StringUtil.indexOf(template, macroStart, ndx1, ndx2);
					if (n == -1) {
						break;
					}
					ndx1 = n + startLen;
				}
			}

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

			// find value and append

			Object value;
			if (missingKeyReplacement != null || !replaceMissingKey) {
				try {
					value = macroResolver.apply(name);
				} catch (Exception ignore) {
					value = null;
				}

				if (value == null) {
					if (replaceMissingKey) {
						value = missingKeyReplacement;
					} else {
						if (detectedStrictFormat) {
							value = template.substring(ndx1 - startLen, ndx2 + endLen);
						} else {
							value = template.substring(ndx1 - 1, ndx2);
						}
					}
				}
			} else {
				value = macroResolver.apply(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;
				if (detectedStrictFormat) {
					i += 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, final Function<String, String> macroResolver) {
		StringBuilder result = new StringBuilder(template.length());

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

		// strict flag means that start and end tag are not necessary
		boolean strict;

		if (macroPrefix == null) {
			// when prefix is not specified, make it equals to macro start
			// so we can use the same code
			macroPrefix = macroStart;

			strict = true;
		}
		else {
			strict = false;
		}

		final int prefixLen = macroPrefix.length();
		final int startLen = macroStart.length();
		final int endLen = macroEnd.length();

		while (i < len) {
			int ndx = template.indexOf(macroPrefix, 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(macroPrefix);

				i = ndx + prefixLen;

				continue;
			}

			// macro started, detect strict format

			boolean detectedStrictFormat = strict;

			if (!detectedStrictFormat) {
				if (StringUtil.isSubstringAt(template, macroStart, ndx)) {
					detectedStrictFormat = true;
				}
			}

			int ndx1;
			int ndx2;

			if (!detectedStrictFormat) {
				// not strict format: $foo

				ndx += prefixLen;
				ndx1 = ndx;
				ndx2 = ndx;

				while ((ndx2 < len) && CharUtil.isPropertyNameChar(template.charAt(ndx2))) {
					ndx2++;
				}

				if (ndx2 == len) {
					ndx2--;
				}

				while ((ndx2 > ndx) && !CharUtil.isAlphaOrDigit(template.charAt(ndx2))) {
					ndx2--;
				}

				ndx2++;

				if (ndx2 == ndx1 + 1) {
					// no value, hence no macro
					result.append(macroPrefix);

					i = ndx1;
					continue;
				}
			}
			else {
				// strict format: ${foo}

				// find macros end
				ndx += startLen;
				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
				ndx1 = ndx;
				while (ndx1 < ndx2) {
					int n = StringUtil.indexOf(template, macroStart, ndx1, ndx2);
					if (n == -1) {
						break;
					}
					ndx1 = n + startLen;
				}
			}

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

			// find value and append

			Object value;
			if (missingKeyReplacement != null || !replaceMissingKey) {
				try {
					value = macroResolver.apply(name);
				} catch (Exception ignore) {
					value = null;
				}

				if (value == null) {
					if (replaceMissingKey) {
						value = missingKeyReplacement;
					} else {
						if (detectedStrictFormat) {
							value = template.substring(ndx1 - startLen, ndx2 + endLen);
						} else {
							value = template.substring(ndx1 - 1, ndx2);
						}
					}
				}
			} else {
				value = macroResolver.apply(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;
				if (detectedStrictFormat) {
					i += 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 , final Function < String , String > macroResolver ) { StringBuilder result = new StringBuilder ( template . length ( ) ) ; int i = 0 ; int len = template . length ( ) ; // strict flag means that start and end tag are not necessary boolean strict ; if ( macroPrefix == null ) { // when prefix is not specified, make it equals to macro start // so we can use the same code macroPrefix = macroStart ; strict = true ; } else { strict = false ; } final int prefixLen = macroPrefix . length ( ) ; final int startLen = macroStart . length ( ) ; final int endLen = macroEnd . length ( ) ; while ( i < len ) { int ndx = template . indexOf ( macroPrefix , 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 ( macroPrefix ) ; i = ndx + prefixLen ; continue ; } // macro started, detect strict format boolean detectedStrictFormat = strict ; if ( ! detectedStrictFormat ) { if ( StringUtil . isSubstringAt ( template , macroStart , ndx ) ) { detectedStrictFormat = true ; } } int ndx1 ; int ndx2 ; if ( ! detectedStrictFormat ) { // not strict format: $foo ndx += prefixLen ; ndx1 = ndx ; ndx2 = ndx ; while ( ( ndx2 < len ) && CharUtil . isPropertyNameChar ( template . charAt ( ndx2 ) ) ) { ndx2 ++ ; } if ( ndx2 == len ) { ndx2 -- ; } while ( ( ndx2 > ndx ) && ! CharUtil . isAlphaOrDigit ( template . charAt ( ndx2 ) ) ) { ndx2 -- ; } ndx2 ++ ; if ( ndx2 == ndx1 + 1 ) { // no value, hence no macro result . append ( macroPrefix ) ; i = ndx1 ; continue ; } } else { // strict format: ${foo} // find macros end ndx += startLen ; 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 ndx1 = ndx ; while ( ndx1 < ndx2 ) { int n = StringUtil . indexOf ( template , macroStart , ndx1 , ndx2 ) ; if ( n == - 1 ) { break ; } ndx1 = n + startLen ; } } final String name = template . substring ( ndx1 , ndx2 ) ; // find value and append Object value ; if ( missingKeyReplacement != null || ! replaceMissingKey ) { try { value = macroResolver . apply ( name ) ; } catch ( Exception ignore ) { value = null ; } if ( value == null ) { if ( replaceMissingKey ) { value = missingKeyReplacement ; } else { if ( detectedStrictFormat ) { value = template . substring ( ndx1 - startLen , ndx2 + endLen ) ; } else { value = template . substring ( ndx1 - 1 , ndx2 ) ; } } } } else { value = macroResolver . apply ( 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 ; if ( detectedStrictFormat ) { i += 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 .