RuleSets.java
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 }