forked from fanruan/easyexcel
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
6.1 KiB
151 lines
6.1 KiB
package com.alibaba.excel.util; |
|
|
|
import java.lang.ref.SoftReference; |
|
import java.lang.reflect.Field; |
|
import java.lang.reflect.Modifier; |
|
import java.util.ArrayList; |
|
import java.util.Collections; |
|
import java.util.HashMap; |
|
import java.util.List; |
|
import java.util.Map; |
|
import java.util.TreeMap; |
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
import com.alibaba.excel.annotation.ExcelIgnore; |
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
|
import com.alibaba.excel.annotation.ExcelProperty; |
|
import com.alibaba.excel.exception.ExcelCommonException; |
|
import com.alibaba.excel.metadata.BaseRowModel; |
|
|
|
/** |
|
* Class utils |
|
* |
|
* @author Jiaju Zhuang |
|
**/ |
|
public class ClassUtils { |
|
private static final Map<Class, SoftReference<FieldCache>> FIELD_CACHE = |
|
new ConcurrentHashMap<Class, SoftReference<FieldCache>>(); |
|
|
|
public static void declaredFields(Class clazz, List<Field> defaultFieldList, Map<Integer, Field> customFiledMap, |
|
Map<String, Field> ignoreMap, Boolean convertAllFiled) { |
|
FieldCache fieldCache = getFieldCache(clazz, convertAllFiled); |
|
if (fieldCache != null) { |
|
defaultFieldList.addAll(fieldCache.getDefaultFieldList()); |
|
customFiledMap.putAll(fieldCache.getCustomFiledMap()); |
|
ignoreMap.putAll(fieldCache.getIgnoreMap()); |
|
} |
|
} |
|
|
|
public static void declaredFields(Class clazz, List<Field> fieldList, Boolean convertAllFiled) { |
|
FieldCache fieldCache = getFieldCache(clazz, convertAllFiled); |
|
if (fieldCache != null) { |
|
fieldList.addAll(fieldCache.getAllFieldList()); |
|
} |
|
} |
|
|
|
private static FieldCache getFieldCache(Class clazz, Boolean convertAllFiled) { |
|
if (clazz == null) { |
|
return null; |
|
} |
|
SoftReference<FieldCache> fieldCacheSoftReference = FIELD_CACHE.get(clazz); |
|
if (fieldCacheSoftReference != null && fieldCacheSoftReference.get() != null) { |
|
return fieldCacheSoftReference.get(); |
|
} |
|
synchronized (clazz) { |
|
fieldCacheSoftReference = FIELD_CACHE.get(clazz); |
|
if (fieldCacheSoftReference != null && fieldCacheSoftReference.get() != null) { |
|
return fieldCacheSoftReference.get(); |
|
} |
|
declaredFields(clazz, convertAllFiled); |
|
} |
|
return FIELD_CACHE.get(clazz).get(); |
|
} |
|
|
|
private static void declaredFields(Class clazz, Boolean convertAllFiled) { |
|
List<Field> tempFieldList = new ArrayList<Field>(); |
|
Class tempClass = clazz; |
|
// When the parent class is null, it indicates that the parent class (Object class) has reached the top |
|
// level. |
|
while (tempClass != null && tempClass != BaseRowModel.class) { |
|
Collections.addAll(tempFieldList, tempClass.getDeclaredFields()); |
|
// Get the parent class and give it to yourself |
|
tempClass = tempClass.getSuperclass(); |
|
} |
|
// Screening of field |
|
List<Field> defaultFieldList = new ArrayList<Field>(); |
|
Map<Integer, Field> customFiledMap = new TreeMap<Integer, Field>(); |
|
List<Field> allFieldList = new ArrayList<Field>(); |
|
Map<String, Field> ignoreMap = new HashMap<String, Field>(16); |
|
|
|
ExcelIgnoreUnannotated excelIgnoreUnannotated = |
|
(ExcelIgnoreUnannotated)clazz.getAnnotation(ExcelIgnoreUnannotated.class); |
|
for (Field field : tempFieldList) { |
|
ExcelIgnore excelIgnore = field.getAnnotation(ExcelIgnore.class); |
|
if (excelIgnore != null) { |
|
ignoreMap.put(field.getName(), field); |
|
continue; |
|
} |
|
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); |
|
boolean noExcelProperty = excelProperty == null |
|
&& ((convertAllFiled != null && !convertAllFiled) || excelIgnoreUnannotated != null); |
|
if (noExcelProperty) { |
|
ignoreMap.put(field.getName(), field); |
|
continue; |
|
} |
|
boolean isStaticFinalOrTransient = |
|
(Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) |
|
|| Modifier.isTransient(field.getModifiers()); |
|
if (excelProperty == null && isStaticFinalOrTransient) { |
|
ignoreMap.put(field.getName(), field); |
|
continue; |
|
} |
|
if (excelProperty == null || excelProperty.index() < 0) { |
|
defaultFieldList.add(field); |
|
allFieldList.add(field); |
|
continue; |
|
} |
|
if (customFiledMap.containsKey(excelProperty.index())) { |
|
throw new ExcelCommonException("The index of '" + customFiledMap.get(excelProperty.index()).getName() |
|
+ "' and '" + field.getName() + "' must be inconsistent"); |
|
} |
|
customFiledMap.put(excelProperty.index(), field); |
|
} |
|
|
|
List<Field> allWriteFieldList = new ArrayList<Field>(customFiledMap.values()); |
|
allWriteFieldList.addAll(allFieldList); |
|
FIELD_CACHE.put(clazz, |
|
new SoftReference<FieldCache>(new FieldCache(defaultFieldList, customFiledMap, allWriteFieldList, ignoreMap))); |
|
} |
|
|
|
private static class FieldCache { |
|
private List<Field> defaultFieldList; |
|
private Map<Integer, Field> customFiledMap; |
|
private List<Field> allFieldList; |
|
private Map<String, Field> ignoreMap; |
|
|
|
public FieldCache(List<Field> defaultFieldList, Map<Integer, Field> customFiledMap, List<Field> allFieldList, |
|
Map<String, Field> ignoreMap) { |
|
this.defaultFieldList = defaultFieldList; |
|
this.customFiledMap = customFiledMap; |
|
this.allFieldList = allFieldList; |
|
this.ignoreMap = ignoreMap; |
|
} |
|
|
|
public List<Field> getDefaultFieldList() { |
|
return defaultFieldList; |
|
} |
|
|
|
public Map<Integer, Field> getCustomFiledMap() { |
|
return customFiledMap; |
|
} |
|
|
|
public List<Field> getAllFieldList() { |
|
return allFieldList; |
|
} |
|
|
|
public Map<String, Field> getIgnoreMap() { |
|
return ignoreMap; |
|
} |
|
|
|
} |
|
}
|
|
|