001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2011 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.api.rules; 021 022 import org.apache.commons.lang.builder.EqualsBuilder; 023 import org.apache.commons.lang.builder.HashCodeBuilder; 024 import org.apache.commons.lang.builder.ReflectionToStringBuilder; 025 import org.sonar.api.resources.Resource; 026 import org.sonar.api.utils.Logs; 027 028 import java.util.Date; 029 030 /** 031 * A class that represents a violation. A violation happens when a resource does not respect a defined rule. 032 */ 033 public class Violation { 034 035 private Resource resource; 036 private Rule rule; 037 private String message; 038 private RulePriority severity; 039 private Integer lineId; 040 private Double cost; 041 private Date createdAt; 042 private boolean switchedOff=false; 043 private String checksum; 044 private boolean isNew=false; 045 046 /** 047 * Creates of a violation from a rule. Will need to define the resource later on 048 * 049 * @deprecated since 2.3. Use the factory method create() 050 */ 051 @Deprecated 052 public Violation(Rule rule) { 053 this.rule = rule; 054 } 055 056 /** 057 * Creates a fully qualified violation 058 * 059 * @param rule 060 * the rule that has been violated 061 * @param resource 062 * the resource the violation should be attached to 063 * @deprecated since 2.3. Use the factory method create() 064 */ 065 @Deprecated 066 public Violation(Rule rule, Resource resource) { 067 this.resource = resource; 068 this.rule = rule; 069 } 070 071 public Resource getResource() { 072 return resource; 073 } 074 075 /** 076 * Sets the resource the violation applies to 077 * 078 * @return the current object 079 */ 080 public Violation setResource(Resource resource) { 081 this.resource = resource; 082 return this; 083 } 084 085 public Rule getRule() { 086 return rule; 087 } 088 089 /** 090 * Sets the rule violated 091 * 092 * @return the current object 093 */ 094 public Violation setRule(Rule rule) { 095 this.rule = rule; 096 return this; 097 } 098 099 public String getMessage() { 100 return message; 101 } 102 103 /** 104 * Sets the violation message 105 * 106 * @return the current object 107 */ 108 public Violation setMessage(String message) { 109 this.message = message; 110 return this; 111 } 112 113 /** 114 * @return line number (numeration starts from 1), or <code>null</code> if violation doesn't belong to concrete line 115 * @see #hasLineId() 116 */ 117 public Integer getLineId() { 118 return lineId; 119 } 120 121 /** 122 * Sets the violation line. 123 * 124 * @param lineId line number (numeration starts from 1), or <code>null</code> if violation doesn't belong to concrete line 125 * @return the current object 126 */ 127 public Violation setLineId(Integer lineId) { 128 if (lineId != null && lineId < 1) { 129 // TODO this normalization was added in 2.8, throw exception in future versions - see http://jira.codehaus.org/browse/SONAR-2386 130 Logs.INFO.warn("line must not be less than 1 - in future versions this will cause IllegalArgumentException"); 131 this.lineId = null; 132 } else { 133 this.lineId = lineId; 134 } 135 return this; 136 } 137 138 /** 139 * @return <code>true<code> if violation belongs to concrete line 140 * @since 2.8 141 */ 142 public boolean hasLineId() { 143 return lineId != null; 144 } 145 146 /** 147 * @since 2.5 148 */ 149 public RulePriority getSeverity() { 150 return severity; 151 } 152 153 /** 154 * For internal use only. 155 * 156 * @since 2.5 157 */ 158 public Violation setSeverity(RulePriority severity) { 159 this.severity = severity; 160 return this; 161 } 162 163 /** 164 * @deprecated since 2.5 use {@link #getSeverity()} instead. See http://jira.codehaus.org/browse/SONAR-1829 165 */ 166 @Deprecated 167 public RulePriority getPriority() { 168 return severity; 169 } 170 171 /** 172 * For internal use only 173 * 174 * @deprecated since 2.5 use {@link #setSeverity(RulePriority)} instead. See http://jira.codehaus.org/browse/SONAR-1829 175 */ 176 @Deprecated 177 public Violation setPriority(RulePriority priority) { 178 this.severity = priority; 179 return this; 180 } 181 182 /** 183 * @see #setCost(Double) 184 * @since 2.4 185 */ 186 public Double getCost() { 187 return cost; 188 } 189 190 /** 191 * The cost to fix a violation can't be precisely computed without this information. Let's take the following example : a rule forbids to 192 * have methods whose complexity is greater than 10. Without this field "cost", the same violation is created with a method whose 193 * complexity is 15 and a method whose complexity is 100. If the cost to fix one point of complexity is 0.05h, then 15mn is necessary to 194 * fix the method whose complexity is 15, and 3h5mn is required to fix the method whose complexity is 100. 195 * 196 * @since 2.4 197 */ 198 public Violation setCost(Double d) { 199 if (d == null || d >= 0) { 200 this.cost = d; 201 return this; 202 } else { 203 throw new IllegalArgumentException("Cost to fix violation can't be negative or NaN"); 204 } 205 } 206 207 /** 208 * @since 2.5 209 */ 210 public Date getCreatedAt() { 211 return createdAt; 212 } 213 214 /** 215 * For internal use only 216 * 217 * @since 2.5 218 */ 219 public Violation setCreatedAt(Date createdAt) { 220 this.createdAt = createdAt; 221 return this; 222 } 223 224 /** 225 * Switches off the current violation. This is a kind of "mute", which means the violation exists but won't be counted as an active 226 * violation (and thus, won't be counted in the total number of violations). It's usually used for false-positives. 227 * 228 * The extensions which call this method must be executed 229 * 230 * @since 2.8 231 * @param b 232 * if true, the violation is considered OFF 233 */ 234 public Violation setSwitchedOff(boolean b) { 235 this.switchedOff = b; 236 return this; 237 } 238 239 /** 240 * Tells whether this violation is ON or OFF. 241 * 242 * @since 2.8 243 */ 244 public boolean isSwitchedOff() { 245 return switchedOff; 246 } 247 248 /** 249 * Checksum is available in decorators executed after the barrier {@link org.sonar.api.batch.DecoratorBarriers#END_OF_VIOLATION_TRACKING} 250 */ 251 public String getChecksum() { 252 return checksum; 253 } 254 255 /** 256 * For internal use only. Checksum is automatically set by Sonar. Plugins must not call this method. 257 */ 258 public Violation setChecksum(String s) { 259 this.checksum = s; 260 return this; 261 } 262 263 /** 264 * A violation is considered as "new" if it has been created after the reference analysis 265 * (the "previous" analysis). 266 * This method must be used only by post-jobs and decorators depending on the barrier 267 * {@link org.sonar.api.batch.DecoratorBarriers#END_OF_VIOLATION_TRACKING} 268 * @since 2.9 269 */ 270 public boolean isNew() { 271 return isNew; 272 } 273 274 /** 275 * For internal use only. MUST NOT BE SET FROM PLUGINS. 276 * @since 2.9 277 */ 278 public Violation setNew(boolean b) { 279 isNew = b; 280 return this; 281 } 282 283 @Override 284 public String toString() { 285 return ReflectionToStringBuilder.toString(this); 286 } 287 288 public static Violation create(ActiveRule activeRule, Resource resource) { 289 return new Violation(activeRule.getRule()).setResource(resource); 290 } 291 292 public static Violation create(Rule rule, Resource resource) { 293 return new Violation(rule).setResource(resource); 294 } 295 296 }