刘光辉
6 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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 {
 
    /**
     * 将打印页面文本解析为升序、去重且不越界的页码集合。
     *
     * <p>支持逗号、顿号、分号或空白分隔,支持 {@code 1-3} 区间,
     * 也支持 {@code all}、{@code 全部} 表示文件全部页面。</p>
     *
     * @param value         C.yema 原始值
     * @param filePageCount 文件总页数
     * @return 有序页码集合
     * @throws DataException 页码为空、格式错误或越界
     */
    public List<Integer> 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<Integer> 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<Integer> 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<Integer> allPages(int filePageCount) {
        List<Integer> pages = new ArrayList<>(filePageCount);
        for (int page = 1; page <= filePageCount; page++) {
            pages.add(page);
        }
        return pages;
    }
}