package jnpf.dmsService.recordprint;
import jnpf.exception.DataException;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;
/**
* 分散打印页码集合解析器。
*/
@Component
public class DmsRecordPrintPageParser {
/**
* 将打印页面文本解析为升序、去重且不越界的页码集合。
*
*
支持逗号、顿号、分号或空白分隔,支持 {@code 1-3} 区间,
* 也支持 {@code all}、{@code 全部} 表示文件全部页面。
*
* @param value C.yema 原始值
* @param filePageCount 文件总页数
* @return 有序页码集合
* @throws DataException 页码为空、格式错误或越界
*/
public List parse(String value, int filePageCount) throws DataException {
if (filePageCount <= 0) {
throw new DataException("文件总页数无效");
}
String normalized = normalize(value);
if (normalized.isEmpty()) {
throw new DataException("分散打印页码不能为空");
}
if ("all".equals(normalized.toLowerCase(Locale.ROOT)) || "全部".equals(normalized)) {
return allPages(filePageCount);
}
Set pages = new TreeSet<>();
String[] tokens = normalized.split("[,,、;;\\s]+");
for (String token : tokens) {
addToken(pages, token, filePageCount);
}
if (pages.isEmpty()) {
throw new DataException("分散打印页码不能为空");
}
return new ArrayList<>(pages);
}
/**
* 规范化页码文本,兼容 JSON 数组外层括号和常见连接符。
*
* @param value 原始页码文本
* @return 规范化文本
*/
private String normalize(String value) {
String normalized = value == null ? "" : value.trim();
if (normalized.startsWith("[") && normalized.endsWith("]")) {
normalized = normalized.substring(1, normalized.length() - 1);
}
return normalized.replace('-', '-').replace('—', '-')
.replace('–', '-').replace("页", "").replace("\"", "").trim();
}
/**
* 解析单个页码或页码区间并加入集合。
*
* @param pages 已解析页码集合
* @param token 单个页码表达式
* @param filePageCount 文件总页数
* @throws DataException 页码格式错误或越界
*/
private void addToken(Set pages, String token, int filePageCount)
throws DataException {
String value = token == null ? "" : token.trim();
if (value.isEmpty()) {
return;
}
int separator = value.indexOf('-');
if (separator < 0) {
pages.add(parsePageNumber(value, filePageCount));
return;
}
if (separator == 0 || separator == value.length() - 1
|| value.indexOf('-', separator + 1) >= 0) {
throw new DataException("分散打印页码格式错误:" + value);
}
int start = parsePageNumber(value.substring(0, separator), filePageCount);
int end = parsePageNumber(value.substring(separator + 1), filePageCount);
if (start > end) {
throw new DataException("分散打印页码区间起始值不能大于结束值:" + value);
}
for (int page = start; page <= end; page++) {
pages.add(page);
}
}
/**
* 解析并校验单个页码。
*
* @param value 页码文本
* @param filePageCount 文件总页数
* @return 合法页码
* @throws DataException 页码不是整数或超出文件范围
*/
private int parsePageNumber(String value, int filePageCount) throws DataException {
final int page;
try {
page = Integer.parseInt(value.trim());
} catch (NumberFormatException exception) {
throw new DataException("分散打印页码格式错误:" + value);
}
if (page < 1 || page > filePageCount) {
throw new DataException("分散打印页码超出文件范围:" + page
+ ",文件共" + filePageCount + "页");
}
return page;
}
/**
* 构造文件全部页面的有序集合。
*
* @param filePageCount 文件总页数
* @return 从 1 开始的全部页码
*/
private List allPages(int filePageCount) {
List pages = new ArrayList<>(filePageCount);
for (int page = 1; page <= filePageCount; page++) {
pages.add(page);
}
return pages;
}
}