package jnpf.dmsEntity.watermark; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import jnpf.exception.DataException; import lombok.Data; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.LinkedHashSet; /** Runtime barcode entries shared by preview, download and print, in caller-specified order. */ @Data public class DmsWatermarkParameters { public static final String CUSTOM_BARCODE_TEMPLATE = "{/CUSTOM_BARCODE_TEXT}"; private List customBarcode; private List watermarkBusinessTypes; public DmsWatermarkParameters normalized() { DmsWatermarkParameters result = new DmsWatermarkParameters(); if (watermarkBusinessTypes != null) { if (watermarkBusinessTypes.size() > 50) throw new DataException("水印业务类型不能超过 50 项"); LinkedHashSet types = new LinkedHashSet<>(); for (String value : watermarkBusinessTypes) { if (value == null || value.isBlank() || value.length() > 100 || !value.equals(value.trim())) { throw new DataException("水印业务类型取值无效"); } types.add(value); } result.setWatermarkBusinessTypes(new ArrayList<>(types)); } if (customBarcode != null) { if (customBarcode.isEmpty()) throw new DataException("customBarcode 数组不能为空;不需要自定义条码时请省略该参数"); if (customBarcode.size() > 10000) throw new DataException("自定义条码数组不能超过 10000 项"); List entries = new ArrayList<>(); for (CustomBarcode item : customBarcode) { if (item == null) throw new DataException("自定义条码数组不能包含空项"); if (item.getPage() != null && item.getPage() < 1) { throw new DataException("水印页码必须是从 1 开始的正整数;省略 page 表示每页渲染"); } validateText(item.getBarValue(), "条码内容 barValue"); validateText(item.getBarText(), "条码显示文字 barText"); CustomBarcode copy = new CustomBarcode(); copy.setPage(item.getPage()); copy.setBarValue(item.getBarValue()); copy.setBarText(item.getBarText()); entries.add(copy); } result.setCustomBarcode(entries); } return result; } private static void validateText(String text, String label) { if (text == null || text.isBlank()) throw new DataException(label + "不能为空"); if (text.length() > 2000) throw new DataException(label + "不能超过 2000 个字符"); } @Data public static class CustomBarcode { /** Null means every physical page. Repeated page entries are intentionally retained. */ @JsonDeserialize(using = PageNumberDeserializer.class) private Integer page; private String barValue; private String barText; } /** Do not let Jackson silently truncate 1.5 or coerce "2" into an integer page. */ public static class PageNumberDeserializer extends JsonDeserializer { @Override public Integer deserialize(JsonParser parser, DeserializationContext context) throws IOException { if (!parser.hasToken(JsonToken.VALUE_NUMBER_INT)) { return (Integer) context.handleUnexpectedToken(Integer.class, parser); } return parser.getIntValue(); } } }