package hudson.plugins.findbugs.parser; import hudson.plugins.analysis.util.model.AbstractAnnotation; import hudson.plugins.analysis.util.model.Priority; import hudson.plugins.findbugs.FindBugsMessages; import org.apache.commons.lang.StringUtils; import org.jvnet.localizer.LocaleProvider; import java.text.DateFormat; import java.util.Date; /** * A serializable Java Bean class representing a warning. * <p> * Note: this class has a natural ordering that is inconsistent with equals. * </p> * * @author Ulli Hafner */ @SuppressWarnings("PMD.CyclomaticComplexity") public class Bug extends AbstractAnnotation { private static final long serialVersionUID = 5171661552905752370L; public static final String ORIGIN = "findbugs"; private String tooltip = StringUtils.EMPTY; /** Unique hash code of this bug. */ private String instanceHash; /** Computed from firstSeen */ private int ageInDays; private long firstSeen; private int reviewCount; private boolean notAProblem; private static final DateFormat FIRST_SEEN_FORMAT = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); /** * Creates a new instance of <code>Bug</code>. * * @param priority * the priority * @param message * the message of the warning * @param category * the warning category * @param type * the identifier of the warning type * @param start * the first line of the line range * @param end * the last line of the line range */ public Bug(final Priority priority, final String message, final String category, final String type, final int start, final int end) { super(priority, message, start, end, category, type); setOrigin(ORIGIN); } /** * Creates a new instance of <code>Bug</code>. * * @param priority * the priority * @param message * the message of the warning * @param category * the warning category * @param type * the identifier of the warning type * @param lineNumber * the line number of the warning in the corresponding file */ public Bug(final Priority priority, final String message, final String category, final String type, final int lineNumber) { this(priority, message, category, type, lineNumber, lineNumber); } /** * Creates a new instance of <code>Bug</code> that has no associated line in code (file warning). * * @param priority * the priority * @param message * the message of the warning * @param category * the warning category * @param type * the identifier of the warning type */ public Bug(final Priority priority, final String message, final String category, final String type) { this(priority, message, category, type, 0, 0); } /** * Creates a new instance of <code>Bug</code>. * * @param priority * the priority * @param message * the message of the warning * @param category * the warning category * @param type * the identifier of the warning type * @param start * the first line of the line range * @param end * the last line of the line range * @param tooltip * the tooltip to show */ public Bug(final Priority priority, final String message, final String category, final String type, final int start, final int end, final String tooltip) { this(priority, message, category, type, start, end); this.tooltip = tooltip; } public long getFirstSeen() { return firstSeen; } public void setFirstSeen(long firstSeen) { this.firstSeen = firstSeen; } public void setAgeInDays(int ageInDays) { this.ageInDays = ageInDays; } public int getAgeInDays() { return ageInDays; } public int getReviewCount() { return reviewCount; } public void setReviewCount(int reviewCount) { this.reviewCount = reviewCount; } public boolean isNotAProblem() { return notAProblem; } public void setNotAProblem(boolean notAProblem) { this.notAProblem = notAProblem; } /** * Rebuilds the priorities mapping. * * @return the created object */ private Object readResolve() { if (instanceHash == null) { instanceHash = String.valueOf(super.hashCode()); } return this; } /** {@inheritDoc} */ public String getToolTip() { return StringUtils.defaultIfEmpty(tooltip, FindBugsMessages.getInstance().getMessage(getType(), LocaleProvider.getLocale())); } @Override public String getMessage() { String msg = ""; if (ageInDays != -1) { String seenAt; if (ageInDays > 0) { seenAt = plural("day", ageInDays) + " ago"; msg += "First seen " + seenAt; if (firstSeen > 0) msg += " at " + FIRST_SEEN_FORMAT.format(new Date(firstSeen)); } } if (reviewCount > 0) { if (msg.length() > 0) msg += " - "; msg += "Evaluated by " + plural("reviewer", reviewCount); } if (msg.length() > 0) return super.getMessage() + "<br><br><u>Cloud info:</u><br>" + msg; else return super.getMessage(); } private String plural(String singular, int number) { return number + " " + (number == 1 ? singular : singular + "s"); } /** * Sets the unique hash code of this bug. * * @param instanceHash the instance hash as generated by the FindBugs library */ public void setInstanceHash(final String instanceHash) { this.instanceHash = instanceHash; } /** {@inheritDoc} */ @Override public int hashCode() { return 31 + ((instanceHash == null) ? 0 : instanceHash.hashCode()); // NOCHECKSTYLE } /** {@inheritDoc} */ @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Bug other = (Bug)obj; if (instanceHash == null) { if (other.instanceHash != null) { return false; } } else if (!instanceHash.equals(other.instanceHash)) { return false; } return true; } }