package com.taobao.top.analysis.statistics.data.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import com.taobao.top.analysis.exception.AnalysisException;
import com.taobao.top.analysis.statistics.data.Alias;
import com.taobao.top.analysis.statistics.data.ICondition;
import com.taobao.top.analysis.util.AnalysisConstants;
import com.taobao.top.analysis.util.ReportUtil;
public class SimpleCondition implements ICondition {
/**
*
*/
private static final long serialVersionUID = -684511768155047811L;
/**
* condition的key保留队列
*/
List<Object> conditionKStack;
/**
* condition的value保留队列
*/
List<Object> conditionVStack;
/**
* condition的操作保留队列
*/
List<Byte> conditionOpStack;
/**
* 条件之间是否是与的关系,当前只支持全部是与或者全部是或。
*/
private boolean andCondition = true;
private String condition;
public String getCondition() {
return condition;
}
public void init(Map<String, Alias> aliasPool) throws AnalysisException{
if (condition != null && !"".equals(condition)) {
conditionKStack = new ArrayList<Object>();
conditionVStack = new ArrayList<Object>();
conditionOpStack = new ArrayList<Byte>();
String[] cons;
if (condition.indexOf("||") > 0) {
cons = StringUtils.split(condition, "||");
this.andCondition = false;
} else {
cons = StringUtils.split(condition, "&");
this.andCondition = true;
}
for (String con : cons) {
con = con.trim();
if (!con.startsWith("$"))
continue;
Object key = ReportUtil.transformVar(
con.substring(1, con.lastIndexOf("$")), aliasPool);
String value = con.substring(con.lastIndexOf("$") + 1).trim();
String operate = null;
if (value.startsWith(AnalysisConstants.CONDITION_NOT_EQUAL_STR)
|| value.startsWith(AnalysisConstants.CONDITION_EQUALORGREATER_STR)
|| value.startsWith(AnalysisConstants.CONDITION_EQUALORLESSER_STR)
|| value.startsWith(AnalysisConstants.CONDITION_IN_STR)) {
operate = value.substring(0, 2);
value = value.substring(2).trim();
} else if(value.startsWith(AnalysisConstants.CONDITION_LIKE_STR)) {
operate = value.substring(0, 4);
value = value.substring(4).trim();
} else {
if (value.startsWith(AnalysisConstants.CONDITION_EQUAL_STR)
|| value.startsWith(AnalysisConstants.CONDITION_LESSER_STR)
|| value.startsWith(AnalysisConstants.CONDITION_GREATER_STR)) {
operate = value.substring(0, 1);
value = value.substring(1).trim();
}
}
if (!key.equals(AnalysisConstants.RECORD_LENGTH))
{
if(!(key instanceof Integer))
conditionKStack.add(Integer.valueOf(String.valueOf(key)));
else
conditionKStack.add(key);
if (operate.equals(AnalysisConstants.CONDITION_EQUAL_STR)
|| operate.equals(AnalysisConstants.CONDITION_NOT_EQUAL_STR)
|| operate.equals(AnalysisConstants.CONDITION_IN_STR))
{
conditionVStack.add(value);
}
else if (operate.equals(AnalysisConstants.CONDITION_LIKE_STR)) {
conditionVStack.add(Pattern.compile(value));
}
else
conditionVStack.add(Double.valueOf(value));
}
else
{
conditionKStack.add(key);
conditionVStack.add(Integer.valueOf(value.trim()));
}
conditionOpStack.add(ReportUtil.generateOperationFlag(operate));
}
}
}
public SimpleCondition(String conditions, Map<String, Alias> aliasPool)throws AnalysisException {
this.condition = conditions;
init(aliasPool);
}
public void appendCondition(String conditions, Map<String, Alias> aliasPool)throws AnalysisException {
if (this.condition != null && !"".equals(this.condition)) {
this.condition += "&" + conditions;
} else {
this.condition = conditions;
}
init(aliasPool);
}
@Override
public boolean isInCondition(String[] contents) {
boolean checkResult = false;
if (conditionKStack != null
&& conditionKStack.size() > 0) {
for (int i = 0; i < conditionKStack.size(); i++) {
Object conditionKey = conditionKStack.get(i);
byte operator = conditionOpStack.get(i);
Object conditionValue = conditionVStack.get(i);
int k = -1;
// 长度condition特殊处理,没有指定的key列
if (!conditionKey.equals(AnalysisConstants.RECORD_LENGTH)) {
k = (Integer) conditionKey;
}
checkResult = checkKeyCondition(operator, k,
conditionValue, contents);
if (andCondition && !checkResult)
return false;
if (!andCondition && checkResult)
return true;
}
}
if (!andCondition && !checkResult)
return false;
return true;
}
/**
* 返回是否符合条件
*
* @param operator
* @param conditionKey
* @param conditionValue
* @param contents
* @return
*/
private static boolean checkKeyCondition(byte operator, int conditionKey,
Object conditionValue, String[] contents) {
boolean result = false;
if(conditionKey > contents.length || (conditionKey >= 1 && StringUtils.isBlank(contents[conditionKey - 1]) || conditionValue == null ))
return result;
if (operator == AnalysisConstants.CONDITION_EQUAL) {
if (conditionKey > 0)
result = contents[conditionKey - 1].equals(conditionValue);
else
result = contents.length == (Integer)conditionValue;
} else if (operator == AnalysisConstants.CONDITION_NOT_EQUAL) {
if (conditionKey > 0)
result = !contents[conditionKey - 1].equals(conditionValue);
else
result = contents.length != (Integer)conditionValue;
}
else if (operator == AnalysisConstants.CONDITION_IN) {
if (conditionKey > 0)
result = (new StringBuilder().append(conditionValue).append(","))
.indexOf(new StringBuilder().append(contents[conditionKey - 1]).append(",").toString())>=0;
} else if(operator == AnalysisConstants.CONDITION_LIKE) {
if(conditionKey > 0 && conditionValue instanceof Pattern)
result = ((Pattern)conditionValue).matcher(contents[conditionKey - 1]).matches();
}
else {
double cmpValue = 0;
if (conditionKey > 0)
cmpValue = Double.valueOf(contents[conditionKey - 1])
- (Double)conditionValue;
else
cmpValue = contents.length - (Integer)conditionValue;
if (operator == AnalysisConstants.CONDITION_EQUALORGREATER)
return cmpValue >= 0;
if (operator == AnalysisConstants.CONDITION_EQUALORLESSER)
return cmpValue <= 0;
if (operator == AnalysisConstants.CONDITION_GREATER)
return cmpValue > 0;
if (operator == AnalysisConstants.CONDITION_LESSER)
return cmpValue < 0;
}
return result;
}
}