Example usage for java.util LinkedHashMap computeIfAbsent

List of usage examples for java.util LinkedHashMap computeIfAbsent

Introduction

In this page you can find the example usage for java.util LinkedHashMap computeIfAbsent.

Prototype

default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) 

Source Link

Document

If the specified key is not already associated with a value (or is mapped to null ), attempts to compute its value using the given mapping function and enters it into this map unless null .

Usage

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;
}