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     */
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    }