public String parse(String template,MacroResolver macroResolver){
  StringBuilder result=new StringBuilder(template.length());
  int i=0;
  int len=template.length();
  boolean strict;
  if (macroPrefix == null) {
    macroPrefix=macroStart;
    strict=true;
  }
 else {
    strict=false;
  }
  int prefixLen=macroPrefix.length();
  int startLen=macroStart.length();
  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;
    }
    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 == true) {
      result.append(macroPrefix);
      i=ndx + prefixLen;
      continue;
    }
    boolean strictFormat=strict;
    if (strictFormat == false) {
      if (StringUtil.isSubstringAt(template,macroStart,ndx)) {
        strictFormat=true;
      }
    }
    int ndx1;
    int ndx2;
    if (!strictFormat) {
      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) {
        result.append(macroPrefix);
        i=ndx1;
        continue;
      }
    }
 else {
      ndx+=startLen;
      ndx2=template.indexOf(macroEnd,ndx);
      if (ndx2 == -1) {
        throw new IllegalArgumentException("Invalid template, unclosed macro at: " + (ndx - startLen));
      }
      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);
    Object value;
    if (missingKeyReplacement != null || replaceMissingKey == false) {
      try {
        value=macroResolver.resolve(name);
      }
 catch (      Exception ignore) {
        value=null;
      }
      if (value == null) {
        if (replaceMissingKey == true) {
          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 == true) {
        if (stringValue.contains(macroStart)) {
          stringValue=parse(stringValue,macroResolver);
        }
      }
      result.append(stringValue);
      i=ndx2;
      if (strictFormat) {
        i+=endLen;
      }
    }
 else {
      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 ( ) ; boolean strict ; if ( macroPrefix == null ) { macroPrefix = macroStart ; strict = true ; } else { strict = false ; } int prefixLen = macroPrefix . length ( ) ; int startLen = macroStart . length ( ) ; 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 ; } 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 == true ) { result . append ( macroPrefix ) ; i = ndx + prefixLen ; continue ; } boolean strictFormat = strict ; if ( strictFormat == false ) { if ( StringUtil . isSubstringAt ( template , macroStart , ndx ) ) { strictFormat = true ; } } int ndx1 ; int ndx2 ; if ( ! strictFormat ) { 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 ) { result . append ( macroPrefix ) ; i = ndx1 ; continue ; } } else { ndx += startLen ; ndx2 = template . indexOf ( macroEnd , ndx ) ; if ( ndx2 == - 1 ) { throw new IllegalArgumentException ( "Invalid template, unclosed macro at: " + ( ndx - startLen ) ) ; } 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 ) ; Object value ; if ( missingKeyReplacement != null || replaceMissingKey == false ) { try { value = macroResolver . resolve ( name ) ; } catch ( Exception ignore ) { value = null ; } if ( value == null ) { if ( replaceMissingKey == true ) { 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 == true ) { if ( stringValue . contains ( macroStart ) ) { stringValue = parse ( stringValue , macroResolver ) ; } } result . append ( stringValue ) ; i = ndx2 ; if ( strictFormat ) { i += endLen ; } } else { 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 .
