use of com.evolveum.midpoint.xml.ns._public.common.common_3.ApprovalPolicyActionType in project midpoint by Evolveum.
the class ProcessSpecifications method createFromRules.
static ProcessSpecifications createFromRules(List<? extends EvaluatedPolicyRule> rules, PrismContext prismContext) throws ObjectNotFoundException {
// Step 1: plain list of approval actions -> map: process-spec -> list of related actions/rules ("collected")
LinkedHashMap<WfProcessSpecificationType, List<Pair<ApprovalPolicyActionType, EvaluatedPolicyRule>>> collectedSpecifications = new LinkedHashMap<>();
for (EvaluatedPolicyRule rule : rules) {
for (ApprovalPolicyActionType approvalAction : rule.getEnabledActions(ApprovalPolicyActionType.class)) {
WfProcessSpecificationType spec = approvalAction.getProcessSpecification();
collectedSpecifications.computeIfAbsent(spec, s -> new ArrayList<>()).add(new ImmutablePair<>(approvalAction, rule));
}
}
// Step 2: resolve references
for (WfProcessSpecificationType spec : new HashSet<>(collectedSpecifications.keySet())) {
// cloned to avoid concurrent modification exception
if (spec != null && spec.getRef() != null) {
List<Map.Entry<WfProcessSpecificationType, List<Pair<ApprovalPolicyActionType, EvaluatedPolicyRule>>>> matching = collectedSpecifications.entrySet().stream().filter(e -> e.getKey() != null && spec.getRef().equals(e.getKey().getName())).collect(Collectors.toList());
if (matching.isEmpty()) {
throw new IllegalStateException("Process specification named '" + spec.getRef() + "' referenced from an approval action couldn't be found");
} else if (matching.size() > 1) {
throw new IllegalStateException("More than one process specification named '" + spec.getRef() + "' referenced from an approval action: " + matching);
} else {
// move all actions/rules to the referenced process specification
List<Pair<ApprovalPolicyActionType, EvaluatedPolicyRule>> referencedSpecActions = matching.get(0).getValue();
referencedSpecActions.addAll(collectedSpecifications.get(spec));
collectedSpecifications.remove(spec);
}
}
}
Map<String, Pair<ApprovalPolicyActionType, EvaluatedPolicyRule>> actionsMap = null;
// Step 3: include other actions
for (Map.Entry<WfProcessSpecificationType, List<Pair<ApprovalPolicyActionType, EvaluatedPolicyRule>>> processSpecificationEntry : collectedSpecifications.entrySet()) {
WfProcessSpecificationType spec = processSpecificationEntry.getKey();
if (spec == null || spec.getIncludeAction().isEmpty() && spec.getIncludeActionIfPresent().isEmpty()) {
continue;
}
if (actionsMap == null) {
actionsMap = createActionsMap(collectedSpecifications.values());
}
for (String actionToInclude : spec.getIncludeAction()) {
processActionToInclude(actionToInclude, actionsMap, processSpecificationEntry, true);
}
for (String actionToInclude : spec.getIncludeActionIfPresent()) {
processActionToInclude(actionToInclude, actionsMap, processSpecificationEntry, false);
}
}
// Step 4: sorts process specifications and wraps into ProcessSpecification objects
ProcessSpecifications rv = new ProcessSpecifications(prismContext);
collectedSpecifications.entrySet().stream().sorted((ps1, ps2) -> {
WfProcessSpecificationType key1 = ps1.getKey();
WfProcessSpecificationType key2 = ps2.getKey();
if (key1 == null) {
// non-empty (key2) records first
return key2 == null ? 0 : 1;
} else if (key2 == null) {
// non-empty (key1) record first
return -1;
}
int order1 = defaultIfNull(key1.getOrder(), Integer.MAX_VALUE);
int order2 = defaultIfNull(key2.getOrder(), Integer.MAX_VALUE);
return Integer.compare(order1, order2);
}).forEach(e -> rv.specifications.add(rv.new ProcessSpecification(e)));
return rv;
}
Aggregations