List of usage examples for java.util LinkedHashMap computeIfAbsent
default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
From source file:com.evolveum.midpoint.wf.impl.processors.primary.policy.ProcessSpecifications.java
static ProcessSpecifications createFromRules(List<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)); }/*from w w w . j a v a2 s .co m*/ } // 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) { return key2 == null ? 0 : 1; // non-empty (key2) records first } else if (key2 == null) { return -1; // non-empty (key1) record first } 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; }