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 and report listeners with the given RuleContext.
46 */
47 public RuleContext(RuleContext ruleContext) {
48 this.attributes = ruleContext.attributes;
49 this.report.addSynchronizedListeners(ruleContext.getReport().getSynchronizedListeners());
50 }
51
52 /**
53 * Get the Report to which Rule Violations are sent.
54 * @return The Report.
55 */
56 public Report getReport() {
57 return report;
58 }
59
60 /**
61 * Set the Report to which Rule Violations are sent.
62 * @param report The Report.
63 */
64 public void setReport(Report report) {
65 this.report = report;
66 }
67
68 /**
69 * Get the File associated with the current source file.
70 * @return The File.
71 */
72 public File getSourceCodeFile() {
73 return sourceCodeFile;
74 }
75
76 /**
77 * Set the File associated with the current source file.
78 * While this may be set to <code>null</code>, the exclude/include
79 * facilities will not work properly without a File.
80 * @param sourceCodeFile The File.
81 */
82 public void setSourceCodeFile(File sourceCodeFile) {
83 this.sourceCodeFile = sourceCodeFile;
84 }
85
86 /**
87 * Get the file name associated with the current source file.
88 * @return The file name.
89 */
90 public String getSourceCodeFilename() {
91 return sourceCodeFilename;
92 }
93
94 /**
95 * Set the file name associated with the current source file.
96 * @param filename The file name.
97 */
98 public void setSourceCodeFilename(String filename) {
99 this.sourceCodeFilename = filename;
100 }
101
102 /**
103 * Get the LanguageVersion associated with the current source file.
104 * @return The LanguageVersion, <code>null</code> if unknown.
105 */
106 public LanguageVersion getLanguageVersion() {
107 return this.languageVersion;
108 }
109
110 /**
111 * Set the LanguageVersion associated with the current source file.
112 * This may be set to <code>null</code> to indicate the version is
113 * unknown and should be automatically determined.
114 *
115 * @param languageVersion The LanguageVersion.
116 */
117 public void setLanguageVersion(LanguageVersion languageVersion) {
118 this.languageVersion = languageVersion;
119 }
120
121 /**
122 * Set an attribute value on the RuleContext, if it does not already exist.
123 * <p>
124 * Attributes can be shared between RuleContext instances. This operation
125 * is thread-safe.
126 * <p>
127 * Attribute values should be modified directly via the reference provided.
128 * It is not necessary to call <code>setAttribute(String, Object)</code> to
129 * update an attribute value. Modifications made to the attribute value
130 * will automatically be seen by other threads. Because of this, you must
131 * ensure the attribute values are themselves thread safe.
132 *
133 * @param name The attribute name.
134 * @param value The attribute value.
135 * @exception IllegalArgumentException if <code>name</code> or <code> value</code> are <code>null</code>
136 * @return <code>true</code> if the attribute was set, <code>false</code> otherwise.
137 */
138 public boolean setAttribute(String name, Object value) {
139 if (name == null) {
140 throw new IllegalArgumentException("Parameter 'name' cannot be null.");
141 }
142 if (value == null) {
143 throw new IllegalArgumentException("Parameter 'value' cannot be null.");
144 }
145 synchronized (this.attributes) {
146 if (!this.attributes.containsKey(name)) {
147 this.attributes.put(name, value);
148 return true;
149 } else {
150 return false;
151 }
152 }
153 }
154
155 /**
156 * Get an attribute value on the RuleContext.
157 * <p>
158 * Attributes can be shared between RuleContext instances. This operation
159 * is thread-safe.
160 * <p>
161 * Attribute values should be modified directly via the reference provided.
162 * It is not necessary to call <code>setAttribute(String, Object)</code> to
163 * update an attribute value. Modifications made to the attribute value
164 * will automatically be seen by other threads. Because of this, you must
165 * ensure the attribute values are themselves thread safe.
166 *
167 * @param name The attribute name.
168 * @return The current attribute value, or <code>null</code> if the attribute does not exist.
169 */
170 public Object getAttribute(String name) {
171 return this.attributes.get(name);
172 }
173
174 /**
175 * Remove an attribute value on the RuleContext.
176 * <p>
177 * Attributes can be shared between RuleContext instances. This operation
178 * is thread-safe.
179 * <p>
180 * Attribute values should be modified directly via the reference provided.
181 * It is not necessary to call <code>setAttribute(String, Object)</code> to
182 * update an attribute value. Modifications made to the attribute value
183 * will automatically be seen by other threads. Because of this, you must
184 * ensure the attribute values are themselves thread safe.
185 *
186 * @param name The attribute name.
187 * @return The current attribute value, or <code>null</code> if the attribute does not exist.
188 */
189 public Object removeAttribute(String name) {
190 return this.attributes.remove(name);
191 }
192 }