001/* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2013 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * SonarQube 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 * SonarQube 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 License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020package org.sonar.api.rules; 021 022import org.apache.commons.lang.builder.ReflectionToStringBuilder; 023import org.sonar.api.resources.Resource; 024import org.sonar.api.utils.Logs; 025 026import java.util.Date; 027 028/** 029 * A class that represents a violation. A violation happens when a resource does not respect a defined rule. 030 * @deprecated in 3.6. Replaced by {@link org.sonar.api.issue.Issue}. 031 */ 032@Deprecated 033public 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 private boolean isManual = false; 046 private Integer permanentId; 047 private Integer personId; 048 049 /** 050 * Creates of a violation from a rule. Will need to define the resource later on 051 * 052 * @deprecated since 2.3. Use the factory method create() 053 */ 054 @Deprecated 055 public Violation(Rule rule) { 056 this.rule = rule; 057 } 058 059 /** 060 * Creates a fully qualified violation 061 * 062 * @param rule the rule that has been violated 063 * @param resource the resource the violation should be attached to 064 * @deprecated since 2.3. Use the factory method create() 065 */ 066 @Deprecated 067 public Violation(Rule rule, Resource resource) { 068 this.resource = resource; 069 this.rule = rule; 070 } 071 072 public Resource getResource() { 073 return resource; 074 } 075 076 /** 077 * Sets the resource the violation applies to 078 * 079 * @return the current object 080 */ 081 public Violation setResource(Resource resource) { 082 this.resource = resource; 083 return this; 084 } 085 086 public Rule getRule() { 087 return rule; 088 } 089 090 /** 091 * Sets the rule violated 092 * 093 * @return the current object 094 */ 095 public Violation setRule(Rule rule) { 096 this.rule = rule; 097 return this; 098 } 099 100 public String getMessage() { 101 return message; 102 } 103 104 /** 105 * Sets the violation message 106 * 107 * @return the current object 108 */ 109 public Violation setMessage(String message) { 110 this.message = message; 111 return this; 112 } 113 114 /** 115 * @return line number (numeration starts from 1), or <code>null</code> if violation doesn't belong to concrete line 116 * @see #hasLineId() 117 */ 118 public Integer getLineId() { 119 return lineId; 120 } 121 122 /** 123 * Sets the violation line. 124 * 125 * @param lineId line number (numeration starts from 1), or <code>null</code> if violation doesn't belong to concrete line 126 * @return the current object 127 */ 128 public Violation setLineId(Integer lineId) { 129 if (lineId != null && lineId < 1) { 130 // TODO this normalization was added in 2.8, throw exception in future versions - see http://jira.codehaus.org/browse/SONAR-2386 131 Logs.INFO.warn("line must not be less than 1 - in future versions this will cause IllegalArgumentException"); 132 this.lineId = null; 133 } else { 134 this.lineId = lineId; 135 } 136 return this; 137 } 138 139 /** 140 * @return <code>true<code> if violation belongs to concrete line 141 * @since 2.8 142 */ 143 public boolean hasLineId() { 144 return lineId != null; 145 } 146 147 /** 148 * @since 2.5 149 */ 150 public RulePriority getSeverity() { 151 return severity; 152 } 153 154 /** 155 * For internal use only. 156 * 157 * @since 2.5 158 */ 159 public Violation setSeverity(RulePriority severity) { 160 this.severity = severity; 161 return this; 162 } 163 164 /** 165 * @deprecated since 2.5 use {@link #getSeverity()} instead. See http://jira.codehaus.org/browse/SONAR-1829 166 */ 167 @Deprecated 168 public RulePriority getPriority() { 169 return severity; 170 } 171 172 /** 173 * For internal use only 174 * 175 * @deprecated since 2.5 use {@link #setSeverity(RulePriority)} instead. See http://jira.codehaus.org/browse/SONAR-1829 176 */ 177 @Deprecated 178 public Violation setPriority(RulePriority priority) { 179 this.severity = priority; 180 return this; 181 } 182 183 /** 184 * @see #setCost(Double) 185 * @since 2.4 186 */ 187 public Double getCost() { 188 return cost; 189 } 190 191 /** 192 * The cost to fix a violation can't be precisely computed without this information. Let's take the following example : a rule forbids to 193 * have methods whose complexity is greater than 10. Without this field "cost", the same violation is created with a method whose 194 * 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 195 * fix the method whose complexity is 15, and 3h5mn is required to fix the method whose complexity is 100. 196 * 197 * @since 2.4 198 */ 199 public Violation setCost(Double d) { 200 if (d == null || d >= 0) { 201 this.cost = d; 202 return this; 203 } else { 204 throw new IllegalArgumentException("Cost to fix violation can't be negative or NaN"); 205 } 206 } 207 208 /** 209 * @since 2.5 210 */ 211 public Date getCreatedAt() { 212 return createdAt; 213 } 214 215 /** 216 * For internal use only 217 * 218 * @since 2.5 219 */ 220 public Violation setCreatedAt(Date createdAt) { 221 this.createdAt = createdAt; 222 return this; 223 } 224 225 /** 226 * Switches off the current violation. This is a kind of "mute", which means the violation exists but won't be counted as an active 227 * violation (and thus, won't be counted in the total number of violations). It's usually used for false-positives. 228 * <p/> 229 * The extensions which call this method must be executed 230 * 231 * @param b if true, the violation is considered OFF 232 * @since 2.8 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 * 269 * @since 2.9 270 */ 271 public boolean isNew() { 272 return isNew; 273 } 274 275 /** 276 * For internal use only. MUST NOT BE SET FROM PLUGINS. 277 * 278 * @since 2.9 279 */ 280 public Violation setNew(boolean b) { 281 isNew = b; 282 return this; 283 } 284 285 /** 286 * @since 2.13 287 */ 288 public boolean isManual() { 289 return isManual; 290 } 291 292 /** 293 * For internal use only. MUST NOT BE SET FROM PLUGINS. 294 * 295 * @since 2.13 296 */ 297 public Violation setManual(boolean b) { 298 isManual = b; 299 return this; 300 } 301 302 /** 303 * For internal use only. MUST NOT BE SET FROM PLUGINS. 304 * 305 * @since 2.13 306 */ 307 public Integer getPermanentId() { 308 return permanentId; 309 } 310 311 /** 312 * For internal use only. MUST NOT BE SET FROM PLUGINS. 313 * 314 * @since 2.13 315 */ 316 public Violation setPermanentId(Integer i) { 317 this.permanentId = i; 318 return this; 319 } 320 321 /** 322 * @since 2.13 323 */ 324 public Integer getPersonId() { 325 return personId; 326 } 327 328 /** 329 * For internal use only. 330 * 331 * @since 2.13 332 */ 333 public Violation setPersonId(Integer i) { 334 this.personId = i; 335 return this; 336 } 337 338 @Override 339 public String toString() { 340 return ReflectionToStringBuilder.toString(this); 341 } 342 343 public static Violation create(ActiveRule activeRule, Resource resource) { 344 return new Violation(activeRule.getRule()).setResource(resource); 345 } 346 347 public static Violation create(Rule rule, Resource resource) { 348 return new Violation(rule).setResource(resource); 349 } 350 351}