1
2
3
4 package de.powerstat.validation.entities;
5
6
7 import java.time.OffsetDateTime;
8 import java.util.ArrayList;
9 import java.util.List;
10 import java.util.NoSuchElementException;
11 import java.util.Objects;
12 import java.util.Optional;
13 import java.util.stream.Collectors;
14
15 import org.apache.logging.log4j.LogManager;
16 import org.apache.logging.log4j.Logger;
17
18 import de.powerstat.validation.containers.HistoryOf;
19 import de.powerstat.validation.interfaces.IEntity;
20 import de.powerstat.validation.values.BloodGroup;
21 import de.powerstat.validation.values.Firstname;
22 import de.powerstat.validation.values.Gender;
23 import de.powerstat.validation.values.Lastname;
24 import de.powerstat.validation.values.UUID;
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 public final class Person implements Comparable<Person>, IEntity
63 {
64
65
66
67 private static final Logger LOGGER = LogManager.getLogger(Person.class);
68
69
70
71
72 private final UUID uuid = UUID.of();
73
74
75
76
77 private final HistoryOf<Lastname> lastname = new HistoryOf<>();
78
79
80
81
82 private final HistoryOf<Gender> sex = new HistoryOf<>();
83
84
85
86
87 private final HistoryOf<List<Firstname>> firstnames = new HistoryOf<>();
88
89
90
91
92 private final HistoryOf<Integer> callname = new HistoryOf<>();
93
94
95
96
97 private Optional<OffsetDateTime> birthday = Optional.empty();
98
99
100
101
102 private Optional<OffsetDateTime> deathdate = Optional.empty();
103
104
105
106
107 private Optional<BloodGroup> bloodGroup = Optional.empty();
108
109
110
111
112
113 private Person()
114 {
115 super();
116 }
117
118
119
120
121
122
123
124 public static Person of()
125 {
126 return new Person();
127 }
128
129
130
131
132
133
134
135
136
137 public static Person of(final Lastname lastname, final Gender gender)
138 {
139 final var person = Person.of();
140 person.addLastname(OffsetDateTime.now(), lastname);
141 person.addGender(OffsetDateTime.now(), gender);
142 return person;
143 }
144
145
146
147
148
149
150
151
152
153
154 public static Person of(final Lastname lastname, final Gender gender, final List<Firstname> firstnames)
155 {
156 final var person = Person.of(lastname, gender);
157 person.addFirstnames(OffsetDateTime.now(), firstnames);
158 return person;
159 }
160
161
162
163
164
165
166
167
168
169
170
171 public static Person of(final Lastname lastname, final Gender gender, final List<Firstname> firstnames, final OffsetDateTime birthdate)
172 {
173 final var person = Person.of(lastname, gender, firstnames);
174 person.setBirthday(birthdate);
175 return person;
176 }
177
178
179
180
181
182
183
184 @Override
185 public String stringValue()
186 {
187 final var builder = new StringBuilder(75);
188 builder.append(this.lastname).append(", ").append(this.firstnames);
189 return builder.toString();
190 }
191
192
193
194
195
196
197
198
199 @Override
200 public int hashCode()
201 {
202 return Objects.hash(this.lastname, this.sex, this.firstnames, this.birthday, this.deathdate, this.bloodGroup);
203 }
204
205
206
207
208
209
210
211
212
213 @Override
214 public boolean equals(final Object obj)
215 {
216 if (this == obj)
217 {
218 return true;
219 }
220 if (!(obj instanceof Person))
221 {
222 return false;
223 }
224 final Person other = (Person)obj;
225 boolean result = this.lastname.equals(other.lastname);
226 if (result)
227 {
228 result = this.sex.equals(other.sex);
229 if (result)
230 {
231 result = this.firstnames.equals(other.firstnames);
232 if (result)
233 {
234 result = this.birthday.equals(other.birthday);
235 if (result)
236 {
237 result = this.deathdate.equals(other.deathdate);
238 if (result)
239 {
240 result = this.bloodGroup.equals(other.bloodGroup);
241 }
242 }
243 }
244 }
245 }
246 return result;
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260 @Override
261 public String toString()
262 {
263 final var builder = new StringBuilder(75);
264 builder.append("Person[lastname=").append(this.lastname.getLatestEntry()).append(", gender=").append(this.sex.getLatestEntry());
265 if (!this.firstnames.isEmpty())
266 {
267 builder.append(", firstnames=").append(this.firstnames.getLatestEntry());
268 }
269 if (this.birthday.isPresent())
270 {
271 builder.append(", birthday=").append(this.birthday);
272 }
273 if (this.deathdate.isPresent())
274 {
275 builder.append(", deathdate=").append(this.deathdate);
276 }
277 if (this.bloodGroup.isPresent())
278 {
279 builder.append(", bloodGroup=").append(this.bloodGroup);
280 }
281 builder.append(']');
282 return builder.toString();
283 }
284
285
286
287
288
289
290
291
292 private static String getFirstnames(final HistoryOf<List<Firstname>> firstnames)
293 {
294 try
295 {
296 return firstnames.getLatestEntry().stream().map(Firstname::stringValue).collect(Collectors.joining(" "));
297 }
298 catch (final NoSuchElementException e)
299 {
300
301 return "";
302 }
303 }
304
305
306
307
308
309
310
311
312
313 @SuppressWarnings("PMD.ConfusingTernary")
314 @Override
315 public int compareTo(final Person obj)
316 {
317 Objects.requireNonNull(obj, "obj");
318 int result = (!this.lastname.isEmpty() && !obj.lastname.isEmpty()) ? this.lastname.getLatestEntry().compareTo(obj.lastname.getLatestEntry()) : Boolean.compare(this.lastname.isEmpty(), obj.lastname.isEmpty());
319 if (result == 0)
320 {
321 result = (!this.sex.isEmpty() && !obj.sex.isEmpty()) ? this.sex.getLatestEntry().compareTo(obj.sex.getLatestEntry()) : Boolean.compare(this.sex.isEmpty(), obj.sex.isEmpty());
322 if (result == 0)
323 {
324 final String thisName = Person.getFirstnames(this.firstnames);
325 final String thatName = Person.getFirstnames(obj.firstnames);
326 result = thisName.compareTo(thatName);
327 if (result == 0)
328 {
329 if (this.birthday.isPresent() && obj.birthday.isPresent())
330 {
331 result = this.birthday.get().compareTo(obj.birthday.get());
332 }
333 else if (!this.birthday.isPresent() && !obj.birthday.isPresent())
334 {
335 result = 0;
336 }
337 else
338 {
339 result = this.birthday.isPresent() ? 1 : -1;
340 }
341 if (result == 0)
342 {
343 if (this.deathdate.isPresent() && obj.deathdate.isPresent())
344 {
345 result = this.deathdate.get().compareTo(obj.deathdate.get());
346 }
347 else if (!this.deathdate.isPresent() && !obj.deathdate.isPresent())
348 {
349 result = 0;
350 }
351 else
352 {
353 result = this.deathdate.isPresent() ? 1 : -1;
354 }
355 if (result == 0)
356 {
357 if (this.bloodGroup.isPresent() && obj.bloodGroup.isPresent())
358 {
359 result = this.bloodGroup.get().compareTo(obj.bloodGroup.get());
360 }
361 else if (!this.bloodGroup.isPresent() && !obj.bloodGroup.isPresent())
362 {
363 result = 0;
364 }
365 else
366 {
367 result = this.bloodGroup.isPresent() ? 1 : -1;
368 }
369
370 }
371 }
372 }
373 }
374 }
375 return result;
376 }
377
378
379
380
381
382
383
384 public Lastname getLastnameAtBirth()
385 {
386 return this.lastname.getFirstEntry();
387 }
388
389
390
391
392
393
394
395 public Lastname getLastnameActual()
396 {
397 return this.lastname.getLatestEntry();
398 }
399
400
401
402
403
404
405
406 public Lastname getLastnamePrevious()
407 {
408 return this.lastname.getPreviousEntry();
409 }
410
411
412
413
414
415
416
417
418
419
420
421 public void addLastname(final OffsetDateTime since, final Lastname name)
422 {
423 this.lastname.addEntry(since, name);
424 }
425
426
427
428
429
430
431
432 public Gender getGenderAtBirth()
433 {
434 return this.sex.getFirstEntry();
435 }
436
437
438
439
440
441
442
443 public Gender getGenderActual()
444 {
445 return this.sex.getLatestEntry();
446 }
447
448
449
450
451
452
453
454 public Gender getGenderPrevious()
455 {
456 return this.sex.getPreviousEntry();
457 }
458
459
460
461
462
463
464
465
466
467 public void addGender(final OffsetDateTime since, final Gender gender)
468 {
469 this.sex.addEntry(since, gender);
470 }
471
472
473
474
475
476
477
478 public List<Firstname> getFirstnamesAtBirth()
479 {
480 return new ArrayList<>(this.firstnames.getFirstEntry());
481 }
482
483
484
485
486
487
488
489 public List<Firstname> getFirstnamesActual()
490 {
491 return new ArrayList<>(this.firstnames.getLatestEntry());
492 }
493
494
495
496
497
498
499
500 public List<Firstname> getFirstnamesPrevious()
501 {
502 return new ArrayList<>(this.firstnames.getPreviousEntry());
503 }
504
505
506
507
508
509
510
511
512
513
514
515 public void addFirstnames(final OffsetDateTime since, final List<Firstname> names)
516 {
517 this.firstnames.addEntry(since, new ArrayList<>(names));
518 }
519
520
521
522
523
524
525
526 public void setBirthday(final OffsetDateTime date)
527 {
528 this.birthday = Optional.ofNullable(date);
529 }
530
531
532
533
534
535
536
537 @SuppressWarnings("PMD.NullAssignment")
538 public Optional<OffsetDateTime> getBirthday()
539 {
540 return Optional.ofNullable(this.birthday.isPresent() ? this.birthday.get() : null);
541 }
542
543
544
545
546
547
548
549
550 public void setDeathdate(final OffsetDateTime date)
551 {
552 if (this.birthday.isPresent() && this.birthday.get().isAfter(date))
553 {
554 throw new IllegalArgumentException("birthday > deathdate");
555 }
556 this.deathdate = Optional.ofNullable(date);
557 }
558
559
560
561
562
563
564
565 @SuppressWarnings("PMD.NullAssignment")
566 public Optional<OffsetDateTime> getDeathdate()
567 {
568 return Optional.ofNullable(this.deathdate.isPresent() ? this.deathdate.get() : null);
569 }
570
571
572
573
574
575
576
577 public void setBloodGroup(final BloodGroup bloodGroup)
578 {
579 this.bloodGroup = Optional.ofNullable(bloodGroup);
580 }
581
582
583
584
585
586
587
588 @SuppressWarnings("PMD.NullAssignment")
589 public Optional<BloodGroup> getBloodGroup()
590 {
591 return Optional.ofNullable(this.bloodGroup.isPresent() ? this.bloodGroup.get() : null);
592 }
593
594 }