浏览代码

Implemented RouteSpecification.isSatisfiedBy()

peter_backlund 17 年前
父节点
当前提交
f6083400b6

+ 50
- 2
dddsample/src/main/java/se/citerus/dddsample/domain/model/cargo/Itinerary.java 查看文件

@@ -3,9 +3,11 @@ package se.citerus.dddsample.domain.model.cargo;
3 3
 import org.apache.commons.lang.Validate;
4 4
 import se.citerus.dddsample.domain.model.ValueObject;
5 5
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
6
+import se.citerus.dddsample.domain.model.location.Location;
6 7
 
7 8
 import java.util.ArrayList;
8 9
 import java.util.Collections;
10
+import java.util.Date;
9 11
 import java.util.List;
10 12
 
11 13
 /**
@@ -17,6 +19,7 @@ public class Itinerary implements ValueObject<Itinerary> {
17 19
   private List<Leg> legs = Collections.emptyList();
18 20
 
19 21
   static final Itinerary EMPTY_ITINERARY = new Itinerary();
22
+  private static final Date END_OF_DAYS = new Date(Long.MAX_VALUE);
20 23
 
21 24
   /**
22 25
    * Constructor.
@@ -76,7 +79,7 @@ public class Itinerary implements ValueObject<Itinerary> {
76 79
 
77 80
     if (event.type() == HandlingEvent.Type.CLAIM) {
78 81
       //Check that the last leg's destination is from the event's location
79
-      final Leg leg = legs.get(legs.size() - 1);
82
+      final Leg leg = lastLeg();
80 83
       return (leg.unloadLocation().equals(event.location()));
81 84
     }
82 85
 
@@ -85,6 +88,52 @@ public class Itinerary implements ValueObject<Itinerary> {
85 88
   }
86 89
 
87 90
   /**
91
+   * @return The initial departure location.
92
+   */
93
+  public Location initialDepartureLocation() {
94
+     if (legs.isEmpty()) {
95
+       return Location.UNKNOWN;
96
+     } else {
97
+       return legs.get(0).loadLocation();
98
+     }
99
+  }
100
+
101
+  /**
102
+   * @return The final arrival location.
103
+   */
104
+  public Location finalArrivalLocation() {
105
+    if (legs.isEmpty()) {
106
+      return Location.UNKNOWN;
107
+    } else {
108
+      return lastLeg().unloadLocation();
109
+    }
110
+  }
111
+
112
+  /**
113
+   * @return Date when cargo arrives at final destination.
114
+   */
115
+  public Date finalArrivalDate() {
116
+    final Leg lastLeg = lastLeg();
117
+
118
+    if (lastLeg == null) {
119
+      return END_OF_DAYS;
120
+    } else {
121
+      return lastLeg.unloadTime();
122
+    }
123
+  }
124
+
125
+  /**
126
+   * @return The last leg on the itinerary.
127
+   */
128
+  public Leg lastLeg() {
129
+    if (legs.isEmpty()) {
130
+      return null;
131
+    } else {
132
+      return legs.get(legs.size() - 1);
133
+    }
134
+  }
135
+
136
+  /**
88 137
    * @param other itinerary to compare
89 138
    * @return <code>true</code> if the legs in this and the other itinerary are all equal.
90 139
    */
@@ -123,5 +172,4 @@ public class Itinerary implements ValueObject<Itinerary> {
123 172
 
124 173
   // Auto-generated surrogate key
125 174
   private Long id;
126
-
127 175
 }

+ 23
- 12
dddsample/src/main/java/se/citerus/dddsample/domain/model/cargo/RouteSpecification.java 查看文件

@@ -10,7 +10,8 @@ import se.citerus.dddsample.domain.shared.AbstractSpecification;
10 10
 import java.util.Date;
11 11
 
12 12
 /**
13
- * Route specification.
13
+ * Route specification. Describes where a cargo orign and destination is,
14
+ * and the arrival deadline.
14 15
  * 
15 16
  */
16 17
 public class RouteSpecification extends AbstractSpecification<Itinerary> implements ValueObject<RouteSpecification> {
@@ -20,41 +21,51 @@ public class RouteSpecification extends AbstractSpecification<Itinerary> impleme
20 21
   private Date arrivalDeadline;
21 22
 
22 23
   /**
23
-   * Factory for creatig a route specification for a cargo, from cargo
24
-   * origin to cargo destination. Use for initial routing.
25
-   *
26 24
    * @param origin origin location
27 25
    * @param destination destination location
28 26
    * @param arrivalDeadline arrival deadline
29 27
    */
30
-  public RouteSpecification(Location origin, Location destination, Date arrivalDeadline) {
31
-    Validate.noNullElements(new Object[] {origin, destination, arrivalDeadline});
32
-    
28
+  public RouteSpecification(final Location origin, final Location destination, final Date arrivalDeadline) {
29
+    Validate.notNull(origin, "Origin is required");
30
+    Validate.notNull(destination, "Destination is required");
31
+    Validate.notNull(arrivalDeadline, "Arrival deadline is required");
32
+
33 33
     this.origin = origin;
34 34
     this.destination = destination;
35 35
     this.arrivalDeadline = arrivalDeadline;
36 36
   }
37 37
 
38
+  /**
39
+   * @return Specified origin location.
40
+   */
38 41
   public Location origin() {
39 42
     return origin;
40 43
   }
41 44
 
45
+  /**
46
+   * @return Specfied destination location.
47
+   */
42 48
   public Location destination() {
43 49
     return destination;
44 50
   }
45 51
 
52
+  /**
53
+   * @return Arrival deadline.
54
+   */
46 55
   public Date arrivalDeadline() {
47 56
     return arrivalDeadline;
48 57
   }
49 58
 
50 59
   @Override
51
-  public boolean isSatisfiedBy(Itinerary itinerary) {
52
-    // TODO implement
53
-    return true;
60
+  public boolean isSatisfiedBy(final Itinerary itinerary) {
61
+    return itinerary != null &&
62
+           origin().sameIdentityAs(itinerary.initialDepartureLocation()) &&
63
+           destination().sameIdentityAs(itinerary.finalArrivalLocation()) &&
64
+           arrivalDeadline().after(itinerary.finalArrivalDate());
54 65
   }
55 66
 
56 67
   @Override
57
-  public boolean sameValueAs(RouteSpecification other) {
68
+  public boolean sameValueAs(final RouteSpecification other) {
58 69
     return other != null && new EqualsBuilder().
59 70
       append(this.origin, other.origin).
60 71
       append(this.destination, other.destination).
@@ -68,7 +79,7 @@ public class RouteSpecification extends AbstractSpecification<Itinerary> impleme
68 79
   }
69 80
 
70 81
   @Override
71
-  public boolean equals(Object o) {
82
+  public boolean equals(final Object o) {
72 83
     if (this == o) return true;
73 84
     if (o == null || getClass() != o.getClass()) return false;
74 85
 

+ 51
- 12
dddsample/src/test/java/se/citerus/dddsample/domain/model/cargo/RouteSpecificationTest.java 查看文件

@@ -1,29 +1,68 @@
1 1
 package se.citerus.dddsample.domain.model.cargo;
2 2
 
3 3
 import junit.framework.TestCase;
4
-import static se.citerus.dddsample.domain.model.location.SampleLocations.CHICAGO;
5
-import static se.citerus.dddsample.domain.model.location.SampleLocations.HONGKONG;
4
+import static se.citerus.dddsample.DateTestUtil.toDate;
5
+import se.citerus.dddsample.domain.model.carrier.Voyage;
6
+import se.citerus.dddsample.domain.model.carrier.VoyageNumber;
7
+import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
6 8
 
7
-import java.util.Date;
9
+import java.util.Arrays;
8 10
 
9 11
 public class RouteSpecificationTest extends TestCase {
10 12
 
11
-  public void testIsSatisfiedBySuccess() {
12
-    RouteSpecification routeSpecification = new RouteSpecification(HONGKONG, CHICAGO, new Date());
13
-    Itinerary itinerary = new Itinerary();
13
+  final Voyage hongKongTokyoNewYork = new Voyage.Builder(
14
+    new VoyageNumber("V001"), HONGKONG).
15
+    addMovement(TOKYO, toDate("2009-02-01"), toDate("2009-02-05")).
16
+    addMovement(NEWYORK, toDate("2009-02-06"), toDate("2009-02-10")).
17
+    addMovement(HONGKONG, toDate("2009-02-11"), toDate("2009-02-14")).
18
+    build();
19
+
20
+  final Voyage dallasNewYorkChicago = new Voyage.Builder(
21
+    new VoyageNumber("V002"), DALLAS).
22
+    addMovement(NEWYORK, toDate("2009-02-06"), toDate("2009-02-07")).
23
+    addMovement(CHICAGO, toDate("2009-02-12"), toDate("2009-02-20")).
24
+    build();
25
+
26
+  // TODO:
27
+  // it shouldn't be possible to create Legs that have load/unload locations
28
+  // and/or dates that don't match the voyage's carrier movements.
29
+  final Itinerary itinerary = new Itinerary(Arrays.asList(
30
+      new Leg(hongKongTokyoNewYork, HONGKONG, NEWYORK,
31
+              toDate("2009-02-01"), toDate("2009-02-10")),
32
+      new Leg(dallasNewYorkChicago, NEWYORK, CHICAGO,
33
+              toDate("2009-02-12"), toDate("2009-02-20")))
34
+  );
35
+
36
+  public void testIsSatisfiedBy_Success() {
37
+    RouteSpecification routeSpecification = new RouteSpecification(
38
+      HONGKONG, CHICAGO, toDate("2009-03-01")
39
+    );
40
+
14 41
     assertTrue(routeSpecification.isSatisfiedBy(itinerary));
15 42
   }
16 43
 
17
-  public void testIsSatisfiedByInvalidDate() {
18
-    // TODO
44
+  public void testIsSatisfiedBy_WrongOrigin() {
45
+    RouteSpecification routeSpecification = new RouteSpecification(
46
+      HANGZOU, CHICAGO, toDate("2009-03-01")
47
+    );
48
+
49
+    assertFalse(routeSpecification.isSatisfiedBy(itinerary));
19 50
   }
20 51
 
21
-  public void testIsSatisfiedByInvalidOrigin() {
22
-    // TODO
52
+  public void testIsSatisfiedBy_WrongDestination() {
53
+    RouteSpecification routeSpecification = new RouteSpecification(
54
+      HONGKONG, DALLAS, toDate("2009-03-01")
55
+    );
56
+
57
+    assertFalse(routeSpecification.isSatisfiedBy(itinerary));
23 58
   }
24 59
 
25
-  public void testIsSatisfiedByInvalidDestination() {
26
-    // TODO
60
+  public void testIsSatisfiedBy_MissedDeadline() {
61
+    RouteSpecification routeSpecification = new RouteSpecification(
62
+      HONGKONG, CHICAGO, toDate("2009-02-15")
63
+    );
64
+
65
+    assertFalse(routeSpecification.isSatisfiedBy(itinerary));
27 66
   }
28 67
 
29 68
 }