package com.taobao.top.analysis.statistics.map;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.taobao.top.analysis.node.job.JobTask;
import com.taobao.top.analysis.statistics.data.ReportEntry;
import com.taobao.top.analysis.util.AnalysisConstants;
/**
* MultiConditionMapper.java
* @author yunzhan.jtq
*
* @since 2012-2-15 下午07:29:49
*/
public class MultiConditionMapper extends DefaultMapper {
/**
*
*/
private static final long serialVersionUID = -5604020449659822007L;
private static final Log logger = LogFactory.getLog(MultiConditionMapper.class);
private static final int c = ';';
private ConcurrentHashMap<String, List<MapAndParam>> mapParamsClass =
new ConcurrentHashMap<String, List<MapAndParam>>();
@Override
public String generateKey(ReportEntry entry, String[] contents, JobTask jobtask) {
String mapParams = entry.getMapParams();
if (StringUtils.isEmpty(mapParams)) {
return super.generateKey(entry, contents, jobtask);
}
else {
List<MapAndParam> multiMap = mapParamsClass.get(mapParams);
if (multiMap == null) {
multiMap = analysisMapParams(mapParams);
mapParamsClass.put(mapParams, multiMap);
}
if (multiMap.size() == 0) {
return AnalysisConstants.IGNORE_PROCESS;
}
MapAndParam generateKeyMap = multiMap.get(0);
ReportEntry rEntry = null;
for (int i = 1, n = multiMap.size(); i < n; i++) {
try {
rEntry = entry.clone();
}
catch (CloneNotSupportedException e) {
logger.error(e);
}
rEntry.setMapClass(multiMap.get(i).getMapInstance());
rEntry.setMapParams(multiMap.get(i).getMapParam());
if (AnalysisConstants.IGNORE_PROCESS.equals(multiMap.get(i).getMapInstance()
.generateKey(rEntry, contents, jobtask))) {
return AnalysisConstants.IGNORE_PROCESS;
}
}
try {
rEntry = entry.clone();
}
catch (CloneNotSupportedException e) {
logger.error(e);
}
rEntry.setMapClass(generateKeyMap.getMapInstance());
rEntry.setMapParams(generateKeyMap.getMapParam());
String key =
generateKeyMap.getMapInstance().generateKey(rEntry, contents, jobtask);
return key;
}
}
@Override
protected Object generateValue(ReportEntry entry,
Object[] contents, JobTask jobtask) {
String mapParams = entry.getMapParams();
if (StringUtils.isEmpty(mapParams)) {
return super.generateValue(entry, contents, jobtask);
} else {
List<MapAndParam> multiMap = mapParamsClass.get(mapParams);
if (multiMap == null) {
multiMap = analysisMapParams(mapParams);
mapParamsClass.put(mapParams, multiMap);
}
if (multiMap.size() == 0) {
return super.generateValue(entry, contents, jobtask);
}
MapAndParam generateKeyMap = multiMap.get(0);
ReportEntry rEntry = null;
try {
rEntry = entry.clone();
}
catch (CloneNotSupportedException e) {
logger.error(e);
}
rEntry.setMapClass(generateKeyMap.getMapInstance());
rEntry.setMapParams(generateKeyMap.getMapParam());
return generateKeyMap.getMapInstance().generateValue(rEntry, contents, jobtask);
}
}
private List<MapAndParam> analysisMapParams(String mapParams) {
String[] params = StringUtils.split(mapParams, ",");
List<MapAndParam> mapAndParamList = new ArrayList<MapAndParam>(params.length);
for (int i = 0, n = params.length; i < n; i++) {
String mapClassStr = null;
String mapParam = null;
int sepIndex = params[i].indexOf(c);
if (sepIndex > -1) {
mapClassStr = params[i].substring(0, sepIndex);
mapParam = params[i].substring(sepIndex + 1, params[i].length());
}
else {
mapClassStr = params[i].trim();
}
try {
mapAndParamList.add(new MapAndParam((AbstractMapper) Class.forName(mapClassStr).newInstance(), mapParam));
}
catch (Exception e) {
logger.error(e, e);
continue;
}
}
if (mapAndParamList.size() == 0) {
logger.warn(new StringBuilder().append(" mapParam:").append(mapParams).append(" is not valid."));
}
return mapAndParamList;
}
/**
* 保存一个map的实例以及这个map的输入参数
*
* @author zhenzi 2010-12-7 上午07:58:22
*/
private class MapAndParam {
private AbstractMapper mapInstance;
private String mapParam;
public MapAndParam(AbstractMapper mapInstance, String mapParam) {
this.mapInstance = mapInstance;
this.mapParam = mapParam;
}
public AbstractMapper getMapInstance() {
return mapInstance;
}
public String getMapParam() {
return mapParam;
}
}
}