View Javadoc
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  
19  package org.itracker.model;
20  
21  import org.apache.commons.lang.builder.CompareToBuilder;
22  import org.apache.commons.lang.builder.ToStringBuilder;
23  
24  import java.io.Serializable;
25  import java.util.ArrayList;
26  import java.util.Comparator;
27  import java.util.List;
28  
29  /**
30   * A project issue.
31   * <p/>
32   * <p>This class contains the core of the information we're managing. </p>
33   *
34   * @author ready
35   */
36  public class Issue extends AbstractEntity implements Comparable<Entity> {
37  
38      /**
39       *
40       */
41      private static final long serialVersionUID = 1L;
42      public static final Comparator<Issue> STATUS_COMPARATOR =
43              new StatusComparator();
44  
45      public static final Comparator<Issue> PROJECT_AND_STATUS_COMPARATOR =
46              new ProjectAndStatusComparator();
47  
48      public static final Comparator<Issue> OWNER_AND_STATUS_COMPARATOR =
49              new OwnerAndStatusComparator();
50  
51      public static final Comparator<Issue> SEVERITY_COMPARATOR =
52              new SeverityComparator();
53  
54      private String description;
55  
56      private Integer severity;
57  
58      private Integer status;
59  
60      /* PENDING: consider using an int enumeration like severity and status. */
61      private String resolution;
62  
63      private Project project;
64  
65      /**
66       * The User who created this Issue.
67       * <p/>
68       * <p>Issue - User (creator) is a N-1 relationship. </p>
69       */
70      private User creator;
71  
72      /**
73       * The User who owns this Issue.
74       * <p/>
75       * <p>This is the user who is responsible for the resolution of
76       * this Issue. </p>
77       * <p/>
78       * <p>Issue - User (owner) is a N-1 relationship. </p>
79       */
80      private User owner;
81  
82      /**
83       * Project version for which this issue must be fixed.
84       * <p/>
85       * <p>Issue - Version (targetVersion) is a N-1 relationship. </p>
86       */
87      private Version targetVersion;
88  
89      /**
90       * List of project components affected by this Issue.
91       * <p/>
92       * <p>An Issue can be associated with 1 or more Components (Issue - Component
93       * is a M-N relationship). </p>
94       */
95      private List<Component> components = new ArrayList<Component>();
96  
97      /**
98       * List of project versions affected by this Issue.
99       * <p/>
100      * <p>Issue - Version (version) is a M-N relationship. </p>
101      */
102     private List<Version> versions = new ArrayList<Version>();
103 
104     /**
105      * List of custom fields and values.
106      * <p/>
107      * <p>Issue - IssueField is a 1-N relationship. </p>
108      */
109     private List<IssueField> fields = new ArrayList<IssueField>();
110 
111     /**
112      * List of files attached to this Issue.
113      * <p/>
114      * <p>Issue - IssueAttachment is a 1-N relationship. </p>
115      */
116     private List<IssueAttachment> attachments = new ArrayList<IssueAttachment>();
117 
118     /**
119      * List of relations with other Issues.
120      * <p/>
121      * <p>Issue - IssueRelation is a 1-N relationship. </p>
122      */
123     private List<IssueRelation> relations = new ArrayList<IssueRelation>();
124 
125     /* PENDING: do we really need to navigate these relationships from an Issue ? 
126     * Moving these as DAO methods would make an Issue more light-weight.
127     */
128 
129     /**
130      * Issue - Notification is 1-N relationship.
131      * <p/>
132      * <p>Does this association need to be navigatable in this direction
133      * as it was in iTracker 2 ? </p>
134      */
135     private List<Notification> notifications = new ArrayList<Notification>();
136 
137     /**
138      * Issue - IssueActivity is 1-N relationship.
139      * <p/>
140      * <p>Does this association need to be navigatable in this direction
141      * as it was in iTracker 2 ? </p>
142      */
143     private List<IssueActivity> activities = new ArrayList<IssueActivity>();
144 
145     /**
146      * Issue - IssueHistory is 1-N relationship.
147      * <p/>
148      * <p>Does this association need to be navigatable in this direction
149      * as it was in iTracker 2 ? </p>
150      */
151     private List<IssueHistory> history = new ArrayList<IssueHistory>();
152 
153 
154     /**
155      * Default constructor (required by Hibernate).
156      * <p/>
157      * <p>PENDING: should be <code>private</code> so that it can only be used
158      * by Hibernate, to ensure that the fields which form an instance's
159      * identity are always initialized/never <tt>null</tt>. </p>
160      */
161     public Issue() {
162     }
163 
164     public List<IssueActivity> getActivities() {
165         return activities;
166     }
167 
168     public void setActivities(List<IssueActivity> activities) {
169         this.activities = activities;
170     }
171 
172     public List<IssueAttachment> getAttachments() {
173         return attachments;
174     }
175 
176     public void setAttachments(List<IssueAttachment> attachments) {
177         this.attachments = attachments;
178     }
179 
180     public List<Component> getComponents() {
181         return components;
182     }
183 
184     public void setComponents(List<Component> components) {
185         this.components = components;
186     }
187 
188     public User getCreator() {
189         return creator;
190     }
191 
192     public void setCreator(User creator) {
193         this.creator = creator;
194     }
195 
196     public String getDescription() {
197         return description;
198     }
199 
200     public void setDescription(String description) {
201         this.description = description;
202     }
203 
204     public List<IssueField> getFields() {
205         return fields;
206     }
207 
208     public void setFields(List<IssueField> fields) {
209         this.fields = fields;
210     }
211 
212     public List<IssueHistory> getHistory() {
213         return history;
214     }
215 
216     public void setHistory(List<IssueHistory> history) {
217         this.history = history;
218     }
219 
220     public List<Notification> getNotifications() {
221         return notifications;
222     }
223 
224     public void setNotifications(List<Notification> notifications) {
225         this.notifications = notifications;
226     }
227 
228     public User getOwner() {
229         return owner;
230     }
231 
232     public void setOwner(User owner) {
233         this.owner = owner;
234     }
235 
236     public Project getProject() {
237         return project;
238     }
239 
240     public void setProject(Project project) {
241         this.project = project;
242     }
243 
244     public List<IssueRelation> getRelations() {
245         return relations;
246     }
247 
248     public void setRelations(List<IssueRelation> relations) {
249         this.relations = relations;
250     }
251 
252     public String getResolution() {
253         return resolution;
254     }
255 
256     public void setResolution(String resolution) {
257         this.resolution = resolution;
258     }
259 
260     public Integer getSeverity() {
261         return severity;
262     }
263 
264     public void setSeverity(Integer severity) {
265         this.severity = severity;
266     }
267 
268     public Integer getStatus() {
269         return status;
270     }
271 
272     public void setStatus(Integer status) {
273         this.status = status;
274     }
275 
276     public Version getTargetVersion() {
277         return targetVersion;
278     }
279 
280     public void setTargetVersion(Version targetVersion) {
281         this.targetVersion = targetVersion;
282     }
283 
284     public List<Version> getVersions() {
285         return versions;
286     }
287 
288     public void setVersions(List<Version> versions) {
289         this.versions = versions;
290     }
291 
292     @Override
293     public String toString() {
294         return new ToStringBuilder(this).append("id", getId()).append("description", getDescription()).append("owner", getOwner()).append("severity", getSeverity()).append("status", getStatus()).append("targetVersion", getTargetVersion()).toString();
295     }
296 
297 
298     /**
299      * Compares 2 Issues by status and severity.
300      */
301     private static class StatusComparator implements Comparator<Issue>, Serializable {
302         /**
303          *
304          */
305         private static final long serialVersionUID = 1L;
306 
307         public int compare(Issue" href="../../../org/itracker/model/Issue.html#Issue">Issue a, Issue b) {
308             return new CompareToBuilder().append(a.getStatus(), b.getStatus()).append(a.getSeverity(), b.getSeverity()).append(a.getId(), b.getId()).toComparison();
309         }
310 
311     }
312 
313     private static class ProjectAndStatusComparator implements Comparator<Issue>, Serializable {
314         /**
315          *
316          */
317         private static final long serialVersionUID = 1L;
318 
319         public int compare(Issue" href="../../../org/itracker/model/Issue.html#Issue">Issue a, Issue b) {
320             return new CompareToBuilder().append(a.getProject(), b.getProject(), Project.PROJECT_COMPARATOR).append(a.getStatus(), b.getStatus()).append(a.getId(), b.getId()).toComparison();
321         }
322 
323     }
324 
325     private static class OwnerAndStatusComparator implements Comparator<Issue>, Serializable {
326         /**
327          *
328          */
329         private static final long serialVersionUID = 1L;
330 
331         public int compare(Issue" href="../../../org/itracker/model/Issue.html#Issue">Issue a, Issue b) {
332 
333             return new CompareToBuilder().append(a.getOwner(), b.getOwner(), User.NAME_COMPARATOR).append(a.getStatus(), b.getStatus()).append(a.getId(), b.getId()).toComparison();
334 
335         }
336     }
337 
338     private static class SeverityComparator implements Comparator<Issue>, Serializable {
339         /**
340          *
341          */
342         private static final long serialVersionUID = 1L;
343 
344         public int compare(Issue" href="../../../org/itracker/model/Issue.html#Issue">Issue a, Issue b) {
345 
346             return new CompareToBuilder().append(a.getSeverity(), b.getSeverity()).append(a.getStatus(), b.getStatus()).append(a.getId(), b.getId()).toComparison();
347         }
348 
349     }
350 
351 }