001 /*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 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 */
020 package org.sonar.api.rules;
021
022 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
023 import org.sonar.api.resources.Resource;
024 import org.sonar.api.utils.Logs;
025
026 import 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
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 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 }