diff --git a/storage/src/main/java/com/zfoo/storage/StorageContext.java b/storage/src/main/java/com/zfoo/storage/StorageContext.java index f837b71c..5445ded0 100644 --- a/storage/src/main/java/com/zfoo/storage/StorageContext.java +++ b/storage/src/main/java/com/zfoo/storage/StorageContext.java @@ -69,18 +69,18 @@ public class StorageContext implements ApplicationListener getHeaders(Iterator iterator, String fileName) { - // 获取配置表的有效列名称,默认第一行就是字段名称 + // Get valid column names from the resource table; row 1 is the field names by default var fieldRow = iterator.next(); if (fieldRow == null) { throw new RunException("Failed to get attribute control column from csv file of resource [class:{}]", fileName); } - //默认第二行字段类型 + // Row 2: field types (default) var typeRow = iterator.next(); if (typeRow == null) { throw new RunException("Failed to get type control column from csv file of resource [class:{}]", fileName); } - // 默认第三行为描述,需要的时候再使用 + // Row 3: descriptions (optional) var descRow = iterator.next(); var headers = new ArrayList(); diff --git a/storage/src/main/java/com/zfoo/storage/interpreter/ExcelReader.java b/storage/src/main/java/com/zfoo/storage/interpreter/ExcelReader.java index b8bde552..3e3c82fe 100644 --- a/storage/src/main/java/com/zfoo/storage/interpreter/ExcelReader.java +++ b/storage/src/main/java/com/zfoo/storage/interpreter/ExcelReader.java @@ -21,7 +21,6 @@ import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; -import java.io.IOException; import java.io.InputStream; import java.util.*; @@ -31,12 +30,12 @@ import java.util.*; public abstract class ExcelReader { public static StorageData readResourceDataFromExcel(InputStream inputStream, String resourceClassName) { - // 只读取代码里写的字段 + // Only read fields declared in the code var wb = createWorkbook(inputStream, resourceClassName); - // 默认取到第一个sheet页 + // Read the first worksheet by default var sheet = wb.getSheetAt(0); var iterator = sheet.iterator(); - // 设置所有列 + // Set all columns var excelHeaders = getHeaders(iterator, resourceClassName); var rows = new ArrayList>(); @@ -57,7 +56,7 @@ public abstract class ExcelReader { rows.add(columns); } - // excel某些格子空的引起的列偏移 + // Handle column offset caused by empty cells in Excel var headers = new ArrayList(); for (var i = 0; i < excelHeaders.size(); i++) { var excelHeader = excelHeaders.get(i); @@ -67,17 +66,17 @@ public abstract class ExcelReader { } private static List getHeaders(Iterator iterator, String resourceClassName) { - // 获取配置表的有效列名称,默认第一行就是字段名称 + // Get valid column names from the resource table; row 1 is the field names by default var fieldRow = iterator.next(); if (fieldRow == null) { throw new RunException("Failed to get attribute control column from excel file of resource [class:{}]", resourceClassName); } - // 默认第二行字段类型 + // Row 2: field types (default) var typeRow = iterator.next(); if (typeRow == null) { throw new RunException("Failed to get type control column from excel file of resource [class:{}]", resourceClassName); } - // 默认第三行为描述,需要的时候再使用 + // Row 3: descriptions (optional) var desRow = iterator.next(); var headerList = new ArrayList(); var cellFieldMap = new HashMap(); diff --git a/storage/src/main/java/com/zfoo/storage/interpreter/ResourceInterpreter.java b/storage/src/main/java/com/zfoo/storage/interpreter/ResourceInterpreter.java index e981ce7b..f826795f 100644 --- a/storage/src/main/java/com/zfoo/storage/interpreter/ResourceInterpreter.java +++ b/storage/src/main/java/com/zfoo/storage/interpreter/ResourceInterpreter.java @@ -47,7 +47,7 @@ public class ResourceInterpreter { } var result = new ArrayList(); - //获取所有字段 + // Get all fields var cellFieldMap = getCellFieldMap(resource, clazz); var fieldInfos = getFieldInfos(cellFieldMap, clazz); @@ -56,7 +56,7 @@ public class ResourceInterpreter { Constructor constructor = ReflectionUtils.getConstructor(clazz, constructParams); var iterator = resource.getRows().iterator(); - // 从ROW_SERVER这行开始读取数据 + // Start reading data from ROW_SERVER while (iterator.hasNext()) { int index = 0; var columns = iterator.next(); @@ -74,7 +74,7 @@ public class ResourceInterpreter { } } else { var iterator = resource.getRows().iterator(); - // 从ROW_SERVER这行开始读取数据 + // Start reading data from ROW_SERVER while (iterator.hasNext()) { var columns = iterator.next(); var instance = ReflectionUtils.newInstance(clazz); @@ -100,15 +100,15 @@ public class ResourceInterpreter { } } - // 优先使用ExcelFieldName注解表示的值当作列名 + // @ExcelFieldName value takes priority as the column name private static String getExcelFieldName(Field field) { return field.isAnnotationPresent(AliasFieldName.class) ? field.getAnnotation(AliasFieldName.class).value() : field.getName(); } - // 只读取代码里写的字段 + // Only read fields declared in the code private static Collection getFieldInfos(Map cellFieldMap, Class clazz) { var fieldList = ReflectionUtils.notStaticAndTransientFields(clazz); - // 检测field的合法性,field必须可以在excel中找到对应的列,有找不到的列在启动时候就发现 + // Validate field: must have a matching column in Excel; missing columns are detected at startup for (var field : fieldList) { var fieldName = getExcelFieldName(field); if (!cellFieldMap.containsKey(fieldName)) { diff --git a/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageData.java b/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageData.java index 1073eebe..52554bbe 100644 --- a/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageData.java +++ b/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageData.java @@ -15,17 +15,17 @@ import java.util.ArrayList; import java.util.List; /** - * 配置文件资源 + * Resource configuration data * * @author meiwei666 */ public class StorageData { - // 文件名 + // File name private String name; - // 配置表字段名 + // Resource table field names private List headers = new ArrayList<>(); - // 配置表数据 + // Resource table data private List> rows = new ArrayList<>(); public static StorageData valueOf(String name, List headers, List> rows) { diff --git a/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageEnum.java b/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageEnum.java index d02353dc..fa976701 100644 --- a/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageEnum.java +++ b/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageEnum.java @@ -19,7 +19,7 @@ import java.util.HashMap; import java.util.Map; /** - * 支持读取配置文件的类型后缀 + * Supported file type suffixes for resource files * * @author godotg */ diff --git a/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageHeader.java b/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageHeader.java index 594ec960..39eba161 100644 --- a/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageHeader.java +++ b/storage/src/main/java/com/zfoo/storage/interpreter/data/StorageHeader.java @@ -16,11 +16,11 @@ package com.zfoo.storage.interpreter.data; */ public class StorageHeader { - //字段名 + // Field name private String name; - //类型 + // Field type private String type; - //列 + // Column private int index; public static StorageHeader valueOf(String name, String type, int index) { diff --git a/storage/src/main/java/com/zfoo/storage/manager/AbstractStorage.java b/storage/src/main/java/com/zfoo/storage/manager/AbstractStorage.java index 54608c9d..8f84a5cf 100644 --- a/storage/src/main/java/com/zfoo/storage/manager/AbstractStorage.java +++ b/storage/src/main/java/com/zfoo/storage/manager/AbstractStorage.java @@ -38,16 +38,16 @@ import java.util.*; public abstract class AbstractStorage implements IStorage { // func index of caches private ConcurrentReferenceHashMap, String> funcCaches = new ConcurrentReferenceHashMap<>(); - // non-unique index (非唯一索引) + // non-unique index protected Map>> indexMap = new HashMap<>(); - // unique index (唯一索引) + // unique index protected Map> uniqueIndexMap = new HashMap<>(); protected Class clazz; protected IdDef idDef; protected Map indexDefMap; // EN: unused configuration tables will clear data to save memory. - // CN: 没有被使用的配置表会清除data数据,以达到节省内存的目的 + // Unused resource tables have their data cleared to save memory protected boolean recycle = true; public static AbstractStorage parse(InputStream inputStream, Class resourceClazz, String suffix) { @@ -56,7 +56,7 @@ public abstract class AbstractStorage implements IStorage { try { var list = ResourceInterpreter.read(inputStream, resourceClazz, suffix); - // 校验id是否重复 + // Check for duplicate ids var set = new HashSet<>(); for (var value : list) { var id = ReflectionUtils.getField(idDef.getField(), value); @@ -89,12 +89,12 @@ public abstract class AbstractStorage implements IStorage { this.idDef = idDef; this.indexDefMap = indexDefMap; for (var value : values) { - // 添加资源 + // Add resource @SuppressWarnings("unchecked") var v = (V) value; - // 添加索引 + // Add index for (var def : indexDefMap.values()) { - // 使用field的名称作为索引的名称 + // Use field name as the index name var indexKey = def.getField().getName(); var indexValue = ReflectionUtils.getField(def.getField(), v); if (def.isUnique()) { @@ -165,7 +165,7 @@ public abstract class AbstractStorage implements IStorage { return indexName; } - // 1. IDEA 调试模式下 lambda 表达式是一个代理 + // 1. In IDEA debug mode, lambda is a proxy if (func instanceof Proxy) { try { var lambda = new IdeaProxyLambdaMeta((Proxy) func); @@ -174,7 +174,7 @@ public abstract class AbstractStorage implements IStorage { } } - // 2. 反射读取 + // 2. Read via reflection if (indexName == null) { try { var method = func.getClass().getDeclaredMethod("writeReplace"); @@ -185,7 +185,7 @@ public abstract class AbstractStorage implements IStorage { } } - // 3. 反射失败使用序列化的方式读取 + // 3. Fallback to serialization if reflection fails if (indexName == null) { try { var lambda = new ShadowLambdaMeta(SerializedLambda.extract(func)); @@ -194,7 +194,7 @@ public abstract class AbstractStorage implements IStorage { } } - // 4. 通过将func带入到dataMap中求解,适合GraalVM环境中 + // 4. Derive from dataMap (suitable for GraalVM environments) if (indexName == null) { try { var fields = Arrays.stream(clazz.getDeclaredFields()) @@ -223,7 +223,7 @@ public abstract class AbstractStorage implements IStorage { } } - // 所有的方法都取不到Func对应的属性名称则抛出异常 + // Throw exception if no method can determine the Func field name if (indexName == null) { throw new RunException("can not get indexName from func:[{}]", func); } diff --git a/storage/src/main/java/com/zfoo/storage/manager/IStorageManager.java b/storage/src/main/java/com/zfoo/storage/manager/IStorageManager.java index bb3d7e90..bae03246 100644 --- a/storage/src/main/java/com/zfoo/storage/manager/IStorageManager.java +++ b/storage/src/main/java/com/zfoo/storage/manager/IStorageManager.java @@ -24,17 +24,17 @@ import java.util.Map; public interface IStorageManager { /** - * 配置表初始化之前,先读取所有的excel + * Read all Excel files before initializing resource tables */ void initBefore(); /** - * 注入 + * Inject */ void inject(); /** - * 程序加载过后,移除没有用到的配置表 + * Remove unused resource tables after loading to free memory */ void initAfter(); diff --git a/storage/src/main/java/com/zfoo/storage/manager/StorageManager.java b/storage/src/main/java/com/zfoo/storage/manager/StorageManager.java index b675bcfa..03008080 100644 --- a/storage/src/main/java/com/zfoo/storage/manager/StorageManager.java +++ b/storage/src/main/java/com/zfoo/storage/manager/StorageManager.java @@ -54,19 +54,19 @@ public class StorageManager implements IStorageManager { private static final Logger logger = LoggerFactory.getLogger(StorageContext.class); - // ANT通配符有三种, ? :匹配任何单字符; * :匹配0或者任意数量的字符; ** :匹配0或者更多的目录 - // 1. /project/*.a 匹配项目根路径下所有在project路径下的.a文件 - // 2. /project/p?ttern 匹配项目根路径下 /project/pattern 和 /app/pXttern,但是不包括/app/pttern - // 3. /**/example 匹配项目根路径下 /project/example, /project/foow/example, 和 /example - // 4. /project/**/dir/file.* 匹配项目根路径下/project/dir/file.jsp, /project/foow/dir/file.html,/project/foow/bar/dir/file.pdf - // 5. /**/*.jsp 匹配项目根路径下任何的.jsp 文件 - // classpath:和classpath*: 的区别,前者只会第一个加载到的类,后者会加载所有的类,包括jar文件下的类 + // ANT wildcards: '?' one char, '*' any chars, '**' any path + // 1. /project/*.a matches all .a files under /project + // 2. /project/p?ttern matches /project/pattern and /project/pXttern (not pttern) + // 3. /**/example matches any path ending with /example + // 4. /project/**/dir/file.* matches /project/**/dir/file.* + // 5. /**/*.jsp matches all .jsp files anywhere + // 'classpath:' loads first match; 'classpath*:' loads all including JARs private static final String SUFFIX_PATTERN = "**/*.class"; private StorageConfig storageConfig; /** - * 在当前项目被依赖注入,被使用的Storage + * Storage resources that are dependency-injected in the current project */ private final Map, IStorage> storageMap = new HashMap<>(); @@ -82,25 +82,25 @@ public class StorageManager implements IStorageManager { public void initBefore() { var resourceDefinitionMap = new HashMap, StorageDefinition>(); - // 获取需要被映射的Excel的class类文件 + // Get the class mapped to Excel var clazzSet = resourceClass(); if (CollectionUtils.isEmpty(clazzSet)) { logger.warn("no any storages found, please check your config. If is in graalvm environment, make sure your storage be annotated with @GraalvmNativeStorage and can be scanned by spring @Component."); return; } - // 通过class类文件扫描excel文件地址 + // Scan for Excel file path based on class for (var resourceClazz : clazzSet) { var resourceFile = resource(resourceClazz); StorageDefinition storageDefinition = new StorageDefinition(resourceClazz, resourceFile); if (resourceDefinitionMap.containsKey(resourceClazz)) { - // 类的资源定义已经存在 + // Resource definition already registered throw new RuntimeException(StringUtils.format("The resource definition of the class [{}] already exists [{}]", resourceClazz, storageDefinition)); } resourceDefinitionMap.put(resourceClazz, storageDefinition); } - // 检查class字段是否合法 + // Validate class fields if (!storageConfig.isWriteable()) { var allRelevantClass = new HashSet>(); resourceDefinitionMap.values().forEach(it -> allRelevantClass.addAll(ClassUtils.relevantClass(it.getClazz()))); @@ -113,7 +113,7 @@ public class StorageManager implements IStorageManager { var fieldList = ReflectionUtils.notStaticAndTransientFields(clazz); for (var field : fieldList) { if (Modifier.isPublic(field.getModifiers())) { - // 因为静态资源类是不能被修改的,资源类的属性不能被public修饰,用private修饰或者开启配置writeable属性 + // Static resource fields must be private; use writeable=true to allow setters throw new RunException("Static resource classes cannot be modified, class:[{}] filed:{}[] cannot be modified by public, use private modified or enable writeable configuration", clazz, field.getName()); } @@ -121,10 +121,10 @@ public class StorageManager implements IStorageManager { try { setMethodName = FieldUtils.fieldToSetMethod(clazz, field); } catch (Exception e) { - // 没有setMethod是正确的 + // No setter is correct for immutable resources } if (StringUtils.isNotBlank(setMethodName)) { - // 因为静态资源类是不能被修改的,资源类的属性不能含有set方法[{}],删除set方法或者开启配置writeable属性 + // Static resource fields must not have setters; remove the setter or enable writeable throw new RunException("Static resource classes cannot be modified, [class:{}][filed:{}] cannot contain set method [{}], delete set method or enable writeable configuration", clazz, field.getName(), setMethodName); } } @@ -150,7 +150,7 @@ public class StorageManager implements IStorageManager { var componentBeans = applicationContext.getBeansWithAnnotation(Component.class); for (var bean : componentBeans.values()) { - //防止被CGLIB代理时 直接赋值无效 + // Prevent direct assignment being ignored when CGLIB-proxied var targetBean = Objects.requireNonNullElse(AopProxyUtils.getSingletonTarget(bean), bean); var clazz = targetBean.getClass(); @@ -181,7 +181,7 @@ public class StorageManager implements IStorageManager { } if (!keyClazz.getSimpleName().toLowerCase().contains(idFields[0].getType().getSimpleName().toLowerCase())) { - // 注入静态类配置资源的类型和泛型类型不匹配 + // Injected type does not match the expected generic type throw new RuntimeException(StringUtils.format("Inject static class configuration storage:[{}] key:[{}] type and generic type type:[{}] do not match", resourceClazz.getSimpleName(), idFields[0].getType().getSimpleName(), keyClazz.getSimpleName())); } @@ -223,7 +223,7 @@ public class StorageManager implements IStorageManager { throw new RunException("There is no [{}] defined Storage and unable to get it", clazz.getCanonicalName()); } if (storage.isRecycle()) { - // Storage没有使用,为了节省内存提前释放了它;只有使用@StorageAutowired注解的Storage才能被动态获取或者关闭配置recycle属性 + // Storage not in use; released to save memory. Use @StorageAutowired or recycle=false to keep it logger.warn("Storage [{}] is not used, it was freed to save memory; use @StorageAutowired or turn off recycle configuration", clazz.getCanonicalName()); } return (T) storage; @@ -245,7 +245,7 @@ public class StorageManager implements IStorageManager { } private Set> resourceClass() { - // graalvm环境 PathMatchingResourcePatternResolver/CachingMetadataReaderFactory 无法使用,所以直接在spring容器中获取 + // In GraalVM: PathMatchingResourcePatternResolver unavailable; get resources from Spring context if (GraalVmUtils.isGraalVM()) { var applicationContext = StorageContext.getApplicationContext(); var nativeResources = applicationContext.getBeansWithAnnotation(GraalvmNativeStorage.class); @@ -301,7 +301,7 @@ public class StorageManager implements IStorageManager { var fileName = StringUtils.isEmpty(alias) ? clazz.getSimpleName() : alias; try { - // 一个class类只能匹配一个资源文件,如果匹配多个则会有歧义 + // A class can match only one resource file; multiple matches are ambiguous var resourceSet = new HashSet(); var resourceLocations = StringUtils.tokenize(storageConfig.getResourceLocation(), ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); for (var resourceLocation : resourceLocations) { @@ -314,7 +314,7 @@ public class StorageManager implements IStorageManager { // do nothing } - // 通配符无法匹配根目录,所以如果找不到,再从根目录查找一遍 + // Wildcards cannot match root directory; retry search from root if (resources.isEmpty()) { packageSearchPath = StringUtils.format("{}/{}.*", resourceLocation, fileName); packageSearchPath = packageSearchPath.replaceAll("//", "/"); diff --git a/storage/src/main/java/com/zfoo/storage/model/IndexDef.java b/storage/src/main/java/com/zfoo/storage/model/IndexDef.java index 62895df1..479b7c0c 100644 --- a/storage/src/main/java/com/zfoo/storage/model/IndexDef.java +++ b/storage/src/main/java/com/zfoo/storage/model/IndexDef.java @@ -24,7 +24,7 @@ import java.util.HashMap; import java.util.Map; /** - * 简化索引的名称,使用字段的名称作为索引的名称 + * Simplified index name using the field name * * @author godotg */ diff --git a/storage/src/main/java/com/zfoo/storage/schema/StorageDefinitionParser.java b/storage/src/main/java/com/zfoo/storage/schema/StorageDefinitionParser.java index 91ec9f01..5f84f96e 100644 --- a/storage/src/main/java/com/zfoo/storage/schema/StorageDefinitionParser.java +++ b/storage/src/main/java/com/zfoo/storage/schema/StorageDefinitionParser.java @@ -29,19 +29,19 @@ import org.w3c.dom.Element; */ public class StorageDefinitionParser implements BeanDefinitionParser { - // 配置标签名称 + // Configuration tag name public static final String STORAGE = "storage"; @Override public AbstractBeanDefinition parse(Element element, ParserContext parserContext) { - // 解析StorageConfig的配置 + // Parse StorageConfig parseStorageConfig(element, parserContext); - // 注册StorageContext + // Register StorageContext registerBeanDefinition(parserContext); - // 注册StorageManager + // Register StorageManager var clazz = StorageManager.class; var name = StringUtils.uncapitalize(clazz.getName()); var builder = BeanDefinitionBuilder.rootBeanDefinition(clazz); @@ -80,7 +80,7 @@ public class StorageDefinitionParser implements BeanDefinitionParser { String name; BeanDefinitionBuilder builder; - // 注册StorageContext + // Register StorageContext clazz = StorageContext.class; name = StringUtils.uncapitalize(clazz.getName()); builder = BeanDefinitionBuilder.rootBeanDefinition(clazz); diff --git a/storage/src/main/java/com/zfoo/storage/util/CellUtils.java b/storage/src/main/java/com/zfoo/storage/util/CellUtils.java index 8e60a7b9..66af067f 100644 --- a/storage/src/main/java/com/zfoo/storage/util/CellUtils.java +++ b/storage/src/main/java/com/zfoo/storage/util/CellUtils.java @@ -32,9 +32,9 @@ public abstract class CellUtils { } /** - * 获取单元格值 + * Get cell value * - * @return 值,类型可能为:Date、Double、Boolean、String + * @return value; possible types: Date, Double, Boolean, String */ public static Object getCellValue(Cell cell) { if (cell == null) { @@ -44,8 +44,8 @@ public abstract class CellUtils { } /** - * 获取单元格值
- * 如果单元格值为数字格式,则判断其格式中是否有小数部分,无则返回Long类型,否则返回Double类型 + * Get cell value
+ * For numeric cells: return Long if no fractional part, otherwise Double */ private static Object getCellValue(Cell cell, CellType cellType) { Object value; @@ -57,7 +57,7 @@ public abstract class CellUtils { value = cell.getBooleanCellValue(); break; case FORMULA: - // 遇到公式时查找公式结果类型 + // For formula cells, check the result type value = getCellValue(cell, cell.getCachedFormulaResultType()); break; case BLANK: @@ -78,9 +78,9 @@ public abstract class CellUtils { // -------------------------------------------------------------------------------------------------------------- Private method start /** - * 获取数字类型的单元格值 + * Get numeric cell value * - * @return 单元格值,可能为Long、Double、Date + * @return cell value; type may be Long, Double, or Date */ private static Object getNumericValue(Cell cell) { var value = cell.getNumericCellValue(); @@ -90,13 +90,13 @@ public abstract class CellUtils { return value; } - // 判断是否为日期 + // Check if value is a date if (DateUtil.isCellDateFormatted(cell)) { return cell.getDateCellValue(); } var format = style.getDataFormatString(); - // 普通数字 + // Plain number if (null != format && !format.contains(StringUtils.PERIOD)) { var longValue = (long) value; if (longValue == value) { diff --git a/storage/src/main/java/com/zfoo/storage/util/ExportUtils.java b/storage/src/main/java/com/zfoo/storage/util/ExportUtils.java index 93845d12..9cedeac1 100644 --- a/storage/src/main/java/com/zfoo/storage/util/ExportUtils.java +++ b/storage/src/main/java/com/zfoo/storage/util/ExportUtils.java @@ -92,7 +92,7 @@ public abstract class ExportUtils { .toList(); } - // 将class里的map自动赋值storage + // Auto-assign class map to storage public static T autoWrapData(Class clazz, Map, IStorage> storageMap) { var instance = ReflectionUtils.newInstance(clazz); @@ -148,25 +148,25 @@ public abstract class ExportUtils { for (char c : valueChars) { if (c == textDelimiter) { - // 字段值中存在包装符 + // Field value contains a quote character containsTextDelimiter = needsTextDelimiter = true; break; } else if (c == fieldSeparator || c == '\n' || c == '\r') { - // 包含分隔符或换行符需要包装符包装 + // Wrap with quotes if value contains delimiter or newline needsTextDelimiter = true; } } - // 包装符开始 + // Opening quote var builder = new StringBuilder(); if (needsTextDelimiter) { builder.append(textDelimiter); } - // 正文 + // Content if (containsTextDelimiter) { for (char c : valueChars) { - // 转义文本包装符 + // Escape embedded quote if (c == textDelimiter) { builder.append(textDelimiter); } @@ -176,7 +176,7 @@ public abstract class ExportUtils { builder.append(valueChars); } - // 包装符结尾 + // Closing quote if (needsTextDelimiter) { builder.append(textDelimiter); } diff --git a/storage/src/main/java/com/zfoo/storage/util/function/Func.java b/storage/src/main/java/com/zfoo/storage/util/function/Func.java index b78dc200..07025f30 100644 --- a/storage/src/main/java/com/zfoo/storage/util/function/Func.java +++ b/storage/src/main/java/com/zfoo/storage/util/function/Func.java @@ -3,25 +3,25 @@ package com.zfoo.storage.util.function; import java.io.Serializable; /** - * 函数对象
- * 接口灵感来自于ActFramework
- * 一个函数接口代表一个一个函数,用于包装一个函数为对象
- * 在JDK8之前,Java的函数并不能作为参数传递,也不能作为返回值存在,此接口用于将一个函数包装成为一个对象,从而传递对象 + * Function object
+ * Inspired by ActFrameworkActFramework
+ * A functional interface wrapping a function as an object
+ * Before JDK 8, functions could not be passed/returned; this wraps a function as an object * * @author Looly * - * @param

参数类型 - * @param 返回值类型 + * @param

parameter type + * @param return type * @since 3.1.0 */ @FunctionalInterface public interface Func extends Serializable { /** - * 执行函数 + * Execute the function * - * @param parameters 参数列表 - * @return 函数执行结果 - * @throws Exception 自定义异常 + * @param parameters parameter list + * @return function result + * @throws Exception custom exception */ @SuppressWarnings("unchecked") R apply(P... parameters) throws Exception; diff --git a/storage/src/main/java/com/zfoo/storage/util/function/Func0.java b/storage/src/main/java/com/zfoo/storage/util/function/Func0.java index 451068d2..044e27e5 100644 --- a/storage/src/main/java/com/zfoo/storage/util/function/Func0.java +++ b/storage/src/main/java/com/zfoo/storage/util/function/Func0.java @@ -3,23 +3,23 @@ package com.zfoo.storage.util.function; import java.io.Serializable; /** - * 无参数的函数对象
- * 接口灵感来自于ActFramework
- * 一个函数接口代表一个一个函数,用于包装一个函数为对象
- * 在JDK8之前,Java的函数并不能作为参数传递,也不能作为返回值存在,此接口用于将一个函数包装成为一个对象,从而传递对象 + * No-parameter Function object
+ * Inspired by ActFrameworkActFramework
+ * A functional interface wrapping a function as an object
+ * Before JDK 8, functions could not be passed/returned; this wraps a function as an object * * @author Looly * - * @param 返回值类型 + * @param return type * @since 4.5.2 */ @FunctionalInterface public interface Func0 extends Serializable { /** - * 执行函数 + * Execute the function * - * @return 函数执行结果 - * @throws Exception 自定义异常 + * @return function result + * @throws Exception custom exception */ R apply() throws Exception; diff --git a/storage/src/main/java/com/zfoo/storage/util/function/Func1.java b/storage/src/main/java/com/zfoo/storage/util/function/Func1.java index f84dfab7..a8e051b6 100644 --- a/storage/src/main/java/com/zfoo/storage/util/function/Func1.java +++ b/storage/src/main/java/com/zfoo/storage/util/function/Func1.java @@ -3,26 +3,26 @@ package com.zfoo.storage.util.function; import java.io.Serializable; /** - * 只有一个参数的函数对象
- * 接口灵感来自于ActFramework
- * 一个函数接口代表一个一个函数,用于包装一个函数为对象
- * 在JDK8之前,Java的函数并不能作为参数传递,也不能作为返回值存在,此接口用于将一个函数包装成为一个对象,从而传递对象 + * Single-parameter Function object
+ * Inspired by ActFrameworkActFramework
+ * A functional interface wrapping a function as an object
+ * Before JDK 8, functions could not be passed/returned; this wraps a function as an object * * @author Looly * - * @param

参数类型 - * @param 返回值类型 + * @param

parameter type + * @param return type * @since 4.2.2 */ @FunctionalInterface public interface Func1 extends Serializable { /** - * 执行函数 + * Execute the function * - * @param parameter 参数 - * @return 函数执行结果 - * @throws Exception 自定义异常 + * @param parameter the parameter + * @return function result + * @throws Exception custom exception */ R apply(P parameter) throws Exception; diff --git a/storage/src/main/java/com/zfoo/storage/util/lambda/IdeaProxyLambdaMeta.java b/storage/src/main/java/com/zfoo/storage/util/lambda/IdeaProxyLambdaMeta.java index 889bc6a8..a2471b08 100644 --- a/storage/src/main/java/com/zfoo/storage/util/lambda/IdeaProxyLambdaMeta.java +++ b/storage/src/main/java/com/zfoo/storage/util/lambda/IdeaProxyLambdaMeta.java @@ -7,7 +7,7 @@ import java.lang.reflect.Executable; import java.lang.reflect.Proxy; /** - * 在 IDEA 的 Evaluate 中执行的 Lambda 表达式元数据需要使用该类处理元数据 + * Handles Lambda metadata for expressions evaluated in IDEA's Evaluate dialog *

* Create by hcl at 2021/5/17 */ diff --git a/storage/src/main/java/com/zfoo/storage/util/lambda/LambdaMeta.java b/storage/src/main/java/com/zfoo/storage/util/lambda/LambdaMeta.java index 9217b0d3..4021cf6e 100644 --- a/storage/src/main/java/com/zfoo/storage/util/lambda/LambdaMeta.java +++ b/storage/src/main/java/com/zfoo/storage/util/lambda/LambdaMeta.java @@ -1,16 +1,16 @@ package com.zfoo.storage.util.lambda; /** - * Lambda 信息 + * Lambda metadata *

* Created by hcl at 2021/5/14 */ public interface LambdaMeta { /** - * 获取 lambda 表达式实现方法的名称 + * Get the implementation method name for the lambda * - * @return lambda 表达式对应的实现方法名称 + * @return the implementation method name */ String getImplMethodName(); diff --git a/storage/src/main/java/com/zfoo/storage/util/lambda/SerializedLambda.java b/storage/src/main/java/com/zfoo/storage/util/lambda/SerializedLambda.java index 2cd684b3..683d8f7d 100644 --- a/storage/src/main/java/com/zfoo/storage/util/lambda/SerializedLambda.java +++ b/storage/src/main/java/com/zfoo/storage/util/lambda/SerializedLambda.java @@ -3,7 +3,7 @@ package com.zfoo.storage.util.lambda; import java.io.*; /** - * 当前类是 {@link java.lang.invoke.SerializedLambda } 的一个镜像 + * A mirror of {@link java.lang.invoke.SerializedLambda} *

* Create by hcl at 2020/7/17 */ diff --git a/storage/src/main/java/com/zfoo/storage/util/lambda/ShadowLambdaMeta.java b/storage/src/main/java/com/zfoo/storage/util/lambda/ShadowLambdaMeta.java index 56dc993e..043fefa6 100644 --- a/storage/src/main/java/com/zfoo/storage/util/lambda/ShadowLambdaMeta.java +++ b/storage/src/main/java/com/zfoo/storage/util/lambda/ShadowLambdaMeta.java @@ -1,7 +1,7 @@ package com.zfoo.storage.util.lambda; /** - * 基于 {@link SerializedLambda} 创建的元信息 + * Metadata based on {@link SerializedLambda} *

* Create by hcl at 2021/7/7 */ diff --git a/storage/src/test/java/com/zfoo/storage/ApplicationTest.java b/storage/src/test/java/com/zfoo/storage/ApplicationTest.java index dfe76a1b..c4c9e53d 100644 --- a/storage/src/test/java/com/zfoo/storage/ApplicationTest.java +++ b/storage/src/test/java/com/zfoo/storage/ApplicationTest.java @@ -38,54 +38,54 @@ public class ApplicationTest { private static final Logger logger = LoggerFactory.getLogger(ApplicationTest.class); - // storage教程 + // Storage tutorial @Test public void startStorageTest() { - // 加载配置文件,配置文件中必须引入storage - // 配置文件中scan,需要映射Excel的类所在位置,会自动搜索文件夹下的Excel文件,Excel文件可以放在指定文件夹的任意目录 - // 配置文件中resource,需要映射Excel的文件所在位置 + // Load config file (must import the storage module) + // 'scan': package containing Excel-mapped classes; Excel files auto-discovered in subdirs + // 'resource': path where Excel files are located var context = new ClassPathXmlApplicationContext("application.xml"); - // Excel的映射内容需要在被Spring管理的bean的方法上加上@ResInjection注解,即可自动注入Excel对应的对象 - // 参考StudentManager中的标准用法 + // Add @ResInjection to a Spring bean method to auto-inject Excel-mapped objects + // See StudentManager for standard usage IStorage storage1 = StorageContext.getStorageManager().getStorage(StudentResource.class); - //根据主键获取数据 + //Get data by primary key StudentResource studentResource = StorageContext.get(StudentResource.class, 1001); TeacherResource teacherResource = StorageContext.get(TeacherResource.class, 1001); - //获取名字索引列表 + //Get name index list List nameIndexList = StorageContext.getIndexes(StudentResource.class, StudentResource::getName, "james1"); - //获取年龄索引列表 + // Get age index list List ageIndexList = StorageContext.getIndexes(StudentResource.class, StudentResource::getAge, 10); - //获取Storage + //Get Storage instance IStorage storage = context.getBean(StorageManager.class).getStorage(StudentResource.class); var studentManager = context.getBean(StudentManager.class); var studentResources = studentManager.studentResources; var studentCsvResources = studentManager.studentCsvResources; - // @Resource注解没指定别名,类名称和Excel名称必须完全一致,没有使用@ExcelFieldName对象属性名会自动对应同名的资源文件列名 + // Without @Resource alias, class and Excel names must match; without @ExcelFieldName, fields map to same-named columns for (StudentResource resource : studentResources.getAll()) { logger.info(JsonUtils.object2String(resource)); } System.out.println(StringUtils.MULTIPLE_HYPHENS); - // 通过id找到对应的行 + // Find row by id var id = 1002; var valueById = studentResources.get(id); logger.info(JsonUtils.object2String(valueById)); System.out.println(StringUtils.MULTIPLE_HYPHENS); - // 通过索引找对应的行 + // Find row by index var valuesByIndex = studentResources.getIndexes(StudentResource::getName, "james0"); logger.info(JsonUtils.object2String(valuesByIndex)); - // 通过索引找对应的行 + // Find row by index var csvValuesByIndex = studentCsvResources.getIndexes(StudentCsvResource::getName, "james0"); logger.info(JsonUtils.object2String(csvValuesByIndex)); - // Excel的映射内容需要在被Spring管理的bean的方法上加上@ResInjection注解,即可自动注入Excel对应的对象 + // Add @ResInjection to a Spring bean method to auto-inject Excel-mapped objects var testManager = context.getBean(TestManager.class); var testResources = testManager.testResources; for (com.zfoo.storage.resource.TestResource resource : testResources.getAll()) { @@ -93,7 +93,7 @@ public class ApplicationTest { AssertionUtils.notNull(map.get(1)); logger.info(JsonUtils.object2String(resource)); } - // 通过id找到对应的行 + // Find row by id id = 2; var resource = testResources.get(id); logger.info(JsonUtils.object2String(resource)); diff --git a/storage/src/test/java/com/zfoo/storage/convert/ConversionTest.java b/storage/src/test/java/com/zfoo/storage/convert/ConversionTest.java index 68aab674..101c3125 100644 --- a/storage/src/test/java/com/zfoo/storage/convert/ConversionTest.java +++ b/storage/src/test/java/com/zfoo/storage/convert/ConversionTest.java @@ -58,7 +58,7 @@ public class ConversionTest { ConversionService conversionService = csfb.getObject(); //Json to Map String str = "{\"1\":1,\"2\":2,\"3\":3}"; - // 注意:第3个参数不能写成TypeDescriptor.valueOf(map.getClass()) 而是要明确指定Map的key和value的类型 + // Note: 3rd arg must NOT be TypeDescriptor.valueOf(map.getClass()); specify key and value types explicitly @SuppressWarnings("unchecked") var map = (Map) conversionService.convert(str, TypeDescriptor.valueOf(String.class), TypeDescriptor.map(HashMap.class, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class))); diff --git a/storage/src/test/java/com/zfoo/storage/excel/ExcelTesting.java b/storage/src/test/java/com/zfoo/storage/excel/ExcelTesting.java index 707a24a0..ffe09c4e 100644 --- a/storage/src/test/java/com/zfoo/storage/excel/ExcelTesting.java +++ b/storage/src/test/java/com/zfoo/storage/excel/ExcelTesting.java @@ -33,50 +33,50 @@ public class ExcelTesting { @Test public void createExcelTest() throws IOException { - //第一步创建workbook + //Step 1: create workbook var wb = WorkbookFactory.create(true); - //第二步创建sheet - var sheet = wb.createSheet("测试"); + //Step 2: create sheet + var sheet = wb.createSheet("TestSheet"); - //第三步创建行row:添加表头0行 + // Step 3: create header row (row 0) var row = sheet.createRow(0); var style = wb.createCellStyle(); - //style.setAlignment(HSSFCellStyle.ALIGN_CENTER); //居中 + //style.setAlignment(HSSFCellStyle.ALIGN_CENTER); //center alignment - //第四步创建单元格 - var cell = row.createCell(0); //第一个单元格 - cell.setCellValue("姓名"); + //Step 4: create cells + var cell = row.createCell(0); //first cell + cell.setCellValue("Name"); cell.setCellStyle(style); - cell = row.createCell(1); //第二个单元格 - cell.setCellValue("年龄"); + cell = row.createCell(1); //second cell + cell.setCellValue("Age"); cell.setCellStyle(style); - //第五步插入数据 + //Step 5: insert data for (int i = 0; i < 5; i++) { - //创建行 + //Create row row = sheet.createRow(i + 1); - //创建单元格并且添加数据 + //Create cells and add data row.createCell(0).setCellValue("aa" + i); row.createCell(1).setCellValue(i); } - //第六步将生成excel文件保存到指定路径下 + //Step 6: save Excel to the specified path FileOutputStream target = new FileOutputStream("target.xlsx"); wb.write(target); target.close(); - System.out.println("Excel文件生成成功..."); + System.out.println("Excel file generated successfully..."); } @Test public void readExcelTest() throws IOException { Workbook wb = WorkbookFactory.create(new File("target.xlsx")); - // 只读取第一个工作簿 + // Read only the first worksheet Sheet sheet = wb.getSheetAt(0); Iterator iterator = sheet.iterator(); @@ -91,7 +91,7 @@ public class ExcelTesting { System.out.println(builder.toString()); } - System.out.println("Excel文件读取成功"); + System.out.println("Excel file read successfully"); } } diff --git a/storage/src/test/java/com/zfoo/storage/export/ExportBinaryTesting.java b/storage/src/test/java/com/zfoo/storage/export/ExportBinaryTesting.java index 315b582e..69f3a941 100644 --- a/storage/src/test/java/com/zfoo/storage/export/ExportBinaryTesting.java +++ b/storage/src/test/java/com/zfoo/storage/export/ExportBinaryTesting.java @@ -50,14 +50,14 @@ public class ExportBinaryTesting { } - // 对应的excel表格,变量对应excel中的列,只有定义过的变量才能导出,没有定义的变量不会导出 + // Variables correspond to Excel columns; only declared variables are exported @Storage public record StudentResource( @Id int id, String idCard, String name, - @AliasFieldName("年龄") + @AliasFieldName("Age") int age, float score, String[] courses, @@ -66,20 +66,20 @@ public class ExportBinaryTesting { ) { } - // 需要定义一个类将所有的excel对象包裹起来 + // Define a wrapper class for all Excel objects public static class ResourceData { public Map studentResources; } - // excel对应的java文件路径,比如ResourceData,StudentResource + // Java class path, e.g. ResourceData, StudentResource public static final String excelClassPath = "com.zfoo.storage.export"; - // excel文件路径,如果是类路径以classpath开头,如果是目录文件路径则以file开头,这里的excel文件在java代码的resources/excel目录里属于类路径 + // Excel path: 'classpath:' for classpath, 'file:' for filesystem public static final String excelFilePath = "classpath:/excel"; - // excel输出的gdscript文件路径,会将excel转为gdscript对象 + // Output GDScript file path public static final String gdscriptOutputPath = "D:\\github\\godot-bird\\excel"; - // excel导出的二进制文件路径 + // Output binary file path public static final String binaryOutputFilePath = "D:/github/godot-bird/excel/binary_data.cfg"; @@ -95,7 +95,7 @@ public class ExportBinaryTesting { storageManager.initBefore(); storageManager.initAfter(); - // 生成协议 + // Generate protocol var protocols = new ArrayList>(); protocols.add(ResourceData.class); protocols.addAll(storageManager.storageMap().keySet()); @@ -104,7 +104,7 @@ public class ExportBinaryTesting { operation.getGenerateLanguages().add(CodeLanguage.GdScript); ProtocolManager.initProtocolAuto(protocols, operation); - // 生成数据 + // Generate data var resourceData = ExportUtils.autoWrapData(ResourceData.class, storageManager.storageMap()); var buffer = new UnpooledHeapByteBuf(ByteBufAllocator.DEFAULT, 100, Integer.MAX_VALUE); ProtocolManager.write(buffer, resourceData); diff --git a/storage/src/test/java/com/zfoo/storage/export/ExportCsvTesting.java b/storage/src/test/java/com/zfoo/storage/export/ExportCsvTesting.java index 73db44ed..0bb7af43 100644 --- a/storage/src/test/java/com/zfoo/storage/export/ExportCsvTesting.java +++ b/storage/src/test/java/com/zfoo/storage/export/ExportCsvTesting.java @@ -34,7 +34,7 @@ public class ExportCsvTesting { var outputDir = "E:\\workspace\\zfoo\\storage\\src\\test\\resources\\excel"; ExportUtils.excel2csv(inputDir, outputDir); - // godot4.x导入csv,莫名奇妙生成了一些translation文件,批量修改一下文件的名称 + // Godot 4.x generates unexpected translation files when importing CSV; batch rename them var csvFiles = ExportUtils.scanCsvFiles(outputDir); csvFiles.stream().forEach(it -> it.renameTo(new File(StringUtils.format("{}.txt", it.getAbsolutePath())))); csvFiles.stream().forEach(it -> FileUtils.deleteFile(it)); diff --git a/storage/src/test/java/com/zfoo/storage/resource/StudentCsvResource.java b/storage/src/test/java/com/zfoo/storage/resource/StudentCsvResource.java index 5243a082..7ae2cdb7 100644 --- a/storage/src/test/java/com/zfoo/storage/resource/StudentCsvResource.java +++ b/storage/src/test/java/com/zfoo/storage/resource/StudentCsvResource.java @@ -27,7 +27,7 @@ public class StudentCsvResource { private int id; /** - * 索引,默认为可重复的索引 + * Index; duplicate entries allowed by default */ @Index private String name; @@ -39,7 +39,7 @@ public class StudentCsvResource { private User user; /** - * 不想映射的字段必须加上transient关键字,这样就不会从Excel中去找对应的列 + * Fields not to be mapped to Excel must be marked with 'transient' */ private transient String notMapContent; diff --git a/storage/src/test/java/com/zfoo/storage/resource/StudentResource.java b/storage/src/test/java/com/zfoo/storage/resource/StudentResource.java index 5f613ca8..1a974544 100644 --- a/storage/src/test/java/com/zfoo/storage/resource/StudentResource.java +++ b/storage/src/test/java/com/zfoo/storage/resource/StudentResource.java @@ -31,12 +31,12 @@ public class StudentResource { private int id; /** - * 索引,默认为可重复的索引 + * Index; duplicate entries allowed by default */ @Index private String name; @Index - @AliasFieldName("年龄") + @AliasFieldName("Age") private int age; private float score; private String[] courses; @@ -47,7 +47,7 @@ public class StudentResource { private List userList; private User user; /** - * 不想映射的字段必须加上transient关键字,这样就不会从Excel中去找对应的列 + * Fields not to be mapped to Excel must be marked with 'transient' */ private transient String notMapContent; diff --git a/storage/src/test/java/com/zfoo/storage/resource/TeacherResource.java b/storage/src/test/java/com/zfoo/storage/resource/TeacherResource.java index 75ff84f7..1363a475 100644 --- a/storage/src/test/java/com/zfoo/storage/resource/TeacherResource.java +++ b/storage/src/test/java/com/zfoo/storage/resource/TeacherResource.java @@ -30,7 +30,7 @@ public record TeacherResource( String idCard, @Index String name, - @AliasFieldName("年龄") + @AliasFieldName("Age") int age, float score, String[] courses,