package org.easyb.util;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.MissingPropertyException;
import org.easyb.BehaviorStep;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* decodes a string passed given a binding. #{} is decoded as a GroovyShell, # is just grabbed as a property.
*
*/
public class TextDecoder {
private static final Pattern VARIABLE_PATTERN = Pattern.compile("((#\\{(.*?)\\})|(#([a-zA-Z_\\$][\\w\\$]*)))");
private final Matcher variableMatcher;
public TextDecoder(String text) {
variableMatcher = VARIABLE_PATTERN.matcher(text);
}
public String replace(Binding binding, BehaviorStep parentStep) {
StringBuffer sb = new StringBuffer(); // variableMatcher needs this instead of Builder
GroovyShell shell = null;
variableMatcher.reset();
while (variableMatcher.find()) {
String variableName = variableMatcher.group(1);
Object prop;
if (variableName.startsWith("#{")) {
if ( shell == null )
shell = new GroovyShell(binding);
prop = evalValue(binding, variableName, shell);
} else
prop = getValue(binding, variableName, parentStep);
String value = ( prop == null ) ? "null" : prop.toString();
variableMatcher.appendReplacement(sb, value);
}
variableMatcher.appendTail(sb);
return sb.toString();
}
private Object evalValue(Binding binding, String script, GroovyShell shell) {
if ( script != null && script.length() > 3 ) {
return shell.evaluate(script.substring(2, script.length() - 1));
} else {
return "<invalid closure>";
}
}
private Object getValue(Binding binding, String variableName, BehaviorStep parentStep) {
if ("#stepName".equalsIgnoreCase(variableName) && parentStep != null ) {
return parentStep.getName();
} else {
try {
return binding.getProperty(variableName.substring(1));
} catch ( MissingPropertyException mpe ) {
return "#{" + variableName.substring(1) + "}";
}
}
}
//
// public static void main(String[] args) {
// Binding b = new Binding();
// b.setProperty( "ikea", new Integer(3));
// System.out.println(new TextDecoder("#{ikea + 7} is #ikea idea").replace(b, null));
// }
}