001 package net.sourceforge.pmd;
002
003 import java.io.File;
004 import java.util.ArrayList;
005 import java.util.Collection;
006 import java.util.HashSet;
007 import java.util.Iterator;
008 import java.util.List;
009 import java.util.Set;
010
011 import net.sourceforge.pmd.lang.Language;
012 import net.sourceforge.pmd.lang.ast.Node;
013
014 /**
015 * Grouping of Rules per Language in a RuleSet.
016 *
017 * @author pieter_van_raemdonck - Application Engineers NV/SA - www.ae.be
018 */
019 public class RuleSets {
020 /**
021 * Map of RuleLanguage on RuleSet.
022 */
023 private Collection<RuleSet> ruleSets = new ArrayList<RuleSet>();
024
025 /**
026 * RuleChain for efficient AST visitation.
027 */
028 private RuleChain ruleChain = new RuleChain();
029
030 /**
031 * Public constructor.
032 */
033 public RuleSets() {
034 }
035
036 /**
037 * Public constructor. Add the given rule set.
038 *
039 * @param ruleSet the RuleSet
040 */
041 public RuleSets(RuleSet ruleSet) {
042 this();
043 addRuleSet(ruleSet);
044 }
045
046 /**
047 * Add a ruleset for a language. Only one ruleset can be added for a specific
048 * language. If ruleSet.getLanguage() is null, it is assumed to be a RuleSet of java
049 * rules.
050 *
051 * @param ruleSet the RuleSet
052 */
053 public void addRuleSet(RuleSet ruleSet) {
054 ruleSets.add(ruleSet);
055 ruleChain.add(ruleSet);
056 }
057
058 /**
059 * Get all the RuleSets.
060 *
061 * @return RuleSet[]
062 */
063 public RuleSet[] getAllRuleSets() {
064 return ruleSets.toArray(new RuleSet[ruleSets.size()]);
065 }
066
067 public Iterator<RuleSet> getRuleSetsIterator() {
068 return ruleSets.iterator();
069 }
070
071 /**
072 * Return all rules from all rulesets.
073 *
074 * @return Set
075 */
076 public Set<Rule> getAllRules() {
077 HashSet<Rule> result = new HashSet<Rule>();
078 for (RuleSet r : ruleSets) {
079 result.addAll(r.getRules());
080 }
081 return result;
082 }
083
084 /**
085 * Check if a given source file should be checked by rules in this RuleSets.
086 *
087 * @param file the source file to check
088 * @return <code>true</code> if the file should be checked, <code>false</code> otherwise
089 */
090 public boolean applies(File file) {
091 for (RuleSet ruleSet : ruleSets) {
092 if (ruleSet.applies(file)) {
093 return true;
094 }
095 }
096 return false;
097 }
098
099 /**
100 * Notify all rules of the start of processing.
101 */
102 public void start(RuleContext ctx) {
103 for (RuleSet ruleSet : ruleSets) {
104 ruleSet.start(ctx);
105 }
106 }
107
108 /**
109 * Apply all applicable rules to the compilation units.
110 * Applicable means the language of the rules must match the language
111 * of the source (@see applies).
112 *
113 * @param acuList the List of compilation units; the type these must have,
114 * depends on the source language
115 * @param ctx the RuleContext
116 * @param language the Language of the source
117 */
118 public void apply(List<Node> acuList, RuleContext ctx, Language language) {
119 ruleChain.apply(acuList, ctx, language);
120 for (RuleSet ruleSet : ruleSets) {
121 if (ruleSet.applies(ctx.getSourceCodeFile())) {
122 ruleSet.apply(acuList, ctx);
123 }
124 }
125 }
126
127 /**
128 * Notify all rules of the end of processing.
129 */
130 public void end(RuleContext ctx) {
131 for (RuleSet ruleSet : ruleSets) {
132 ruleSet.end(ctx);
133 }
134 }
135
136 /**
137 * Check if the rules that apply to a source of the given language
138 * use DFA.
139 *
140 * @param language the language of a source
141 * @return true if any rule in the RuleSet needs the DFA layer
142 */
143 public boolean usesDFA(Language language) {
144 for (RuleSet ruleSet : ruleSets) {
145 if (ruleSet.usesDFA(language)) {
146 return true;
147 }
148 }
149 return false;
150 }
151
152 /**
153 * Returns the Rule with the given name
154 *
155 * @param ruleName the name of the rule to find
156 * @return the rule or null if not found
157 */
158 public Rule getRuleByName(String ruleName) {
159 Rule rule = null;
160 for (Iterator<RuleSet> i = ruleSets.iterator(); i.hasNext() && rule == null;) {
161 RuleSet ruleSet = i.next();
162 rule = ruleSet.getRuleByName(ruleName);
163 }
164 return rule;
165 }
166
167 public boolean usesTypeResolution(Language language) {
168 for (RuleSet ruleSet : ruleSets) {
169 if (ruleSet.usesTypeResolution(language)) {
170 return true;
171 }
172 }
173 return false;
174 }
175 }
|