package scrum.client.issues;
import ilarkesto.core.base.Str;
import ilarkesto.core.logging.Log;
import ilarkesto.gwt.client.Date;
import ilarkesto.gwt.client.DateAndTime;
import ilarkesto.gwt.client.HyperlinkWidget;
import ilarkesto.gwt.client.LabelProvider;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import scrum.client.ScrumGwt;
import scrum.client.admin.User;
import scrum.client.collaboration.ForumSupport;
import scrum.client.common.ReferenceSupport;
import scrum.client.common.ShowEntityAction;
import scrum.client.project.Project;
import com.google.gwt.user.client.ui.Widget;
public class Issue extends GIssue implements ReferenceSupport, ForumSupport {
private static Log log = Log.get(Issue.class);
public static final String INIT_TYPE = Types.ISSUE;
public static final String REFERENCE_PREFIX = "iss";
public static final int CRITICAL = 2;
public static final int SEVERE = 1;
public static final int NORMAL = 0;
public static final int MINOR = -1;
public static final Integer[] SEVERITY_OPTIONS = { CRITICAL, SEVERE, NORMAL, MINOR };
public Issue(Project project) {
setType(Types.ISSUE);
setProject(project);
setDate(DateAndTime.now());
}
public Issue(Map data) {
super(data);
}
public String getIssuer() {
if (isCreatorSet()) return getCreator().getName();
String name = getIssuerName();
String email = getIssuerEmail();
if (name == null && email == null) return null;
if (name == null) return email;
if (email == null) return name;
return name + " (" + email + ")";
}
public boolean isSuspended() {
Date date = getSuspendedUntilDate();
if (date == null) return false;
return date.isAfter(Date.today());
}
public void suspend(int days) {
Date date = Date.today().addDays(days);
log.info("Suspending for", days, "days, until", date);
setSuspendedUntilDate(date);
}
public void unsuspend() {
setSuspendedUntilDate(null);
}
public void appendStatement(String text) {
String statement = getStatement();
if (Str.isBlank(statement)) {
setStatement(text);
return;
}
setStatement(statement + "\n\n" + text);
}
public void claim(User user) {
setOwner(user);
}
public boolean isAccepted() {
if (isClosed()) return false;
return getAcceptDate() != null;
}
public boolean isBug() {
return isAccepted() && isUrgent();
}
public boolean isIdea() {
return isAccepted() && !isUrgent();
}
public boolean isOpen() {
return !isClosed() && !isAccepted();
}
public boolean isClosed() {
return getCloseDate() != null;
}
public String getStatusLabel() {
if (isClosed()) return "closed on " + getCloseDate();
if (isBug()) {
String s = "";
if (isFixed()) s += "fixed by ";
if (isOwnerSet()) s += getOwner().getName();
return s;
}
if (isIdea()) return "accepted on " + getAcceptDate();
if (isSuspended()) return "suspended until " + getSuspendedUntilDate();
return "issued on " + getDate().getDate();
}
public void setFixed(User user) {
setOwner(user);
setFixDate(Date.today());
}
public void rejectFix() {
setFixDate(null);
}
public boolean isFixed() {
return getFixDate() != null;
}
public void close() {
setOwner(null);
setCloseDate(Date.today());
}
public void acceptAsIdea() {
setAcceptDate(Date.today());
}
public void acceptAsBug() {
setAcceptDate(Date.today());
setUrgent(true);
}
public void reopen() {
setAcceptDate(null);
setUrgent(false);
setCloseDate(null);
}
public String getSeverityLabel() {
return SEVERITY_LABELS.getLabel(getSeverity());
}
@Override
public List<Integer> getSeverityOptions() {
return Arrays.asList(SEVERITY_OPTIONS);
}
public String getReference() {
return REFERENCE_PREFIX + getNumber();
}
public String getReferenceAndLabel() {
return getReference() + " " + getLabel();
}
@Override
public List<String> getTypeOptions() {
return Types.ALL;
}
@Override
public String toHtml() {
return ScrumGwt.toHtml(getReference(), getLabel());
}
@Override
public String toString() {
return getReference() + " (" + getType() + ") " + getLabel();
}
public Widget createForumItemWidget() {
return new HyperlinkWidget(new ShowEntityAction(this, getLabel()));
}
public static final Comparator<Issue> SEVERITY_COMPARATOR = new Comparator<Issue>() {
public int compare(Issue a, Issue b) {
int aSeverity = a.getSeverity();
int bSeverity = b.getSeverity();
if (aSeverity == bSeverity) return ACCEPT_DATE_COMPARATOR.compare(a, b);
return bSeverity - aSeverity;
}
};
public static final Comparator<Issue> ISSUE_DATE_COMPARATOR = new Comparator<Issue>() {
public int compare(Issue a, Issue b) {
return b.getDate().compareTo(a.getDate());
}
};
public static final Comparator<Issue> CLOSE_DATE_COMPARATOR = new Comparator<Issue>() {
public int compare(Issue a, Issue b) {
return b.getCloseDate().compareTo(a.getCloseDate());
}
};
public static final Comparator<Issue> ACCEPT_DATE_COMPARATOR = new Comparator<Issue>() {
public int compare(Issue a, Issue b) {
return b.getAcceptDate().compareTo(a.getAcceptDate());
}
};
public static LabelProvider<Integer> SEVERITY_LABELS = new LabelProvider<Integer>() {
public String getLabel(Integer severity) {
switch (severity) {
case 2:
return "critical";
case 1:
return "severe";
case 0:
return "normal";
case -1:
return "minor ";
}
return String.valueOf(severity);
}
};
@Deprecated
public static class Types {
public static final String ISSUE = "issue";
public static final String BUG = "bug";
public static final String REQUIREMENT = "requirement";
public static final String QUALITY = "quality";
public static final String IDEA = "idea";
public static final List<String> ALL = Arrays.asList(ISSUE, BUG, REQUIREMENT, QUALITY, IDEA);
}
}