package org.test4j.module.dbfit.utility; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.test4j.tools.commons.DateHelper; import org.test4j.tools.commons.FieldHelper; import org.test4j.tools.commons.StringHelper; import org.test4j.tools.exception.NoSuchFieldRuntimeException; import fit.Fixture; /** * ugly workaround for fit change in release 200807, which internally converts * NULL into a string value "null"; for db access, we need to make a difference * between NULL and "null" so this class provides a centralised place for the * change; for dbfit fixtures use this class to access symbols rather than * directly fit.fixture */ @SuppressWarnings("rawtypes") public class SymbolUtil { private static final Object dbNull = new Object(); public static void setSymbol(String name, Object value) { validateSymbol(name, true); fit.Fixture.setSymbol(name, value == null ? dbNull : value); } /** * 获取symbol变量值<br> * <br> * o 单值类型 name=symbol, symbol由 [a-zA-Z_-]+ 组成 <br> * o Map类型 name=symbol[key], symbol为Map变量的名称,key为map中的key值<br> * o PoJo类型 name=symbol[property], symbol为pojo的变量名称, property为pojo中的属性值 * * @param name * @return */ public static Object getSymbol(String name) { validateSymbol(name, true); int index = name.indexOf("["); if (index > 0) { String symbolName = StringHelper.trim(name.substring(0, index)); String keyName = StringHelper.trim(name.substring(index + 1, name.length() - 1)); Object symbol = fit.Fixture.getSymbol(symbolName); if (symbol instanceof Map) { Object o = ((Map) symbol).get(keyName); return o; } else { try { Object o = FieldHelper.getFieldValue(symbol, keyName); return o; } catch (NoSuchFieldRuntimeException e) { return null; } } } else { if (system_symbols.containsKey(name)) { return system_symbols.get(name); } else { Object value = fit.Fixture.getSymbol(name); if (value == dbNull) { return null; } else { return value; } } } } /** * 是否存在var这个变量 * * @param var * @return */ public static boolean hasSymbol(String var) { if (Fixture.hasSymbol(var)) { return true; } else if (system_symbols.containsKey(var)) { return true; } else { return false; } } /** * 清空wiki中已设置的变量 */ public static void cleanSymbols() { fit.Fixture.ClearSymbols(); } public static void init() { // do nothing; } /** * 批量设置wiki中用到的变量 * * @param symbols */ public static void setSymbol(Map<String, ?> symbols) { for (Map.Entry<String, ?> symbol : symbols.entrySet()) { setSymbol(symbol.getKey(), symbol.getValue()); } } /** * 系统预设的变量 * * @return */ private final static Map<String, Object> system_symbols = new HashMap<String, Object>() { private static final long serialVersionUID = 2824018273733392296L; { put("date", DateHelper.currDateStr()); put("datetime", DateHelper.currDateTimeStr()); put("space", " "); put("at", "@"); } }; private final static String VARIABLE_REGEX = "[a-zA-Z0-9_\\-]+"; /** * 验证变量名称的有效性 * * @param name 变量名称 * @param isThrowable 如果无效,是否抛出异常 * @return */ private static final boolean validateSymbol(String name, boolean isThrowable) { if (StringHelper.isBlankOrNull(name)) { if (isThrowable) { throw new RuntimeException("the symbol name can't be null."); } else { return false; } } int index = name.indexOf('['); String _name = name; String _key = "nokey"; if (index >= 0 && name.endsWith("]")) { _name = name.substring(0, index); _key = name.substring(index + 1, name.length() - 1); } else if (index >= 0 && name.endsWith("]") == false) { if (isThrowable) { throw new RuntimeException("the symbol's format must be 'variable[key]', but actual value is " + name); } else { return false; } } boolean matchedName = _name.matches(VARIABLE_REGEX); boolean matchedKey = _key.matches(VARIABLE_REGEX); if (isThrowable) { if (matchedName == false || matchedKey == false) { String error = String.format( "illegal symbol format, the symbol's format must be 'variable[key]', but actual value is '%s'", name); throw new RuntimeException(String.format(error, "symbol key", _key)); } else { return true; } } else { return matchedName && matchedKey; } } private final static Pattern symbolPattern = Pattern.compile("@\\{([a-zA-Z0-9_\\-\\[\\]]+)\\}"); /** * 替换text文本中的@{var}变量 * * @param text * @return 替换过后的文本 */ public static final String replacedBySymbols(String text) { ArrayList<String> vars = new ArrayList<String>(); Matcher mc = symbolPattern.matcher(text); while (mc.find()) { String name = mc.group(1); validateSymbol(name, true); vars.add(name); } String replaced = text; for (String var : vars) { Object o = SymbolUtil.getSymbol(var); String value = String.valueOf(o); if (value != null) { replaced = replaced.replace("@{" + var + "}", value); } } return replaced; } }