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 }