1 package se.citerus.dddsample.domain.model.handling;
2
3 import org.apache.commons.lang.Validate;
4 import org.apache.commons.lang.builder.EqualsBuilder;
5 import org.apache.commons.lang.builder.HashCodeBuilder;
6 import se.citerus.dddsample.domain.model.cargo.Cargo;
7 import se.citerus.dddsample.domain.model.location.Location;
8 import se.citerus.dddsample.domain.model.voyage.Voyage;
9 import se.citerus.dddsample.domain.shared.DomainEvent;
10 import se.citerus.dddsample.domain.shared.DomainObjectUtils;
11 import se.citerus.dddsample.domain.shared.ValueObject;
12
13 import java.util.Date;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 public final class HandlingEvent implements DomainEvent<HandlingEvent> {
32
33 private Type type;
34 private Voyage voyage;
35 private Location location;
36 private Date completionTime;
37 private Date registrationTime;
38 private Cargo cargo;
39
40
41
42
43
44 public enum Type implements ValueObject<Type> {
45 LOAD(true),
46 UNLOAD(true),
47 RECEIVE(false),
48 CLAIM(false),
49 CUSTOMS(false);
50
51 private final boolean voyageRequired;
52
53
54
55
56
57
58 private Type(final boolean voyageRequired) {
59 this.voyageRequired = voyageRequired;
60 }
61
62
63
64
65 public boolean requiresVoyage() {
66 return voyageRequired;
67 }
68
69
70
71
72 public boolean prohibitsVoyage() {
73 return !requiresVoyage();
74 }
75
76 @Override
77 public boolean sameValueAs(Type other) {
78 return other != null && this.equals(other);
79 }
80
81 }
82
83
84
85
86
87
88
89
90
91 public HandlingEvent(final Cargo cargo,
92 final Date completionTime,
93 final Date registrationTime,
94 final Type type,
95 final Location location,
96 final Voyage voyage) {
97 Validate.notNull(cargo, "Cargo is required");
98 Validate.notNull(completionTime, "Completion time is required");
99 Validate.notNull(registrationTime, "Registration time is required");
100 Validate.notNull(type, "Handling event type is required");
101 Validate.notNull(location, "Location is required");
102 Validate.notNull(voyage, "Voyage is required");
103
104 if (type.prohibitsVoyage()) {
105 throw new IllegalArgumentException("Voyage is not allowed with event type " + type);
106 }
107
108 this.voyage = voyage;
109 this.completionTime = (Date) completionTime.clone();
110 this.registrationTime = (Date) registrationTime.clone();
111 this.type = type;
112 this.location = location;
113 this.cargo = cargo;
114 }
115
116
117
118
119
120
121
122
123 public HandlingEvent(final Cargo cargo,
124 final Date completionTime,
125 final Date registrationTime,
126 final Type type,
127 final Location location) {
128 Validate.notNull(cargo, "Cargo is required");
129 Validate.notNull(completionTime, "Completion time is required");
130 Validate.notNull(registrationTime, "Registration time is required");
131 Validate.notNull(type, "Handling event type is required");
132 Validate.notNull(location, "Location is required");
133
134 if (type.requiresVoyage()) {
135 throw new IllegalArgumentException("Voyage is required for event type " + type);
136 }
137
138 this.completionTime = (Date) completionTime.clone();
139 this.registrationTime = (Date) registrationTime.clone();
140 this.type = type;
141 this.location = location;
142 this.cargo = cargo;
143 this.voyage = null;
144 }
145
146 public Type type() {
147 return this.type;
148 }
149
150 public Voyage voyage() {
151 return DomainObjectUtils.nullSafe(this.voyage, Voyage.NONE);
152 }
153
154 public Date completionTime() {
155 return new Date(this.completionTime.getTime());
156 }
157
158 public Date registrationTime() {
159 return new Date(this.registrationTime.getTime());
160 }
161
162 public Location location() {
163 return this.location;
164 }
165
166 public Cargo cargo() {
167 return this.cargo;
168 }
169
170 @Override
171 public boolean equals(final Object o) {
172 if (this == o) return true;
173 if (o == null || getClass() != o.getClass()) return false;
174
175 final HandlingEvent event = (HandlingEvent) o;
176
177 return sameEventAs(event);
178 }
179
180 @Override
181 public boolean sameEventAs(final HandlingEvent other) {
182 return other != null && new EqualsBuilder().
183 append(this.cargo, other.cargo).
184 append(this.voyage, other.voyage).
185 append(this.completionTime, other.completionTime).
186 append(this.location, other.location).
187 append(this.type, other.type).
188 isEquals();
189 }
190
191 @Override
192 public int hashCode() {
193 return new HashCodeBuilder().
194 append(cargo).
195 append(voyage).
196 append(completionTime).
197 append(location).
198 append(type).
199 toHashCode();
200 }
201
202 @Override
203 public String toString() {
204 final StringBuilder builder = new StringBuilder("\n--- Handling event ---\n").
205 append("Cargo: ").append(cargo.trackingId()).append("\n").
206 append("Type: ").append(type).append("\n").
207 append("Location: ").append(location.name()).append("\n").
208 append("Completed on: ").append(completionTime).append("\n").
209 append("Registered on: ").append(registrationTime).append("\n");
210
211 if (voyage != null) {
212 builder.append("Voyage: ").append(voyage.voyageNumber()).append("\n");
213 }
214
215 return builder.toString();
216 }
217
218 HandlingEvent() {
219
220 }
221
222
223
224 private Long id;
225
226 }