Files
YschcmsService/src/main/java/com/yunhai/cms/theme/ThemePackageValidator.java
T

76 lines
3.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.yunhai.cms.theme;
import java.util.List;
import java.util.function.Predicate;
/**
* 主题包规范校验(W1 重构点,方案 §5.5:校验语义收敛于本类,Registry 与 PackageService 共用,
* 杜绝两套校验漂移)。原 ThemeRegistry.validate 的规则原文平移:
* specVersion=1、name 规范、name=目录名、必备模板(home/list/detail/single)、
* fragments/head.html、param 规范、screenshot 存在。
* existsFn 判定资源存在:classpath 包用 ClassPathResource、外部包用 Files.exists(§5.4 步骤 1)。
*/
public final class ThemePackageValidator {
private ThemePackageValidator() {
}
/** 校验不通过抛 IllegalArgumentException(bad package 语义,Registry 剔除 + log.warn) */
public static void validate(ThemeInfo info, String dirName, Predicate<String> existsFn) {
if (info == null) {
throw new IllegalArgumentException("清单为空");
}
if (info.getSpecVersion() == null || info.getSpecVersion() != 1) {
throw new IllegalArgumentException("specVersion 必须为 1");
}
if (!ThemeRegistry.isValidName(info.getName())) {
throw new IllegalArgumentException("name 缺失或不符合命名规范:" + info.getName());
}
if (!info.getName().equals(dirName)) {
throw new IllegalArgumentException("name 与目录名不一致:" + dirName + " != " + info.getName());
}
for (String template : ThemeRegistry.requiredTemplates()) {
if (!existsFn.test(template)) {
throw new IllegalArgumentException("缺必备模板 " + template);
}
}
// fragments/ 目录存在性以 head.html 片段代替(jar 内目录项不可靠)
if (!existsFn.test("fragments/head.html")) {
throw new IllegalArgumentException("缺 fragments/head.html 公共片段");
}
validateParams(info);
String shot = info.screenshotPath();
if (!existsFn.test(shot)) {
throw new IllegalArgumentException("声明的 screenshot 不存在:" + shot);
}
}
/** param 规范(key/类型/重复/cssVar 仅 color/select 必带 options);不合法抛 IllegalArgumentException */
public static void validateParams(ThemeInfo info) {
List<ThemeParam> params = info.getParams();
List<String> seen = new java.util.ArrayList<>();
for (ThemeParam p : params) {
if (p.getKey() == null || !ThemeParam.KEY_PATTERN.matcher(p.getKey()).matches()) {
throw new IllegalArgumentException("param key 非法:" + p.getKey());
}
if (seen.contains(p.getKey())) {
throw new IllegalArgumentException("param key 重复:" + p.getKey());
}
seen.add(p.getKey());
String type = p.getType();
boolean knownType = ThemeParam.TYPE_COLOR.equals(type) || ThemeParam.TYPE_IMAGE.equals(type)
|| ThemeParam.TYPE_SELECT.equals(type) || ThemeParam.TYPE_TEXT.equals(type);
if (!knownType) {
throw new IllegalArgumentException("param " + p.getKey() + " 类型非法:" + type);
}
if (p.getCssVar() != null && !p.getCssVar().isEmpty() && !ThemeParam.TYPE_COLOR.equals(type)) {
throw new IllegalArgumentException("cssVar 仅允许 color 类型参数:" + p.getKey());
}
if (ThemeParam.TYPE_SELECT.equals(type)
&& (p.getOptions() == null || p.getOptions().isEmpty())) {
throw new IllegalArgumentException("select 参数缺 options:" + p.getKey());
}
}
}
}