diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/JsonToXmlConversionService.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/JsonToXmlConversionService.java index 3dfccd0..ec28fbe 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/JsonToXmlConversionService.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/JsonToXmlConversionService.java @@ -22,7 +22,7 @@ import java.util.List; /** * JSON到XML转换服务。 - * + * * 职责: * 1. 接收JSON格式的MappingDocument * 2. 基于规则文件和模板,将JSON数据转换为XML格式 @@ -30,86 +30,128 @@ import java.util.List; */ @Component public class JsonToXmlConversionService { - + private final ObjectMapper objectMapper; private final RuleBasedXmlMappingService ruleBasedXmlMappingService; - + public JsonToXmlConversionService(RuleBasedXmlMappingService ruleBasedXmlMappingService) { this.ruleBasedXmlMappingService = ruleBasedXmlMappingService; this.objectMapper = new ObjectMapper(); this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } - + /** * 从JSON字符串转换为XML文件 - * - * @param mappingJson JSON格式的映射文档 - * @param templateStream XML模板流 - * @param ruleStreams 规则文件流列表 - * @param indexMapping 索引映射配置 - * @return 生成的XML文件路径 - * @throws Exception 转换异常 */ public String convertFromJson(String mappingJson, InputStream templateStream, List ruleStreams, IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception { - + long startTime = System.currentTimeMillis(); System.out.println("[JSON转XML] 开始转换..."); - + try { MappingDocument mappingDocument = objectMapper.readValue(mappingJson, MappingDocument.class); - + long parseTime = System.currentTimeMillis(); System.out.println("[JSON转XML] JSON解析完成,耗时: " + (parseTime - startTime) + " ms"); - - String xmlContent = buildXmlFromMapping(mappingDocument, templateStream, ruleStreams, indexMapping); - + + ConversionResult conversionResult = buildXmlFromMappingWithResult(mappingDocument, templateStream, ruleStreams, indexMapping); + long totalTime = System.currentTimeMillis() - startTime; System.out.println("[JSON转XML] 转换完成,总耗时: " + totalTime + " ms"); - - return xmlContent; + + if (conversionResult.getUnmatchedRuleDetails() != null && !conversionResult.getUnmatchedRuleDetails().isEmpty()) { + System.err.println("[JSON转XML] 警告: 有 " + conversionResult.getUnmatchedRuleDetails().size() + " 条规则未匹配到指标"); + } + + return conversionResult.getXmlContent(); } catch (Exception e) { long totalTime = System.currentTimeMillis() - startTime; System.err.println("[JSON转XML] 转换失败,已耗时: " + totalTime + " ms,错误: " + e.getMessage()); throw e; } } - + + /** + * 从JSON字符串转换为XML,并返回包含未匹配规则信息的完整结果。 + */ + public ConversionResult convertFromJsonWithResult(String mappingJson, + InputStream templateStream, + List ruleStreams, + IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception { + + long startTime = System.currentTimeMillis(); + System.out.println("[JSON转XML] 开始转换(带结果)..."); + + try { + MappingDocument mappingDocument = objectMapper.readValue(mappingJson, MappingDocument.class); + + long parseTime = System.currentTimeMillis(); + System.out.println("[JSON转XML] JSON解析完成,耗时: " + (parseTime - startTime) + " ms"); + + ConversionResult conversionResult = buildXmlFromMappingWithResult(mappingDocument, templateStream, ruleStreams, indexMapping); + + long totalTime = System.currentTimeMillis() - startTime; + System.out.println("[JSON转XML] 转换完成,总耗时: " + totalTime + " ms"); + + if (conversionResult.getUnmatchedRuleDetails() != null && !conversionResult.getUnmatchedRuleDetails().isEmpty()) { + System.err.println("[JSON转XML] 警告: 有 " + conversionResult.getUnmatchedRuleDetails().size() + " 条规则未匹配到指标"); + } + + return conversionResult; + } catch (Exception e) { + long totalTime = System.currentTimeMillis() - startTime; + System.err.println("[JSON转XML] 转换失败,已耗时: " + totalTime + " ms,错误: " + e.getMessage()); + throw e; + } + } + private String buildXmlFromMapping(MappingDocument mappingDocument, InputStream templateStream, List ruleStreams, IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception { - + + return buildXmlFromMappingWithResult(mappingDocument, templateStream, ruleStreams, indexMapping).getXmlContent(); + } + + private ConversionResult buildXmlFromMappingWithResult(MappingDocument mappingDocument, + InputStream templateStream, + List ruleStreams, + IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception { + long stepStart = System.currentTimeMillis(); - + String templateContent = readInputStreamToString(templateStream); - + long templateTime = System.currentTimeMillis(); System.out.println(" [步骤1] 读取模板完成,耗时: " + (templateTime - stepStart) + " ms"); - + String xmlContent = fillIedInfo(templateContent, mappingDocument); - + long iedTime = System.currentTimeMillis(); System.out.println(" [步骤2] 填充IED信息完成,耗时: " + (iedTime - templateTime) + " ms"); - + xmlContent = fillReportControlsFromMapping(xmlContent, mappingDocument); - + long reportTime = System.currentTimeMillis(); System.out.println(" [步骤3] 填充ReportControl完成,耗时: " + (reportTime - iedTime) + " ms"); - - xmlContent = applyRulesFromMapping(xmlContent, mappingDocument, ruleStreams, indexMapping); - + + RuleMatchingResult matchingResult = applyRulesFromMappingWithResult(xmlContent, mappingDocument, ruleStreams, indexMapping); + long rulesTime = System.currentTimeMillis(); System.out.println(" [步骤4] 应用规则完成,耗时: " + (rulesTime - reportTime) + " ms"); - + long totalStepTime = System.currentTimeMillis() - stepStart; System.out.println(" [buildXmlFromMapping] 总计耗时: " + totalStepTime + " ms"); - - return xmlContent; + + ConversionResult result = new ConversionResult(); + result.setXmlContent(matchingResult.getXmlContent()); + result.setUnmatchedRuleDetails(matchingResult.getUnmatchedRuleDetails()); + return result; } - + private String readInputStreamToString(InputStream inputStream) throws Exception { java.io.ByteArrayOutputStream result = new java.io.ByteArrayOutputStream(); byte[] buffer = new byte[1024]; @@ -119,10 +161,7 @@ public class JsonToXmlConversionService { } return result.toString(StandardCharsets.UTF_8.name()); } - - /** - * 填充IED信息 - */ + private String fillIedInfo(String xmlContent, MappingDocument mappingDocument) { if (mappingDocument == null) { return xmlContent; @@ -133,24 +172,21 @@ public class JsonToXmlConversionService { if (iedName != null && !iedName.isEmpty()) { xmlContent = xmlContent.replaceAll( - "\n"); + .append(escapeXml(reportControlStr)) + .append("\" />\n"); } } } @@ -184,21 +220,18 @@ public class JsonToXmlConversionService { reportStatBuilder.append("\t\t"); xmlContent = xmlContent.replaceAll( - "[\\s\\S]*?", - reportStatBuilder.toString().replace("$", "\\$").replace("[", "\\[").replace("]", "\\]") + "[\\s\\S]*?", + reportStatBuilder.toString().replace("$", "\\$").replace("[", "\\[").replace("]", "\\]") ); return xmlContent; } - - /** - * 构建ReportControl字符串 - */ + private String buildReportControlString(ReportMapItem rc) { StringBuilder sb = new StringBuilder(); sb.append("LLN0$").append(rc.getBuffered() != null && rc.getBuffered().equals("BR") ? "BR$" : "RP$").append(rc.getName()); - + if(rc.getName().contains("PLT") || rc.getName().contains("Flicker") || rc.getName().contains("PST") || rc.getName().contains("Fluc")){ sb.append(",600"); }else{ @@ -220,7 +253,7 @@ public class JsonToXmlConversionService { sb.append(",1"); sb.append(",1"); sb.append(",3"); - + if(rc.getName().contains("PLT") || rc.getName().contains("Flicker")){ sb.append(",1"); }else if(rc.getName().contains("PST") || rc.getName().contains("Fluc")){ @@ -231,60 +264,63 @@ public class JsonToXmlConversionService { return sb.toString(); } - - /** - * 从MappingDocument应用规则 - */ + private String applyRulesFromMapping(String xmlContent, MappingDocument mappingDocument, List ruleStreams, IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception { - + + return applyRulesFromMappingWithResult(xmlContent, mappingDocument, ruleStreams, indexMapping).getXmlContent(); + } + + private RuleMatchingResult applyRulesFromMappingWithResult(String xmlContent, + MappingDocument mappingDocument, + List ruleStreams, + IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception { + long stepStart = System.currentTimeMillis(); - + var mergedRules = mergeAllRulesDesc(ruleStreams, indexMapping); - + long mergeTime = System.currentTimeMillis(); System.out.println(" [规则合并] 耗时: " + (mergeTime - stepStart) + " ms,规则数: " + mergedRules.size()); - + var mappingMetrics = extractMetricsFromMapping(mappingDocument); - + long extractTime = System.currentTimeMillis(); System.out.println(" [指标提取] 耗时: " + (extractTime - mergeTime) + " ms,指标数: " + mappingMetrics.size()); - + System.out.println("========== 开始从JSON匹配规则 =========="); System.out.println("规则总数: " + mergedRules.size()); System.out.println("JSON中指标总数: " + mappingMetrics.size()); - - var applicableRules = findApplicableRulesDesc(mergedRules, mappingMetrics); - + + RuleMatchingResult matchingResult = findApplicableRulesDescWithUnmatched(mergedRules, mappingMetrics); + long matchTime = System.currentTimeMillis(); System.out.println(" [规则匹配] 耗时: " + (matchTime - extractTime) + " ms"); - - System.out.println("匹配成功: " + applicableRules.size() + " 条规则"); - System.out.println("匹配失败: " + (mergedRules.size() - applicableRules.size()) + " 条规则"); - - String resultXml = applyRulesToXml(xmlContent, applicableRules); - + + System.out.println("匹配成功: " + matchingResult.getApplicableRules().size() + " 条规则"); + System.out.println("匹配失败: " + matchingResult.getUnmatchedRuleDetails().size() + " 条规则"); + + String resultXml = applyRulesToXml(xmlContent, matchingResult.getApplicableRules()); + long applyTime = System.currentTimeMillis(); System.out.println(" [规则应用] 耗时: " + (applyTime - matchTime) + " ms"); - + long totalApplyTime = System.currentTimeMillis() - stepStart; System.out.println(" [applyRulesFromMapping] 总计耗时: " + totalApplyTime + " ms"); System.out.println("========== JSON规则匹配结束 ==========\n"); - - return resultXml; + + matchingResult.setXmlContent(resultXml); + return matchingResult; } - - /** - * 合并所有规则文件 - */ + private java.util.Map> mergeAllRules( List ruleStreams, IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception { - + java.util.Map> mergedRules = new java.util.LinkedHashMap<>(); - + for (InputStream ruleStream : ruleStreams) { var rules = parseRuleFile(ruleStream, indexMapping); for (var entry : rules.entrySet()) { @@ -293,7 +329,7 @@ public class JsonToXmlConversionService { mergedRules.computeIfAbsent(key, k -> new ArrayList<>()).addAll(ruleList); } } - + return mergedRules; } @@ -314,40 +350,37 @@ public class JsonToXmlConversionService { return mergedRules; } - - /** - * 解析规则文件 - */ + private java.util.Map> parseRuleFile( InputStream ruleStream, IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception { - + java.util.Map> rules = new java.util.HashMap<>(); - + java.io.BufferedReader reader = new java.io.BufferedReader( - new java.io.InputStreamReader(ruleStream, StandardCharsets.UTF_8) + new java.io.InputStreamReader(ruleStream, StandardCharsets.UTF_8) ); - + String line; String currentGroup = ""; - + java.util.regex.Pattern valueRulePattern = java.util.regex.Pattern.compile( - "", java.util.regex.Pattern.CASE_INSENSITIVE + "", java.util.regex.Pattern.CASE_INSENSITIVE ); - + while ((line = reader.readLine()) != null) { line = line.trim(); - + if (line.startsWith("