com.publicobject.issuesbrowser.Issue Maven / Gradle / Ivy
Show all versions of glazedlists_java15 Show documentation
/* Glazed Lists (c) 2003-2006 */
/* http://publicobject.com/glazedlists/ publicobject.com,*/
/* O'Dell Engineering Ltd.*/
package com.publicobject.issuesbrowser;
import ca.odell.glazedlists.jfreechart.DefaultValueSegment;
import ca.odell.glazedlists.jfreechart.ValueSegment;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
/**
* An issue models a work effort either due to an existing problem or a desired
* enhancement.
*
* @author James Lemieux
* @author Jesse Wilson
*/
public class Issue implements Comparable {
public static final DateFormat TABLE_DATE_FORMAT = DateFormat.getDateInstance(DateFormat.MEDIUM);
public static final DateFormat DETAILS_DATE_FORMAT = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
// the project that this issue is attached to
private Project owner;
// mandatory issue fields
private String id;
private String statusCode;
private String status;
private Priority priority;
private String resolution;
private String component;
private String version;
private String repPlatform;
private String assignedTo;
private Date deltaTimestamp;
private String subcomponent;
private String reporter;
private String targetMilestone;
private String issueType;
private Date creationTimestamp;
private String qaContact;
private String statusWhiteboard;
private String fileLocation;
private String votes;
private String operatingSystem;
private String shortDescription;
private PeerIssue isDuplicate;
// optional fields
private List keywords = new ArrayList();
private List blocks = new ArrayList();
private List cc = new ArrayList();
// issue rich fields
private List descriptions = new ArrayList();
private List attachments = new ArrayList();
private List activities = new ArrayList();
private List> stateChanges = new ArrayList>();
private List duplicates = new ArrayList();
private List dependsOn = new ArrayList();
private List allUsers;
/**
* Creates a new empty issue.
*/
public Issue(Project owner) {
this.owner = owner;
}
/**
* Creates a new issue that uses the specified issue as a template.
*/
public Issue(Project owner, Issue template) {
this.owner = owner;
id = template.id;
status = template.status;
priority = template.priority;
resolution = template.resolution;
component = template.component;
version = template.version;
repPlatform = template.repPlatform;
assignedTo = template.assignedTo;
deltaTimestamp = template.deltaTimestamp;
subcomponent = template.subcomponent;
reporter = template.reporter;
targetMilestone = template.targetMilestone;
issueType = template.issueType;
creationTimestamp = template.creationTimestamp;
qaContact = template.qaContact;
statusWhiteboard = template.statusWhiteboard;
votes = template.votes;
operatingSystem = template.operatingSystem;
shortDescription = template.shortDescription;
keywords.addAll(template.keywords);
blocks.addAll(template.blocks);
dependsOn.addAll(template.dependsOn);
cc.addAll(template.cc);
descriptions.addAll(template.descriptions);
attachments.addAll(template.attachments);
activities.addAll(template.activities);
}
/**
* This convenience method processes a fully loaded Issue and produces a
* List of RangedValues which describe the duration of each Status within
* the lifetime of the given issue
. For example, an Issue
* might have a series of state changes such as:
*
* {NEW: Issue creation Timestamp -> Feb}, {STARTED: Feb -> Apr}, {CLOSED: Apr -> Mar}, {RESOLVED: Mar -> lastDate}
*
*
and each part of that progression will be a {@link ValueSegment}
* containing a start and end Date and a status.
*
* @param issue the Issue to compute the state changes for
* @return a List of {@link ValueSegment} objecs describing the duration
* of each Status within the lifetime of the issue
*/
public static List> computeStateChanges(Issue issue, Date lastDate) {
// this stores the sequence of state changes in chronological order, like a timeline
final List> timeline = new ArrayList>();
final IssueTrackingSystem issueTracker = issue.getProject().getOwner();
String state = issueTracker.getSupportedStati()[0].getName();
// the end Date of the previous ValueSegment
Date last = issue.getCreationTimestamp();
// Iterate the issues in chronological (natural) order
for (Iterator i = issue.getActivities().iterator(); i.hasNext();) {
Activity activity = i.next();
// if the Activity represents a change in status
if ("issue_status" == activity.getField()) {
// create an entry in the timeline
Date when = activity.getWhen();
timeline.add(new DefaultValueSegment(last, when, state));
last = when;
state = activity.getNewValue();
}
}
// create one last entry in the time timeline that ends at the given lastDate
timeline.add(new DefaultValueSegment(last, lastDate, state));
return timeline;
}
/**
* Gets all users related to this issue.
*/
public List getAllUsers() {
// init the users list if necessary
if(allUsers == null) {
allUsers = new ArrayList();
if(assignedTo != null) allUsers.add(assignedTo);
if(reporter != null) allUsers.add(reporter);
if(qaContact != null) allUsers.add(qaContact);
for(Iterator d = descriptions.iterator(); d.hasNext(); ) {
allUsers.add(d.next().getWho());
}
}
return allUsers;
}
/**
* ID of this issue (unique key).
*/
public String getId() { return id; }
public void setId(String id) { this.id = id; }
/**
* Get the web address of this issue for use with a browser like IE or Firefox.
*/
public URL getURL() {
try {
return new URL(getProject().getIssueDetailUri(this));
} catch(MalformedURLException e) {
throw new RuntimeException(e);
}
}
/**
* HTTP-like status code of this issue, such as "200".
*/
public String getStatusCode() { return statusCode; }
public void setStatusCode(String statusCode) { this.statusCode = statusCode; }
/**
* Current status of this issue.
*/
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
/**
* Priority (severity) assigned to issue.
*/
public Priority getPriority() { return priority; }
public void setPriority(Priority priority) { this.priority = priority; }
/**
* The issue's resolution, if any
*/
public String getResolution() { return resolution; }
public void setResolution(String resolution) { this.resolution = resolution; }
/**
* Product against which issue is reported.
*/
public String getComponent() { return component; }
public void setComponent(String component) { this.component = component; }
/**
* Version associated with component.
*/
public String getVersion() { return version; }
public void setVersion(String version) { this.version = version; }
/**
* Platform that the issue was reported against.
*/
public String getRepPlatform() { return repPlatform; }
public void setRepPlatform(String repPlatform) { this.repPlatform = repPlatform; }
/**
* Email of person issue currently assigned to.
*/
public String getAssignedTo() { return assignedTo; }
public void setAssignedTo(String assignedTo) { this.assignedTo = assignedTo; }
/**
* Last modified timestamp ('yyyyMMddhhmmss').
*/
public Date getDeltaTimestamp() { return deltaTimestamp; }
public void setDeltaTimestamp(Date deltaTimestamp) { this.deltaTimestamp = deltaTimestamp; }
/**
* Component of component issue reported against.
*/
public String getSubcomponent() { return subcomponent; }
public void setSubcomponent(String subcomponent) { this.subcomponent = subcomponent; }
/**
* Email of initial issue reporter.
*/
public String getReporter() { return reporter; }
public void setReporter(String reporter) { this.reporter = reporter; }
/**
* Milestone for this issue's resolution.
*/
public String getTargetMilestone() { return targetMilestone; }
public void setTargetMilestone(String targetMilestone) { this.targetMilestone = targetMilestone; }
/**
* Nature of issue. This refers to whether the issue is a defect, task,
* enhancement, etc.
*/
public String getIssueType() { return issueType; }
public void setIssueType(String issueType) { this.issueType = issueType; }
/**
* Issue creation timestamp ('yyyy-mm-dd hh:mm:ss').
*/
public Date getCreationTimestamp() { return creationTimestamp; }
public void setCreationTimestamp(Date creationTimestamp) { this.creationTimestamp = creationTimestamp; }
/**
* Email of the QA contact for this issue.
*/
public String getQAContact() { return qaContact; }
public void setQAContact(String qaContact) { this.qaContact = qaContact; }
/**
* Free text 'whiteboard' for issue comments.
*/
public String getStatusWhiteboard() { return statusWhiteboard; }
public void setStatusWhiteboard(String statusWhiteboard) { this.statusWhiteboard = statusWhiteboard; }
/**
* current votes for issue.
*/
public String getVotes() { return votes; }
public void setVotes(String votes) { this.votes = votes; }
/**
* URL related to issue
*/
public String getFileLocation() { return fileLocation; }
public void setFileLocation(String fileLocation) { this.fileLocation = fileLocation; }
/**
* Operating system issue reported against.
*/
public String getOperatingSystem() { return operatingSystem; }
public void setOperatingSystem(String operatingSystem) { this.operatingSystem = operatingSystem; }
/**
* Short description of issue.
*/
public String getShortDescription() { return shortDescription; }
public void setShortDescription(String shortDescription) { this.shortDescription = shortDescription; }
/**
* List of keywords for this issue.
*/
public List getKeywords() { return keywords; }
/**
* List of email addresses of interested parties.
*/
public List getCC() { return cc; }
/**
* Data from the longdescs table for this issue id. Essentially
* the log of additional comments.
*/
public List getDescriptions() { return descriptions; }
/**
* Get the attachments to this issue.
*/
public List getAttachments() { return attachments; }
/**
* Get the activities upon this issue.
*/
public List getActivities() { return activities; }
/**
* Get the List of RangedValues describing the succession of state changes
* this Issue has experienced.
*/
public List> getStateChanges() { return stateChanges; }
/**
* Other issues which were closed as a duplicate of this issue.
*/
public List getDuplicates() { return duplicates; }
/**
* List of local issue IDs that depend on this one.
*/
public List getDependsOn() { return dependsOn; }
/**
* List of local issue IDs blocked by this one.
*/
public List getBlocks() { return blocks; }
/**
* The issue which this issue was closed as a duplicate of.
*/
public PeerIssue getDuplicate() { return isDuplicate; }
public void setDuplicate(PeerIssue isDuplicate) { this.isDuplicate = isDuplicate; }
/**
* @return the owning project
*/
public Project getProject() {
return owner;
}
/**
* Write this issue for debugging.
*/
@Override
public String toString() {
return "Issue " + id + ": " + getPriority().getRating();
}
/**
* Compares two issues by ID.
*/
public int compareTo(Object other) {
if (other == null) return -1;
Issue otherIssue = (Issue) other;
return id.compareTo(otherIssue.id);
}
}