com.khartec.waltz.service.authoritative_source.AuthoritativeSourceCalculator.java Source code

Java tutorial

Introduction

Here is the source code for com.khartec.waltz.service.authoritative_source.AuthoritativeSourceCalculator.java

Source

/*
 *  This file is part of Waltz.
 *
 *     Waltz is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     Waltz is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with Waltz.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.khartec.waltz.service.authoritative_source;

import com.khartec.waltz.common.hierarchy.Node;
import com.khartec.waltz.model.EntityKind;
import com.khartec.waltz.model.authoritativesource.AuthoritativeSource;
import com.khartec.waltz.model.orgunit.OrganisationalUnit;
import com.khartec.waltz.service.orgunit.OrganisationalUnitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import static com.khartec.waltz.common.ListUtilities.*;
import static com.khartec.waltz.common.MapUtilities.groupBy;
import static com.khartec.waltz.common.MapUtilities.newHashMap;
import static com.khartec.waltz.common.hierarchy.HierarchyUtilities.parents;

@Service
public class AuthoritativeSourceCalculator {

    private final OrganisationalUnitService organisationalUnitService;
    private final AuthoritativeSourceService authoritativeSourceService;

    @Autowired
    public AuthoritativeSourceCalculator(OrganisationalUnitService organisationalUnitService,
            AuthoritativeSourceService authoritativeSourceService) {
        this.organisationalUnitService = organisationalUnitService;
        this.authoritativeSourceService = authoritativeSourceService;
    }

    /**
     * Calculates all the auth sources for a organisation tree centered around the given orgUnitId.
     *
     * <br>
     *
     * Gives back a structure which is like:
     *
     * <pre>
     *    [ orgUnitId -> dataType -> appId -> authSource ]
     * </pre>
     *
     * Typically you will just want to get the rating from the authSources, however
     * you may want more details for display purposes or similar.
     *
     * @param orgUnitId
     * @return
     */
    public Map<Long, Map<String, Map<Long, AuthoritativeSource>>> calculateAuthSourcesForOrgUnitTree(
            long orgUnitId) {
        Node<OrganisationalUnit, Long> orgUnitNode = organisationalUnitService.loadHierarchy(orgUnitId);
        return calculateAuthSourcesForOrgUnitTree(orgUnitNode);
    }

    public Map<String, Map<Long, AuthoritativeSource>> calculateAuthSourcesForOrgUnit(
            Node<OrganisationalUnit, Long> startNode) {
        List<AuthoritativeSource> allAuthSources = authoritativeSourceService.findByEntityKind(EntityKind.ORG_UNIT);
        Map<Long, Collection<AuthoritativeSource>> authSourcesByOrgId = groupBy(as -> as.parentReference().id(),
                allAuthSources);
        return calculateCumulativeRules(startNode, authSourcesByOrgId);
    }

    public Map<Long, Map<String, Map<Long, AuthoritativeSource>>> calculateAuthSourcesForOrgUnitTree(
            Node<OrganisationalUnit, Long> startNode) {
        List<AuthoritativeSource> allAuthSources = authoritativeSourceService.findByEntityKind(EntityKind.ORG_UNIT);
        Map<Long, Collection<AuthoritativeSource>> authSourcesByOrgId = groupBy(as -> as.parentReference().id(),
                allAuthSources);

        Map<Long, Map<String, Map<Long, AuthoritativeSource>>> rulesByOrgUnitId = newHashMap();
        traverse(startNode, rulesByOrgUnitId, authSourcesByOrgId);

        return rulesByOrgUnitId;
    }

    private void traverse(Node<OrganisationalUnit, Long> node,
            Map<Long, Map<String, Map<Long, AuthoritativeSource>>> accumulator,
            Map<Long, Collection<AuthoritativeSource>> authSourcesByOrgId) {
        Map<String, Map<Long, AuthoritativeSource>> cumulativeRules = calculateCumulativeRules(node,
                authSourcesByOrgId);
        accumulator.put(node.getId(), cumulativeRules);
        for (Node<OrganisationalUnit, Long> child : node.getChildren()) {
            traverse(child, accumulator, authSourcesByOrgId);
        }
    }

    /** (ouNode, ouId -> [authSource]) -> dataType -> appId -> rating */
    private Map<String, Map<Long, AuthoritativeSource>> calculateCumulativeRules(
            Node<OrganisationalUnit, Long> node, Map<Long, Collection<AuthoritativeSource>> authSourcesByOrgId) {

        // get orgIds in order from root (reverse of our parents + us)
        List<Long> ids = append(reverse(map(parents(node), x -> x.getId())), node.getId());

        Map<String, Map<Long, AuthoritativeSource>> cumulativeRules = newHashMap();

        for (Long unitId : ids) {
            Collection<AuthoritativeSource> authSources = authSourcesByOrgId.getOrDefault(unitId, newArrayList());
            Map<String, Collection<AuthoritativeSource>> byType = groupBy(as -> as.dataType(), authSources);
            for (String type : byType.keySet()) {
                Map<Long, AuthoritativeSource> appRatingMap = cumulativeRules.getOrDefault(type, newHashMap());
                byType.get(type).forEach(as -> appRatingMap.put(as.applicationReference().id(), as));
                cumulativeRules.put(type, appRatingMap);
            }
        }

        return cumulativeRules;

    }

    public static void prettyPrint(Map<String, Map<Long, AuthoritativeSource>> cumulativeRules) {
        cumulativeRules.entrySet().stream().forEach(e -> {
            System.out.println(e.getKey() + " ==> ");
            e.getValue().values().forEach(v -> System.out.println("\t" + v.applicationReference().id() + " - "
                    + v.applicationReference().name() + " ( " + v.parentReference().id() + ")"));
        });
    }

}