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 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 }