package jnpf.flowable.util.filepermission; import jnpf.flowable.model.filepermission.FilePermissionPolicy.Action; import java.util.*; /** 原生保存前的附件引用差异;调用者仍负责从可信旧值提取主子行及验证新附件来源。 */ public final class FileAttachmentChanges { private FileAttachmentChanges() { } public static Set classify(Collection before, Collection after) { Set oldIds = ids(before); Set newIds = ids(after); Set removed = new HashSet<>(oldIds); removed.removeAll(newIds); Set added = new HashSet<>(newIds); added.removeAll(oldIds); Set changes = EnumSet.noneOf(Action.class); if (!removed.isEmpty() && !added.isEmpty()) changes.add(Action.REPLACE); if (added.size() > removed.size()) changes.add(Action.ADD); if (removed.size() > added.size()) changes.add(Action.REMOVE); return Collections.unmodifiableSet(changes); } /** 编辑另存的可信采用需先由工作稿服务验证,不能把客户端 fileId 替换认作 EDIT。 */ public static void requireAllowed(Collection before, Collection after, Map actions) { Objects.requireNonNull(actions, "actions"); for (Action action : classify(before, after)) { if (!Boolean.TRUE.equals(actions.get(action))) throw new IllegalArgumentException("没有附件操作权限: " + action); } } private static Set ids(Collection files) { Objects.requireNonNull(files, "files"); Set result = new HashSet<>(); for (String file : files) { if (file == null || file.trim().isEmpty() || !result.add(file)) { throw new IllegalArgumentException("附件标识为空或重复"); } } return result; } }