Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.fieldintercept.KeyValueFieldIntercept Maven / Gradle / Ivy
package com.github.fieldintercept;
import com.github.fieldintercept.util.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* key value 字段字段设置名称
*
* @author acer01
*/
public class KeyValueFieldIntercept implements ReturnFieldDispatchAop.FieldIntercept, ReturnFieldDispatchAop.SelectMethodHolder {
protected final Class keyClass;
protected final Class valueClass;
protected final Function, Map> selectValueMapByKeys;
protected Object configurableEnvironment;
public KeyValueFieldIntercept() {
this(null, null);
}
public KeyValueFieldIntercept(Class keyClass) {
this(keyClass, null);
}
public KeyValueFieldIntercept(Class keyClass, Class valueClass) {
this(keyClass, valueClass, null);
}
public KeyValueFieldIntercept(Class keyClass, Class valueClass, Function, Map> selectValueMapByKeys) {
if (keyClass == null) {
if (getClass() != KeyValueFieldIntercept.class) {
try {
Class> key = TypeUtil.findGenericType(this, KeyValueFieldIntercept.class, "KEY");
keyClass = (Class) key;
} catch (IllegalStateException ignored) {
}
}
if (keyClass == null) {
keyClass = (Class) Integer.class;
}
}
if (valueClass == null) {
try {
valueClass = (Class) TypeUtil.findGenericType(this, KeyValueFieldIntercept.class, "VALUE");
} catch (Exception e) {
valueClass = (Class) Object.class;
}
}
this.keyClass = keyClass;
this.valueClass = valueClass;
this.selectValueMapByKeys = selectValueMapByKeys;
}
private static String cacheKey(Object key) {
return String.valueOf(key);
}
public Class getValueClass() {
return valueClass;
}
public Class getKeyClass() {
return keyClass;
}
public Function, Map> getSelectValueMapByKeys() {
return selectValueMapByKeys;
}
@Override
public final void accept(JOIN_POINT joinPoint, List cFields) {
Set keyDataList = getKeyDataByFields(cFields);
if (keyDataList == null || keyDataList.isEmpty()) {
return;
}
Map currentLocalCache = ReturnFieldDispatchAop.getLocalCache(cFields, this);
Map valueMap = cacheSelectValueMapByKeys(currentLocalCache, cFields, keyDataList);
SnapshotCompletableFuture> future = ReturnFieldDispatchAop.getAsync(cFields, this);
if (future != null) {
future.addBeforeCompleteListener((result, throwable) -> {
if (result != null && !result.isEmpty()) {
valueMap.putAll(result);
putCache(currentLocalCache, result);
}
if (!valueMap.isEmpty()) {
Map attachment = PlatformDependentUtil.removeAttachment(valueMap);
setProperty(cFields, valueMap, attachment);
}
});
} else if (!valueMap.isEmpty()) {
Map attachment = PlatformDependentUtil.removeAttachment(valueMap);
setProperty(cFields, valueMap, attachment);
}
}
private Map cacheSelectValueMapByKeys(Map currentLocalCache, List cFields, Set keys) {
// 从缓存中加载
Map valueMap = loadCache(currentLocalCache, keys);
// 全部命中
if (valueMap.size() == keys.size()) {
return valueMap;
}
// 未命中的查库
Set remainingCacheMissKeys;
if (valueMap.isEmpty()) {
remainingCacheMissKeys = keys;
} else {
remainingCacheMissKeys = new LinkedHashSet<>(keys);
remainingCacheMissKeys.removeAll(valueMap.keySet());
}
// 查库与缓存数据合并
Map loadValueMap = selectValueMapByKeys(cFields, remainingCacheMissKeys);
if (loadValueMap != null) {
valueMap.putAll(loadValueMap);
// 放入缓存
putCache(currentLocalCache, loadValueMap);
}
return valueMap;
}
private Map loadCache(Map currentLocalCache, Set keys) {
Map valueMap = new LinkedHashMap<>((int) (keys.size() / 0.75F + 1));
if (currentLocalCache != null && !currentLocalCache.isEmpty()) {
for (KEY key : keys) {
String stringKey = cacheKey(key);
if (currentLocalCache.containsKey(stringKey)) {
valueMap.put(key, currentLocalCache.get(stringKey));
}
}
}
return valueMap;
}
private void putCache(Map currentLocalCache, Map valueMap) {
// 放入缓存
if (currentLocalCache != null) {
for (Map.Entry entry : valueMap.entrySet()) {
currentLocalCache.put(cacheKey(entry.getKey()), entry.getValue());
}
}
}
/**
* 查询名称by keys
*
* @param keys 多个key
* @return key 与名称的映射
*/
public Map selectValueMapByKeys(Collection keys) {
return null;
}
public Map selectSerializeValueMapByKeys(List serializeCFields, Collection keys) {
Map valueMap = selectValueMapByKeys(CField.parse(serializeCFields), keys);
Map attachment = newtSerializeAttachment(serializeCFields, valueMap);
return PlatformDependentUtil.mergeAttachment(valueMap, attachment);
}
protected Map newtSerializeAttachment(List serializeCFields, Map valueMap) {
return null;
}
public Map selectValueMapByKeys(List cFields, Collection keys) {
Map valueMap = selectValueMapByKeys(keys);
if (valueMap == null) {
if (selectValueMapByKeys == null) {
throw new UnsupportedOperationException("您的selectValueMapByKeys方法未实现完全");
}
valueMap = selectValueMapByKeys.apply(keys);
}
return valueMap;
}
protected KEY[] rewriteKeyDataIfNeed(KEY keyData, CField cField, Map valueMap, Map attachment) {
Object[] attachmentValue;
if (attachment != null && !attachment.isEmpty() && (attachmentValue = TypeUtil.cast(attachment.get(cField.keyDataId(keyData)), Object[].class)) != null) {
return (KEY[]) attachmentValue;
} else {
KEY[] arr = (KEY[]) Array.newInstance(keyData.getClass(), 1);
arr[0] = keyData;
return arr;
}
}
protected Set getKeyDataByFields(List cFields) {
Set totalKeyDataList = new LinkedHashSet<>();
for (CField cField : cFields) {
String[] keyFieldNames = getKeyFieldName(cField.getAnnotation());
Object keyData = getKeyDataByField(cField.getBeanHandler(), keyFieldNames);
Collection keyDataList = splitKeyData(keyData);
if (keyDataList != null) {
totalKeyDataList.addAll(keyDataList);
cField.setKeyDataList(keyDataList);
}
}
return totalKeyDataList;
}
protected String[] getKeyFieldName(Annotation annotation) {
Object keyField = AnnotationUtil.getValue(annotation, "keyField");
if (keyField instanceof String[]) {
return (String[]) keyField;
} else if (keyField instanceof String) {
return new String[]{(String) keyField};
} else {
return null;
}
}
protected boolean isNull(Object value) {
return value == null || "".equals(value) || "null".equals(value);
}
protected Object getKeyDataByField(BeanMap beanHandler, String[] keyFieldNames) {
if (keyFieldNames != null) {
for (String keyFieldName : keyFieldNames) {
Object keyData = beanHandler.get(keyFieldName);
if (!isNull(keyData)) {
return keyData;
}
}
}
return null;
}
protected Collection splitKeyData(Object keyData) {
Collection keyDataList = null;
if (isNull(keyData)) {
return null;
} else if (keyData.getClass().isArray()) {
int length = Array.getLength(keyData);
for (int i = 0; i < length; i++) {
Object e = Array.get(keyData, i);
if (isNull(e)) {
continue;
}
KEY key = cast(e, keyClass);
if (key != null) {
if (keyDataList == null) {
keyDataList = new ArrayList<>();
}
keyDataList.add(key);
}
}
} else if (keyData instanceof Iterable) {
for (Object e : (Iterable) keyData) {
if (isNull(e)) {
continue;
}
KEY key = cast(e, keyClass);
if (key != null) {
if (keyDataList == null) {
keyDataList = new ArrayList<>();
}
keyDataList.add(key);
}
}
} else if (keyData instanceof CharSequence) {
for (String e : keyData.toString().split(",")) {
if (isNull(e)) {
continue;
}
KEY key = cast(e, keyClass);
if (key != null) {
if (keyDataList == null) {
keyDataList = new ArrayList<>();
}
keyDataList.add(key);
}
}
} else {
try {
KEY key = cast(keyData, keyClass);
if (key != null) {
keyDataList = Collections.singletonList(key);
}
} catch (Exception e) {
//skip
}
}
return keyDataList;
}
protected void addList(CField cField, Object value, Class genericType, Consumer list) {
if (value == null) {
return;
}
if (value instanceof Collection && !Collection.class.isAssignableFrom(genericType)) {
for (Object o : (Collection) value) {
addList(cField, o, genericType, list);
}
} else {
String resolveValue = cField.resolvePlaceholders(value);
if (resolveValue != null) {
value = resolveValue;
}
if (cField.getType() != String.class && value instanceof String && ((String) value).contains(",")) {
for (String s : ((String) value).split(",")) {
list.accept(cast(s, genericType));
}
} else {
list.accept(cast(value, genericType));
}
}
}
protected void setProperty(List cFieldList, Map valueMap, Map attachment) {
Map stringKeyMap = null;
for (CField cField : cFieldList) {
Class genericType = cField.getGenericType();
Class> fieldType = cField.getField().getType();
Collection keyDataList = cField.getKeyDataList();
VALUE value = null;
StringJoiner joiner = null;
if (keyDataList == null || keyDataList.isEmpty()) {
if (List.class.isAssignableFrom(fieldType)) {
value = (VALUE) new ArrayList();
} else if (Set.class.isAssignableFrom(fieldType)) {
value = (VALUE) new LinkedHashSet(1);
} else if (fieldType.isArray()) {
value = (VALUE) Array.newInstance(genericType, 0);
}
} else if (keyDataList.size() == 1) {
KEY[] rewriteKeyDataList = rewriteKeyDataIfNeed(keyDataList.iterator().next(), cField, valueMap, attachment);
setKeyData(cField, rewriteKeyDataList);
value = choseValue(valueMap, rewriteKeyDataList);
if (value == null && rewriteKeyDataList != null && rewriteKeyDataList.length > 0) {
if (stringKeyMap == null) {
stringKeyMap = toStringKeyMap(valueMap);
}
value = choseValue((Map) stringKeyMap, (KEY[]) toStringKey(rewriteKeyDataList));
}
if (List.class.isAssignableFrom(fieldType)) {
Collection list = new ArrayList<>(1);
addList(cField, value, genericType, list::add);
value = (VALUE) list;
} else if (Set.class.isAssignableFrom(fieldType)) {
Collection list = new LinkedHashSet<>(1);
addList(cField, value, genericType, list::add);
value = (VALUE) list;
} else if (fieldType.isArray()) {
Object array = Array.newInstance(genericType, 1);
String resolveValue = cField.resolvePlaceholders(value);
if (resolveValue != null) {
value = (VALUE) cast(resolveValue, genericType);
}
Array.set(array, 0, value);
value = (VALUE) array;
}
} else {
List list = null;
Set set = null;
Object array = null;
if (List.class.isAssignableFrom(fieldType)) {
list = new ArrayList<>(10);
value = (VALUE) list;
} else if (Set.class.isAssignableFrom(fieldType)) {
set = new LinkedHashSet<>(10);
value = (VALUE) set;
} else if (fieldType.isArray()) {
array = Array.newInstance(genericType, keyDataList.size());
value = (VALUE) array;
} else if (fieldType == String.class) {
String joinDelimiter = getAnnotationJoinDelimiter(cField.getAnnotation());
joiner = new StringJoiner(joinDelimiter);
}
int i = 0;
for (KEY keyData : keyDataList) {
i++;
KEY[] rewriteKeyDataList = rewriteKeyDataIfNeed(keyData, cField, valueMap, attachment);
setKeyData(cField, rewriteKeyDataList);
VALUE eachValue = choseValue(valueMap, rewriteKeyDataList);
if (eachValue == null && rewriteKeyDataList != null && rewriteKeyDataList.length > 0) {
if (stringKeyMap == null) {
stringKeyMap = toStringKeyMap(valueMap);
}
eachValue = choseValue((Map) stringKeyMap, (KEY[]) toStringKey(rewriteKeyDataList));
}
if (eachValue == null) {
continue;
}
if (list != null) {
addList(cField, eachValue, genericType, list::add);
} else if (set != null) {
addList(cField, eachValue, genericType, set::add);
} else if (array != null) {
String resolveValue = cField.resolvePlaceholders(eachValue);
if (resolveValue != null) {
eachValue = (VALUE) cast(resolveValue, genericType);
}
Array.set(array, i, eachValue);
} else if (joiner != null && !isNull(eachValue)) {
addList(cField, eachValue, String.class, joiner::add);
} else {
value = eachValue;
break;
}
}
}
if (joiner != null && joiner.length() > 0) {
value = (VALUE) joiner.toString();
}
if (value != null) {
if (fieldType.isEnum() && value.getClass().isEnum()) {
cField.setValue(value);
} else if (cField.existPlaceholder()) {
String resolveValue = cField.resolvePlaceholders(value);
if (resolveValue != null) {
cField.setValue(resolveValue);
}
} else {
cField.setValue(value);
}
}
}
}
private void setKeyData(CField cField, KEY[] rewriteKeyDataList) {
if (rewriteKeyDataList == null) {
return;
}
Object keyData;
if (rewriteKeyDataList.length == 1) {
keyData = rewriteKeyDataList[0];
} else if (rewriteKeyDataList.length == 0) {
keyData = null;
} else {
keyData = new ArrayList<>(Arrays.asList(rewriteKeyDataList));
}
cField.setKeyData(keyData);
}
protected TYPE cast(Object object, Class type) {
if (Enum.class.isAssignableFrom(type)) {
if (type.isEnum()) {
return (TYPE) castEnum(object, (Class) type);
} else {
throw new IllegalStateException("cast need " + type + " extends java.lang.Enum");
}
}
return TypeUtil.castIfBeanCast(object, type);
}
protected TYPE castEnum(Object object, Class type) {
Collection enumSet = (Collection) EnumSet.allOf((Class) type);
if (enumSet.isEmpty()) {
return null;
}
Class> keyClass = enumSet.stream()
.map(Enum::getKey)
.filter(Objects::nonNull)
.findFirst()
.map(Object::getClass)
.orElse(null);
Object keyCast;
if (keyClass == null) {
keyCast = null;
} else {
keyCast = TypeUtil.castIfBeanCast(object, keyClass);
}
for (Enum o : enumSet) {
Object key = o.getKey();
if (Objects.equals(key, keyCast)) {
return (TYPE) o;
}
}
return null;
}
protected VALUE choseValue(Map valueMap, KEY[] keyDataList) {
if (keyDataList == null) {
return null;
}
for (KEY keyData : keyDataList) {
VALUE value = valueMap.get(keyData);
if (value != null) {
return value;
}
}
return null;
}
protected String getAnnotationJoinDelimiter(Annotation annotation) {
Object joinDelimiter = AnnotationUtil.getValue(annotation, "joinDelimiter");
if (joinDelimiter == null) {
return ",";
} else {
return joinDelimiter.toString();
}
}
public void setConfigurableEnvironment(Object configurableEnvironment) {
this.configurableEnvironment = configurableEnvironment;
}
private Map toStringKeyMap(Map nameMap) {
Map result = new HashMap<>();
for (Map.Entry entry : nameMap.entrySet()) {
result.put(Objects.toString(entry.getKey(), null), entry.getValue());
}
return result;
}
private String[] toStringKey(KEY[] rewriteKeyDataList) {
String[] strings = new String[rewriteKeyDataList.length];
for (int i = 0; i < rewriteKeyDataList.length; i++) {
strings[i] = Objects.toString(rewriteKeyDataList[i], null);
}
return strings;
}
}