package jnpf.flowable.util;
|
|
import jnpf.util.JsonUtil;
|
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.Locale;
|
import java.util.Map;
|
|
/** Renders the selected audit fields of the current form for a flow notification. */
|
final class FlowAuditTitleUtil {
|
|
interface ValueResolver {
|
String resolve(Map<String, Object> field, Map<String, Object> config, Object value, Map<String, Object> row);
|
}
|
|
private static final int MAX_SUFFIX_LENGTH = 200;
|
|
private FlowAuditTitleUtil() {
|
}
|
|
static String append(String title, String suffix) {
|
if (title == null || title.trim().isEmpty() || suffix == null || suffix.trim().isEmpty()
|
|| title.endsWith("/" + suffix)) {
|
return title;
|
}
|
return title + "/" + suffix;
|
}
|
|
static String suffix(String formDataJson, Map<String, Object> data) {
|
return suffix(formDataJson, data, (field, config, value, row) -> display(value));
|
}
|
|
static String suffix(String formDataJson, Map<String, Object> data, ValueResolver resolver) {
|
if (formDataJson == null || data == null || data.isEmpty()) {
|
return null;
|
}
|
try {
|
Map<String, Object> form = JsonUtil.stringToMap(formDataJson);
|
if (form == null) {
|
return null;
|
}
|
List<String> values = new ArrayList<>();
|
collect(list(form.get("fields")), data, values, resolver);
|
if (values.isEmpty()) {
|
return null;
|
}
|
String suffix = String.join("/", values);
|
return suffix.length() > MAX_SUFFIX_LENGTH ? suffix.substring(0, MAX_SUFFIX_LENGTH) : suffix;
|
} catch (RuntimeException ignored) {
|
return null;
|
}
|
}
|
|
@SuppressWarnings("unchecked")
|
private static void collect(List<?> fields, Map<String, Object> row, List<String> values,
|
ValueResolver resolver) {
|
for (Object raw : fields) {
|
if (!(raw instanceof Map)) {
|
continue;
|
}
|
Map<String, Object> field = (Map<String, Object>) raw;
|
Object rawConfig = field.containsKey("config") ? field.get("config") : field.get("__config__");
|
if (!(rawConfig instanceof Map)) {
|
continue;
|
}
|
Map<String, Object> config = (Map<String, Object>) rawConfig;
|
List<?> children = list(config.get("children"));
|
if ("table".equals(config.get("jnpfKey"))) {
|
Object tableData = value(row, model(field));
|
List<?> rows = list(tableData);
|
// A configured child table contributes values from its actual first row only.
|
if (!rows.isEmpty() && rows.get(0) instanceof Map) {
|
collect(children, (Map<String, Object>) rows.get(0), values, resolver);
|
}
|
continue;
|
}
|
String model = model(field);
|
if (model != null && Boolean.parseBoolean(String.valueOf(config.get("biz_log_enabled")))
|
&& !sensitive(model, config)) {
|
String display;
|
try {
|
display = resolver.resolve(field, config, value(row, model), row);
|
} catch (RuntimeException ignored) {
|
display = null;
|
}
|
if (display != null) {
|
values.add(display);
|
}
|
}
|
if (!children.isEmpty()) {
|
collect(children, row, values, resolver);
|
}
|
}
|
}
|
|
private static String model(Map<String, Object> field) {
|
Object raw = field.containsKey("vModel") ? field.get("vModel") : field.get("__vModel__");
|
return raw == null || String.valueOf(raw).trim().isEmpty() ? null : String.valueOf(raw).trim();
|
}
|
|
private static Object value(Map<String, Object> row, String model) {
|
if (model == null) {
|
return null;
|
}
|
Object direct = row.get(model);
|
if (direct != null) {
|
return direct;
|
}
|
for (Map.Entry<String, Object> entry : row.entrySet()) {
|
if (entry.getKey() != null && model.equalsIgnoreCase(entry.getKey())) {
|
return entry.getValue();
|
}
|
}
|
return null;
|
}
|
|
static String display(Object raw) {
|
if (raw == null || raw instanceof Map) {
|
return null;
|
}
|
if (raw instanceof List) {
|
List<String> parts = new ArrayList<>();
|
for (Object item : (List<?>) raw) {
|
if (item != null && !(item instanceof Map) && !String.valueOf(item).trim().isEmpty()) {
|
parts.add(String.valueOf(item).trim());
|
}
|
}
|
return parts.isEmpty() ? null : String.join(",", parts);
|
}
|
String value = String.valueOf(raw).trim();
|
return value.isEmpty() || "***".equals(value) ? null : value;
|
}
|
|
private static boolean sensitive(String model, Map<String, Object> config) {
|
String name = model.toLowerCase(Locale.ROOT);
|
String key = String.valueOf(config.get("jnpfKey")).toLowerCase(Locale.ROOT);
|
return name.equals("biz_sign") || name.equals("bizsign") || name.equals("sign_id")
|
|| name.equals("signid") || name.endsWith("sign") || name.endsWith("signid")
|
|| name.contains("password") || name.contains("mima") || key.contains("password")
|
|| key.contains("signature");
|
}
|
|
@SuppressWarnings("unchecked")
|
private static List<?> list(Object raw) {
|
if (raw instanceof List) {
|
return (List<?>) raw;
|
}
|
if (raw instanceof String && !((String) raw).trim().isEmpty()) {
|
List<?> parsed = JsonUtil.getJsonToList((String) raw, Map.class);
|
return parsed == null ? Collections.emptyList() : parsed;
|
}
|
return Collections.emptyList();
|
}
|
}
|