From 8890cd86cb4ee594cc878797d545410ef5b7f5b7 Mon Sep 17 00:00:00 2001 From: liuyibing Date: Fri, 10 May 2024 10:14:22 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=8A=A5=E6=96=87=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=96=B0=E5=A2=9E=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=20https://gitee.com/asuka2001/alatka-message?= =?UTF-8?q?s/issues/I9O259?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- db/ddl.mysql.sql | 42 +++ .../messages/annotation/IsoFieldMeta.java | 2 +- .../messages/context/FieldDefinition.java | 2 +- .../messages/context/MessageDefinition.java | 2 +- .../AbstractMessageDefinitionBuilder.java | 38 ++- .../AnnotationMessageDefinitionBuilder.java | 32 ++- .../DatabaseMessageDefinitionBuilder.java | 163 +++++++++++- ...xedAnnotationMessageDefinitionBuilder.java | 5 +- ...FixedDatabaseMessageDefinitionBuilder.java | 19 +- .../FixedXmlMessageDefinitionBuilder.java | 1 + .../FixedYamlMessageDefinitionBuilder.java | 1 + ...IsoAnnotationMessageDefinitionBuilder.java | 12 +- .../IsoDatabaseMessageDefinitionBuilder.java | 19 +- .../IsoXmlMessageDefinitionBuilder.java | 3 +- .../IsoYamlMessageDefinitionBuilder.java | 3 +- .../DatabaseMessageDefinitionBuilderTest.java | 239 ++++++++++++++++++ .../FileMessageDefinitionBuilderTest.java | 51 ++++ ...nnotationMessageDefinitionBuilderTest.java | 67 +++++ ...dDatabaseMessageDefinitionBuilderTest.java | 16 ++ .../FixedXmlMessageDefinitionBuilderTest.java | 38 +++ ...FixedYamlMessageDefinitionBuilderTest.java | 38 +++ ...nnotationMessageDefinitionBuilderTest.java | 72 ++++++ ...oDatabaseMessageDefinitionBuilderTest.java | 16 ++ .../IsoXmlMessageDefinitionBuilderTest.java | 34 +++ .../IsoYamlMessageDefinitionBuilderTest.java | 34 +++ .../XmlMessageDefinitionBuilderTest.java | 24 ++ src/test/resources/jcb.common.iso.xml | 2 +- src/test/resources/test/9001.3006.fixed.xml | 0 29 files changed, 914 insertions(+), 64 deletions(-) create mode 100644 db/ddl.mysql.sql create mode 100644 src/test/java/com/alatka/messages/definition/DatabaseMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/FileMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/FixedAnnotationMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/FixedDatabaseMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/FixedXmlMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/FixedYamlMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/IsoAnnotationMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/IsoDatabaseMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/IsoXmlMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/IsoYamlMessageDefinitionBuilderTest.java create mode 100644 src/test/java/com/alatka/messages/definition/XmlMessageDefinitionBuilderTest.java create mode 100644 src/test/resources/test/9001.3006.fixed.xml diff --git a/README.md b/README.md index 6517f78..2268a72 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,9 @@ - 支持各卡组织(visa/万事达/美运/jcb/银联/连通/网联)报文规范; - 支持8583**子域**及其**嵌套子域**解析; - 支持报文域值类型**映射java类型**(Boolean/Integer/String/LocalDate/BigDecimal/List/Map/POJO...); -- 支持**YAML**、**XML**、**注解**、**数据库表**(待实现)四种配置形式; +- 支持**YAML**、**XML**、**注解**、**数据库表**四种配置形式; - **YAML**、**XML**、**数据库表**支持动态配置,可做热更新; + ### [访问wiki获取详情](https://gitee.com/asuka2001/alatka-messages/wikis) \ No newline at end of file diff --git a/db/ddl.mysql.sql b/db/ddl.mysql.sql new file mode 100644 index 0000000..9976ed8 --- /dev/null +++ b/db/ddl.mysql.sql @@ -0,0 +1,42 @@ +-- alatka.ALK_FIELD_DEFINITION definition + +CREATE TABLE `ALK_FIELD_DEFINITION` +( + `M_ID` int unsigned NOT NULL COMMENT 'ALK_MESSAGE_DEFINITION主键', + `F_ID` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', + `F_DOMAIN_NO` int NOT NULL COMMENT '域序号', + `F_NAME` varchar(50) NOT NULL COMMENT '域名称', + `F_ALIAS_NAME` varchar(10) DEFAULT NULL COMMENT '域别名', + `F_FIXED` tinyint(1) NOT NULL COMMENT '是否定长', + `F_LENGTH` int NOT NULL COMMENT '域字节长度', + `F_MAX_LENGTH` int NOT NULL COMMENT '域最大长度', + `F_CLAZZ` varchar(100) NOT NULL COMMENT '域java类型', + `F_PATTERN` varchar(20) DEFAULT NULL COMMENT '域值格式,日期类型使用', + `F_REMARK` varchar(100) NOT NULL COMMENT '域描述', + `F_STATUS` varchar(10) NOT NULL COMMENT '状态', + `F_PAGE_SIZE_NAME` varchar(50) DEFAULT NULL COMMENT '分页记录数字段名称', + `F_PARSE_TYPE` varchar(10) NOT NULL COMMENT '域解析类型', + `F_EXIST_SUBDOMAIN` tinyint(1) NOT NULL COMMENT '是否存在子域', + `F_SUBDOMAIN_TYPE` varchar(10) DEFAULT NULL COMMENT '子域类型', + `F_NON_SUBDOMAIN_EXCEPTION` tinyint(1) DEFAULT NULL COMMENT '未配置子域异常', + PRIMARY KEY (`F_ID`) +) ENGINE=InnoDB AUTO_INCREMENT=468 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='报文域定义表'; + + +-- alatka.ALK_MESSAGE_DEFINITION definition + +CREATE TABLE `ALK_MESSAGE_DEFINITION` +( + `M_ID` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', + `M_TYPE` varchar(10) NOT NULL COMMENT '报文类型 iso: 8583 fixed: 固定格式', + `M_GROUP` varchar(20) NOT NULL COMMENT '报文分组', + `M_CODE` varchar(20) NOT NULL COMMENT '报文交易码', + `M_KIND` varchar(20) NOT NULL COMMENT '报文种类', + `M_DOMAIN` varchar(20) DEFAULT NULL COMMENT '报文子域名称', + `M_USAGE` varchar(2) DEFAULT NULL COMMENT '8583报文子域usage', + `M_DOMAIN_TYPE` varchar(10) DEFAULT NULL COMMENT '报文域类型', + `M_HOLDER` varchar(100) DEFAULT NULL COMMENT '报文实体类', + `M_CHARSET` varchar(100) DEFAULT NULL COMMENT '报文编码', + `M_REMARK` varchar(100) NOT NULL COMMENT '报文描述', + PRIMARY KEY (`M_ID`) +) ENGINE=InnoDB AUTO_INCREMENT=67 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='报文定义表'; \ No newline at end of file diff --git a/src/main/java/com/alatka/messages/annotation/IsoFieldMeta.java b/src/main/java/com/alatka/messages/annotation/IsoFieldMeta.java index bd9d451..e8f1804 100644 --- a/src/main/java/com/alatka/messages/annotation/IsoFieldMeta.java +++ b/src/main/java/com/alatka/messages/annotation/IsoFieldMeta.java @@ -36,7 +36,7 @@ public @interface IsoFieldMeta { /** * {@link IsoFieldDefinition#setLength(Integer)} */ - int length() default Integer.MIN_VALUE; + int length() default 0; /** * {@link IsoFieldDefinition#setMaxLength(Integer)} diff --git a/src/main/java/com/alatka/messages/context/FieldDefinition.java b/src/main/java/com/alatka/messages/context/FieldDefinition.java index e43126e..e15891f 100644 --- a/src/main/java/com/alatka/messages/context/FieldDefinition.java +++ b/src/main/java/com/alatka/messages/context/FieldDefinition.java @@ -60,7 +60,7 @@ public class FieldDefinition implements Comparable { */ private ParseType parseType; /** - * 是否是子域 + * 是否存在子域 */ private Boolean existSubdomain = Boolean.FALSE; /** diff --git a/src/main/java/com/alatka/messages/context/MessageDefinition.java b/src/main/java/com/alatka/messages/context/MessageDefinition.java index 7b21564..372c1d3 100644 --- a/src/main/java/com/alatka/messages/context/MessageDefinition.java +++ b/src/main/java/com/alatka/messages/context/MessageDefinition.java @@ -44,7 +44,7 @@ public class MessageDefinition implements Comparable { */ private String usage; /** - * 8583子域类型 + * 报文域类型 */ private DomainType domainType; /** diff --git a/src/main/java/com/alatka/messages/definition/AbstractMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/AbstractMessageDefinitionBuilder.java index cc45f2c..8a06650 100644 --- a/src/main/java/com/alatka/messages/definition/AbstractMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/AbstractMessageDefinitionBuilder.java @@ -26,7 +26,7 @@ public abstract class AbstractMessageDefinitionBuilder implements MessageDefi @Override public void build() { - this.logger.debug("报文配置{}加载开始执行...", this.getClass().getSimpleName()); + this.logger.debug("报文配置类{}开始执行...", this.getClass().getSimpleName()); MessageDefinitionContext context = MessageDefinitionContext.getInstance(); List messageDefinitions = new ArrayList<>(); @@ -34,8 +34,8 @@ public abstract class AbstractMessageDefinitionBuilder implements MessageDefi Map mapping = this.getSources().stream() .peek(source -> this.logger.info("scan source: " + source)) .flatMap(source -> this.buildMessageDefinitions(source).stream() - .peek(this::postBuildMessageDefinition) - .map(definition -> new Wrapper(definition, source))) + .map(definition -> new Wrapper<>(definition, source))) + .peek(wrapper -> this.logger.debug("build {}", wrapper.definition)) .peek(wrapper -> messageDefinitions.add(wrapper.definition)) .peek(wrapper -> { if (!this.isTemplate(wrapper.definition)) { @@ -43,7 +43,7 @@ public abstract class AbstractMessageDefinitionBuilder implements MessageDefi context.messageDefinition(wrapper.definition.identity(), wrapper.definition); } } - ).collect(Collectors.toMap(wrapper -> wrapper.definition, wrapper -> wrapper.source)); + ).collect(Collectors.toMap(wrapper -> wrapper.definition, wrapper -> wrapper.object)); // 模板对象,减少FieldDefinition对象创建,节省内存开销 Map> fieldDefinitionsTemplate = messageDefinitions.stream() @@ -58,10 +58,14 @@ public abstract class AbstractMessageDefinitionBuilder implements MessageDefi // context 设置 List messageDefinitions.stream() .filter(definition -> !isTemplate(definition)) - .forEach(definition -> - context.fieldDefinitions(definition, - buildFieldDefinitions(definition, mapping.get(definition), fieldDefinitionsTemplate))); - this.logger.debug("报文配置{}加载执行完成", this.getClass().getSimpleName()); + .map(definition -> { + List fieldDefinitions = + this.buildFieldDefinitions(definition, mapping.get(definition), fieldDefinitionsTemplate); + return new Wrapper<>(definition, fieldDefinitions); + }) + .peek(wrapper -> this.logger.debug("build {}: {}", wrapper.definition, wrapper.object)) + .forEach(wrapper -> context.fieldDefinitions(wrapper.definition, wrapper.object)); + this.logger.debug("报文配置类{}执行完成", this.getClass().getSimpleName()); } @Override @@ -92,14 +96,6 @@ public abstract class AbstractMessageDefinitionBuilder implements MessageDefi .collect(Collectors.toList()); } - /** - * {@link MessageDefinition}后处理器 - * - * @param definition {@link MessageDefinition} - */ - private void postBuildMessageDefinition(MessageDefinition definition) { - } - /** * 是否为模板配置 * @@ -127,7 +123,7 @@ public abstract class AbstractMessageDefinitionBuilder implements MessageDefi * * @param definition {@link FieldDefinition} */ - protected void postBuildFieldDefinition(FieldDefinition definition) { + private void postBuildFieldDefinition(FieldDefinition definition) { if (definition.getClazz().isPrimitive()) { throw new IllegalArgumentException("fieldDefinition: " + definition + "不支持原始类型"); } @@ -169,14 +165,14 @@ public abstract class AbstractMessageDefinitionBuilder implements MessageDefi /** * source & {@link MessageDefinition} container */ - private class Wrapper { + private class Wrapper { private final MessageDefinition definition; - private final T source; + private final S object; - public Wrapper(MessageDefinition definition, T source) { + public Wrapper(MessageDefinition definition, S object) { this.definition = definition; - this.source = source; + this.object = object; } } diff --git a/src/main/java/com/alatka/messages/definition/AnnotationMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/AnnotationMessageDefinitionBuilder.java index 26edea9..bfa6ef8 100644 --- a/src/main/java/com/alatka/messages/definition/AnnotationMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/AnnotationMessageDefinitionBuilder.java @@ -9,6 +9,7 @@ import com.alatka.messages.holder.UsageSubdomain; import com.alatka.messages.util.ClassUtil; import org.reflections.Reflections; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.*; import java.util.function.Function; @@ -34,7 +35,7 @@ public abstract class AnnotationMessageDefinitionBuilder extends AbstractMessage ClassUtil.buildDeclaredFields(source, list); return list.stream() - .filter(this::filter) + .filter(field -> field.isAnnotationPresent(annotationClass())) .map(field -> new Wrapper(field, this.buildFieldDefinition(field))) .peek(wrapper -> this.postBuildFieldDefinition(wrapper.field, wrapper.fieldDefinition)) .map(wrapper -> (S) wrapper.fieldDefinition) @@ -74,6 +75,17 @@ public abstract class AnnotationMessageDefinitionBuilder extends AbstractMessage return Collections.singletonList(definition); } + @Override + protected List> getSources() { + Reflections reflections = new Reflections(this.packageName); + Set> set = reflections.getTypesAnnotatedWith(MessageMeta.class, true); + ArrayList> list = new ArrayList<>(set); + return list.stream() + .filter(clazz -> clazz.getAnnotation(MessageMeta.class).type() == this.type()) + .sorted(Comparator.comparing(this::buildMessageDefinition)) + .collect(Collectors.toList()); + } + private MessageDefinition buildMessageDefinition(Class clazz) { MessageMeta annotation = clazz.getAnnotation(MessageMeta.class); MessageDefinition definition = new MessageDefinition(); @@ -90,17 +102,6 @@ public abstract class AnnotationMessageDefinitionBuilder extends AbstractMessage return definition; } - @Override - protected List> getSources() { - Reflections reflections = new Reflections(this.packageName); - Set> set = reflections.getTypesAnnotatedWith(MessageMeta.class, true); - ArrayList> list = new ArrayList<>(set); - return list.stream() - .filter(clazz -> clazz.getAnnotation(MessageMeta.class).type() == this.type()) - .sorted(Comparator.comparing(this::buildMessageDefinition)) - .collect(Collectors.toList()); - } - @Override public void refresh() { throw new UnsupportedOperationException("注解不支持动态加载"); @@ -115,7 +116,12 @@ public abstract class AnnotationMessageDefinitionBuilder extends AbstractMessage */ protected abstract S buildFieldDefinition(Field field); - protected abstract boolean filter(Field field); + /** + * 域注解类 + * + * @return + */ + protected abstract Class annotationClass(); private class Wrapper { private final Field field; diff --git a/src/main/java/com/alatka/messages/definition/DatabaseMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/DatabaseMessageDefinitionBuilder.java index f636cd4..e1708b8 100644 --- a/src/main/java/com/alatka/messages/definition/DatabaseMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/DatabaseMessageDefinitionBuilder.java @@ -1,34 +1,169 @@ package com.alatka.messages.definition; -import com.alatka.messages.context.FieldDefinition; -import com.alatka.messages.context.MessageDefinition; +import com.alatka.messages.context.*; +import com.alatka.messages.holder.MessageHolder; +import com.alatka.messages.support.Constant; +import com.alatka.messages.util.ClassUtil; -import java.util.List; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; /** - * TODO + * database报文定义解析器 * * @author ybliu + * @see AbstractMessageDefinitionBuilder */ -public abstract class DatabaseMessageDefinitionBuilder extends AbstractMessageDefinitionBuilder { +public abstract class DatabaseMessageDefinitionBuilder extends AbstractMessageDefinitionBuilder> { - @Override - protected List buildMessageDefinitions(Object source) { - return null; + private DataSource dataSource; + + public DatabaseMessageDefinitionBuilder(DataSource dataSource) { + this.dataSource = dataSource; } @Override - protected List buildFieldDefinitions(MessageDefinition definition, Object source) { - return null; + protected List buildMessageDefinitions(Map source) { + MessageDefinition definition = this.buildMessageDefinition(source); + return Collections.singletonList(definition); } @Override - protected List getSources() { - return null; + protected List buildFieldDefinitions(MessageDefinition definition, Map source) { + List> list = new ArrayList<>(); + String sql = "select * from ALK_FIELD_DEFINITION WHERE M_ID = ?"; + + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setInt(1, Integer.parseInt(source.get("id").toString())); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + Map result = new HashMap<>(); + result.put("domainNo", resultSet.getInt("F_DOMAIN_NO")); + result.put("name", resultSet.getString("F_NAME")); + result.put("clazz", resultSet.getString("F_CLAZZ")); + result.put("pattern", resultSet.getString("F_PATTERN")); + result.put("fixed", resultSet.getBoolean("F_FIXED")); + result.put("length", resultSet.getInt("F_LENGTH")); + result.put("remark", resultSet.getString("F_REMARK")); + result.put("status", resultSet.getString("F_STATUS")); + result.put("pageSizeName", resultSet.getString("F_PAGE_SIZE_NAME")); + result.put("parseType", resultSet.getString("F_PARSE_TYPE")); + result.put("existSubdomain", resultSet.getBoolean("F_EXIST_SUBDOMAIN")); + result.put("subdomainType", resultSet.getString("F_SUBDOMAIN_TYPE")); + result.put("aliasName", resultSet.getString("F_ALIAS_NAME")); + result.put("maxLength", resultSet.getInt("F_MAX_LENGTH")); + boolean nonSubdomainException = resultSet.getString("F_NON_SUBDOMAIN_EXCEPTION") == null ? + true : resultSet.getBoolean("F_NON_SUBDOMAIN_EXCEPTION"); + result.put("nonSubdomainException", nonSubdomainException); + list.add(result); + } + } + } catch (SQLException e) { + throw new RuntimeException("查询ALK_FIELD_DEFINITION失败", e); + } + + return list.stream() + .map(map -> this.buildFieldDefinition(map, definition)) + .map(entity -> (S) entity) + .sorted() + .collect(Collectors.toList()); + } + + private FieldDefinition buildFieldDefinition(Map result, MessageDefinition definition) { + FieldDefinition fieldDefinition = definition.getType() == MessageDefinition.Type.fixed ? + new FixedFieldDefinition() : new IsoFieldDefinition(); + + fieldDefinition.setDomainNo((Integer) result.get("domainNo")); + fieldDefinition.setName(result.get("name").toString()); + fieldDefinition.setClazz(result.get("clazz").toString()); + fieldDefinition.setPattern(result.get("pattern") == null ? + null : result.get("pattern").toString()); + fieldDefinition.setFixed((boolean) result.get("fixed")); + fieldDefinition.setLength((Integer) result.get("length")); + fieldDefinition.setRemark(result.get("remark").toString()); + fieldDefinition.setStatus(FieldDefinition.Status.valueOf(result.get("status").toString())); + fieldDefinition.setPageSizeName(result.get("pageSizeName") == null ? + null : result.get("pageSizeName").toString()); + fieldDefinition.setParseType(result.get("parseType") == null ? + null : FieldDefinition.ParseType.valueOf(result.get("parseType").toString())); + fieldDefinition.setExistSubdomain((boolean) result.get("existSubdomain")); + fieldDefinition.setSubdomainType(result.get("subdomainType") == null ? + null : MessageDefinition.DomainType.valueOf(result.get("subdomainType").toString())); + if (fieldDefinition instanceof IsoFieldDefinition) { + ((IsoFieldDefinition) fieldDefinition).setMaxLength((Integer) result.get("maxLength")); + ((IsoFieldDefinition) fieldDefinition).setAliasName(result.get("aliasName") == null ? null : result.get("aliasName").toString()); + ((IsoFieldDefinition) fieldDefinition).setNonSubdomainException((boolean) result.get("nonSubdomainException")); + } + if (fieldDefinition.getExistSubdomain()) { + List list = MessageDefinitionContext.getInstance() + .childrenMessageDefinitions(definition, fieldDefinition); + Map messageDefinitionMap = + list.stream().collect(Collectors.toMap(d -> + d.getUsage().isEmpty() ? FieldDefinition.SUBFIELD_KEY_DEFAULT : d.getUsage(), Function.identity())); + fieldDefinition.setMessageDefinitionMap(messageDefinitionMap); + } + return fieldDefinition; } @Override - protected MessageDefinition.Type type() { - return null; + protected List> getSources() { + List> list = new ArrayList<>(); + String sql = "select * from ALK_MESSAGE_DEFINITION WHERE M_TYPE = ?"; + + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, this.type().name()); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + Map result = new HashMap<>(); + result.put("id", resultSet.getInt("M_ID")); + result.put("type", resultSet.getString("M_TYPE")); + result.put("group", resultSet.getString("M_GROUP")); + result.put("code", resultSet.getString("M_CODE")); + result.put("kind", resultSet.getString("M_KIND")); + result.put("domain", resultSet.getString("M_DOMAIN")); + result.put("usage", resultSet.getString("M_USAGE")); + result.put("domainType", resultSet.getString("M_DOMAIN_TYPE")); + result.put("holder", resultSet.getString("M_HOLDER")); + result.put("charset", resultSet.getString("M_CHARSET")); + result.put("remark", resultSet.getString("M_REMARK")); + list.add(result); + } + } + } catch (SQLException e) { + throw new RuntimeException("查询ALK_MESSAGE_DEFINITION失败", e); + } + + return list.stream() + .sorted(Comparator.comparing(this::buildMessageDefinition)) + .collect(Collectors.toList()); } + + private MessageDefinition buildMessageDefinition(Map source) { + MessageDefinition definition = new MessageDefinition(); + definition.setType(MessageDefinition.Type.valueOf(source.get("type").toString())); + definition.setGroup(source.get("group").toString()); + definition.setCode(source.get("code").toString()); + definition.setKind(MessageDefinition.Kind.valueOf(source.get("kind").toString())); + definition.setDomain(source.get("domain") == null ? + "" : source.get("domain").toString()); + definition.setUsage(source.get("usage") == null ? + "" : source.get("usage").toString()); + definition.setDomainType(source.get("domainType") == null ? + MessageDefinition.DomainType.NONE : MessageDefinition.DomainType.valueOf(source.get("domainType").toString())); + definition.setHolder(source.get("holder") == null ? + MessageHolder.class : ClassUtil.forName(source.get("holder").toString())); + definition.setCharset(source.get("charset") == null ? + Constant.DEFAULT_CHARSET : source.get("charset").toString()); + definition.setRemark(source.get("remark").toString()); + return definition; + } + } diff --git a/src/main/java/com/alatka/messages/definition/FixedAnnotationMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/FixedAnnotationMessageDefinitionBuilder.java index 014fe3b..11a6b14 100644 --- a/src/main/java/com/alatka/messages/definition/FixedAnnotationMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/FixedAnnotationMessageDefinitionBuilder.java @@ -4,6 +4,7 @@ import com.alatka.messages.annotation.FixedFieldMeta; import com.alatka.messages.context.FixedFieldDefinition; import com.alatka.messages.context.MessageDefinition; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; /** @@ -20,8 +21,8 @@ public class FixedAnnotationMessageDefinitionBuilder extends AnnotationMessageDe } @Override - protected boolean filter(Field field) { - return field.isAnnotationPresent(FixedFieldMeta.class); + protected Class annotationClass() { + return FixedFieldMeta.class; } @Override diff --git a/src/main/java/com/alatka/messages/definition/FixedDatabaseMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/FixedDatabaseMessageDefinitionBuilder.java index 284a148..04ba863 100644 --- a/src/main/java/com/alatka/messages/definition/FixedDatabaseMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/FixedDatabaseMessageDefinitionBuilder.java @@ -1,8 +1,25 @@ package com.alatka.messages.definition; +import com.alatka.messages.context.MessageDefinition; + +import javax.sql.DataSource; + /** - * TODO + * 固定格式database报文定义解析器 + * + * @author ybliu + * @see DatabaseMessageDefinitionBuilder + * @see AbstractMessageDefinitionBuilder */ public class FixedDatabaseMessageDefinitionBuilder extends DatabaseMessageDefinitionBuilder { + public FixedDatabaseMessageDefinitionBuilder(DataSource dataSource) { + super(dataSource); + } + + @Override + protected MessageDefinition.Type type() { + return MessageDefinition.Type.fixed; + } + } diff --git a/src/main/java/com/alatka/messages/definition/FixedXmlMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/FixedXmlMessageDefinitionBuilder.java index 64ff93d..87d369b 100644 --- a/src/main/java/com/alatka/messages/definition/FixedXmlMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/FixedXmlMessageDefinitionBuilder.java @@ -9,6 +9,7 @@ import com.alatka.messages.context.MessageDefinition; * * @author ybliu * @see XmlMessageDefinitionBuilder + * @see FileMessageDefinitionBuilder * @see AbstractMessageDefinitionBuilder */ public class FixedXmlMessageDefinitionBuilder extends XmlMessageDefinitionBuilder { diff --git a/src/main/java/com/alatka/messages/definition/FixedYamlMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/FixedYamlMessageDefinitionBuilder.java index 5269bc9..8e2e573 100644 --- a/src/main/java/com/alatka/messages/definition/FixedYamlMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/FixedYamlMessageDefinitionBuilder.java @@ -9,6 +9,7 @@ import com.alatka.messages.context.MessageDefinition; * * @author ybliu * @see YamlMessageDefinitionBuilder + * @see FileMessageDefinitionBuilder * @see AbstractMessageDefinitionBuilder */ public class FixedYamlMessageDefinitionBuilder extends YamlMessageDefinitionBuilder { diff --git a/src/main/java/com/alatka/messages/definition/IsoAnnotationMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/IsoAnnotationMessageDefinitionBuilder.java index 2fa2353..5fd8397 100644 --- a/src/main/java/com/alatka/messages/definition/IsoAnnotationMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/IsoAnnotationMessageDefinitionBuilder.java @@ -4,6 +4,7 @@ import com.alatka.messages.annotation.IsoFieldMeta; import com.alatka.messages.context.IsoFieldDefinition; import com.alatka.messages.context.MessageDefinition; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; /** @@ -20,8 +21,8 @@ public class IsoAnnotationMessageDefinitionBuilder extends AnnotationMessageDefi } @Override - protected boolean filter(Field field) { - return field.isAnnotationPresent(IsoFieldMeta.class); + protected Class annotationClass() { + return IsoFieldMeta.class; } @Override @@ -44,12 +45,13 @@ public class IsoAnnotationMessageDefinitionBuilder extends AnnotationMessageDefi fieldDefinition.setParseType(annotation.parseType()); fieldDefinition.setExistSubdomain(annotation.existSubdomain()); fieldDefinition.setSubdomainType(annotation.subdomainType()); - fieldDefinition.setNonSubdomainException(annotation.nonSubdomainException()); fieldDefinition.setPageSizeName(annotation.pageSizeName()); + fieldDefinition.setNonSubdomainException(annotation.nonSubdomainException()); fieldDefinition.setAliasName(annotation.aliasName()); - fieldDefinition.setMaxLength(fieldDefinition.getFixed() && annotation.maxLength() == -1 ? - fieldDefinition.getLength() : annotation.maxLength()); + int maxLength = annotation.maxLength(); + fieldDefinition.setMaxLength(fieldDefinition.getFixed() && maxLength == -1 ? + fieldDefinition.getLength() : maxLength); return fieldDefinition; } } diff --git a/src/main/java/com/alatka/messages/definition/IsoDatabaseMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/IsoDatabaseMessageDefinitionBuilder.java index c3000c4..cee4149 100644 --- a/src/main/java/com/alatka/messages/definition/IsoDatabaseMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/IsoDatabaseMessageDefinitionBuilder.java @@ -1,7 +1,24 @@ package com.alatka.messages.definition; +import com.alatka.messages.context.MessageDefinition; + +import javax.sql.DataSource; + /** - * TODO + * 8583 database报文定义解析器 + * + * @author ybliu + * @see DatabaseMessageDefinitionBuilder + * @see AbstractMessageDefinitionBuilder */ public class IsoDatabaseMessageDefinitionBuilder extends DatabaseMessageDefinitionBuilder { + + public IsoDatabaseMessageDefinitionBuilder(DataSource dataSource) { + super(dataSource); + } + + @Override + protected MessageDefinition.Type type() { + return MessageDefinition.Type.iso; + } } diff --git a/src/main/java/com/alatka/messages/definition/IsoXmlMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/IsoXmlMessageDefinitionBuilder.java index 1d48ef5..29e8559 100644 --- a/src/main/java/com/alatka/messages/definition/IsoXmlMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/IsoXmlMessageDefinitionBuilder.java @@ -9,6 +9,7 @@ import com.alatka.messages.context.MessageDefinition; * * @author ybliu * @see XmlMessageDefinitionBuilder + * @see FileMessageDefinitionBuilder * @see AbstractMessageDefinitionBuilder */ public class IsoXmlMessageDefinitionBuilder extends XmlMessageDefinitionBuilder { @@ -25,7 +26,7 @@ public class IsoXmlMessageDefinitionBuilder extends XmlMessageDefinitionBuilder protected void postBuildFieldDefinition(MessageDefinition messageDefinition, FieldDefinition fieldDefinition) { IsoFieldDefinition definition = (IsoFieldDefinition) fieldDefinition; if (definition.getLength() == null) { - definition.setLength(Integer.MIN_VALUE); + definition.setLength(0); } if (definition.getFixed() && definition.getMaxLength() == null) { definition.setMaxLength(definition.getLength()); diff --git a/src/main/java/com/alatka/messages/definition/IsoYamlMessageDefinitionBuilder.java b/src/main/java/com/alatka/messages/definition/IsoYamlMessageDefinitionBuilder.java index 06ee6b6..014c91b 100644 --- a/src/main/java/com/alatka/messages/definition/IsoYamlMessageDefinitionBuilder.java +++ b/src/main/java/com/alatka/messages/definition/IsoYamlMessageDefinitionBuilder.java @@ -9,6 +9,7 @@ import com.alatka.messages.context.MessageDefinition; * * @author ybliu * @see YamlMessageDefinitionBuilder + * @see FileMessageDefinitionBuilder * @see AbstractMessageDefinitionBuilder */ public class IsoYamlMessageDefinitionBuilder extends YamlMessageDefinitionBuilder { @@ -25,7 +26,7 @@ public class IsoYamlMessageDefinitionBuilder extends YamlMessageDefinitionBuilde protected void postBuildFieldDefinition(MessageDefinition messageDefinition, FieldDefinition fieldDefinition) { IsoFieldDefinition definition = (IsoFieldDefinition) fieldDefinition; if (definition.getLength() == null) { - definition.setLength(Integer.MIN_VALUE); + definition.setLength(0); } if (definition.getFixed() && definition.getMaxLength() == null) { definition.setMaxLength(definition.getLength()); diff --git a/src/test/java/com/alatka/messages/definition/DatabaseMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/DatabaseMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..d187ba3 --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/DatabaseMessageDefinitionBuilderTest.java @@ -0,0 +1,239 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.context.FieldDefinition; +import com.alatka.messages.context.IsoFieldDefinition; +import com.alatka.messages.context.MessageDefinition; +import com.alatka.messages.context.MessageDefinitionContext; +import com.alatka.messages.holder.MessageHolder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import javax.sql.DataSource; +import java.nio.charset.Charset; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.LocalDate; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mockStatic; + +public class DatabaseMessageDefinitionBuilderTest { + + @Test + @DisplayName("getSources()") + void test01() throws SQLException { + ResultSet resultSet = Mockito.mock(ResultSet.class); + doReturn(true, true, false).when(resultSet).next(); + doReturn(2, 1).when(resultSet).getInt("M_ID"); + doReturn("fixed", "iso").when(resultSet).getString("M_TYPE"); + doReturn("0901", "visa").when(resultSet).getString("M_GROUP"); + doReturn("3006", "common").when(resultSet).getString("M_CODE"); + doReturn("request", "payload").when(resultSet).getString("M_KIND"); + doReturn(null, null).when(resultSet).getString("M_DOMAIN"); + doReturn(null, null).when(resultSet).getString("M_USAGE"); + doReturn("NONE", "NONE").when(resultSet).getString("M_DOMAIN_TYPE"); + doReturn(null, "com.alatka.messages.holder.MessageHolder").when(resultSet).getString("M_HOLDER"); + doReturn(null, "GB18030").when(resultSet).getString("M_CHARSET"); + doReturn("fixed testing", "8583 testing").when(resultSet).getString("M_REMARK"); + + PreparedStatement statement = Mockito.mock(PreparedStatement.class); + doReturn(resultSet).when(statement).executeQuery(); + Connection connection = Mockito.mock(Connection.class); + doReturn(statement).when(connection).prepareStatement(ArgumentMatchers.any()); + DataSource dataSource = Mockito.mock(DataSource.class); + doReturn(connection).when(dataSource).getConnection(); + + FixedDatabaseMessageDefinitionBuilder builder = Mockito.spy(new FixedDatabaseMessageDefinitionBuilder(dataSource)); + + List> sources = builder.getSources(); + + Assertions.assertEquals(2, sources.size()); + + Assertions.assertEquals(1, sources.get(0).get("id")); + Assertions.assertEquals("iso", sources.get(0).get("type")); + Assertions.assertEquals("visa", sources.get(0).get("group")); + Assertions.assertEquals("common", sources.get(0).get("code")); + Assertions.assertEquals("payload", sources.get(0).get("kind")); + Assertions.assertNull(sources.get(0).get("domain")); + Assertions.assertNull(sources.get(0).get("usage")); + Assertions.assertEquals("NONE", sources.get(0).get("domainType")); + Assertions.assertEquals("com.alatka.messages.holder.MessageHolder", sources.get(0).get("holder")); + Assertions.assertEquals("GB18030", sources.get(0).get("charset")); + Assertions.assertEquals("8583 testing", sources.get(0).get("remark")); + + Assertions.assertEquals(2, sources.get(1).get("id")); + Assertions.assertEquals("fixed", sources.get(1).get("type")); + Assertions.assertEquals("0901", sources.get(1).get("group")); + Assertions.assertEquals("3006", sources.get(1).get("code")); + Assertions.assertEquals("request", sources.get(1).get("kind")); + Assertions.assertNull(sources.get(1).get("domain")); + Assertions.assertNull(sources.get(1).get("usage")); + Assertions.assertEquals("NONE", sources.get(1).get("domainType")); + Assertions.assertNull(sources.get(1).get("holder")); + Assertions.assertNull(sources.get(1).get("charset")); + Assertions.assertEquals("fixed testing", sources.get(1).get("remark")); + } + + @Test + @DisplayName("getSources() exception") + void test02() { + DataSource dataSource = Mockito.mock(DataSource.class); + try { + Mockito.doThrow(SQLException.class).when(dataSource).getConnection(); + } catch (SQLException e) { + e.printStackTrace(); + } + FixedDatabaseMessageDefinitionBuilder builder = Mockito.spy(new FixedDatabaseMessageDefinitionBuilder(dataSource)); + + Assertions.assertThrows(RuntimeException.class, () -> builder.getSources()); + } + + @Test + @DisplayName("buildMessageDefinitions()") + void test03() { + Map source = Mockito.mock(HashMap.class); + doReturn("fixed", "iso").when(source).get("type"); + doReturn("9001", "visa").when(source).get("group"); + doReturn("3004", "common").when(source).get("code"); + doReturn("request", "subPayload").when(source).get("kind"); + doReturn(null, "F13").when(source).get("domain"); + doReturn(null, "AB").when(source).get("usage"); + doReturn(null, "UV").when(source).get("domainType"); + doReturn(null, "com.alatka.messages.holder.MessageHolder").when(source).get("holder"); + doReturn(null, "GBK").when(source).get("charset"); + doReturn("fixed testing", "8583 testing").when(source).get("remark"); + + FixedDatabaseMessageDefinitionBuilder builder = new FixedDatabaseMessageDefinitionBuilder(null); + List list1 = builder.buildMessageDefinitions(source); + Assertions.assertEquals(1, list1.size()); + Assertions.assertEquals(MessageDefinition.Type.fixed, list1.get(0).getType()); + Assertions.assertEquals("9001", list1.get(0).getGroup()); + Assertions.assertEquals("3004", list1.get(0).getCode()); + Assertions.assertEquals(MessageDefinition.Kind.request, list1.get(0).getKind()); + Assertions.assertEquals("", list1.get(0).getDomain()); + Assertions.assertEquals("", list1.get(0).getUsage()); + Assertions.assertEquals(MessageDefinition.DomainType.NONE, list1.get(0).getDomainType()); + Assertions.assertEquals(MessageHolder.class, list1.get(0).getHolder()); + Assertions.assertEquals(Charset.forName("GB18030"), list1.get(0).getCharset()); + Assertions.assertEquals("fixed testing", list1.get(0).getRemark()); + + List list2 = builder.buildMessageDefinitions(source); + Assertions.assertEquals(1, list2.size()); + Assertions.assertEquals(MessageDefinition.Type.iso, list2.get(0).getType()); + Assertions.assertEquals("visa", list2.get(0).getGroup()); + Assertions.assertEquals("common", list2.get(0).getCode()); + Assertions.assertEquals(MessageDefinition.Kind.subPayload, list2.get(0).getKind()); + Assertions.assertEquals("F13", list2.get(0).getDomain()); + Assertions.assertEquals("AB", list2.get(0).getUsage()); + Assertions.assertEquals(MessageDefinition.DomainType.UV, list2.get(0).getDomainType()); + Assertions.assertEquals(MessageHolder.class, list2.get(0).getHolder()); + Assertions.assertEquals(Charset.forName("GBK"), list2.get(0).getCharset()); + Assertions.assertEquals("8583 testing", list2.get(0).getRemark()); + } + + @Test + @DisplayName("buildFieldDefinitions()") + void test04() throws SQLException { + ResultSet resultSet = Mockito.mock(ResultSet.class); + doReturn(true, true, false).when(resultSet).next(); + doReturn(1, 2).when(resultSet).getInt("F_DOMAIN_NO"); + doReturn("test1", "test2").when(resultSet).getString("F_NAME"); + doReturn("java.lang.String", "java.time.LocalDate").when(resultSet).getString("F_CLAZZ"); + doReturn(null, "yyyyMMdd").when(resultSet).getString("F_PATTERN"); + doReturn(true, false).when(resultSet).getBoolean("F_FIXED"); + doReturn(20, 8).when(resultSet).getInt("F_LENGTH"); + doReturn("fixed testing", "8583 testing").when(resultSet).getString("F_REMARK"); + doReturn("OPEN", "RAW").when(resultSet).getString("F_STATUS"); + doReturn(null, "counts").when(resultSet).getString("F_PAGE_SIZE_NAME"); + doReturn("ASCII", "BCD").when(resultSet).getString("F_PARSE_TYPE"); + doReturn(false, true).when(resultSet).getBoolean("F_EXIST_SUBDOMAIN"); + doReturn("FIXED", "PAGE").when(resultSet).getString("F_SUBDOMAIN_TYPE"); + doReturn(null, "alias").when(resultSet).getString("F_ALIAS_NAME"); + doReturn(20, 10).when(resultSet).getInt("F_MAX_LENGTH"); + doReturn(false, true).when(resultSet).getBoolean("F_NON_SUBDOMAIN_EXCEPTION"); + + PreparedStatement statement = Mockito.mock(PreparedStatement.class); + doReturn(resultSet).when(statement).executeQuery(); + Connection connection = Mockito.mock(Connection.class); + doReturn(statement).when(connection).prepareStatement(ArgumentMatchers.any()); + DataSource dataSource = Mockito.mock(DataSource.class); + doReturn(connection).when(dataSource).getConnection(); + + FixedDatabaseMessageDefinitionBuilder builder = Mockito.spy(new FixedDatabaseMessageDefinitionBuilder(dataSource)); + + MessageDefinition subdomain = new MessageDefinition(); + subdomain.setUsage(""); + + List definitions = Collections.singletonList(subdomain); + MessageDefinitionContext mock = Mockito.mock(MessageDefinitionContext.class); + doReturn(definitions).when(mock).childrenMessageDefinitions(any(), any()); + MockedStatic mockedStatic = mockStatic(MessageDefinitionContext.class); + mockedStatic.when(MessageDefinitionContext::getInstance).thenReturn(mock); + + MessageDefinition definition = Mockito.mock(MessageDefinition.class); + doReturn(MessageDefinition.Type.fixed, MessageDefinition.Type.iso).when(definition).getType(); + + List list = builder.buildFieldDefinitions(definition, Collections.singletonMap("id", 1)); + + Assertions.assertEquals(2, list.size()); + + Assertions.assertEquals(1, list.get(0).getDomainNo()); + Assertions.assertEquals("test1", list.get(0).getName()); + Assertions.assertEquals(String.class, list.get(0).getClazz()); + Assertions.assertNull(list.get(0).getPattern()); + Assertions.assertTrue(list.get(0).getFixed()); + Assertions.assertEquals(20, list.get(0).getLength()); + Assertions.assertEquals("fixed testing", list.get(0).getRemark()); + Assertions.assertEquals(FieldDefinition.Status.OPEN, list.get(0).getStatus()); + Assertions.assertNull(list.get(0).getPageSizeName()); + Assertions.assertEquals(FieldDefinition.ParseType.ASCII, list.get(0).getParseType()); + Assertions.assertFalse(list.get(0).getExistSubdomain()); + Assertions.assertEquals(MessageDefinition.DomainType.FIXED, list.get(0).getSubdomainType()); + + Assertions.assertEquals(2, list.get(1).getDomainNo()); + Assertions.assertEquals("test2", list.get(1).getName()); + Assertions.assertEquals(LocalDate.class, list.get(1).getClazz()); + Assertions.assertEquals("yyyyMMdd", list.get(1).getPattern()); + Assertions.assertFalse(list.get(1).getFixed()); + Assertions.assertEquals(8, list.get(1).getLength()); + Assertions.assertEquals("8583 testing", list.get(1).getRemark()); + Assertions.assertEquals(FieldDefinition.Status.RAW, list.get(1).getStatus()); + Assertions.assertEquals("counts", list.get(1).getPageSizeName()); + Assertions.assertEquals(FieldDefinition.ParseType.BCD, list.get(1).getParseType()); + Assertions.assertTrue(list.get(1).getExistSubdomain()); + Assertions.assertEquals(MessageDefinition.DomainType.PAGE, list.get(1).getSubdomainType()); + Assertions.assertEquals("alias", ((IsoFieldDefinition) list.get(1)).getAliasName()); + Assertions.assertEquals(10, ((IsoFieldDefinition) list.get(1)).getMaxLength()); + Assertions.assertTrue(((IsoFieldDefinition) list.get(1)).getNonSubdomainException()); + Map messageDefinitionMap = list.get(1).getMessageDefinitionMap(); + Assertions.assertEquals(1, messageDefinitionMap.size()); + Assertions.assertEquals(subdomain, messageDefinitionMap.get(FieldDefinition.SUBFIELD_KEY_DEFAULT)); + + mockedStatic.close(); + } + + @Test + @DisplayName("buildFieldDefinitions() exception") + void test05() { + DataSource dataSource = Mockito.mock(DataSource.class); + try { + Mockito.doThrow(SQLException.class).when(dataSource).getConnection(); + } catch (SQLException e) { + e.printStackTrace(); + } + FixedDatabaseMessageDefinitionBuilder builder = Mockito.spy(new FixedDatabaseMessageDefinitionBuilder(dataSource)); + + Assertions.assertThrows(RuntimeException.class, () -> builder.buildFieldDefinitions(null, null)); + } +} diff --git a/src/test/java/com/alatka/messages/definition/FileMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/FileMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..37621f7 --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/FileMessageDefinitionBuilderTest.java @@ -0,0 +1,51 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.context.MessageDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.nio.file.Path; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.any; + +public class FileMessageDefinitionBuilderTest { + + @Test + @DisplayName("getValueWithMap()") + void test01() throws SQLException { + FileMessageDefinitionBuilder builder = Mockito.spy(new FixedXmlMessageDefinitionBuilder()); + + Map map = new HashMap<>(); + map.put("123", 123); + Assertions.assertEquals(123, (int) builder.getValueWithMap(map, "123")); + Assertions.assertNull(builder.getValueWithMap(map, "1")); + } + + @Test + @DisplayName("getSources()") + void test02() { + FileMessageDefinitionBuilder builder = Mockito.spy(new FixedXmlMessageDefinitionBuilder("test")); + Mockito.doReturn(MessageDefinition.Type.fixed).when(builder).type(); + Mockito.doReturn(".xml").when(builder).fileSuffix(); + + List list = builder.getSources(); + Assertions.assertEquals(1, list.size()); + Assertions.assertEquals("9001.3006.fixed.xml", list.get(0).toFile().getName()); + } + + @Disabled + @Test + @DisplayName("buildFieldDefinitions()") + void test03() { + FileMessageDefinitionBuilder builder = Mockito.spy(new FixedXmlMessageDefinitionBuilder()); + // TODO + Mockito.doReturn(null).when(builder).doBuildFieldDefinitions(any(), any()); + } +} diff --git a/src/test/java/com/alatka/messages/definition/FixedAnnotationMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/FixedAnnotationMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..b0da0d5 --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/FixedAnnotationMessageDefinitionBuilderTest.java @@ -0,0 +1,67 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.annotation.FixedFieldMeta; +import com.alatka.messages.context.FieldDefinition; +import com.alatka.messages.context.FixedFieldDefinition; +import com.alatka.messages.context.MessageDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.lang.reflect.Field; + +public class FixedAnnotationMessageDefinitionBuilderTest { + + private FixedAnnotationMessageDefinitionBuilder builder = new FixedAnnotationMessageDefinitionBuilder(""); + + @Test + @DisplayName("type()") + void test01() { + Assertions.assertEquals(MessageDefinition.Type.fixed, builder.type()); + } + + @Test + @DisplayName("annotationClass()") + void test02() { + Assertions.assertEquals(FixedFieldMeta.class, builder.annotationClass()); + } + + @Test + @DisplayName("buildFieldDefinition()") + void test03() { + FixedFieldMeta annotation = Mockito.mock(FixedFieldMeta.class); + Mockito.doReturn(1).when(annotation).domainNo(); + Mockito.doReturn("yyyyMMdd").when(annotation).pattern(); + Mockito.doReturn(false).when(annotation).fixed(); + Mockito.doReturn(20).when(annotation).length(); + Mockito.doReturn("testing").when(annotation).remark(); + Mockito.doReturn(FieldDefinition.Status.OPEN).when(annotation).status(); + Mockito.doReturn(FieldDefinition.ParseType.ASCII).when(annotation).parseType(); + Mockito.doReturn(false).when(annotation).existSubdomain(); + Mockito.doReturn(MessageDefinition.DomainType.FIXED).when(annotation).subdomainType(); + Mockito.doReturn("counts").when(annotation).pageSizeName(); + + + Field field = Mockito.mock(Field.class); + Mockito.doReturn("test").when(field).getName(); + Mockito.doReturn(String.class).when(field).getType(); + Mockito.doReturn(annotation).when(field).getAnnotation(Mockito.any()); + + FixedFieldDefinition definition = builder.buildFieldDefinition(field); + + Assertions.assertEquals(1, definition.getDomainNo()); + Assertions.assertEquals("test", definition.getName()); + Assertions.assertEquals(String.class, definition.getClazz()); + Assertions.assertEquals("yyyyMMdd", definition.getPattern()); + Assertions.assertFalse(definition.getFixed()); + Assertions.assertEquals(20, definition.getLength()); + Assertions.assertEquals("testing", definition.getRemark()); + Assertions.assertEquals(FieldDefinition.Status.OPEN, definition.getStatus()); + Assertions.assertEquals(FieldDefinition.ParseType.ASCII, definition.getParseType()); + Assertions.assertFalse(definition.getExistSubdomain()); + Assertions.assertEquals(MessageDefinition.DomainType.FIXED, definition.getSubdomainType()); + Assertions.assertEquals("counts", definition.getPageSizeName()); + + } +} diff --git a/src/test/java/com/alatka/messages/definition/FixedDatabaseMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/FixedDatabaseMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..9cec0c6 --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/FixedDatabaseMessageDefinitionBuilderTest.java @@ -0,0 +1,16 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.context.MessageDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class FixedDatabaseMessageDefinitionBuilderTest { + + @Test + @DisplayName("type()") + void test01() { + FixedDatabaseMessageDefinitionBuilder builder = new FixedDatabaseMessageDefinitionBuilder(null); + Assertions.assertEquals(MessageDefinition.Type.fixed, builder.type()); + } +} diff --git a/src/test/java/com/alatka/messages/definition/FixedXmlMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/FixedXmlMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..ecd36f8 --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/FixedXmlMessageDefinitionBuilderTest.java @@ -0,0 +1,38 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.context.FieldDefinition; +import com.alatka.messages.context.FixedFieldDefinition; +import com.alatka.messages.context.MessageDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class FixedXmlMessageDefinitionBuilderTest { + + @Test + @DisplayName("type()") + void test01() { + FixedXmlMessageDefinitionBuilder builder = new FixedXmlMessageDefinitionBuilder(); + Assertions.assertEquals(MessageDefinition.Type.fixed, builder.type()); + } + + @Test + @DisplayName("fieldDefinitionClass()") + void test02() { + FixedXmlMessageDefinitionBuilder builder = new FixedXmlMessageDefinitionBuilder(); + Assertions.assertEquals(FixedFieldDefinition.class, builder.fieldDefinitionClass()); + } + + @Test + @DisplayName("postBuildFieldDefinition()") + void test03() { + FixedXmlMessageDefinitionBuilder builder = new FixedXmlMessageDefinitionBuilder(); + + MessageDefinition messageDefinition = null; + FieldDefinition fieldDefinition = null; + builder.postBuildFieldDefinition(messageDefinition, fieldDefinition); + + Assertions.assertNull(messageDefinition); + Assertions.assertNull(fieldDefinition); + } +} diff --git a/src/test/java/com/alatka/messages/definition/FixedYamlMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/FixedYamlMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..c970b5e --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/FixedYamlMessageDefinitionBuilderTest.java @@ -0,0 +1,38 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.context.FieldDefinition; +import com.alatka.messages.context.FixedFieldDefinition; +import com.alatka.messages.context.MessageDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class FixedYamlMessageDefinitionBuilderTest { + + @Test + @DisplayName("type()") + void test01() { + FixedYamlMessageDefinitionBuilder builder = new FixedYamlMessageDefinitionBuilder(); + Assertions.assertEquals(MessageDefinition.Type.fixed, builder.type()); + } + + @Test + @DisplayName("fieldDefinitionClass()") + void test02() { + FixedYamlMessageDefinitionBuilder builder = new FixedYamlMessageDefinitionBuilder(); + Assertions.assertEquals(FixedFieldDefinition.class, builder.fieldDefinitionClass()); + } + + @Test + @DisplayName("postBuildFieldDefinition()") + void test03() { + FixedYamlMessageDefinitionBuilder builder = new FixedYamlMessageDefinitionBuilder(); + + MessageDefinition messageDefinition = null; + FieldDefinition fieldDefinition = null; + builder.postBuildFieldDefinition(messageDefinition, fieldDefinition); + + Assertions.assertNull(messageDefinition); + Assertions.assertNull(fieldDefinition); + } +} diff --git a/src/test/java/com/alatka/messages/definition/IsoAnnotationMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/IsoAnnotationMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..2046177 --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/IsoAnnotationMessageDefinitionBuilderTest.java @@ -0,0 +1,72 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.annotation.IsoFieldMeta; +import com.alatka.messages.context.FieldDefinition; +import com.alatka.messages.context.IsoFieldDefinition; +import com.alatka.messages.context.MessageDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.lang.reflect.Field; + +public class IsoAnnotationMessageDefinitionBuilderTest { + + private IsoAnnotationMessageDefinitionBuilder builder = new IsoAnnotationMessageDefinitionBuilder(""); + + @Test + @DisplayName("type()") + void test01() { + Assertions.assertEquals(MessageDefinition.Type.iso, builder.type()); + } + + @Test + @DisplayName("annotationClass()") + void test02() { + Assertions.assertEquals(IsoFieldMeta.class, builder.annotationClass()); + } + + @Test + @DisplayName("buildFieldDefinition()") + void test03() { + IsoFieldMeta annotation = Mockito.mock(IsoFieldMeta.class); + Mockito.doReturn(1).when(annotation).domainNo(); + Mockito.doReturn("yyyyMMdd").when(annotation).pattern(); + Mockito.doReturn(true).when(annotation).fixed(); + Mockito.doReturn(20).when(annotation).length(); + Mockito.doReturn("testing").when(annotation).remark(); + Mockito.doReturn(FieldDefinition.Status.OPEN).when(annotation).status(); + Mockito.doReturn(FieldDefinition.ParseType.ASCII).when(annotation).parseType(); + Mockito.doReturn(false).when(annotation).existSubdomain(); + Mockito.doReturn(MessageDefinition.DomainType.FIXED).when(annotation).subdomainType(); + Mockito.doReturn("counts").when(annotation).pageSizeName(); + Mockito.doReturn(false).when(annotation).nonSubdomainException(); + Mockito.doReturn("alias").when(annotation).aliasName(); + Mockito.doReturn(-1).when(annotation).maxLength(); + + + Field field = Mockito.mock(Field.class); + Mockito.doReturn("test").when(field).getName(); + Mockito.doReturn(String.class).when(field).getType(); + Mockito.doReturn(annotation).when(field).getAnnotation(Mockito.any()); + + IsoFieldDefinition definition = builder.buildFieldDefinition(field); + + Assertions.assertEquals(1, definition.getDomainNo()); + Assertions.assertEquals("test", definition.getName()); + Assertions.assertEquals(String.class, definition.getClazz()); + Assertions.assertEquals("yyyyMMdd", definition.getPattern()); + Assertions.assertTrue(definition.getFixed()); + Assertions.assertEquals(20, definition.getLength()); + Assertions.assertEquals("testing", definition.getRemark()); + Assertions.assertEquals(FieldDefinition.Status.OPEN, definition.getStatus()); + Assertions.assertEquals(FieldDefinition.ParseType.ASCII, definition.getParseType()); + Assertions.assertFalse(definition.getExistSubdomain()); + Assertions.assertEquals(MessageDefinition.DomainType.FIXED, definition.getSubdomainType()); + Assertions.assertEquals("counts", definition.getPageSizeName()); + Assertions.assertFalse(definition.getNonSubdomainException()); + Assertions.assertEquals("alias", definition.getAliasName()); + Assertions.assertEquals(20, definition.getMaxLength()); + } +} diff --git a/src/test/java/com/alatka/messages/definition/IsoDatabaseMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/IsoDatabaseMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..a975e5b --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/IsoDatabaseMessageDefinitionBuilderTest.java @@ -0,0 +1,16 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.context.MessageDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class IsoDatabaseMessageDefinitionBuilderTest { + + @Test + @DisplayName("type()") + void test01() { + IsoDatabaseMessageDefinitionBuilder builder = new IsoDatabaseMessageDefinitionBuilder(null); + Assertions.assertEquals(MessageDefinition.Type.iso, builder.type()); + } +} diff --git a/src/test/java/com/alatka/messages/definition/IsoXmlMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/IsoXmlMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..6f1a4fc --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/IsoXmlMessageDefinitionBuilderTest.java @@ -0,0 +1,34 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.context.IsoFieldDefinition; +import com.alatka.messages.context.MessageDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class IsoXmlMessageDefinitionBuilderTest { + + private IsoXmlMessageDefinitionBuilder builder = new IsoXmlMessageDefinitionBuilder(); + + @Test + @DisplayName("type()") + void test01() { + Assertions.assertEquals(MessageDefinition.Type.iso, builder.type()); + } + + @Test + @DisplayName("fieldDefinitionClass()") + void test02() { + Assertions.assertEquals(IsoFieldDefinition.class, builder.fieldDefinitionClass()); + } + + @Test + @DisplayName("postBuildFieldDefinition()") + void test03() { + IsoFieldDefinition definition = new IsoFieldDefinition(); + definition.setFixed(true); + builder.postBuildFieldDefinition(null, definition); + Assertions.assertEquals(0, definition.getLength()); + Assertions.assertEquals(0, definition.getMaxLength()); + } +} diff --git a/src/test/java/com/alatka/messages/definition/IsoYamlMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/IsoYamlMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..d4aad60 --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/IsoYamlMessageDefinitionBuilderTest.java @@ -0,0 +1,34 @@ +package com.alatka.messages.definition; + +import com.alatka.messages.context.IsoFieldDefinition; +import com.alatka.messages.context.MessageDefinition; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class IsoYamlMessageDefinitionBuilderTest { + + private IsoYamlMessageDefinitionBuilder builder = new IsoYamlMessageDefinitionBuilder(); + + @Test + @DisplayName("type()") + void test01() { + Assertions.assertEquals(MessageDefinition.Type.iso, builder.type()); + } + + @Test + @DisplayName("fieldDefinitionClass()") + void test02() { + Assertions.assertEquals(IsoFieldDefinition.class, builder.fieldDefinitionClass()); + } + + @Test + @DisplayName("postBuildFieldDefinition()") + void test03() { + IsoFieldDefinition definition = new IsoFieldDefinition(); + definition.setFixed(true); + builder.postBuildFieldDefinition(null, definition); + Assertions.assertEquals(0, definition.getLength()); + Assertions.assertEquals(0, definition.getMaxLength()); + } +} diff --git a/src/test/java/com/alatka/messages/definition/XmlMessageDefinitionBuilderTest.java b/src/test/java/com/alatka/messages/definition/XmlMessageDefinitionBuilderTest.java new file mode 100644 index 0000000..0f4c16e --- /dev/null +++ b/src/test/java/com/alatka/messages/definition/XmlMessageDefinitionBuilderTest.java @@ -0,0 +1,24 @@ +package com.alatka.messages.definition; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class XmlMessageDefinitionBuilderTest { + + @Test + @DisplayName("fileSuffix()") + void test01() { + FixedXmlMessageDefinitionBuilder definitionBuilder = new FixedXmlMessageDefinitionBuilder(); + Assertions.assertEquals(".xml", definitionBuilder.fileSuffix()); + } + + @Disabled + @Test + @DisplayName("()") + void test02() { + // TODO + + } +} diff --git a/src/test/resources/jcb.common.iso.xml b/src/test/resources/jcb.common.iso.xml index b9d58be..9ae4168 100644 --- a/src/test/resources/jcb.common.iso.xml +++ b/src/test/resources/jcb.common.iso.xml @@ -131,7 +131,7 @@ - + diff --git a/src/test/resources/test/9001.3006.fixed.xml b/src/test/resources/test/9001.3006.fixed.xml new file mode 100644 index 0000000..e69de29 -- Gitee From c306a07b9b918e38fc51e562d1514daebf191d58 Mon Sep 17 00:00:00 2001 From: liuyibing123456 Date: Sun, 2 Jun 2024 14:29:22 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E5=8F=98?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 899c545..8f1a716 100644 --- a/pom.xml +++ b/pom.xml @@ -6,11 +6,11 @@ alatka com.alatka - 0.2.3 + 1.0.0 alatka-messages - 0.2.3 + 1.0.0 -- Gitee