package com.codechecker.cache.detector; import lombok.AccessLevel; import lombok.Data; import lombok.Setter; /** * 一个 Redis / MQ value 写入(投递)点的静态描述。 */ @Data public class WritePoint { public static final String CHANNEL_REDIS = "REDIS"; public static final String CHANNEL_ROCKETMQ = "ROCKETMQ"; public static final String CHANNEL_KAFKA = "KAFKA"; private String filePath; private int lineNumber; private String enclosingClass; private String enclosingMethod; private String pattern; private String keyExpression; private String resolvedKeyPattern; private String valueExpression; private String resolvedValueType; private boolean rootArray; private double confidence = 1.0; /** REDIS / ROCKETMQ / KAFKA;默认 REDIS 兼容现网 */ @Setter(AccessLevel.NONE) private String channel = CHANNEL_REDIS; public void setChannel(String channel) { this.channel = channel == null || channel.isEmpty() ? CHANNEL_REDIS : channel; } /** 稳定标识:用于在 old/new 两个版本间配对同一写入点 */ public String signature() { return enclosingClass + "#" + enclosingMethod + "|" + normalizeKey(); } private String normalizeKey() { return keyExpression == null ? "" : keyExpression.replaceAll("\\s+", ""); } /** @return 是否为 MQ 通道(RocketMQ / Kafka) */ public boolean isMq() { return CHANNEL_ROCKETMQ.equals(channel) || CHANNEL_KAFKA.equals(channel); } /** * @return 展示用写入位置,形如 {@code SimpleClass#method:line} */ public String location() { String simpleClass = enclosingClass; if (simpleClass != null && simpleClass.contains(".")) { simpleClass = simpleClass.substring(simpleClass.lastIndexOf('.') + 1); } return simpleClass + "#" + enclosingMethod + ":" + lineNumber; } }