1 package org.unitedfront2.domain.communication;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.Date;
7 import java.util.List;
8 import java.util.Locale;
9
10 import org.apache.commons.lang.RandomStringUtils;
11 import org.apache.commons.lang.builder.EqualsBuilder;
12 import org.apache.commons.lang.builder.HashCodeBuilder;
13 import org.apache.commons.lang.builder.ToStringBuilder;
14 import org.apache.commons.logging.LogFactory;
15 import org.unitedfront2.dao.DateDao;
16 import org.unitedfront2.dao.MailDao;
17 import org.unitedfront2.domain.AccountTable;
18 import org.unitedfront2.domain.Domain;
19 import org.unitedfront2.domain.Identifiable;
20 import org.unitedfront2.domain.SimpleUser;
21 import org.unitedfront2.domain.SimpleUserTable;
22 import org.unitedfront2.domain.Storable;
23 import org.unitedfront2.domain.User;
24
25
26
27
28
29
30
31
32 public class Mail implements Identifiable<Mail>, Storable, Serializable,
33 Domain {
34
35
36 public static final int GENERATED_CODE_LENGTH = 32;
37
38
39 private static final long serialVersionUID = -8522418960016784969L;
40
41
42 private static final int MAX_CHALLENGE_COUNT = 10;
43
44
45 private Integer id;
46
47
48 private String code;
49
50
51 private Integer toId;
52
53
54 private Integer fromId;
55
56
57 private Date sentDate;
58
59
60 private String subject;
61
62
63 private String body;
64
65
66 private boolean read;
67
68
69 private transient SimpleUser to;
70
71
72 private transient SimpleUser from;
73
74
75 private transient String toMailAddr;
76
77
78 private transient Mail next;
79
80
81 private transient DateDao dateDao;
82
83
84 private transient MailDao mailDao;
85
86
87 private transient SimpleUserTable simpleUserTable;
88
89
90 private transient AccountTable accountTable;
91
92 public Mail() {
93 super();
94 }
95
96 public Mail(Integer toId, Integer fromId, String subject, String body) {
97 super();
98 this.toId = toId;
99 this.fromId = fromId;
100 this.subject = subject;
101 this.body = body;
102 }
103
104 public Mail(Integer id, String code, Integer toId, Integer fromId,
105 String subject, String body, Date sentDate, boolean read) {
106 this(toId, fromId, subject, body);
107 this.id = id;
108 this.code = code;
109 this.sentDate = (Date) sentDate.clone();
110 this.read = read;
111 }
112
113 @Override
114 public String toString() {
115 ToStringBuilder tsb = new ToStringBuilder(this)
116 .append("id", id)
117 .append("code", code)
118 .append("toId", toId)
119 .append("fromId", fromId)
120 .append("sentDate", sentDate)
121 .append("subject", subject)
122 .append("body", body)
123 .append("read", read)
124 .append("next", next);
125 return tsb.toString();
126 }
127
128 @Override
129 public boolean equals(final Object other) {
130 if (!(other instanceof Mail)) {
131 return false;
132 }
133 Mail castOther = (Mail) other;
134 return new EqualsBuilder()
135 .append(id, castOther.id)
136 .append(code, castOther.code)
137 .append(toId, castOther.toId)
138 .append(fromId, castOther.fromId)
139 .append(sentDate, castOther.sentDate)
140 .append(subject, castOther.subject)
141 .append(body, castOther.body)
142 .append(read, castOther.read).isEquals();
143 }
144
145 @Override
146 public int hashCode() {
147 return new HashCodeBuilder()
148 .append(id)
149 .append(code)
150 .append(toId)
151 .append(fromId)
152 .append(sentDate)
153 .append(subject)
154 .append(body)
155 .append(read).toHashCode();
156 }
157
158 @Override
159 public boolean identify(Mail other) {
160 if (id == null || other.getId() == null) {
161 return false;
162 }
163 return id.equals(other.getId());
164 }
165
166
167
168
169
170
171 @Override
172 public void store() {
173 send();
174 }
175
176
177
178
179
180
181
182
183
184 public Mail send() {
185 if (toId == null) {
186 String message = "The toId must not be null. Mail[" + this + "]";
187 LogFactory.getLog(getClass()).error(message);
188 throw new IllegalStateException(message);
189 }
190 this.code = generateCode();
191 this.sentDate = dateDao.getCurrentDate();
192 mailDao.register(this);
193 return this;
194 }
195
196 private String generateCode() {
197 for (int i = 0; i < MAX_CHALLENGE_COUNT; i++) {
198 String code = RandomStringUtils.randomAlphanumeric(
199 GENERATED_CODE_LENGTH).toLowerCase(Locale.ENGLISH);
200 if (mailDao.findByCode(code) == null) {
201 return code;
202 }
203 }
204 String message = "Failed to generate code.";
205 LogFactory.getLog(getClass()).error(message);
206 throw new IllegalStateException(message);
207 }
208
209
210
211
212
213
214
215
216
217
218
219 public void send(int parentId) {
220 if (toId == null) {
221 String message = "The To must not be null. Mail[" + this + "]";
222 LogFactory.getLog(getClass()).error(message);
223 throw new IllegalStateException(message);
224 }
225 if (fromId == null) {
226 String message = "The from must not be null. Mail[" + this + "]";
227 LogFactory.getLog(getClass()).error(message);
228 throw new IllegalStateException(message);
229 }
230 this.code = generateCode();
231 this.sentDate = dateDao.getCurrentDate();
232 mailDao.register(this, parentId);
233 }
234
235
236
237
238
239
240
241 public void read(int userId) {
242 if (userId == toId.intValue()) {
243 read = true;
244 mailDao.updateRead(id, true);
245 }
246 }
247
248
249
250
251
252
253
254
255 public void readAll(int userId) {
256 read(userId);
257 if (next != null) {
258 next.readAll(userId);
259 }
260 }
261
262
263
264
265
266
267
268 public void unread(int userId) {
269 if (userId == toId.intValue()) {
270 read = false;
271 mailDao.updateRead(id, false);
272 }
273 }
274
275
276
277
278
279
280
281
282 public void unreadAll(int userId) {
283 unread(userId);
284 if (next != null) {
285 next.unreadAll(userId);
286 }
287 }
288
289
290
291
292
293
294
295 public boolean hasUnread(int toId) {
296 if (toId == this.toId && !isRead()) {
297 return true;
298 } else {
299 return next != null && next.hasUnread(toId);
300 }
301 }
302
303
304
305
306
307
308 public int getCount() {
309 int count = 1;
310 if (next != null) {
311 count += next.getCount();
312 }
313 return count;
314 }
315
316
317
318
319
320
321 public List<Mail> asList() {
322 List<Mail> list = new ArrayList<Mail>(getCount());
323 addToList(list, this);
324 return list;
325 }
326
327 private void addToList(List<Mail> list, Mail mail) {
328 list.add(mail);
329 if (mail.next != null) {
330 addToList(list, mail.next);
331 }
332 }
333
334
335
336
337
338
339 public List<Mail> asListDesc() {
340 List<Mail> list = asList();
341 Collections.reverse(list);
342 return list;
343 }
344
345
346
347
348
349
350 public Mail getTail() {
351 Mail mail = this;
352 while (mail.getNext() != null) {
353 mail = mail.getNext();
354 }
355 return mail;
356 }
357
358
359
360
361
362
363
364
365
366
367 public SimpleUser other(User user) {
368 if (user.identify(getTo())) {
369 return getFrom();
370 } else if (user.identify(getFrom())) {
371 return getTo();
372 } else {
373 throw new IllegalArgumentException("The user '" + user
374 + "' is neither TO or FROM.");
375 }
376 }
377
378 public Integer getId() {
379 return id;
380 }
381
382 public void setId(Integer id) {
383 this.id = id;
384 }
385
386 public String getCode() {
387 return code;
388 }
389
390 public void setCode(String code) {
391 this.code = code;
392 }
393
394 public Integer getToId() {
395 return toId;
396 }
397
398 public void setToId(Integer toId) {
399 this.toId = toId;
400 }
401
402 public Integer getFromId() {
403 return fromId;
404 }
405
406 public void setFromId(Integer fromId) {
407 this.fromId = fromId;
408 }
409
410 public Date getSentDate() {
411 if (sentDate == null) {
412 return null;
413 } else {
414 return (Date) sentDate.clone();
415 }
416 }
417
418 public void setSentDate(Date sentDate) {
419 if (sentDate == null) {
420 this.sentDate = null;
421 } else {
422 this.sentDate = (Date) sentDate.clone();
423 }
424 }
425
426 public String getSubject() {
427 return subject;
428 }
429
430 public void setSubject(String subject) {
431 this.subject = subject;
432 }
433
434 public String getBody() {
435 return body;
436 }
437
438 public void setBody(String body) {
439 this.body = body;
440 }
441
442 public boolean isRead() {
443 return read;
444 }
445
446 public void setRead(boolean read) {
447 this.read = read;
448 }
449
450 public SimpleUser getTo() {
451 if (to == null && this.toId != null && simpleUserTable != null) {
452 this.to = simpleUserTable.find(this.toId);
453 }
454 return to;
455 }
456
457 public void setTo(SimpleUser to) {
458 this.to = to;
459 if (to != null) {
460 this.toId = to.getId();
461 }
462 }
463
464 public SimpleUser getFrom() {
465 if (from == null && this.fromId != null && simpleUserTable != null) {
466 this.from = simpleUserTable.find(this.fromId);
467 }
468 return from;
469 }
470
471 public void setFrom(SimpleUser from) {
472 this.from = from;
473 if (from != null) {
474 this.fromId = from.getId();
475 }
476 }
477
478 public String getToName() {
479 if (to == null) {
480 return null;
481 } else {
482 return to.getName();
483 }
484 }
485
486 public void setToName(String toName) {
487 if (to != null) {
488 to.setName(toName);
489 }
490 }
491
492 public String getToMailAddr() {
493 if (toMailAddr == null && accountTable != null && getTo() != null
494 && getTo().getId() != null) {
495 this.toMailAddr = accountTable.find(getTo().getId()).getMailAddr();
496 }
497 return toMailAddr;
498 }
499
500 public void setToMailAddr(String toMailAddr) {
501 this.toMailAddr = toMailAddr;
502 }
503
504 public Mail getNext() {
505 return next;
506 }
507
508 public void setNext(Mail next) {
509 this.next = next;
510 }
511
512 public void setDateDao(DateDao dateDao) {
513 this.dateDao = dateDao;
514 }
515
516 public void setMailDao(MailDao mailDao) {
517 this.mailDao = mailDao;
518 }
519
520 public void setSimpleUserTable(SimpleUserTable simpleUserTable) {
521 this.simpleUserTable = simpleUserTable;
522 }
523
524 public void setAccountTable(AccountTable accountTable) {
525 this.accountTable = accountTable;
526 }
527 }