/
JoiningState.java
91 lines (73 loc) · 2.99 KB
/
JoiningState.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package org.example.jet.petclinic;
import org.example.jet.petclinic.model.Owner;
import org.example.jet.petclinic.model.Pet;
import org.example.jet.petclinic.model.Visit;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
class JoiningState implements Serializable {
Map<Integer, Owner> ownerIdToOwner = new HashMap<>();
Map<Integer, Owner> petIdToOwner = new HashMap<>();
Map<Integer, Pet> petIdToPet = new HashMap<>();
public Owner join(Object item) {
if (item instanceof Owner) {
Owner owner = (Owner) item;
return ownerIdToOwner.compute(owner.id, (key, currentOwner) -> {
if (currentOwner == null) {
// There is no owner with this id, the incoming item is stored and returned
return owner;
} else {
// There is an existing owner, update the incoming item with already collected data and return it
return owner.update(currentOwner);
}
});
} else if (item instanceof Pet) {
Pet pet = (Pet) item;
Pet currentPet = petIdToPet.compute(pet.id, (key, aPet) -> {
if (aPet == null) {
// There is no pet with this id, the incoming item is stored and returned
return pet;
} else {
// There is an existing pet, update the incoming item with already collected data and return it
return pet.update(aPet);
}
});
Owner petOwner = updatePetForOwner(currentPet);
return ownerIfNameSet(petOwner);
} else if (item instanceof Visit) {
Visit visit = (Visit) item;
Pet pet = petIdToPet.computeIfAbsent(visit.petId, key -> new Pet(visit.petId));
Pet updatedPet = pet.addVisit(visit);
if (updatedPet.ownerId != null) {
return updatePetForOwner(updatedPet);
} else {
return null;
}
} else {
throw new IllegalArgumentException("Unknown type " + item.getClass());
}
}
private Owner updatePetForOwner(Pet pet) {
Owner petOwner = ownerIdToOwner.compute(pet.ownerId, (ownerId, currentOwner) -> {
if (currentOwner == null) {
// There is no Owner yet for this ownerId, create a empty "shell" owner to put pets in
Owner newOwner = new Owner(pet.ownerId, pet);
newOwner.id = pet.ownerId;
return newOwner;
} else {
// Owner exists, add a pet to it and replace
return currentOwner.addPet(pet);
}
});
petIdToOwner.putIfAbsent(pet.id, petOwner);
return petOwner;
}
private Owner ownerIfNameSet(Owner owner) {
if (owner.firstName == null) {
//
return null;
} else {
return owner;
}
}
}