|
|
@@ -36,7 +36,7 @@ public final class Cargo implements Entity<Cargo> {
|
|
36
|
36
|
private Location origin;
|
|
37
|
37
|
private Location destination;
|
|
38
|
38
|
private Itinerary itinerary;
|
|
39
|
|
- private DeliveryHistory deliveryHistory = DeliveryHistory.EMPTY_DELIVERY_HISTORY;
|
|
|
39
|
+ private DeliveryHistory deliveryHistory;
|
|
40
|
40
|
|
|
41
|
41
|
/**
|
|
42
|
42
|
* @param trackingId tracking id
|
|
|
@@ -44,7 +44,9 @@ public final class Cargo implements Entity<Cargo> {
|
|
44
|
44
|
* @param destination destination location
|
|
45
|
45
|
*/
|
|
46
|
46
|
public Cargo(final TrackingId trackingId, final Location origin, final Location destination) {
|
|
47
|
|
- Validate.noNullElements(new Object[] {trackingId, origin, destination});
|
|
|
47
|
+ Validate.notNull(trackingId);
|
|
|
48
|
+ Validate.notNull(origin);
|
|
|
49
|
+ Validate.notNull(destination);
|
|
48
|
50
|
|
|
49
|
51
|
this.trackingId = trackingId;
|
|
50
|
52
|
this.origin = origin;
|
|
|
@@ -77,35 +79,31 @@ public final class Cargo implements Entity<Cargo> {
|
|
77
|
79
|
}
|
|
78
|
80
|
|
|
79
|
81
|
/**
|
|
80
|
|
- * @return Final destination.
|
|
|
82
|
+ * @return Destination of the cargo.
|
|
81
|
83
|
*/
|
|
82
|
84
|
public Location destination() {
|
|
83
|
85
|
return this.destination;
|
|
84
|
86
|
}
|
|
85
|
87
|
|
|
86
|
88
|
/**
|
|
87
|
|
- * @return Delivery history.
|
|
|
89
|
+ * @return The delivery history. Never null.
|
|
88
|
90
|
*/
|
|
89
|
91
|
public DeliveryHistory deliveryHistory() {
|
|
90
|
|
- return this.deliveryHistory;
|
|
|
92
|
+ return nullSafe(this.deliveryHistory, DeliveryHistory.EMPTY_DELIVERY_HISTORY);
|
|
91
|
93
|
}
|
|
92
|
94
|
|
|
93
|
95
|
/**
|
|
94
|
|
- * @return The itinerary.
|
|
|
96
|
+ * @return The itinerary. Never null.
|
|
95
|
97
|
*/
|
|
96
|
98
|
public Itinerary itinerary() {
|
|
97
|
|
- if (this.itinerary == null) {
|
|
98
|
|
- return Itinerary.EMPTY_ITINERARY;
|
|
99
|
|
- } else {
|
|
100
|
|
- return this.itinerary;
|
|
101
|
|
- }
|
|
|
99
|
+ return nullSafe(this.itinerary, Itinerary.EMPTY_ITINERARY);
|
|
102
|
100
|
}
|
|
103
|
101
|
|
|
104
|
102
|
/**
|
|
105
|
103
|
* @return Last known location of the cargo, or Location.UNKNOWN if the delivery history is empty.
|
|
106
|
104
|
*/
|
|
107
|
105
|
public Location lastKnownLocation() {
|
|
108
|
|
- final HandlingEvent lastEvent = deliveryHistory.lastEvent();
|
|
|
106
|
+ final HandlingEvent lastEvent = deliveryHistory().lastEvent();
|
|
109
|
107
|
if (lastEvent != null) {
|
|
110
|
108
|
return lastEvent.location();
|
|
111
|
109
|
} else {
|
|
|
@@ -128,11 +126,11 @@ public final class Cargo implements Entity<Cargo> {
|
|
128
|
126
|
public void attachItinerary(final Itinerary itinerary) {
|
|
129
|
127
|
Validate.notNull(itinerary);
|
|
130
|
128
|
|
|
131
|
|
- // Decouple the old itinerary from this cargo
|
|
|
129
|
+ // Decouple the old itinerary from this cargo
|
|
132
|
130
|
itinerary().setCargo(null);
|
|
133
|
131
|
// Couple this cargo and the new itinerary
|
|
134
|
132
|
this.itinerary = itinerary;
|
|
135
|
|
- itinerary().setCargo(this);
|
|
|
133
|
+ this.itinerary.setCargo(this);
|
|
136
|
134
|
}
|
|
137
|
135
|
|
|
138
|
136
|
/**
|
|
|
@@ -146,7 +144,7 @@ public final class Cargo implements Entity<Cargo> {
|
|
146
|
144
|
/**
|
|
147
|
145
|
* @param deliveryHistory Cargo delivery history
|
|
148
|
146
|
*/
|
|
149
|
|
- public void setDeliveryHistory(final DeliveryHistory deliveryHistory) {
|
|
|
147
|
+ void setDeliveryHistory(final DeliveryHistory deliveryHistory) {
|
|
150
|
148
|
Validate.notNull(deliveryHistory);
|
|
151
|
149
|
this.deliveryHistory = deliveryHistory;
|
|
152
|
150
|
}
|
|
|
@@ -163,23 +161,23 @@ public final class Cargo implements Entity<Cargo> {
|
|
163
|
161
|
* @return <code>true</code> if the cargo has been misdirected,
|
|
164
|
162
|
*/
|
|
165
|
163
|
public boolean isMisdirected() {
|
|
166
|
|
- final HandlingEvent lastEvent = deliveryHistory.lastEvent();
|
|
167
|
|
- if (itinerary == null || lastEvent == null) {
|
|
|
164
|
+ final HandlingEvent lastEvent = deliveryHistory().lastEvent();
|
|
|
165
|
+ if (lastEvent == null) {
|
|
168
|
166
|
return false;
|
|
169
|
167
|
} else {
|
|
170
|
|
- return !itinerary.isExpected(lastEvent);
|
|
|
168
|
+ return !itinerary().isExpected(lastEvent);
|
|
171
|
169
|
}
|
|
172
|
170
|
}
|
|
173
|
171
|
|
|
174
|
172
|
/**
|
|
175
|
|
- * Does not take into account the possibility of the cargo havin been
|
|
|
173
|
+ * Does not take into account the possibility of the cargo having been
|
|
176
|
174
|
* (errouneously) loaded onto another carrier after it has been unloaded
|
|
177
|
175
|
* at the final destination.
|
|
178
|
176
|
*
|
|
179
|
177
|
* @return True if the cargo has been unloaded at the final destination.
|
|
180
|
178
|
*/
|
|
181
|
179
|
public boolean isUnloadedAtDestination() {
|
|
182
|
|
- for (HandlingEvent event : deliveryHistory.eventsOrderedByCompletionTime()) {
|
|
|
180
|
+ for (HandlingEvent event : deliveryHistory().eventsOrderedByCompletionTime()) {
|
|
183
|
181
|
if (HandlingEvent.Type.UNLOAD.equals(event.type())
|
|
184
|
182
|
&& destination.equals(event.location())) {
|
|
185
|
183
|
return true;
|
|
|
@@ -214,6 +212,11 @@ public final class Cargo implements Entity<Cargo> {
|
|
214
|
212
|
return trackingId.hashCode();
|
|
215
|
213
|
}
|
|
216
|
214
|
|
|
|
215
|
+ // Utility for Null Object Pattern - should be moved out of this class
|
|
|
216
|
+ private <T> T nullSafe(T actual, T safe) {
|
|
|
217
|
+ return actual == null ? safe : actual;
|
|
|
218
|
+ }
|
|
|
219
|
+
|
|
217
|
220
|
Cargo() {
|
|
218
|
221
|
// Needed by Hibernate
|
|
219
|
222
|
}
|