summaryrefslogtreecommitdiffstats
path: root/src/com/gitblit/models/IssueModel.java
diff options
context:
space:
mode:
authorJames Moger <james.moger@gitblit.com>2012-01-15 19:07:34 -0500
committerJames Moger <james.moger@gitblit.com>2012-01-15 19:07:34 -0500
commit69a55934079b299740fa4679fbbd9faeb8319726 (patch)
treedecf6a8f296cd08b2ee87c6aace5db9757888b94 /src/com/gitblit/models/IssueModel.java
parentc508386dba5dd84de1f83fef8781b06acf903f15 (diff)
downloadgitblit-69a55934079b299740fa4679fbbd9faeb8319726.tar.gz
gitblit-69a55934079b299740fa4679fbbd9faeb8319726.zip
More functional issues.
Diffstat (limited to 'src/com/gitblit/models/IssueModel.java')
-rw-r--r--src/com/gitblit/models/IssueModel.java305
1 files changed, 256 insertions, 49 deletions
diff --git a/src/com/gitblit/models/IssueModel.java b/src/com/gitblit/models/IssueModel.java
index 3c6d9a0b..19241c29 100644
--- a/src/com/gitblit/models/IssueModel.java
+++ b/src/com/gitblit/models/IssueModel.java
@@ -18,10 +18,13 @@ package com.gitblit.models;
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 @@ import com.gitblit.utils.StringUtils;
*/
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 class IssueModel implements Serializable, Comparable<IssueModel> {
public List<Change> changes;
public IssueModel() {
- created = new Date();
+ created = new Date((System.currentTimeMillis() / 1000) * 1000);
type = Type.Defect;
status = Status.New;
@@ -72,15 +75,16 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
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)) {
@@ -89,10 +93,6 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
return list;
}
- public boolean hasLabel(String label) {
- return getLabels().contains(label);
- }
-
public Attachment getAttachment(String name) {
Attachment attachment = null;
for (Change change : changes) {
@@ -106,16 +106,55 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
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,41 +174,72 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
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 final String author;
- public 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 void addAttachment(Attachment attachment) {
+ if (attachments == null) {
+ attachments = new LinkedHashSet<Attachment>();
+ }
+ attachments.add(attachment);
+ }
+
+ public Attachment getAttachment(String name) {
+ for (Attachment attachment : attachments) {
+ if (attachment.name.equalsIgnoreCase(name)) {
+ return attachment;
+ }
+ }
+ return null;
+ }
+
+ public boolean hasField(Field field) {
+ return !StringUtils.isEmpty(getString(field));
+ }
+
public boolean hasFieldChanges() {
return !ArrayUtils.isEmpty(fieldChanges);
}
- public FieldChange getField(Field field) {
+ public Object getField(Field field) {
if (fieldChanges != null) {
for (FieldChange fieldChange : fieldChanges) {
if (fieldChange.field == field) {
- return fieldChange;
+ return fieldChange.value;
}
}
}
@@ -177,42 +247,74 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
}
public void setField(Field field, Object value) {
- FieldChange fieldChange = new FieldChange();
- fieldChange.field = field;
- fieldChange.value = value;
+ FieldChange fieldChange = new FieldChange(field, value);
if (fieldChanges == null) {
- fieldChanges = new ArrayList<FieldChange>();
+ fieldChanges = new LinkedHashSet<FieldChange>();
}
fieldChanges.add(fieldChange);
}
public String getString(Field field) {
- FieldChange fieldChange = getField(field);
- if (fieldChange == null) {
+ Object value = getField(field);
+ if (value == null) {
return null;
}
- return fieldChange.value.toString();
+ return value.toString();
}
- public void addAttachment(Attachment attachment) {
- if (attachments == null) {
- attachments = new ArrayList<Attachment>();
- }
- attachments.add(attachment);
+ @Override
+ public int compareTo(Change c) {
+ return created.compareTo(c.created);
}
- public Attachment getAttachment(String name) {
- for (Attachment attachment : attachments) {
- if (attachment.name.equalsIgnoreCase(name)) {
- return attachment;
- }
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Change) {
+ return id.equals(((Change) o).id);
}
- return null;
+ 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 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
private static final long serialVersionUID = 1L;
public String text;
+
+ public String id;
+
public boolean deleted;
Comment(String text) {
@@ -237,9 +342,27 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
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 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
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,26 +385,105 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
}
@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 @@ public class IssueModel implements Serializable, Comparable<IssueModel> {
return ordinal() > status.ordinal();
}
+ public boolean isClosed() {
+ return ordinal() >= Done.ordinal();
+ }
+
public Status next() {
switch (this) {
case New: