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 java.io.Serializable;
22  import java.util.ArrayList;
23  import java.util.Comparator;
24  import java.util.List;
25  
26  import org.apache.commons.lang.builder.CompareToBuilder;
27  import org.apache.commons.lang.builder.ToStringBuilder;
28  
29  /**
30   * A project issue. 
31   * 
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       * 
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       * 
75       * <p>This is the user who is responsible for the resolution of 
76       * this Issue. </p>
77       * 
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       * 
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       * 
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       * 
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      * 
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      * 
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      * 
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      * 
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      * 
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      * 
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      * 
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(int 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 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 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 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 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 }