From 69a55934079b299740fa4679fbbd9faeb8319726 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Sun, 15 Jan 2012 19:07:34 -0500 Subject: [PATCH] More functional issues. --- src/com/gitblit/models/IssueModel.java | 333 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 270 insertions(+), 63 deletions(-) diff --git a/src/com/gitblit/models/IssueModel.java b/src/com/gitblit/models/IssueModel.java index 3c6d9a0..19241c2 100644 --- a/src/com/gitblit/models/IssueModel.java +++ b/src/com/gitblit/models/IssueModel.java @@ -18,10 +18,13 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Date; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.StringUtils; +import com.gitblit.utils.TimeUtils; /** * The Gitblit Issue model, its component classes, and enums. @@ -31,7 +34,7 @@ */ public class IssueModel implements Serializable, Comparable<IssueModel> { - private static final long serialVersionUID = 1L;; + private static final long serialVersionUID = 1L; public String id; @@ -56,7 +59,7 @@ public List<Change> changes; public IssueModel() { - created = new Date(); + created = new Date((System.currentTimeMillis() / 1000) * 1000); type = Type.Defect; status = Status.New; @@ -72,25 +75,22 @@ return s; } + public boolean hasLabel(String label) { + return getLabels().contains(label); + } + public List<String> getLabels() { List<String> list = new ArrayList<String>(); String labels = null; for (Change change : changes) { - if (change.hasFieldChanges()) { - FieldChange field = change.getField(Field.Labels); - if (field != null) { - labels = field.value.toString(); - } + if (change.hasField(Field.Labels)) { + labels = change.getString(Field.Labels); } } if (!StringUtils.isEmpty(labels)) { list.addAll(StringUtils.getStringsFromValue(labels, " ")); } return list; - } - - public boolean hasLabel(String label) { - return getLabels().contains(label); } public Attachment getAttachment(String name) { @@ -106,16 +106,55 @@ return attachment; } - public void addChange(Change change) { - if (changes == null) { - changes = new ArrayList<Change>(); - } + public void applyChange(Change change) { changes.add(change); + + if (change.hasFieldChanges()) { + for (FieldChange fieldChange : change.fieldChanges) { + switch (fieldChange.field) { + case Id: + id = fieldChange.value.toString(); + break; + case Type: + type = IssueModel.Type.fromObject(fieldChange.value); + break; + case Status: + status = IssueModel.Status.fromObject(fieldChange.value); + break; + case Priority: + priority = IssueModel.Priority.fromObject(fieldChange.value); + break; + case Summary: + summary = fieldChange.value.toString(); + break; + case Description: + description = fieldChange.value.toString(); + break; + case Reporter: + reporter = fieldChange.value.toString(); + break; + case Owner: + owner = fieldChange.value.toString(); + break; + case Milestone: + milestone = fieldChange.value.toString(); + break; + } + } + } } @Override public String toString() { - return summary; + StringBuilder sb = new StringBuilder(); + sb.append("issue "); + sb.append(id.substring(0, 8)); + sb.append(" (" + summary + ")\n"); + for (Change change : changes) { + sb.append(change); + sb.append('\n'); + } + return sb.toString(); } @Override @@ -135,68 +174,46 @@ return id.hashCode(); } - public static class Change implements Serializable { + public static class Change implements Serializable, Comparable<Change> { private static final long serialVersionUID = 1L; - public Date created; + public final Date created; - public String author; + public final String author; + + public String id; + + public char code; public Comment comment; - public List<FieldChange> fieldChanges; + public Set<FieldChange> fieldChanges; - public List<Attachment> attachments; + public Set<Attachment> attachments; - public void comment(String text) { - comment = new Comment(text); + public Change(String author) { + this.created = new Date((System.currentTimeMillis() / 1000) * 1000); + this.author = author; + this.id = StringUtils.getSHA1(created.toString() + author); } public boolean hasComment() { - return comment != null; + return comment != null && !comment.deleted; + } + + public void comment(String text) { + comment = new Comment(text); + comment.id = StringUtils.getSHA1(created.toString() + author + text); } public boolean hasAttachments() { return !ArrayUtils.isEmpty(attachments); } - public boolean hasFieldChanges() { - return !ArrayUtils.isEmpty(fieldChanges); - } - - public FieldChange getField(Field field) { - if (fieldChanges != null) { - for (FieldChange fieldChange : fieldChanges) { - if (fieldChange.field == field) { - return fieldChange; - } - } - } - return null; - } - - public void setField(Field field, Object value) { - FieldChange fieldChange = new FieldChange(); - fieldChange.field = field; - fieldChange.value = value; - if (fieldChanges == null) { - fieldChanges = new ArrayList<FieldChange>(); - } - fieldChanges.add(fieldChange); - } - - public String getString(Field field) { - FieldChange fieldChange = getField(field); - if (fieldChange == null) { - return null; - } - return fieldChange.value.toString(); - } - public void addAttachment(Attachment attachment) { if (attachments == null) { - attachments = new ArrayList<Attachment>(); + attachments = new LinkedHashSet<Attachment>(); } attachments.add(attachment); } @@ -210,9 +227,94 @@ return null; } + public boolean hasField(Field field) { + return !StringUtils.isEmpty(getString(field)); + } + + public boolean hasFieldChanges() { + return !ArrayUtils.isEmpty(fieldChanges); + } + + public Object getField(Field field) { + if (fieldChanges != null) { + for (FieldChange fieldChange : fieldChanges) { + if (fieldChange.field == field) { + return fieldChange.value; + } + } + } + return null; + } + + public void setField(Field field, Object value) { + FieldChange fieldChange = new FieldChange(field, value); + if (fieldChanges == null) { + fieldChanges = new LinkedHashSet<FieldChange>(); + } + fieldChanges.add(fieldChange); + } + + public String getString(Field field) { + Object value = getField(field); + if (value == null) { + return null; + } + return value.toString(); + } + + @Override + public int compareTo(Change c) { + return created.compareTo(c.created); + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Change) { + return id.equals(((Change) o).id); + } + return false; + } + @Override public String toString() { - return created.toString() + " by " + author; + StringBuilder sb = new StringBuilder(); + sb.append(TimeUtils.timeAgo(created)); + switch (code) { + case '+': + sb.append(" created by "); + break; + default: + if (hasComment()) { + sb.append(" commented on by "); + } else { + sb.append(" changed by "); + } + } + sb.append(author).append(" - "); + if (hasComment()) { + if (comment.deleted) { + sb.append("(deleted) "); + } + sb.append(comment.text).append(" "); + } + if (hasFieldChanges()) { + switch (code) { + case '+': + break; + default: + for (FieldChange fieldChange : fieldChanges) { + sb.append("\n "); + sb.append(fieldChange); + } + break; + } + } + return sb.toString(); } } @@ -221,6 +323,9 @@ private static final long serialVersionUID = 1L; public String text; + + public String id; + public boolean deleted; Comment(String text) { @@ -237,9 +342,27 @@ private static final long serialVersionUID = 1L; - public Field field; + public final Field field; - public Object value; + public final Object value; + + FieldChange(Field field, Object value) { + this.field = field; + this.value = value; + } + + @Override + public int hashCode() { + return field.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof FieldChange) { + return field.equals(((FieldChange) o).field); + } + return false; + } @Override public String toString() { @@ -251,7 +374,8 @@ private static final long serialVersionUID = 1L; - public String name; + public final String name; + public String id; public long size; public byte[] content; public boolean deleted; @@ -261,25 +385,104 @@ } @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Attachment) { + return name.equalsIgnoreCase(((Attachment) o).name); + } + return false; + } + + @Override public String toString() { return name; } } public static enum Field { - Summary, Description, Reporter, Owner, Type, Status, Priority, Milestone, Labels; + Id, Summary, Description, Reporter, Owner, Type, Status, Priority, Milestone, Component, Labels; } public static enum Type { Defect, Enhancement, Task, Review, Other; + + public static Type fromObject(Object o) { + if (o instanceof Type) { + // cast and return + return (Type) o; + } else if (o instanceof String) { + // find by name + for (Type type : values()) { + String str = o.toString(); + if (type.toString().equalsIgnoreCase(str)) { + return type; + } + } + } else if (o instanceof Number) { + // by ordinal + int id = ((Number) o).intValue(); + if (id >= 0 && id < values().length) { + return values()[id]; + } + } + return null; + } } public static enum Priority { Low, Medium, High, Critical; + + public static Priority fromObject(Object o) { + if (o instanceof Priority) { + // cast and return + return (Priority) o; + } else if (o instanceof String) { + // find by name + for (Priority priority : values()) { + String str = o.toString(); + if (priority.toString().equalsIgnoreCase(str)) { + return priority; + } + } + } else if (o instanceof Number) { + // by ordinal + int id = ((Number) o).intValue(); + if (id >= 0 && id < values().length) { + return values()[id]; + } + } + return null; + } } public static enum Status { New, Accepted, Started, Review, Queued, Testing, Done, Fixed, WontFix, Duplicate, Invalid; + + public static Status fromObject(Object o) { + if (o instanceof Status) { + // cast and return + return (Status) o; + } else if (o instanceof String) { + // find by name + for (Status status : values()) { + String str = o.toString(); + if (status.toString().equalsIgnoreCase(str)) { + return status; + } + } + } else if (o instanceof Number) { + // by ordinal + int id = ((Number) o).intValue(); + if (id >= 0 && id < values().length) { + return values()[id]; + } + } + return null; + } public boolean atLeast(Status status) { return ordinal() >= status.ordinal(); @@ -289,6 +492,10 @@ return ordinal() > status.ordinal(); } + public boolean isClosed() { + return ordinal() >= Done.ordinal(); + } + public Status next() { switch (this) { case New: -- Gitblit v1.9.1