package com.taobao.tddl.rule.impl; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.taobao.tddl.rule.Rule; /** * 通过表达式来表达规则的基类 * * @author linxuan * @param <T> */ public abstract class ExpressionRule<T> implements Rule<T> { private static final Pattern DOLLER_PATTERN; static { // 提供一个可配置的机会,但是在绝大多数默认的情况下,不想影响接口层次和代码结构 String regex = System.getProperty("com.taobao.tddl.rule.columnParamRegex", "#.*?#"); DOLLER_PATTERN = Pattern.compile(regex); } /** * 当前规则需要用到的参数 */ protected final Map<String/* 大写列名 */, RuleColumn> parameters; protected final Set<RuleColumn> parameterSet; // 规则列 /** * 当前规则需要用到的表达式 */ protected String expression; protected final String originExpression; // 原始的表达式 public ExpressionRule(String expression){ this.originExpression = expression; this.expression = expression; this.parameters = Collections.unmodifiableMap(parse()); this.parameterSet = new HashSet<RuleColumn>(parameters.size()); this.parameterSet.addAll(parameters.values()); } private Map<String, RuleColumn> parse() { Map<String, RuleColumn> parameters = new HashMap<String, RuleColumn>(); Matcher matcher = DOLLER_PATTERN.matcher(expression); int start = 0; StringBuffer sb = new StringBuffer(); while (matcher.find(start)) { String realParam = matcher.group(); realParam = realParam.substring(1, realParam.length() - 1); sb.append(expression.substring(start, matcher.start())); sb.append(parseParam(realParam, parameters)); start = matcher.end(); } sb.append(expression.substring(start)); expression = sb.toString(); return parameters; } /** * 子类将paramInDoller解析为RuleColumn,加入到parameters中,并返回替换后的字串 * * @param paramInDoller * @param parameters * @return 替换后的字串 */ abstract protected String parseParam(String paramInDoller, Map<String, RuleColumn> parameters); public Map<String, RuleColumn> getRuleColumns() { return parameters; } public Set<RuleColumn> getRuleColumnSet() { return parameterSet; } /** * originExpression相同则相同,eclipse生成 */ public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ExpressionRule other = (ExpressionRule) obj; if (originExpression == null) { if (other.originExpression != null) return false; } else if (!originExpression.equals(other.originExpression)) return false; return true; } /** * eclipse生成 */ public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((originExpression == null) ? 0 : originExpression.hashCode()); return result; } }