perf[storage]: 优化storage,调整了结构并减少了重复的代码块

This commit is contained in:
godot committed 2022-07-08 15:34:10 +08:00
1 parent a6a276c8de
commit ba3e9051bc
41 files changed
+326 -335

No files matched your search

@@ -14,13 +14,11 @@ package com.zfoo.protocol.util;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.PrettyPrinter;
import com.fasterxml.jackson.core.util.DefaultIndenter; import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule; import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import com.zfoo.protocol.exception.RunException; import com.zfoo.protocol.exception.RunException;
@@ -29,7 +27,7 @@ import java.io.IOException;
import java.util.*; import java.util.*;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 3.0
*/ */
public abstract class JsonUtils { public abstract class JsonUtils {
@@ -58,12 +56,10 @@ public abstract class JsonUtils {
//当反序列化有未知属性则抛异常,true打开这个设置 //当反序列化有未知属性则抛异常,true打开这个设置
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
//美化输出 //美化输出
SerializationConfig config = MAPPER.getSerializationConfig(); DefaultPrettyPrinter prettyPrinter = (DefaultPrettyPrinter) MAPPER.getSerializationConfig().getDefaultPrettyPrinter();
PrettyPrinter prettyPrinter = config.getDefaultPrettyPrinter(); DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(StringUtils.TAB_ASCII, FileUtils.LS);
DefaultPrettyPrinter defpp = (DefaultPrettyPrinter) prettyPrinter; prettyPrinter.indentObjectsWith(indenter);
DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(" ", DefaultIndenter.SYS_LF); prettyPrinter.indentArraysWith(indenter);
defpp.indentArraysWith(indenter);
defpp.indentObjectsWith(indenter);
MAPPER_TURBO.setSerializationInclusion(JsonInclude.Include.NON_NULL); MAPPER_TURBO.setSerializationInclusion(JsonInclude.Include.NON_NULL);
MAPPER_TURBO.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); MAPPER_TURBO.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
@@ -88,7 +84,7 @@ public abstract class JsonUtils {
} }
} }
//格式化/美化/优雅的输出 // 格式化/美化/优雅的输出
public static String object2StringPrettyPrinter(Object object) { public static String object2StringPrettyPrinter(Object object) {
try { try {
return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object); return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object);
@@ -214,9 +210,9 @@ public abstract class JsonUtils {
// 循环遍历子节点下的信息 // 循环遍历子节点下的信息
while (iterator.hasNext()) { while (iterator.hasNext()) {
var node = iterator.next(); var node = iterator.next();
var filed = node.getKey(); var field = node.getKey();
var value = node.getValue().asText(); var value = node.getValue().asText();
jsonMap.put(filed, value); jsonMap.put(field, value);
} }
} }
return jsonMap; return jsonMap;
@@ -10,7 +10,6 @@
* See the License for the specific language governing permissions and limitations under the License. * See the License for the specific language governing permissions and limitations under the License.
* *
*/ */
package com.zfoo.protocol.util; package com.zfoo.protocol.util;
import com.zfoo.protocol.model.Triple; import com.zfoo.protocol.model.Triple;
@@ -21,11 +20,9 @@ import org.junit.Test;
import java.util.*; import java.util.*;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 3.0
*/ */
public class JsonUtilTest { public class JsonUtilTest {
public static String id = "\"id\":\"1000\""; public static String id = "\"id\":\"1000\"";
@@ -114,5 +111,11 @@ public class JsonUtilTest {
var tripleStr = JsonUtils.object2String(triple); var tripleStr = JsonUtils.object2String(triple);
var temp = JsonUtils.string2Object(tripleStr, Triple.class); var temp = JsonUtils.string2Object(tripleStr, Triple.class);
} }
@Test
public void prettyPrinterTest() {
var user = JsonUtils.string2Object(userJson, User.class);
System.out.println(JsonUtils.object2StringPrettyPrinter(user));
}
} }
@@ -26,8 +26,8 @@ import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class StorageContext implements ApplicationListener<ApplicationContextEvent>, Ordered { public class StorageContext implements ApplicationListener<ApplicationContextEvent>, Ordered {
@@ -13,6 +13,7 @@
package com.zfoo.storage.interpreter; package com.zfoo.storage.interpreter;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
@@ -22,11 +23,11 @@ import java.util.List;
* interpreter [in'ter·pret·er || ɪn'tɜrprɪtə(r) /-'tɜːp-] * interpreter [in'ter·pret·er || ɪn'tɜrprɪtə(r) /-'tɜːp-]
* n. 直译程序, 翻译员, 解释者 * n. 直译程序, 翻译员, 解释者
* *
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public interface IResourceReader { public interface IResourceReader {
<T> List<T> read(InputStream inputStream, Class<T> clazz, String suffix); <T> List<T> read(InputStream inputStream, Class<T> clazz, String suffix) throws IOException;
} }
@@ -1,83 +0,0 @@
package com.zfoo.storage.interpreter;
import java.util.ArrayList;
import java.util.List;
/**
* 配置文件资源
*
*/
public class ResourceConfig {
// 文件名
private String name;
//配置表字段名
private List<Header> header = new ArrayList<>();
// 配置表数据
private List<List<String>> data = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Header> getHeader() {
return header;
}
public void setHeader(List<Header> header) {
this.header = header;
}
public List<List<String>> getData() {
return data;
}
public void setData(List<List<String>> data) {
this.data = data;
}
public static class Header {
//字段名
private String name;
//类型
private String type;
//列
private int index;
public Header() {
}
public Header(String name, String type, int index) {
this.name = name;
this.type = type;
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
}
@@ -10,20 +10,18 @@
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License. * See the License for the specific language governing permissions and limitations under the License.
*/ */
package com.zfoo.storage.interpreter; package com.zfoo.storage.interpreter;
import com.zfoo.protocol.exception.RunException; import com.zfoo.protocol.exception.RunException;
import com.zfoo.protocol.util.IOUtils;
import com.zfoo.protocol.util.JsonUtils; import com.zfoo.protocol.util.JsonUtils;
import com.zfoo.protocol.util.ReflectionUtils; import com.zfoo.protocol.util.ReflectionUtils;
import com.zfoo.protocol.util.StringUtils; import com.zfoo.protocol.util.StringUtils;
import com.zfoo.storage.interpreter.ResourceConfig.Header;
import com.zfoo.storage.model.anno.Id; import com.zfoo.storage.model.anno.Id;
import com.zfoo.storage.model.resource.ResourceData;
import com.zfoo.storage.model.resource.ResourceEnum;
import com.zfoo.storage.strategy.*; import com.zfoo.storage.strategy.*;
import com.zfoo.storage.util.CellUtils; import com.zfoo.storage.util.ExcelToJsonUtils;
import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.context.support.ConversionServiceFactoryBean; import org.springframework.context.support.ConversionServiceFactoryBean;
@@ -33,13 +31,12 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class ResourceReader implements IResourceReader { public class ResourceReader implements IResourceReader {
@@ -60,20 +57,23 @@ public class ResourceReader implements IResourceReader {
} }
@Override @Override
public <T> List<T> read(InputStream inputStream, Class<T> clazz, String suffix) { public <T> List<T> read(InputStream inputStream, Class<T> clazz, String suffix) throws IOException {
ResourceConfig resource = null; ResourceData resource = null;
if (suffix.equals("txt")) { var resourceEnum = ResourceEnum.getResourceEnumByType(suffix);
resource = readJson(inputStream, clazz.getSimpleName()); if (resourceEnum == ResourceEnum.JSON) {
} else { resource = JsonUtils.string2Object(StringUtils.bytesToString(IOUtils.toByteArray(inputStream)), ResourceData.class);
resource = readExcel(inputStream, clazz.getSimpleName()); } else if (resourceEnum == ResourceEnum.EXCEL_XLS || resourceEnum == ResourceEnum.EXCEL_XLSX) {
} resource = ExcelToJsonUtils.readResourceDataFromExcel(inputStream, clazz.getSimpleName());
} else {
throw new RunException("不支持文件[{}]的配置类型[{}]", clazz.getSimpleName(), suffix);
}
var result = new ArrayList<T>(); var result = new ArrayList<T>();
//获取所有字段 //获取所有字段
var cellFieldMap = getFieldMap(resource, clazz); var cellFieldMap = getFieldMap(resource, clazz);
var fieldInfos = getFieldInfos(cellFieldMap, clazz); var fieldInfos = getFieldInfos(cellFieldMap, clazz);
var iterator = resource.getData().iterator(); var iterator = resource.getRows().iterator();
// 从ROW_SERVER这行开始读取数据 // 从ROW_SERVER这行开始读取数据
while (iterator.hasNext()) { while (iterator.hasNext()) {
var row = iterator.next(); var row = iterator.next();
@@ -89,81 +89,7 @@ public class ResourceReader implements IResourceReader {
} }
return result; return result;
} }
public ResourceConfig readExcel(InputStream inputStream, String name) {
var wb = createWorkbook(inputStream, name);
var resource = new ResourceConfig();
resource.setName(name);
// 默认取到第一个sheet页
var sheet = wb.getSheetAt(0);
//设置所有列
var headers = getHeaders(sheet, name);
resource.setHeader(headers);
// 行数定位到有效数据行,默认是第四行为有效数据行
var iterator = sheet.iterator();
iterator.next();
iterator.next();
iterator.next();
// 从ROW_SERVER这行开始读取数据
List<List<String>> data = new ArrayList<>();
while (iterator.hasNext()) {
var row = iterator.next();
List<String> rowData = new ArrayList<>();
for (var header : headers) {
var cell = row.getCell(header.getIndex());
var content = CellUtils.getCellStringValue(cell);
rowData.add(content);
}
data.add(rowData);
}
resource.setData(data);
return resource;
}
// 只读取代码里写的字段
private List<Header> getHeaders(Sheet sheet, String fileName) {
var iterator = sheet.iterator();
// 获取配置表的有效列名称,默认第一行就是字段名称
var fieldRow = iterator.next();
if (fieldRow == null) {
throw new RunException("无法获取资源[class:{}]的Excel文件的属性控制列", fileName);
}
//默认第二行字段类型
var typeRow = iterator.next();
if (typeRow == null) {
throw new RunException("无法获取资源[class:{}]的Excel文件的类型控制列", fileName);
}
var headerList = new ArrayList<Header>();
var cellFieldMap = new HashMap<String, Integer>();
for (var i = 0; i < fieldRow.getLastCellNum(); i++) {
var fieldCell = fieldRow.getCell(i);
if (Objects.isNull(fieldCell)) {
continue;
}
var typeCell = typeRow.getCell(i);
if (Objects.isNull(typeCell)) {
continue;
}
var fieldName = CellUtils.getCellStringValue(fieldCell);
if (StringUtils.isEmpty(fieldName)) {
continue;
}
var typeName = CellUtils.getCellStringValue(typeCell);
if (StringUtils.isEmpty(typeName)) {
continue;
}
var previousValue = cellFieldMap.put(fieldName, i);
if (Objects.nonNull(previousValue)) {
throw new RunException("资源[class:{}]的Excel文件出现重复的属性控制列[field:{}]", fileName, fieldName);
}
headerList.add(new Header(fieldName, typeName, i));
}
return headerList;
}
private void inject(Object instance, Field field, String content) { private void inject(Object instance, Field field, String content) {
try { try {
var targetType = new TypeDescriptor(field); var targetType = new TypeDescriptor(field);
@@ -229,9 +155,9 @@ public class ResourceReader implements IResourceReader {
this.field = field; this.field = field;
} }
} }
public Map<String, Integer> getFieldMap(ResourceConfig resource, Class<?> clazz) { public Map<String, Integer> getFieldMap(ResourceData resource, Class<?> clazz) {
var header = resource.getHeader(); var header = resource.getHeaders();
if (header == null) { if (header == null) {
throw new RunException("无法获取资源[class:{}]的Excel文件的属性控制列", clazz.getSimpleName()); throw new RunException("无法获取资源[class:{}]的Excel文件的属性控制列", clazz.getSimpleName());
} }
@@ -255,13 +181,4 @@ public class ResourceReader implements IResourceReader {
return cellFieldMap; return cellFieldMap;
} }
private ResourceConfig readJson(InputStream input, String name) {
try {
var jsonStr = IOUtils.toString(input, StandardCharsets.UTF_8);
//将json字符转换成对象
return JsonUtils.string2Object(jsonStr, ResourceConfig.class);
} catch (IOException e) {
throw new RunException("静态资源[{}]异常,无法读取文件", name);
}
}
} }
@@ -19,8 +19,8 @@ import org.springframework.lang.Nullable;
import java.util.Map; import java.util.Map;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public interface IStorageManager { public interface IStorageManager {
@@ -38,8 +38,8 @@ import java.lang.reflect.Type;
import java.util.*; import java.util.*;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class StorageManager implements IStorageManager { public class StorageManager implements IStorageManager {
@@ -19,8 +19,8 @@ import java.lang.annotation.*;
/** /**
* 主键 * 主键
* *
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Documented @Documented
@@ -18,8 +18,8 @@ import java.lang.annotation.*;
/** /**
* 索引,索引的名称使用字段属性的名称,用HaspMap实现 * 索引,索引的名称使用字段属性的名称,用HaspMap实现
* *
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Documented @Documented
@@ -18,8 +18,8 @@ import java.lang.annotation.*;
/** /**
* 静态数据的注入 * 静态数据的注入
* *
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Documented @Documented
@@ -18,8 +18,8 @@ import java.lang.annotation.*;
/** /**
* 资源注解 * 资源注解
* *
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Documented @Documented
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@@ -14,8 +14,8 @@
package com.zfoo.storage.model.config; package com.zfoo.storage.model.config;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class StorageConfig { public class StorageConfig {
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.storage.model.resource;
import java.util.ArrayList;
import java.util.List;
/**
* 配置文件资源
*
* @author meiwei666
*/
public class ResourceData {
// 文件名
private String name;
// 配置表字段名
private List<ResourceHeader> headers = new ArrayList<>();
// 配置表数据
private List<List<String>> rows = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<ResourceHeader> getHeaders() {
return headers;
}
public void setHeaders(List<ResourceHeader> headers) {
this.headers = headers;
}
public List<List<String>> getRows() {
return rows;
}
public void setRows(List<List<String>> rows) {
this.rows = rows;
}
}
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.storage.model.resource;
import com.zfoo.protocol.util.AssertionUtils;
import org.springframework.lang.Nullable;
import java.util.HashMap;
import java.util.Map;
/**
* 支持读取配置文件的类型后缀
*
* @author godotg
* @version 4.0
*/
public enum ResourceEnum {
EXCEL_XLS("xls"),
EXCEL_XLSX("xlsx"),
JSON("json"),
;
private static Map<String, ResourceEnum> typeMap = new HashMap<>();
static {
for (var resourceEnum : ResourceEnum.values()) {
var previousValue = typeMap.putIfAbsent(resourceEnum.type, resourceEnum);
AssertionUtils.isNull(previousValue, "ResourceEnum中不应该含有重复type的枚举类[{}]和[{}]", resourceEnum, previousValue);
}
}
private String type;
ResourceEnum(String type) {
this.type = type;
}
@Nullable
public static ResourceEnum getResourceEnumByType(String type) {
return typeMap.get(type);
}
public static boolean containsResourceEnum(String type) {
return typeMap.containsKey(type);
}
public String getType() {
return type;
}
}
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.storage.model.resource;
/**
* @author godotg
* @version 4.0
*/
public class ResourceHeader {
//字段名
private String name;
//类型
private String type;
//列
private int index;
public ResourceHeader() {
}
public ResourceHeader(String name, String type, int index) {
this.name = name;
this.type = type;
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
@@ -20,8 +20,8 @@ import com.zfoo.storage.model.anno.Id;
import java.lang.reflect.Field; import java.lang.reflect.Field;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class IdDef { public class IdDef {
@@ -27,8 +27,8 @@ import java.util.Map;
/** /**
* 简化索引的名称,使用字段的名称作为索引的名称 * 简化索引的名称,使用字段的名称作为索引的名称
* *
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class IndexDef { public class IndexDef {
@@ -16,8 +16,8 @@ package com.zfoo.storage.model.vo;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class ResourceDef { public class ResourceDef {
@@ -25,8 +25,8 @@ import java.io.InputStream;
import java.util.*; import java.util.*;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class Storage<K, V> { public class Storage<K, V> {
@@ -16,8 +16,8 @@ package com.zfoo.storage.schema;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport; import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class NamespaceHandler extends NamespaceHandlerSupport { public class NamespaceHandler extends NamespaceHandlerSupport {
@@ -26,8 +26,8 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element; import org.w3c.dom.Element;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class StorageDefinitionParser implements BeanDefinitionParser { public class StorageDefinitionParser implements BeanDefinitionParser {
@@ -22,8 +22,8 @@ import java.util.Collections;
import java.util.Set; import java.util.Set;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class JsonToArrayConverter implements ConditionalGenericConverter { public class JsonToArrayConverter implements ConditionalGenericConverter {
@@ -22,8 +22,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class JsonToMapConverter implements ConditionalGenericConverter { public class JsonToMapConverter implements ConditionalGenericConverter {
@Override @Override
@@ -24,8 +24,8 @@ import java.util.Set;
/** /**
* 转换一个String到一个POJO对象,且这个对象不能继承如何接口 * 转换一个String到一个POJO对象,且这个对象不能继承如何接口
* *
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class JsonToObjectConverter implements ConditionalGenericConverter { public class JsonToObjectConverter implements ConditionalGenericConverter {
@@ -18,8 +18,8 @@ import com.zfoo.storage.StorageContext;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class StringToClassConverter implements Converter<String, Class<?>> { public class StringToClassConverter implements Converter<String, Class<?>> {
@@ -21,8 +21,8 @@ import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class StringToDateConverter implements Converter<String, Date> { public class StringToDateConverter implements Converter<String, Date> {
@@ -19,8 +19,8 @@ import org.springframework.core.convert.converter.Converter;
import java.util.Map; import java.util.Map;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class StringToMapConverter implements Converter<String, Map<String, Object>> { public class StringToMapConverter implements Converter<String, Map<String, Object>> {
@Override @Override
@@ -20,8 +20,8 @@ import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FormulaError; import org.apache.poi.ss.usermodel.FormulaError;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public abstract class CellUtils { public abstract class CellUtils {
@@ -14,76 +14,55 @@
package com.zfoo.storage.util; package com.zfoo.storage.util;
import com.zfoo.protocol.exception.RunException; import com.zfoo.protocol.exception.RunException;
import com.zfoo.protocol.util.FileUtils;
import com.zfoo.protocol.util.JsonUtils; import com.zfoo.protocol.util.JsonUtils;
import com.zfoo.protocol.util.StringUtils; import com.zfoo.protocol.util.StringUtils;
import com.zfoo.storage.interpreter.ResourceConfig; import com.zfoo.storage.model.resource.ResourceData;
import com.zfoo.storage.interpreter.ResourceConfig.Header; import com.zfoo.storage.model.resource.ResourceEnum;
import com.zfoo.storage.model.resource.ResourceHeader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.usermodel.WorkbookFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/** /**
* @author meiwei666 * @author meiwei666
* @version 3.0 * @version 4.0
*/ */
public class ExcelToJsonUtils { public class ExcelToJsonUtils {
public static void excelConvertJson(String inputDir, String outputDir) throws Exception{ public static void excelConvertJson(String inputDir, String outputDir) throws IOException {
var listFiles = FileUtils.listFiles(new File(inputDir), new String[] { "xls", "xlsx"}, true); var listFiles = FileUtils.getAllReadableFiles(new File(inputDir))
.stream()
.filter(it -> ResourceEnum.containsResourceEnum(FileUtils.fileExtName(it.getName())))
.collect(Collectors.toList());
for (var file : listFiles) { for (var file : listFiles) {
var fileName = getFileName(file); var fileName = StringUtils.format("{}.json", FileUtils.fileSimpleName(file.getName()));
var inputStream = FileUtils.openInputStream(file); var inputStream = FileUtils.openInputStream(file);
var jsonStr = read(inputStream, fileName); var resourceData = readResourceDataFromExcel(inputStream, fileName);
writeJsonFile(outputDir, jsonStr, fileName); FileUtils.writeStringToFile(new File(FileUtils.joinPath(outputDir, fileName)), JsonUtils.object2StringPrettyPrinter(resourceData));
} }
} }
private static void writeJsonFile(String outDir, String jsonStr, String name) {
System.out.println("resource: " + name + ".txt");
PrintWriter pw = null;
try {
File outFile = new File(outDir, name + ".txt");
if (!outFile.exists())
outFile.createNewFile();
pw = new PrintWriter(outFile, "utf-8");
pw.write(jsonStr);
} catch (IOException e) {
System.err.println("error resource:" + name);
} finally {
if (pw != null)
pw.close();
}
}
private static String getFileName(File file) {
String name = file.getName();
int index = name.lastIndexOf(".");
if (index <= 0) {
return "";
}
return name.substring(0, index);
}
public static String read(InputStream inputStream, String fileName) { public static ResourceData readResourceDataFromExcel(InputStream inputStream, String fileName) {
// 只读取代码里写的字段
var wb = createWorkbook(inputStream, fileName); var wb = createWorkbook(inputStream, fileName);
var resource = new ResourceConfig(); var resource = new ResourceData();
resource.setName(fileName); resource.setName(fileName);
// 默认取到第一个sheet页 // 默认取到第一个sheet页
var sheet = wb.getSheetAt(0); var sheet = wb.getSheetAt(0);
//设置所有列 //设置所有列
var headers = getHeaders(sheet, fileName); var headers = getHeaders(sheet, fileName);
resource.setHeader(headers); resource.setHeaders(headers);
// 行数定位到有效数据行,默认是第四行为有效数据行 // 行数定位到有效数据行,默认是第四行为有效数据行
var iterator = sheet.iterator(); var iterator = sheet.iterator();
@@ -102,12 +81,12 @@ public class ExcelToJsonUtils {
} }
data.add(rowData); data.add(rowData);
} }
resource.setData(data); resource.setRows(data);
return JsonUtils.object2StringPrettyPrinter(resource); return resource;
} }
// 只读取代码里写的字段 // 只读取代码里写的字段
private static List<Header> getHeaders(Sheet sheet, String fileName) { private static List<ResourceHeader> getHeaders(Sheet sheet, String fileName) {
var iterator = sheet.iterator(); var iterator = sheet.iterator();
// 获取配置表的有效列名称,默认第一行就是字段名称 // 获取配置表的有效列名称,默认第一行就是字段名称
var fieldRow = iterator.next(); var fieldRow = iterator.next();
@@ -120,7 +99,7 @@ public class ExcelToJsonUtils {
throw new RunException("无法获取资源[class:{}]的Excel文件的类型控制列", fileName); throw new RunException("无法获取资源[class:{}]的Excel文件的类型控制列", fileName);
} }
var headerList = new ArrayList<Header>(); var headerList = new ArrayList<ResourceHeader>();
var cellFieldMap = new HashMap<String, Integer>(); var cellFieldMap = new HashMap<String, Integer>();
for (var i = 0; i < fieldRow.getLastCellNum(); i++) { for (var i = 0; i < fieldRow.getLastCellNum(); i++) {
var fieldCell = fieldRow.getCell(i); var fieldCell = fieldRow.getCell(i);
@@ -143,9 +122,9 @@ public class ExcelToJsonUtils {
if (Objects.nonNull(previousValue)) { if (Objects.nonNull(previousValue)) {
throw new RunException("资源[class:{}]的Excel文件出现重复的属性控制列[field:{}]", fileName, fieldName); throw new RunException("资源[class:{}]的Excel文件出现重复的属性控制列[field:{}]", fileName, fieldName);
} }
headerList.add(new Header(fieldName, typeName, i)); headerList.add(new ResourceHeader(fieldName, typeName, i));
} }
return headerList; return headerList;
} }
private static Workbook createWorkbook(InputStream input, String fileName) { private static Workbook createWorkbook(InputStream input, String fileName) {
@@ -155,5 +134,5 @@ public class ExcelToJsonUtils {
throw new RunException("静态资源[{}]异常,无法读取文件", fileName); throw new RunException("静态资源[{}]异常,无法读取文件", fileName);
} }
} }
} }
@@ -25,8 +25,8 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Map; import java.util.Map;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Ignore @Ignore
@@ -19,8 +19,8 @@ import com.zfoo.storage.resource.StudentResource;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Component @Component
public class StudentManager { public class StudentManager {
@@ -15,14 +15,12 @@ package com.zfoo.storage;
import com.zfoo.storage.model.anno.ResInjection; import com.zfoo.storage.model.anno.ResInjection;
import com.zfoo.storage.model.vo.Storage; import com.zfoo.storage.model.vo.Storage;
import com.zfoo.storage.resource.StudentResource;
import com.zfoo.storage.resource.TestResource; import com.zfoo.storage.resource.TestResource;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Component @Component
public class TestManager { public class TestManager {
@@ -29,8 +29,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class ConversionTest { public class ConversionTest {
private static final ConversionServiceFactoryBean csfb = new ConversionServiceFactoryBean(); private static final ConversionServiceFactoryBean csfb = new ConversionServiceFactoryBean();
@@ -27,8 +27,8 @@ import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Ignore @Ignore
public class ExcelTest { public class ExcelTest {
@@ -22,8 +22,8 @@ import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.IOException; import java.io.IOException;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Ignore @Ignore
public class PathMatchTest { public class PathMatchTest {
@@ -14,8 +14,8 @@
package com.zfoo.storage.resource; package com.zfoo.storage.resource;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class Item { public class Item {
@@ -18,8 +18,8 @@ import com.zfoo.storage.model.anno.Index;
import com.zfoo.storage.model.anno.Resource; import com.zfoo.storage.model.anno.Resource;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Resource @Resource
public class StudentResource { public class StudentResource {
@@ -13,16 +13,14 @@
package com.zfoo.storage.resource; package com.zfoo.storage.resource;
import java.util.List;
import java.util.Map;
import com.zfoo.storage.model.anno.Id; import com.zfoo.storage.model.anno.Id;
import com.zfoo.storage.model.anno.Index;
import com.zfoo.storage.model.anno.Resource; import com.zfoo.storage.model.anno.Resource;
import java.util.Map;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
@Resource @Resource
public class TestResource { public class TestResource {
@@ -14,8 +14,8 @@
package com.zfoo.storage.resource; package com.zfoo.storage.resource;
/** /**
* @author jaysunxiao * @author godotg
* @version 3.0 * @version 4.0
*/ */
public class User { public class User {
@@ -1,15 +1,15 @@
{ {
"name": "Test", "name": "Test",
"header": [ "headers": [
{ {
"name": "Id", "name": "Id",
"type": "int", "type": "int",
"index" : 0 "index": 0
}, },
{ {
"name": "Type0", "name": "Type0",
"type": "long", "type": "long",
"index" : 0 "index": 0
}, },
{ {
"name": "Type1", "name": "Type1",
@@ -52,7 +52,7 @@
"index" : 0 "index" : 0
} }
], ],
"data": [ "rows": [
[ [
"1", "1",
"0", "0",