package com.skyline.energy.definition;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import com.skyline.energy.annotation.Param;
import com.skyline.energy.exception.DaoGenerateException;
import com.skyline.energy.parser.ExpressionParser;
import com.skyline.energy.parser.ParsedExpression;
import com.skyline.energy.utils.CommonUtils;
import com.skyline.energy.utils.Page;
public class BaseCacheDefinition {
private ParsedExpression parsedKey;
private Method[] keyGetterMethods;
private Integer[] keyParameterIndexes;
private ParsedExpression parsedVkey;
private Method[] vkeyGetterMethods;
private Integer[] vkeyParameterIndexes;
private int pageIndex = -1;
public ParsedExpression getParsedKey() {
return parsedKey;
}
public Method[] getKeyGetterMethods() {
return keyGetterMethods;
}
public Integer[] getKeyParameterIndexes() {
return keyParameterIndexes;
}
public ParsedExpression getParsedVkey() {
return parsedVkey;
}
public Method[] getVkeyGetterMethods() {
return vkeyGetterMethods;
}
public Integer[] getVkeyParameterIndexes() {
return vkeyParameterIndexes;
}
public int getPageIndex() {
return pageIndex;
}
protected void parseParameterAnnotations(Annotation[][] annotations, Class<?>[] paramTypes,
Map<String, Integer> paramIndexes) {
for (int index = 0; index < annotations.length; index++) {
if (CommonUtils.isTypePage(paramTypes[index])) {
pageIndex = index;
}
for (Annotation annotation : annotations[index]) {
Class<? extends Annotation> annotationType = annotation.annotationType();
if (Param.class.equals(annotationType)) {
Param param = (Param) annotation;
String value = param.value();
paramIndexes.put(value, index);
}
}
}
}
protected void configCacheKey(String key, String vkey, Class<?>[] paramTypes, Map<String, Integer> paramIndexes,
Class<?> returnType) throws DaoGenerateException {
if (StringUtils.isNotEmpty(key)) {
parsedKey = ExpressionParser.parseExpression(key);
List<String> keyParameterNames = parsedKey.getParameterNames();
Object[] keyGettersAndIndexes = CommonUtils.getGettersAndIndexes(keyParameterNames, paramIndexes,
paramTypes);
keyGetterMethods = (Method[]) keyGettersAndIndexes[0];
keyParameterIndexes = (Integer[]) keyGettersAndIndexes[1];
}
if (StringUtils.isNotEmpty(vkey) && CommonUtils.isTypeCollection(returnType)) {// 集合版本号
parsedVkey = ExpressionParser.parseExpression(vkey);
List<String> vkeyParameterNames = parsedVkey.getParameterNames();
Object[] vkeyGettersAndIndexes = CommonUtils.getGettersAndIndexes(vkeyParameterNames, paramIndexes,
paramTypes);
vkeyGetterMethods = (Method[]) vkeyGettersAndIndexes[0];
vkeyParameterIndexes = (Integer[]) vkeyGettersAndIndexes[1];
} else if (StringUtils.isNotEmpty(vkey)) {
parsedVkey = ExpressionParser.parseExpression(vkey);
List<String> vkeyParameterNames = parsedVkey.getParameterNames();
Map<String, Integer> returnIndexes = new HashMap<String, Integer>(1);
returnIndexes.put("result", 0);
Class<?>[] retTypes = new Class<?>[] { returnType };
Object[] vkeyGettersAndIndexes = CommonUtils.getGettersAndIndexes(vkeyParameterNames, returnIndexes,
retTypes);
vkeyGetterMethods = (Method[]) vkeyGettersAndIndexes[0];
vkeyParameterIndexes = (Integer[]) vkeyGettersAndIndexes[1];
}
}
protected void configCacheKey(String key, String vkey, Class<?>[] paramTypes, Map<String, Integer> paramIndexes)
throws DaoGenerateException {
// 此方法需要按集合类处理vkey
configCacheKey(key, vkey, paramTypes, paramIndexes, List.class);
}
private String buildSimpleKey(Object[] args, ParsedExpression parsedExpression, Method[] getterMethods,
Integer[] parameterIndexes) {
CommonUtils.assertNotNull(parsedExpression, "parsedExpression can't be null while generate a key");
String oriKey = parsedExpression.getOriginalExpression();
List<String> parameterNames = parsedExpression.getParameterNames();
int length = parameterNames.size();
int lastIndex = 0;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length; i++) {
int[] indexes = parsedExpression.getParameterIndexes(i);
int startIndex = indexes[0];
int endIndex = indexes[1];
builder.append(oriKey.substring(lastIndex, startIndex));
Method method = getterMethods[i];
Integer index = parameterIndexes[i];
Object value = CommonUtils.fetchVlaue(method, index, args, parameterNames);
if (value != null) {
builder.append(value.toString());
}
lastIndex = endIndex;
}
builder.append(oriKey.substring(lastIndex));
return builder.toString();
}
public String generateCacheKey(Object[] args) {
String oriKey = buildSimpleKey(args, parsedKey, keyGetterMethods, keyParameterIndexes);
StringBuilder cacheKey = new StringBuilder();
cacheKey.append(oriKey);
Page page = CommonUtils.getPageArgument(args, pageIndex);
if (page != null) {
cacheKey.append("-p").append(page.getCurpage());
}
return cacheKey.toString();
}
public String generateVersionKey(Object[] args) {
String oriKey = buildSimpleKey(args, parsedVkey, vkeyGetterMethods, vkeyParameterIndexes);
return oriKey;
}
public String generatePageKey(Object[] args, String key) {
Page page = CommonUtils.getPageArgument(args, pageIndex);
if (page == null) {
return null;
}
if (StringUtils.isEmpty(key)) {
key = generateCacheKey(args);
}
if (StringUtils.isEmpty(key)) { // 无法创建key
return null;
}
StringBuilder builder = new StringBuilder("page-");
builder.append(key);
return builder.toString();
}
}