Issue.java

  1. /*
  2.  * This software was designed and created by Jason Carroll.
  3.  * Copyright (c) 2002, 2003, 2004 Jason Carroll.
  4.  * The author can be reached at jcarroll@cowsultants.com
  5.  * ITracker website: http://www.cowsultants.com
  6.  * ITracker forums: http://www.cowsultants.com/phpBB/index.php
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it only under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  */

  18. package org.itracker.model;

  19. import org.apache.commons.lang.builder.CompareToBuilder;
  20. import org.apache.commons.lang.builder.ToStringBuilder;

  21. import java.io.Serializable;
  22. import java.util.ArrayList;
  23. import java.util.Comparator;
  24. import java.util.List;

  25. /**
  26.  * A project issue.
  27.  * <p/>
  28.  * <p>This class contains the core of the information we're managing. </p>
  29.  *
  30.  * @author ready
  31.  */
  32. public class Issue extends AbstractEntity implements Comparable<Entity> {

  33.     /**
  34.      *
  35.      */
  36.     private static final long serialVersionUID = 1L;
  37.     public static final Comparator<Issue> STATUS_COMPARATOR =
  38.             new StatusComparator();

  39.     public static final Comparator<Issue> PROJECT_AND_STATUS_COMPARATOR =
  40.             new ProjectAndStatusComparator();

  41.     public static final Comparator<Issue> OWNER_AND_STATUS_COMPARATOR =
  42.             new OwnerAndStatusComparator();

  43.     public static final Comparator<Issue> SEVERITY_COMPARATOR =
  44.             new SeverityComparator();

  45.     private String description;

  46.     private Integer severity;

  47.     private Integer status;

  48.     /* PENDING: consider using an int enumeration like severity and status. */
  49.     private String resolution;

  50.     private Project project;

  51.     /**
  52.      * The User who created this Issue.
  53.      * <p/>
  54.      * <p>Issue - User (creator) is a N-1 relationship. </p>
  55.      */
  56.     private User creator;

  57.     /**
  58.      * The User who owns this Issue.
  59.      * <p/>
  60.      * <p>This is the user who is responsible for the resolution of
  61.      * this Issue. </p>
  62.      * <p/>
  63.      * <p>Issue - User (owner) is a N-1 relationship. </p>
  64.      */
  65.     private User owner;

  66.     /**
  67.      * Project version for which this issue must be fixed.
  68.      * <p/>
  69.      * <p>Issue - Version (targetVersion) is a N-1 relationship. </p>
  70.      */
  71.     private Version targetVersion;

  72.     /**
  73.      * List of project components affected by this Issue.
  74.      * <p/>
  75.      * <p>An Issue can be associated with 1 or more Components (Issue - Component
  76.      * is a M-N relationship). </p>
  77.      */
  78.     private List<Component> components = new ArrayList<Component>();

  79.     /**
  80.      * List of project versions affected by this Issue.
  81.      * <p/>
  82.      * <p>Issue - Version (version) is a M-N relationship. </p>
  83.      */
  84.     private List<Version> versions = new ArrayList<Version>();

  85.     /**
  86.      * List of custom fields and values.
  87.      * <p/>
  88.      * <p>Issue - IssueField is a 1-N relationship. </p>
  89.      */
  90.     private List<IssueField> fields = new ArrayList<IssueField>();

  91.     /**
  92.      * List of files attached to this Issue.
  93.      * <p/>
  94.      * <p>Issue - IssueAttachment is a 1-N relationship. </p>
  95.      */
  96.     private List<IssueAttachment> attachments = new ArrayList<IssueAttachment>();

  97.     /**
  98.      * List of relations with other Issues.
  99.      * <p/>
  100.      * <p>Issue - IssueRelation is a 1-N relationship. </p>
  101.      */
  102.     private List<IssueRelation> relations = new ArrayList<IssueRelation>();

  103.     /* PENDING: do we really need to navigate these relationships from an Issue ?
  104.     * Moving these as DAO methods would make an Issue more light-weight.
  105.     */

  106.     /**
  107.      * Issue - Notification is 1-N relationship.
  108.      * <p/>
  109.      * <p>Does this association need to be navigatable in this direction
  110.      * as it was in iTracker 2 ? </p>
  111.      */
  112.     private List<Notification> notifications = new ArrayList<Notification>();

  113.     /**
  114.      * Issue - IssueActivity is 1-N relationship.
  115.      * <p/>
  116.      * <p>Does this association need to be navigatable in this direction
  117.      * as it was in iTracker 2 ? </p>
  118.      */
  119.     private List<IssueActivity> activities = new ArrayList<IssueActivity>();

  120.     /**
  121.      * Issue - IssueHistory is 1-N relationship.
  122.      * <p/>
  123.      * <p>Does this association need to be navigatable in this direction
  124.      * as it was in iTracker 2 ? </p>
  125.      */
  126.     private List<IssueHistory> history = new ArrayList<IssueHistory>();


  127.     /**
  128.      * Default constructor (required by Hibernate).
  129.      * <p/>
  130.      * <p>PENDING: should be <code>private</code> so that it can only be used
  131.      * by Hibernate, to ensure that the fields which form an instance's
  132.      * identity are always initialized/never <tt>null</tt>. </p>
  133.      */
  134.     public Issue() {
  135.     }

  136.     public List<IssueActivity> getActivities() {
  137.         return activities;
  138.     }

  139.     public void setActivities(List<IssueActivity> activities) {
  140.         this.activities = activities;
  141.     }

  142.     public List<IssueAttachment> getAttachments() {
  143.         return attachments;
  144.     }

  145.     public void setAttachments(List<IssueAttachment> attachments) {
  146.         this.attachments = attachments;
  147.     }

  148.     public List<Component> getComponents() {
  149.         return components;
  150.     }

  151.     public void setComponents(List<Component> components) {
  152.         this.components = components;
  153.     }

  154.     public User getCreator() {
  155.         return creator;
  156.     }

  157.     public void setCreator(User creator) {
  158.         this.creator = creator;
  159.     }

  160.     public String getDescription() {
  161.         return description;
  162.     }

  163.     public void setDescription(String description) {
  164.         this.description = description;
  165.     }

  166.     public List<IssueField> getFields() {
  167.         return fields;
  168.     }

  169.     public void setFields(List<IssueField> fields) {
  170.         this.fields = fields;
  171.     }

  172.     public List<IssueHistory> getHistory() {
  173.         return history;
  174.     }

  175.     public void setHistory(List<IssueHistory> history) {
  176.         this.history = history;
  177.     }

  178.     public List<Notification> getNotifications() {
  179.         return notifications;
  180.     }

  181.     public void setNotifications(List<Notification> notifications) {
  182.         this.notifications = notifications;
  183.     }

  184.     public User getOwner() {
  185.         return owner;
  186.     }

  187.     public void setOwner(User owner) {
  188.         this.owner = owner;
  189.     }

  190.     public Project getProject() {
  191.         return project;
  192.     }

  193.     public void setProject(Project project) {
  194.         this.project = project;
  195.     }

  196.     public List<IssueRelation> getRelations() {
  197.         return relations;
  198.     }

  199.     public void setRelations(List<IssueRelation> relations) {
  200.         this.relations = relations;
  201.     }

  202.     public String getResolution() {
  203.         return resolution;
  204.     }

  205.     public void setResolution(String resolution) {
  206.         this.resolution = resolution;
  207.     }

  208.     public Integer getSeverity() {
  209.         return severity;
  210.     }

  211.     public void setSeverity(Integer severity) {
  212.         this.severity = severity;
  213.     }

  214.     public Integer getStatus() {
  215.         return status;
  216.     }

  217.     public void setStatus(Integer status) {
  218.         this.status = status;
  219.     }

  220.     public Version getTargetVersion() {
  221.         return targetVersion;
  222.     }

  223.     public void setTargetVersion(Version targetVersion) {
  224.         this.targetVersion = targetVersion;
  225.     }

  226.     public List<Version> getVersions() {
  227.         return versions;
  228.     }

  229.     public void setVersions(List<Version> versions) {
  230.         this.versions = versions;
  231.     }

  232.     @Override
  233.     public String toString() {
  234.         return new ToStringBuilder(this).append("id", getId()).append("description", getDescription()).append("owner", getOwner()).append("severity", getSeverity()).append("status", getStatus()).append("targetVersion", getTargetVersion()).toString();
  235.     }


  236.     /**
  237.      * Compares 2 Issues by status and severity.
  238.      */
  239.     private static class StatusComparator implements Comparator<Issue>, Serializable {
  240.         /**
  241.          *
  242.          */
  243.         private static final long serialVersionUID = 1L;

  244.         public int compare(Issue a, Issue b) {
  245.             return new CompareToBuilder().append(a.getStatus(), b.getStatus()).append(a.getSeverity(), b.getSeverity()).append(a.getId(), b.getId()).toComparison();
  246.         }

  247.     }

  248.     private static class ProjectAndStatusComparator implements Comparator<Issue>, Serializable {
  249.         /**
  250.          *
  251.          */
  252.         private static final long serialVersionUID = 1L;

  253.         public int compare(Issue a, Issue b) {
  254.             return new CompareToBuilder().append(a.getProject(), b.getProject(), Project.PROJECT_COMPARATOR).append(a.getStatus(), b.getStatus()).append(a.getId(), b.getId()).toComparison();
  255.         }

  256.     }

  257.     private static class OwnerAndStatusComparator implements Comparator<Issue>, Serializable {
  258.         /**
  259.          *
  260.          */
  261.         private static final long serialVersionUID = 1L;

  262.         public int compare(Issue a, Issue b) {

  263.             return new CompareToBuilder().append(a.getOwner(), b.getOwner(), User.NAME_COMPARATOR).append(a.getStatus(), b.getStatus()).append(a.getId(), b.getId()).toComparison();

  264.         }
  265.     }

  266.     private static class SeverityComparator implements Comparator<Issue>, Serializable {
  267.         /**
  268.          *
  269.          */
  270.         private static final long serialVersionUID = 1L;

  271.         public int compare(Issue a, Issue b) {

  272.             return new CompareToBuilder().append(a.getSeverity(), b.getSeverity()).append(a.getStatus(), b.getStatus()).append(a.getId(), b.getId()).toComparison();
  273.         }

  274.     }

  275. }