View Javadoc

1   /**
2    * Copyright (c) 2009-2010, Elias Gomes. All rights reserved.
3    * 
4    * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
5    * following conditions are met:
6    * 
7    * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
8    * disclaimer.
9    * 
10   * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided with the distribution.
12   * 
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
14   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
16   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
17   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
18   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
19   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20   */
21  package net.sourceforge.mystique.domain.entity;
22  
23  import java.util.Date;
24  import java.util.LinkedList;
25  import java.util.List;
26  
27  import javax.persistence.CascadeType;
28  import javax.persistence.Column;
29  import javax.persistence.Entity;
30  import javax.persistence.EnumType;
31  import javax.persistence.Enumerated;
32  import javax.persistence.GeneratedValue;
33  import javax.persistence.GenerationType;
34  import javax.persistence.Id;
35  import javax.persistence.JoinColumn;
36  import javax.persistence.JoinTable;
37  import javax.persistence.ManyToMany;
38  import javax.persistence.ManyToOne;
39  import javax.persistence.NamedQueries;
40  import javax.persistence.NamedQuery;
41  import javax.persistence.OneToMany;
42  import javax.persistence.SequenceGenerator;
43  import javax.persistence.Table;
44  import javax.persistence.Temporal;
45  import javax.persistence.TemporalType;
46  import javax.persistence.Transient;
47  
48  import net.sourceforge.mystique.domain.valueobject.Priority;
49  import net.sourceforge.mystique.domain.valueobject.Resolution;
50  import net.sourceforge.mystique.domain.valueobject.Severity;
51  import net.sourceforge.mystique.domain.valueobject.Status;
52  import net.sourceforge.mystique.domain.valueobject.Type;
53  
54  /**
55   * @author Elias Gomes [eliasgomes@users.sourceforge.net]
56   */
57  @Entity
58  @Table(name = "TB_TICKET")
59  @SequenceGenerator(name = "ticketIdSeq", sequenceName = "TICKET_ID_SEQ", initialValue = 1, allocationSize = 1)
60  @NamedQueries(@NamedQuery(name = "Ticket.findAll", query = "SELECT t FROM Ticket t ORDER BY t.reported"))
61  /*
62   * TODO: Any of the QA users can set the ticket as verified or all of them have to agree? Maybe both. If just one QA
63   * user, any or all does not apply, so first add the QA users, then select the verification mode.
64   * 
65   * TODO: Ticket needs observers
66   * 
67   * TODO: Update "modified" after each method invocation
68   */
69  public class Ticket {
70  
71  	@Id
72  	@GeneratedValue(generator = "ticketIdSeq", strategy = GenerationType.SEQUENCE)
73  	@Column(name = "ID")
74  	private Long id;
75  
76  	@Column(name = "SUMMARY", nullable = false)
77  	private String summary;
78  
79  	@Column(name = "DESCRIPTION", nullable = false)
80  	private String description;
81  
82  	@ManyToOne
83  	@JoinColumn(name = "REPORTER_USER_ID", nullable = false)
84  	private User reporter;
85  
86  	@Temporal(TemporalType.TIMESTAMP)
87  	@Column(name = "REPORTED", nullable = false)
88  	private Date reported;
89  
90  	@Temporal(TemporalType.TIMESTAMP)
91  	@Column(name = "MODIFIED", nullable = false)
92  	private Date modified;
93  
94  	@ManyToOne
95  	@JoinColumn(name = "PROJECT_ID", nullable = false)
96  	private Project project;
97  
98  	@ManyToOne
99  	@JoinColumn(name = "COMPONENT_ID")
100 	private Component component;
101 
102 	@ManyToOne
103 	@JoinColumn(name = "MILESTONE_ID")
104 	private Milestone milestone;
105 
106 	@ManyToOne
107 	@JoinColumn(name = "VERSION_ID")
108 	private Version version;
109 
110 	@Enumerated(EnumType.STRING)
111 	@Column(name = "SEVERITY", nullable = false)
112 	private Severity severity;
113 
114 	@Enumerated(EnumType.STRING)
115 	@Column(name = "PRIORITY", nullable = false)
116 	private Priority priority;
117 
118 	@ManyToOne
119 	@JoinColumn(name = "DUPLICATE_OF_TICKET_ID")
120 	private Ticket duplicateOf;
121 
122 	@OneToMany(mappedBy = "duplicateOf")
123 	private List<Ticket> duplicates;
124 
125 	@Enumerated(EnumType.STRING)
126 	@Column(name = "TYPE", nullable = false)
127 	private Type type;
128 
129 	@Enumerated(EnumType.STRING)
130 	@Column(name = "STATUS", nullable = false)
131 	private Status status;
132 
133 	@Enumerated(EnumType.STRING)
134 	@Column(name = "RESOLUTION")
135 	private Resolution resolution;
136 
137 	@ManyToMany
138 	@JoinTable(name = "TB_TICKET_ASSIGNED_TO_USER", joinColumns = @JoinColumn(name = "TICKET_ID"), inverseJoinColumns = @JoinColumn(name = "USER_ID"))
139 	private List<User> usersAssignedTo;
140 
141 	@ManyToMany(mappedBy = "ticketsToApprove")
142 	private List<User> qualityAssuranceUsers;
143 
144 	@ManyToMany
145 	@JoinTable(name = "TB_TICKET_DEPENDS_ON_TICKET", joinColumns = @JoinColumn(name = "TICKET_ID"), inverseJoinColumns = @JoinColumn(name = "TICKET_DEPENDENCY_ID"))
146 	private List<Ticket> itDependsOn;
147 
148 	@ManyToMany(mappedBy = "itDependsOn")
149 	private List<Ticket> dependsOnIt;
150 
151 	@OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL)
152 	private List<Attachment> attachments;
153 
154 	@OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL)
155 	private List<Comment> comments;
156 
157 	@OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL)
158 	private List<Confirmation> confirmations;
159 
160 	public Ticket() {
161 		setReported(new Date());
162 		setModified(new Date());
163 		setDuplicates(new LinkedList<Ticket>());
164 		setUsersAssignedTo(new LinkedList<User>());
165 		setQualityAssuranceUsers(new LinkedList<User>());
166 		setAttachments(new LinkedList<Attachment>());
167 		setItDependsOn(new LinkedList<Ticket>());
168 		setDependsOnIt(new LinkedList<Ticket>());
169 		setComments(new LinkedList<Comment>());
170 		setConfirmations(new LinkedList<Confirmation>());
171 	}
172 
173 	@Transient
174 	public boolean isNew() {
175 		return (id == null);
176 	}
177 
178 	public void addAttachment(Attachment attachment) {
179 		attachment.setTicket(this);
180 		getAttachments().add(attachment);
181 	}
182 
183 	public void addComment(Comment comment) {
184 		comment.setTicket(this);
185 		getComments().add(comment);
186 	}
187 
188 	public void addConfirmation(Confirmation confirmation) {
189 		confirmation.setTicket(this);
190 		for (Confirmation c : getConfirmations()) {
191 			if (c.getResponsible().equals(confirmation.getResponsible())) {
192 				return;
193 			}
194 		}
195 		getConfirmations().add(confirmation);
196 	}
197 
198 	public Long getId() {
199 		return id;
200 	}
201 
202 	public void setId(Long id) {
203 		this.id = id;
204 	}
205 
206 	public String getSummary() {
207 		return summary;
208 	}
209 
210 	public void setSummary(String summary) {
211 		if (summary != null) {
212 			this.summary = summary.trim();
213 		}
214 		this.summary = summary;
215 	}
216 
217 	public String getDescription() {
218 		return description;
219 	}
220 
221 	public void setDescription(String description) {
222 		if (description != null) {
223 			this.description = description.trim();
224 		}
225 		this.description = description;
226 	}
227 
228 	public User getReporter() {
229 		return reporter;
230 	}
231 
232 	public void setReporter(User reporter) {
233 		this.reporter = reporter;
234 	}
235 
236 	public Date getReported() {
237 		return reported;
238 	}
239 
240 	public void setReported(Date reported) {
241 		this.reported = reported;
242 	}
243 
244 	public Date getModified() {
245 		return modified;
246 	}
247 
248 	public void setModified(Date modified) {
249 		this.modified = modified;
250 	}
251 
252 	public Project getProject() {
253 		return project;
254 	}
255 
256 	public void setProject(Project project) {
257 		this.project = project;
258 	}
259 
260 	public Component getComponent() {
261 		return component;
262 	}
263 
264 	public void setComponent(Component component) {
265 		this.component = component;
266 	}
267 
268 	public Milestone getMilestone() {
269 		return milestone;
270 	}
271 
272 	public void setMilestone(Milestone milestone) {
273 		this.milestone = milestone;
274 	}
275 
276 	public Version getVersion() {
277 		return version;
278 	}
279 
280 	public void setVersion(Version version) {
281 		this.version = version;
282 	}
283 
284 	public Severity getSeverity() {
285 		return severity;
286 	}
287 
288 	public void setSeverity(Severity severity) {
289 		this.severity = severity;
290 	}
291 
292 	public Priority getPriority() {
293 		return priority;
294 	}
295 
296 	public void setPriority(Priority priority) {
297 		this.priority = priority;
298 	}
299 
300 	public Ticket getDuplicateOf() {
301 		return duplicateOf;
302 	}
303 
304 	public void setDuplicateOf(Ticket duplicateOf) {
305 		this.duplicateOf = duplicateOf;
306 	}
307 
308 	public List<Ticket> getDuplicates() {
309 		return duplicates;
310 	}
311 
312 	public void setDuplicates(List<Ticket> duplicates) {
313 		this.duplicates = duplicates;
314 	}
315 
316 	public Type getType() {
317 		return type;
318 	}
319 
320 	public void setType(Type type) {
321 		this.type = type;
322 	}
323 
324 	public Status getStatus() {
325 		return status;
326 	}
327 
328 	public void setStatus(Status status) {
329 		this.status = status;
330 	}
331 
332 	public Resolution getResolution() {
333 		return resolution;
334 	}
335 
336 	public void setResolution(Resolution resolution) {
337 		this.resolution = resolution;
338 	}
339 
340 	public List<User> getUsersAssignedTo() {
341 		return usersAssignedTo;
342 	}
343 
344 	public void setUsersAssignedTo(List<User> usersAssignedTo) {
345 		this.usersAssignedTo = usersAssignedTo;
346 	}
347 
348 	public List<User> getQualityAssuranceUsers() {
349 		return qualityAssuranceUsers;
350 	}
351 
352 	public void setQualityAssuranceUsers(List<User> qualityAssuranceUsers) {
353 		this.qualityAssuranceUsers = qualityAssuranceUsers;
354 	}
355 
356 	public List<Ticket> getItDependsOn() {
357 		return itDependsOn;
358 	}
359 
360 	public void setItDependsOn(List<Ticket> itDependsOn) {
361 		this.itDependsOn = itDependsOn;
362 	}
363 
364 	public List<Ticket> getDependsOnIt() {
365 		return dependsOnIt;
366 	}
367 
368 	public void setDependsOnIt(List<Ticket> dependsOnIt) {
369 		this.dependsOnIt = dependsOnIt;
370 	}
371 
372 	public List<Attachment> getAttachments() {
373 		return attachments;
374 	}
375 
376 	public void setAttachments(List<Attachment> attachments) {
377 		this.attachments = attachments;
378 	}
379 
380 	public List<Comment> getComments() {
381 		return comments;
382 	}
383 
384 	public void setComments(List<Comment> comments) {
385 		this.comments = comments;
386 	}
387 
388 	public List<Confirmation> getConfirmations() {
389 		return confirmations;
390 	}
391 
392 	public void setConfirmations(List<Confirmation> confirmations) {
393 		this.confirmations = confirmations;
394 	}
395 
396 	@Override
397 	public int hashCode() {
398 		final int prime = 31;
399 		int result = 1;
400 		result = prime * result + ((id == null) ? 0 : id.hashCode());
401 		return result;
402 	}
403 
404 	@Override
405 	public boolean equals(Object obj) {
406 		if (this == obj)
407 			return true;
408 		if (obj == null)
409 			return false;
410 		if (getClass() != obj.getClass())
411 			return false;
412 		Ticket other = (Ticket) obj;
413 		if (id == null) {
414 			if (other.id != null)
415 				return false;
416 		} else if (!id.equals(other.id))
417 			return false;
418 		return true;
419 	}
420 
421 }