View Javadoc

1   package net.sourceforge.pmd;
2   
3   import java.io.File;
4   import java.util.ArrayList;
5   import java.util.Collection;
6   import java.util.HashSet;
7   import java.util.Iterator;
8   import java.util.List;
9   import java.util.Set;
10  
11  import net.sourceforge.pmd.ast.CompilationUnit;
12  
13  /**
14   * Grouping of Rules per Language in a RuleSet.
15   *
16   * @author pieter_van_raemdonck - Application Engineers NV/SA - www.ae.be
17   */
18  public class RuleSets {
19      /**
20       * Map of RuleLanguage on RuleSet.
21       */
22      private Collection<RuleSet> ruleSets = new ArrayList<RuleSet>();
23  
24      /**
25       * RuleChain for efficient AST visitation.
26       */
27      private RuleChain ruleChain = new RuleChain();
28  
29      /**
30       * Public constructor.
31       */
32      public RuleSets() {
33      }
34  
35      /**
36       * Public constructor. Add the given rule set.
37       *
38       * @param ruleSet the RuleSet
39       */
40      public RuleSets(RuleSet ruleSet) {
41          this();
42          addRuleSet(ruleSet);
43      }
44  
45      /**
46       * Add a ruleset for a language. Only one ruleset can be added for a specific
47       * language. If ruleSet.getLanguage() is null, it is assumed to be a RuleSet of java
48       * rules.
49       *
50       * @param ruleSet the RuleSet
51       */
52      public void addRuleSet(RuleSet ruleSet) {
53          ruleSets.add(ruleSet);
54          ruleChain.add(ruleSet);
55      }
56  
57      /**
58       * Get all the RuleSets.
59       *
60       * @return RuleSet[]
61       */
62      public RuleSet[] getAllRuleSets() {
63          return ruleSets.toArray(new RuleSet[ruleSets.size()]);
64      }
65  
66      public Iterator<RuleSet> getRuleSetsIterator() {
67          return ruleSets.iterator();
68      }
69  
70      /**
71       * Return all rules from all rulesets.
72       *
73       * @return Set
74       */
75      public Set<Rule> getAllRules() {
76          HashSet<Rule> result = new HashSet<Rule>();
77          for (RuleSet r: ruleSets) {
78              result.addAll(r.getRules());
79          }
80          return result;
81      }
82      
83      /**
84       * Check if a given source file should be checked by rules in this RuleSets.
85       * 
86       * @param file the source file to check
87       * @return <code>true</code> if the file should be checked, <code>false</code> otherwise
88       */
89      public boolean applies(File file) {
90          for (Iterator i = ruleSets.iterator(); i.hasNext();) {
91              if (((RuleSet)i.next()).applies(file)) {
92                  return true;
93              }
94          }
95          return false;
96      }
97  
98      /**
99       * Check if a source with given language should be checked by rules for a given
100      * language. This is the case if both languages are equal, or if the source is in
101      * java, and the language of the rules is unknown (for backward-compatibility
102      * reasons).
103      *
104      * @param languageOfSource language of a source; can not be null
105      * @param languageOfRule   language of a ruleset; can be null
106      * @return  boolean true if the rule applies, else false
107      */
108     public boolean applies(Language languageOfSource, Language languageOfRule) {
109         return (languageOfSource.equals(languageOfRule) || (languageOfSource
110                 .equals(Language.JAVA) && (null == languageOfRule)));
111     }
112     
113     /**
114      * Notify all rules of the start of processing.
115      */
116     public void start(RuleContext ctx) {
117         for (RuleSet ruleSet: ruleSets) {
118         	ruleSet.start(ctx);
119         }
120     }
121 
122     /**
123      * Apply all applicable rules to the compilation units.
124      * Applicable means the language of the rules must match the language
125      * of the source (@see applies).
126      *
127      * @param acuList  the List of compilation units; the type these must have,
128      *                 depends on the source language
129      * @param ctx      the RuleContext
130      * @param language the Language of the source
131      */
132     public void apply(List<CompilationUnit> acuList, RuleContext ctx, Language language) {
133         ruleChain.apply(acuList, ctx, language);
134         for (RuleSet ruleSet: ruleSets) {
135             if (applies(language, ruleSet.getLanguage())) {
136 		// This is the finer RuleSet specific check
137 		if (ruleSet.applies(ctx.getSourceCodeFile())) {
138 		    ruleSet.apply(acuList, ctx);
139 		}
140             }
141         }
142     }
143     
144     /**
145      * Notify all rules of the end of processing.
146      */
147     public void end(RuleContext ctx) {
148         for (RuleSet ruleSet: ruleSets) {
149         	ruleSet.end(ctx);
150         }
151     }
152 
153     /**
154      * Check if the rules that apply to a source of the given language
155      * use DFA.
156      *
157      * @param language the language of a source
158      * @return true if any rule in the RuleSet needs the DFA layer
159      */
160     public boolean usesDFA(Language language) {
161         for (RuleSet ruleSet: ruleSets) {
162             if (applies(language, ruleSet.getLanguage()) && ruleSet.usesDFA()) {
163                 return true;
164             }
165         }
166         return false;
167     }
168 
169     /**
170      * Returns the Rule with the given name
171      *
172      * @param ruleName the name of the rule to find
173      * @return the rule or null if not found
174      */
175     public Rule getRuleByName(String ruleName) {
176         Rule rule = null;
177         for (Iterator<RuleSet> i = ruleSets.iterator(); i.hasNext() && (rule == null);) {
178             RuleSet ruleSet = i.next();
179             rule = ruleSet.getRuleByName(ruleName);
180         }
181         return rule;
182     }
183 
184 	public boolean usesTypeResolution(Language language) {
185 		for (RuleSet ruleSet: ruleSets) {
186 			if (applies(language, ruleSet.getLanguage()) && ruleSet.usesTypeResolution()) {
187 				return true;
188 			}
189 		}
190 		return false;
191 	}
192 }