1 package net.sourceforge.pmd;
2
3 import java.util.HashMap;
4 import java.util.List;
5 import java.util.Map;
6
7 import net.sourceforge.pmd.ast.CompilationUnit;
8 import net.sourceforge.pmd.ast.JavaRuleChainVisitor;
9 import net.sourceforge.pmd.jsp.ast.JspRuleChainVisitor;
10
11 /**
12 * The RuleChain is a means by which Rules can participate in a uniform
13 * visitation of the AST, and not need perform their own independent visitation.
14 * The RuleChain exists as a means to improve the speed of PMD when there are
15 * many Rules.
16 */
17 public class RuleChain {
18
19 private final Map<Language, RuleChainVisitor> languageToRuleChainVisitor = new HashMap<Language, RuleChainVisitor>();
20
21 /**
22 * Add all Rules from the given RuleSet which want to participate in the
23 * RuleChain.
24 *
25 * @param ruleSet
26 * The RuleSet to add Rules from.
27 */
28 public void add(RuleSet ruleSet) {
29 Language language = ruleSet.getLanguage();
30 for (Rule r: ruleSet.getRules()) {
31 add(ruleSet, r, language);
32 }
33 }
34
35 /**
36 * Add the given Rule if it wants to participate in the RuleChain.
37 *
38 * @param ruleSet
39 * The RuleSet to which the rule belongs.
40 * @param rule
41 * The Rule to add.
42 * @param language
43 * The Language used by the Rule.
44 */
45 private void add(RuleSet ruleSet, Rule rule, Language language) {
46 RuleChainVisitor visitor = getRuleChainVisitor(language);
47 if (visitor != null) {
48 visitor.add(ruleSet, rule);
49 }
50 }
51
52 /**
53 * Apply the RuleChain to the given ASTCompilationUnits using the given
54 * RuleContext, for those rules using the given Language.
55 *
56 * @param astCompilationUnits
57 * The ASTCompilationUnits.
58 * @param ctx
59 * The RuleContext.
60 * @param language
61 * The Language.
62 */
63 public void apply(List<CompilationUnit> astCompilationUnits, RuleContext ctx,
64 Language language) {
65 RuleChainVisitor visitor = getRuleChainVisitor(language);
66 if (visitor != null) {
67 visitor.visitAll(astCompilationUnits, ctx);
68 }
69 }
70
71
72 private RuleChainVisitor getRuleChainVisitor(Language language) {
73 if (language == null) {
74 language = Language.JAVA;
75 }
76 RuleChainVisitor visitor = languageToRuleChainVisitor.get(language);
77 if (visitor == null) {
78 if (Language.JAVA.equals(language)) {
79 visitor = new JavaRuleChainVisitor();
80 } else if (Language.JSP.equals(language)) {
81 visitor = new JspRuleChainVisitor();
82 } else {
83 throw new IllegalArgumentException("Unknown language: "
84 + language);
85 }
86 languageToRuleChainVisitor.put(language, visitor);
87 }
88 return visitor;
89 }
90 }