package jef.entity;
import java.util.Arrays;
import jef.tools.StringUtils;
import jef.tools.string.RegexpUtils;
/**
* 通用模糊策略类
* <p>
* 实现一些较为常用的模糊策略,如替换前几位字符为*、末几位字符为*、将第几位之后、末几位之前的所有字符替换为*等。
* </p>
*
* @Company Asiainfo-Linkage Technologies (China), Inc.
* @author majj3@asiainfo-linkage.com
* @Date 2012-7-12
*/
public class CommonMaskStrategy implements EvalStrategy {
private static final String REGEX_EXPRESSION = "^([\\*,#])?(\\d*)?(\\(-?\\d*)\\,(-?\\d*\\))$";
/**
* 默认替换所有字符为"*"
*/
private static final String DEFAULT_MASK_EXPRESSION = "*(,)";
/**
* 默认替换符为"*"
*/
private static final String DEFAULT_MASK_CHAR = "*";
private String[] parsedExpressions;
/**
* 使用默认替换表达式,即替换所有字符为"*"
*/
public CommonMaskStrategy() {
parsedExpressions = parse(DEFAULT_MASK_EXPRESSION);
}
/**
* @param expression
* 表达式格式为:替换符fixed(leftOffset, rightOffset)<br>
* 替换符仅支持*和#, <br>
* 替换符, fixed, leftOffset, rightOffset 均可以不指定,但位置需保留;<br>
* leftOffset 支持负数,负数表示距离末尾的偏移位置(即替换末几位字符),负数时rightOffset值无效,<br>
* leftOffset 不指定则默认为0; <br>
* rightOffset 支持负数,负数表示距离末尾的偏移位置。<br>
* 举例:<br>
* "(,)", 表示将所有字符替换为*<br>
* "#(,)", 表示将所有字符替换为#<br>
* "#3(,)", 表示将所有字符替换为3个#(即###)<br>
* "#(2,8)", 表示将2-8位字符替换为#<br>
* "#3(2,8)", 表示将2-8位字符替换3个#(即###)<br>
* "#(2,)", 表示将第2个字符之后的所有字符替换为#<br>
* "#(-2,)", 表示将末2位替换为#<br>
* "#(,8)", 表示将1-8位字符替换为#(即替换第9位之前的所有字符)<br>
* "#(,-2)", 表示将末2位之前的所有字符替换为#<br>
* "#(3,-2)", 表示将第3位之后、末2位之前的所有字符替换为#
*/
public CommonMaskStrategy(String expression) {
parsedExpressions = parse(expression);
if (parsedExpressions == null) {
throw new IllegalArgumentException("Illeagal mask expression:" + expression);
}
if (parsedExpressions[0] == null) {
parsedExpressions[0] = DEFAULT_MASK_CHAR;
}
}
private String[] parse(String expression) {
return RegexpUtils.getMatcherResult(expression, REGEX_EXPRESSION, true);
}
public String eval(Object srcValue, Object thisEntityObj) {
if (srcValue == null)
return null;
String value = toStringValue(srcValue);
return mask(value, parseRange(value, parsedExpressions[2], parsedExpressions[3]));
}
private String toStringValue(Object srcValue) {
return srcValue instanceof String ? (String) srcValue : srcValue.toString();
}
private Integer[] parseRange(String value, String leftOffset, String rightOffset) {
// 初始化下界为0, 上界为value.length
Integer[] result = new Integer[] { 0, value.length() };
// 计算起始位置
String boundaryValue = leftOffset.substring(1);
if (StringUtils.isNotBlank(boundaryValue)) {
result[0] = Integer.valueOf(boundaryValue);
// 起始位置为负数时,忽略rightOffset
if (result[0] < 0) {
result[0] = value.length() + result[0];
return result;
}
}
// 计算替换长度
boundaryValue = rightOffset.substring(0, rightOffset.length() - 1);
if (StringUtils.isNotBlank(boundaryValue)) {
int rightIndex = Integer.valueOf(boundaryValue);
result[1] = calculateReplaceLength(value.length(), result[0], rightIndex);
}
return result;
}
private int calculateReplaceLength(int totalLength, int leftIndex, int rightIndex) {
int len = rightIndex;
if (rightIndex < 0) {
len = totalLength - leftIndex + rightIndex;
} else {
len = rightIndex - leftIndex;
}
return len;
}
private String mask(String srcValue, Integer[] ranges) {
if (StringUtils.isBlank(parsedExpressions[1])) {
return StringUtils.replace(srcValue, parsedExpressions[0].charAt(0), ranges[0],
ranges[1]);
} else {
return StringUtils.replace(srcValue, parsedExpressions[0].charAt(0),
Integer.parseInt(parsedExpressions[1]), ranges[0], ranges[1]);
}
}
public static void main(String[] args) {
CommonMaskStrategy maskStategy = new CommonMaskStrategy();
String[] ranges = maskStategy.parse("*(4,)");
System.out.println(ranges[0] + ranges[1] + ranges[2]);
ranges = maskStategy.parse("(4,6)");
System.out.println(ranges[0] + ranges[1] + ranges[2]);
System.out.println("parse(\"*(,)\"): " + Arrays.toString(maskStategy.parse("*(,)")));
System.out.println("parse(\"*(4,6)\"): " + Arrays.toString(maskStategy.parse("*(4,6)")));
System.out.println("parse(\"*(4,6]\"): " + Arrays.toString(maskStategy.parse("*(4,6]")));
System.out.println("parse(\"*(4,]\"): " + Arrays.toString(maskStategy.parse("*(4,]")));
System.out.println("parse(\"*[,6)\"): " + Arrays.toString(maskStategy.parse("*[,6)")));
System.out.println("parse(\"&[,6)\"): " + Arrays.toString(maskStategy.parse("&[,6)")));
System.out.println("parse(\"#3(0,6)\"): " + Arrays.toString(maskStategy.parse("#3(0,6)")));
System.out.println("parse(\"#(0,-6)\"): " + Arrays.toString(maskStategy.parse("#(0,-6)")));
System.out.println("parse(\"#3(0,-6)\"): " +
Arrays.toString(maskStategy.parse("#3(0,-6)")));
System.out.println("parse(\"#(-4,)\"): " + Arrays.toString(maskStategy.parse("#(-4,)")));
}
}