001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright (c) 2009-2019 CQSE GmbH                                        |
004|                                                                          |
005+-------------------------------------------------------------------------*/
006package eu.cqse.check.framework.core.ruleset;
007
008import java.lang.annotation.Annotation;
009import java.lang.reflect.InvocationTargetException;
010import java.util.ArrayList;
011import java.util.HashMap;
012import java.util.List;
013import java.util.Map;
014
015import org.atteo.classindex.ClassIndex;
016import org.conqat.lib.commons.collections.CollectionUtils;
017
018import eu.cqse.check.framework.core.Check;
019
020/**
021 * Utility program for generating mapping for standard rule sets.
022 */
023public class RulesetMappingGenerator {
024
025        /** Entry method. */
026        @SuppressWarnings("unchecked")
027        public static void main(String[] args) {
028                for (Class<?> ruleset : ClassIndex.getAnnotated(RulesetAnnotation.class)) {
029                        if (!ruleset.isAnnotation()) {
030                                continue;
031                        }
032
033                        processRuleset((Class<? extends Annotation>) ruleset);
034                }
035        }
036
037        /** Processes a single ruleset. */
038        private static void processRuleset(Class<? extends Annotation> ruleset) {
039                RulesetAnnotation rulesetInfomation = ruleset.getAnnotation(RulesetAnnotation.class);
040                System.out.println("# " + rulesetInfomation.name());
041
042                Map<String, List<String>> rulesetToCheck = buildRulesetToCheckMapping(ruleset);
043
044                IRulesetRule[] allRules = rulesetInfomation.rules().getEnumConstants();
045                for (IRulesetRule rule : allRules) {
046                        List<String> teamscaleCheck = rulesetToCheck.get(rule.getRuleId());
047                        if (CollectionUtils.isNullOrEmpty(teamscaleCheck)) {
048                                continue;
049                        }
050
051                        System.out.println();
052                        System.out.println("## " + rule.getRuleId() + ": " + rule.getRuleText());
053                        for (String check : teamscaleCheck) {
054                                System.out.println("\t- " + check);
055                        }
056                }
057
058                System.out.println();
059        }
060
061        private static Map<String, List<String>> buildRulesetToCheckMapping(Class<? extends Annotation> ruleset) {
062                Map<String, List<String>> rulesetRuleToTeamscaleCheck = new HashMap<>();
063                Iterable<Class<?>> checks = ClassIndex.getAnnotated(ruleset);
064                for (Class<?> check : checks) {
065                        Check checkAnnotation = check.getAnnotation(Check.class);
066                        if (checkAnnotation == null) {
067                                continue;
068                        }
069
070                        for (Annotation ruleAnnotation : check.getAnnotationsByType(ruleset)) {
071                                processRuleAnnotations(checkAnnotation, ruleAnnotation, rulesetRuleToTeamscaleCheck);
072                        }
073                }
074                return rulesetRuleToTeamscaleCheck;
075        }
076
077        private static void processRuleAnnotations(Check checkAnnotation, Annotation ruleAnnotation,
078                        Map<String, List<String>> rulesetRuleToTeamscaleCheck) {
079                try {
080                        Object value = ruleAnnotation.getClass().getMethod("value").invoke(ruleAnnotation);
081                        if (value instanceof IRulesetRule) {
082                                rulesetRuleToTeamscaleCheck.computeIfAbsent(((IRulesetRule) value).getRuleId(), x -> new ArrayList<>())
083                                                .add(checkAnnotation.name());
084                        }
085                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException
086                                | SecurityException e) {
087                        throw new RuntimeException(e);
088                }
089        }
090
091}