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 }