All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.issues.checks.RulesCatalogImpl Maven / Gradle / Ivy

package cdc.issues.checks;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import cdc.issues.checks.IssuesDetector.Factory;
import cdc.issues.rules.Rule;
import cdc.issues.rules.RuleId;
import cdc.util.lang.Checks;
import cdc.util.lang.Introspection;

/**
 * Default implementation of {@link RulesCatalog}.
 *
 * @author Damien Carbonne
 */
public class RulesCatalogImpl implements RulesCatalog {
    /**
     * (domain -> Set[Rule]) map.
     */
    private final Map> domainToRules = new HashMap<>();

    /**
     * Set of Rules.
     */
    private final Set rules = new HashSet<>();

    private final Map idToRules = new HashMap<>();

    /**
     * Set of factories.
     */
    private final Set> factories = new HashSet<>();

    /**
     * ((Rule, Data class) -> Descriptor) map.
     */
    private final Map> ruleDataClassToFactory = new HashMap<>();

    /**
     * (dataClass -> Set) map.
     */
    private final Map, Set>> dataClassToFactories = new HashMap<>();

    private static record RuleClassKey(Rule rule,
                                       Class cls) {
    }

    public RulesCatalogImpl() {
        super();
    }

    public RulesCatalogImpl register(Rule rule) {
        Checks.isNotNull(rule, "rule");
        Checks.doesNotContain(rules, rule, "rules");
        Checks.doesNotContainKey(idToRules, rule.getId(), "idToRules");

        rules.add(rule);
        idToRules.put(rule.getId(), rule);
        final Set set = domainToRules.computeIfAbsent(rule.getId().getDomain(), k -> new HashSet<>());
        set.add(rule);
        return this;
    }

    public  RulesCatalogImpl register(IssuesDetector.Factory factory) {
        Checks.isNotNull(factory, "factory");
        Checks.doesNotContain(factories, factory, "factory");

        factories.add(factory);
        final Set> set =
                dataClassToFactories.computeIfAbsent(factory.getDataClass(), k -> new HashSet<>());
        set.add(factory);

        for (final Rule rule : factory.getSupportedRules()) {
            final RuleClassKey key = new RuleClassKey(rule, factory.getDataClass());
            if (!hasRule(rule)) {
                register(rule);
            }
            if (ruleDataClassToFactory.containsKey(key)) {
                throw new IllegalArgumentException("Duplicate factory for " + key);
            } else {
                ruleDataClassToFactory.put(key, factory);
            }
        }
        return this;
    }

    @Override
    public Set getDomains() {
        return domainToRules.keySet();
    }

    @Override
    public Set getRules() {
        return rules;
    }

    @Override
    public Set getRules(String domain) {
        return domainToRules.getOrDefault(domain, Collections.emptySet());
    }

    @Override
    public Optional getRule(RuleId id) {
        return Optional.ofNullable(idToRules.get(id));
    }

    @Override
    public Set> getFactories() {
        return factories;
    }

    @Override
    public  Set> getFactories(Class dataClass) {
        final Set> set =
                dataClassToFactories.getOrDefault(dataClass, Collections.emptySet());
        return Introspection.uncheckedCast(set);
    }

    @Override
    public  Optional> getFactory(Rule rule,
                                               Class dataClass) {
        final RuleClassKey key = new RuleClassKey(rule, dataClass);
        final Factory value = Introspection.uncheckedCast(ruleDataClassToFactory.get(key));
        return Optional.ofNullable(value);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy