001 /**
002 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003 */
004 package net.sourceforge.pmd;
005
006 import java.io.File;
007 import java.util.Map;
008 import java.util.concurrent.ConcurrentHashMap;
009
010 import net.sourceforge.pmd.lang.LanguageVersion;
011
012 /**
013 * The RuleContext provides access to Rule processing state. This information
014 * includes the following global information:
015 * <ul>
016 * <li>The Report to which Rule Violations are sent.</li>
017 * <li>Named attributes.</li>
018 * </ul>
019 * As well as the following source file specific information:
020 * <ul>
021 * <li>A File for the source file.</li>
022 * <li>A String for the name of the source file.</li>
023 * <li>The Language Version of the source file.</li>
024 * </ul>
025 * It is <strong>required</strong> that all source file specific options
026 * be set between calls to difference source files. Failure to do so, may
027 * result in undefined behavior.
028 */
029 public class RuleContext {
030
031 private Report report = new Report();
032 private File sourceCodeFile;
033 private String sourceCodeFilename;
034 private LanguageVersion languageVersion;
035 private final Map<String, Object> attributes;
036
037 /**
038 * Default constructor.
039 */
040 public RuleContext() {
041 attributes = new ConcurrentHashMap<String, Object>();
042 }
043
044 /**
045 * Constructor which shares attributes with the given RuleContext.
046 */
047 public RuleContext(RuleContext ruleContext) {
048 this.attributes = ruleContext.attributes;
049 }
050
051 /**
052 * Get the Report to which Rule Violations are sent.
053 * @return The Report.
054 */
055 public Report getReport() {
056 return report;
057 }
058
059 /**
060 * Set the Report to which Rule Violations are sent.
061 * @param report The Report.
062 */
063 public void setReport(Report report) {
064 this.report = report;
065 }
066
067 /**
068 * Get the File associated with the current source file.
069 * @return The File.
070 */
071 public File getSourceCodeFile() {
072 return sourceCodeFile;
073 }
074
075 /**
076 * Set the File associated with the current source file.
077 * While this may be set to <code>null</code>, the exclude/include
078 * facilities will not work properly without a File.
079 * @param sourceCodeFile The File.
080 */
081 public void setSourceCodeFile(File sourceCodeFile) {
082 this.sourceCodeFile = sourceCodeFile;
083 }
084
085 /**
086 * Get the file name associated with the current source file.
087 * @return The file name.
088 */
089 public String getSourceCodeFilename() {
090 return sourceCodeFilename;
091 }
092
093 /**
094 * Set the file name associated with the current source file.
095 * @param filename The file name.
096 */
097 public void setSourceCodeFilename(String filename) {
098 this.sourceCodeFilename = filename;
099 }
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 }
|