View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd;
5   
6   import java.io.File;
7   import java.util.Map;
8   import java.util.concurrent.ConcurrentHashMap;
9   
10  import net.sourceforge.pmd.lang.LanguageVersion;
11  
12  /**
13   * The RuleContext provides access to Rule processing state.  This information
14   * includes the following global information:
15   * <ul>
16   * 	<li>The Report to which Rule Violations are sent.</li>
17   * 	<li>Named attributes.</li>
18   * </ul>
19   * As well as the following source file specific information:
20   * <ul>
21   * 	<li>A File for the source file.</li>
22   * 	<li>A String for the name of the source file.</li>
23   * 	<li>The Language Version of the source file.</li>
24   * </ul>
25   * It is <strong>required</strong> that all source file specific options
26   * be set between calls to difference source files.  Failure to do so, may
27   * result in undefined behavior.
28   */
29  public class RuleContext {
30  
31      private Report report = new Report();
32      private File sourceCodeFile;
33      private String sourceCodeFilename;
34      private LanguageVersion languageVersion;
35      private final Map<String, Object> attributes;
36  
37      /**
38       * Default constructor.
39       */
40      public RuleContext() {
41  	attributes = new ConcurrentHashMap<String, Object>();
42      }
43  
44      /**
45       * Constructor which shares attributes with the given RuleContext.
46       */
47      public RuleContext(RuleContext ruleContext) {
48  	this.attributes = ruleContext.attributes;
49      }
50  
51      /**
52       * Get the Report to which Rule Violations are sent.
53       * @return The Report.
54       */
55      public Report getReport() {
56  	return report;
57      }
58  
59      /**
60       * Set the Report to which Rule Violations are sent.
61       * @param report The Report.
62       */
63      public void setReport(Report report) {
64  	this.report = report;
65      }
66  
67      /**
68       * Get the File associated with the current source file.
69       * @return The File.
70       */
71      public File getSourceCodeFile() {
72  	return sourceCodeFile;
73      }
74  
75      /**
76       * Set the File associated with the current source file.
77       * While this may be set to <code>null</code>, the exclude/include
78       * facilities will not work properly without a File.
79       * @param sourceCodeFile The File.
80       */
81      public void setSourceCodeFile(File sourceCodeFile) {
82  	this.sourceCodeFile = sourceCodeFile;
83      }
84  
85      /**
86       * Get the file name associated with the current source file.
87       * @return The file name.
88       */
89      public String getSourceCodeFilename() {
90  	return sourceCodeFilename;
91      }
92  
93      /**
94       * Set the file name associated with the current source file.
95       * @param filename The file name.
96       */
97      public void setSourceCodeFilename(String filename) {
98  	this.sourceCodeFilename = filename;
99      }
100 
101     /**
102      * Get the LanguageVersion associated with the current source file.
103      * @return The LanguageVersion, <code>null</code> if unknown.
104      */
105     public LanguageVersion getLanguageVersion() {
106 	return this.languageVersion;
107     }
108 
109     /**
110      * Set the LanguageVersion associated with the current source file.
111      * This may be set to <code>null</code> to indicate the version is
112      * unknown and should be automatically determined.
113      *
114      * @param languageVersion The LanguageVersion.
115      */
116     public void setLanguageVersion(LanguageVersion languageVersion) {
117 	this.languageVersion = languageVersion;
118     }
119 
120     /**
121      * Set an attribute value on the RuleContext, if it does not already exist.
122      * <p>
123      * Attributes can be shared between RuleContext instances.  This operation
124      * is thread-safe.
125      * <p>
126      * Attribute values should be modified directly via the reference provided.
127      * It is not necessary to call <code>setAttribute(String, Object)</code> to
128      * update an attribute value.  Modifications made to the attribute value
129      * will automatically be seen by other threads.  Because of this, you must
130      * ensure the attribute values are themselves thread safe.
131      *
132      * @param name The attribute name.
133      * @param value The attribute value.
134      * @exception IllegalArgumentException if <code>name</code> or <code> value</code> are <code>null</code>
135      * @return <code>true</code> if the attribute was set, <code>false</code> otherwise.
136      */
137     public boolean setAttribute(String name, Object value) {
138 	if (name == null) {
139 	    throw new IllegalArgumentException("Parameter 'name' cannot be null.");
140 	}
141 	if (value == null) {
142 	    throw new IllegalArgumentException("Parameter 'value' cannot be null.");
143 	}
144 	synchronized (this.attributes) {
145 	    if (!this.attributes.containsKey(name)) {
146 		this.attributes.put(name, value);
147 		return true;
148 	    } else {
149 		return false;
150 	    }
151 	}
152     }
153 
154     /**
155      * Get an attribute value on the RuleContext.
156      * <p>
157      * Attributes can be shared between RuleContext instances.  This operation
158      * is thread-safe.
159      * <p>
160      * Attribute values should be modified directly via the reference provided.
161      * It is not necessary to call <code>setAttribute(String, Object)</code> to
162      * update an attribute value.  Modifications made to the attribute value
163      * will automatically be seen by other threads.  Because of this, you must
164      * ensure the attribute values are themselves thread safe.
165      *
166      * @param name The attribute name.
167      * @return The current attribute value, or <code>null</code> if the attribute does not exist.
168      */
169     public Object getAttribute(String name) {
170 	return this.attributes.get(name);
171     }
172 
173     /**
174      * Remove an attribute value on the RuleContext.
175      * <p>
176      * Attributes can be shared between RuleContext instances.  This operation
177      * is thread-safe.
178      * <p>
179      * Attribute values should be modified directly via the reference provided.
180      * It is not necessary to call <code>setAttribute(String, Object)</code> to
181      * update an attribute value.  Modifications made to the attribute value
182      * will automatically be seen by other threads.  Because of this, you must
183      * ensure the attribute values are themselves thread safe.
184      *
185      * @param name The attribute name.
186      * @return The current attribute value, or <code>null</code> if the attribute does not exist.
187      */
188     public Object removeAttribute(String name) {
189 	return this.attributes.remove(name);
190     }
191 }