|
@@ -0,0 +1,392 @@
|
|
|
+package com.persagy.fm.translate.model;
|
|
|
+
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 翻译描述信息
|
|
|
+ * @author Charlie Yu
|
|
|
+ * @Date 2021-03-03
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+public class TransMeta {
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 默认参数字段
|
|
|
+ */
|
|
|
+ public final static String DEFAULT_CONDITIONFIELD = "id";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 默认结果字段
|
|
|
+ */
|
|
|
+ public final static String DEFAULT_RESULTFIELD = "name";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 配置属性-翻译类型
|
|
|
+ */
|
|
|
+ public final static String OP_TYPE = "type";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 配置属性-翻译参数
|
|
|
+ */
|
|
|
+ public final static String OP_PARAMETER = "parameter";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 配置属性-翻译数据来源
|
|
|
+ */
|
|
|
+ public final static String OP_SOURCE = "source";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 配置属性-翻译数据来源
|
|
|
+ */
|
|
|
+ public final static String OP_RESULT = "result";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 配置属性-翻译条件
|
|
|
+ */
|
|
|
+ public final static String OP_CONDITION = "con";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 配置属性-批量翻译的结果映射键值一般为参数值,这里主要为数据库翻译使用
|
|
|
+ */
|
|
|
+ public final static String OP_MAPKEY = "batchKey";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 配置属性-是否为批量翻译
|
|
|
+ */
|
|
|
+ public final static String OP_BATCH = "batch";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 配置属性-目标属性
|
|
|
+ */
|
|
|
+ public final static String OP_TARGET = "target";
|
|
|
+
|
|
|
+ /** 匹配符-前缀 */
|
|
|
+ private static final char BRACKET_BEGIN = '(';
|
|
|
+ /** 匹配符-后缀 */
|
|
|
+ private static final char BRACKET_END = ')';
|
|
|
+ /** 匹配符-分隔 */
|
|
|
+ private static final char COMMA = ',';
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 翻译类型
|
|
|
+ */
|
|
|
+ private String type = TransType.DB;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 参数字段(原始对象的使用的外键)
|
|
|
+ */
|
|
|
+ private String parameter = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 数据来源(服务名,实体名,表名,公式)
|
|
|
+ */
|
|
|
+ private String source = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询结果字段名
|
|
|
+ */
|
|
|
+ private String result = DEFAULT_RESULTFIELD;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询条件字段名
|
|
|
+ */
|
|
|
+ private String condition = DEFAULT_CONDITIONFIELD;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 多条结果时映射的字段,不是必须使用
|
|
|
+ */
|
|
|
+ private String mapKey = condition;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 目标字段(原始对象的对应的翻译结果字段)
|
|
|
+ */
|
|
|
+ private String target = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否为批量翻译,默认根据类型决定
|
|
|
+ */
|
|
|
+ private boolean isBatch = false;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 目标字段
|
|
|
+ */
|
|
|
+ private String[] targetFields = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 结果字段
|
|
|
+ */
|
|
|
+ private String[] resultFields = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析json串,生成翻译元数据对象
|
|
|
+ * @param transMetas json串
|
|
|
+ * @return 翻译元数据对象
|
|
|
+ */
|
|
|
+ public static List<TransMeta> parseMetas(String transMetas){
|
|
|
+ if(StringUtils.isEmpty(transMetas)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return JSONUtil.parseArray(transMetas).toList(TransMeta.class);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 解析json串,生成翻译元数据对象
|
|
|
+ * @param transors json串
|
|
|
+ * @return 翻译元数据对象
|
|
|
+ */
|
|
|
+ public static Map<String,List<TransMeta>> parseMetasMap(String transors){
|
|
|
+ if(StringUtils.isEmpty(transors)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+// try {
|
|
|
+// JsonNode node = Json2ObjectMapper.getInstance().readTree(transors);
|
|
|
+// Iterator<Map.Entry<String, JsonNode>> it = node.fields();
|
|
|
+// Map<String,List<TransMeta>> metas = new HashMap<>(16);
|
|
|
+// while(it.hasNext()){
|
|
|
+// Map.Entry<String, JsonNode> en = it.next();
|
|
|
+// metas.put(en.getKey(), parseJsonMetas(en.getValue()));
|
|
|
+// }
|
|
|
+// return metas;
|
|
|
+// } catch (JsonProcessingException e) {
|
|
|
+// log.error("翻译配置出错",e);
|
|
|
+// } catch (IOException e) {
|
|
|
+// log.error("翻译配置出错",e);
|
|
|
+// }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 解析json串,生成翻译元数据对象
|
|
|
+ * @param node
|
|
|
+ * @return 翻译元数据对象
|
|
|
+ */
|
|
|
+ public static List<TransMeta> parseJsonMetas(JsonNode node){
|
|
|
+ if(!node.isArray()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ int len = node.size();
|
|
|
+ List<TransMeta> metas = new ArrayList<TransMeta>();
|
|
|
+ for(int i = 0; i < len; i++){
|
|
|
+ TransMeta meta = parseJsonMeta(node.get(i));
|
|
|
+ if(meta != null){
|
|
|
+ metas.add(meta);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return metas;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 解析json串,生成翻译元数据对象
|
|
|
+ * @param transMeta json串
|
|
|
+ * @return 翻译元数据对象
|
|
|
+ */
|
|
|
+ public static TransMeta parseMeta(String transMeta){
|
|
|
+ if(StringUtils.isEmpty(transMeta)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return JSONUtil.toBean(transMeta, TransMeta.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析json对象,生成翻译元数据对象
|
|
|
+ * @param node json节点
|
|
|
+ * @return 翻译元数据对象
|
|
|
+ */
|
|
|
+ public static TransMeta parseJsonMeta(JsonNode node){
|
|
|
+ if(node == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ TransMeta meta = new TransMeta();
|
|
|
+ String type = null;
|
|
|
+ if(node.has(OP_TYPE)){
|
|
|
+ JsonNode typeNode = node.get(OP_TYPE);
|
|
|
+ if(!typeNode.isNull()){
|
|
|
+ type = typeNode.asText();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(type != null) {
|
|
|
+ meta.setType(type);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(node.has(OP_PARAMETER)){
|
|
|
+ JsonNode paramNode = node.get(OP_PARAMETER);
|
|
|
+ if(!paramNode.isNull()) {
|
|
|
+ meta.setParameter(paramNode.asText());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(node.has(OP_CONDITION)){
|
|
|
+ JsonNode conNode = node.get(OP_CONDITION);
|
|
|
+ if(!conNode.isNull()) {
|
|
|
+ meta.setCondition(conNode.asText());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(node.has(OP_MAPKEY)){
|
|
|
+ JsonNode conNode = node.get(OP_MAPKEY);
|
|
|
+ if(!conNode.isNull()) {
|
|
|
+ meta.setMapKey(conNode.asText());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(node.has(OP_BATCH)){
|
|
|
+ JsonNode conNode = node.get(OP_BATCH);
|
|
|
+ if(!conNode.isNull()) {
|
|
|
+ meta.setBatch(Boolean.parseBoolean(conNode.asText()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(node.has(OP_RESULT)){
|
|
|
+ JsonNode resultNode = node.get(OP_RESULT);
|
|
|
+ if(!resultNode.isNull()) {
|
|
|
+ meta.setResult(resultNode.asText());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(node.has(OP_SOURCE)){
|
|
|
+ JsonNode sourceNode = node.get(OP_SOURCE);
|
|
|
+ if(!sourceNode.isNull()) {
|
|
|
+ meta.setSource(sourceNode.asText());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(node.has(OP_TARGET)){
|
|
|
+ JsonNode targetNode = node.get(OP_TARGET);
|
|
|
+ if(!targetNode.isNull()) {
|
|
|
+ meta.setTarget(targetNode.asText());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return meta;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public String getType() {
|
|
|
+ return type;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void setType(String type) {
|
|
|
+ this.type = type;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public String getParameter() {
|
|
|
+ return parameter;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void setParameter(String parameter) {
|
|
|
+ this.parameter = parameter;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public String getSource() {
|
|
|
+ return source;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void setSource(String source) {
|
|
|
+ this.source = source;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public String getResult() {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setResult(String result) {
|
|
|
+ this.result = result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getTarget() {
|
|
|
+ if (StringUtils.isEmpty(target)) {
|
|
|
+ return parameter+"_showname";
|
|
|
+ }
|
|
|
+ return target;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setTarget(String target) {
|
|
|
+ this.target = target;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getCondition() {
|
|
|
+ return condition;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void setCondition(String condition) {
|
|
|
+ this.condition = condition;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getMapKey() {
|
|
|
+ if (StringUtils.isEmpty(mapKey)) {
|
|
|
+ return getCondition();
|
|
|
+ }
|
|
|
+ return mapKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setMapKey(String mapKey) {
|
|
|
+ this.mapKey = mapKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean isBatch() {
|
|
|
+ if(type == TransType.DB) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return isBatch;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setBatch(boolean batch) {
|
|
|
+ isBatch = batch;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 取得目标字段
|
|
|
+ * @return 取得目标字段
|
|
|
+ */
|
|
|
+ public String[] getTargetFields(){
|
|
|
+ if(targetFields == null){
|
|
|
+ targetFields = getTarget().split(",");
|
|
|
+ }
|
|
|
+ return targetFields;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 取得结果字段
|
|
|
+ * @return 结果字段
|
|
|
+ */
|
|
|
+ public String[] getResultFields(){
|
|
|
+ if(resultFields == null){
|
|
|
+ List<String> rs = new ArrayList<>();
|
|
|
+ char[] cs = result.toCharArray();
|
|
|
+ int bracketCount = 0;
|
|
|
+ StringBuilder section = new StringBuilder();
|
|
|
+ for(int i = 0; i < cs.length; i++){
|
|
|
+ char c = cs[i];
|
|
|
+ if(c == BRACKET_BEGIN){
|
|
|
+ bracketCount++;
|
|
|
+ }else if(c==COMMA && bracketCount == 0){
|
|
|
+ if(section.length() > 0){
|
|
|
+ rs.add(section.toString().trim());
|
|
|
+ section = new StringBuilder();
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }else if(c == BRACKET_END){
|
|
|
+ bracketCount--;
|
|
|
+ }else if(c=='a' && i >0 && i+3 < cs.length && cs[i-1] == ' ' && cs[i+1] == 's' && cs[i+2] == ' '){
|
|
|
+ section = new StringBuilder();
|
|
|
+ i+=2;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ section.append(c);
|
|
|
+ }
|
|
|
+ if(section.length()>0) {
|
|
|
+ rs.add(section.toString().trim());
|
|
|
+ }
|
|
|
+ resultFields = rs.toArray(new String[rs.size()]);
|
|
|
+ }
|
|
|
+ return resultFields;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|