public Writer resolveTo()

in juneau-core/juneau-marshall/src/main/java/org/apache/juneau/svl/VarResolverSession.java [254:362]


	public Writer resolveTo(String s, Writer out) throws IOException {

		int S1 = 1;	   // Not in variable, looking for $
		int S2 = 2;    // Found $, Looking for {
		int S3 = 3;    // Found {, Looking for }

		int state = S1;
		boolean isInEscape = false;
		boolean hasInternalVar = false;
		boolean hasInnerEscapes = false;
		String varType = null;
		String varVal = null;
		int x = 0, x2 = 0;
		int depth = 0;
		int length = s.length();
		for (int i = 0; i < length; i++) {
			char c = s.charAt(i);
			if (state == S1) {
				if (isInEscape) {
					if (c == '\\' || c == '$') {
						out.append(c);
					} else {
						out.append('\\').append(c);
					}
					isInEscape = false;
				} else if (c == '\\') {
					isInEscape = true;
				} else if (c == '$') {
					x = i;
					x2 = i;
					state = S2;
				} else {
					out.append(c);
				}
			} else if (state == S2) {
				if (isInEscape) {
					isInEscape = false;
				} else if (c == '\\') {
					hasInnerEscapes = true;
					isInEscape = true;
				} else if (c == '{') {
					varType = s.substring(x+1, i);
					x = i;
					state = S3;
				} else if (c < 'A' || c > 'z' || (c > 'Z' && c < 'a')) {  // False trigger "$X "
					if (hasInnerEscapes)
						out.append(unEscapeChars(s.substring(x, i+1), AS1));
					else
						out.append(s, x, i+1);
					x = i + 1;
					state = S1;
					hasInnerEscapes = false;
				}
			} else if (state == S3) {
				if (isInEscape) {
					isInEscape = false;
				} else if (c == '\\') {
					isInEscape = true;
					hasInnerEscapes = true;
				} else if (c == '{') {
					depth++;
					hasInternalVar = true;
				} else if (c == '}') {
					if (depth > 0) {
						depth--;
					} else {
						varVal = s.substring(x+1, i);
						Var r = getVar(varType);
						if (r == null) {
							if (hasInnerEscapes)
								out.append(unEscapeChars(s.substring(x2, i+1), AS2));
							else
								out.append(s, x2, i+1);
							x = i+1;
						} else {
							varVal = (hasInternalVar && r.allowNested() ? resolve(varVal) : varVal);
							try {
								if (r.streamed)
									r.resolveTo(this, out, varVal);
								else {
									String replacement = r.doResolve(this, varVal);
									if (replacement == null)
										replacement = "";
									// If the replacement also contains variables, replace them now.
									if (replacement.indexOf('$') != -1 && r.allowRecurse())
										replacement = resolve(replacement);
									out.append(replacement);
								}
							} catch (VarResolverException e) {
								throw e;
							} catch (Exception e) {
								throw new VarResolverException(e, "Problem occurred resolving variable ''{0}'' in string ''{1}''", varType, s);
							}
							x = i+1;
						}
						state = 1;
						hasInnerEscapes = false;
					}
				}
			}
		}
		if (isInEscape)
			out.append('\\');
		else if (state == S2)
			out.append('$').append(unEscapeChars(s.substring(x+1), AS1));
		else if (state == S3)
			out.append('$').append(varType).append('{').append(unEscapeChars(s.substring(x+1), AS2));
		return out;
	}