Просмотр исходного кода

Removed DeliveryHistory, part 1. Need to do some more clean up, specially with the InMem repositories

jorgen_falk 18 лет назад
Родитель
Сommit
abf2f02137

+ 47
- 8
dddsample/src/main/java/se/citerus/dddsample/domain/Cargo.java Просмотреть файл

@@ -1,5 +1,11 @@
1 1
 package se.citerus.dddsample.domain;
2 2
 
3
+import java.util.ArrayList;
4
+import java.util.Collections;
5
+import java.util.HashSet;
6
+import java.util.List;
7
+import java.util.Set;
8
+
3 9
 import org.apache.commons.lang.builder.EqualsBuilder;
4 10
 import org.apache.commons.lang.builder.HashCodeBuilder;
5 11
 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
@@ -8,6 +14,7 @@ import org.apache.commons.lang.builder.ToStringStyle;
8 14
 import javax.persistence.EmbeddedId;
9 15
 import javax.persistence.Entity;
10 16
 import javax.persistence.ManyToOne;
17
+import javax.persistence.OneToMany;
11 18
 
12 19
 
13 20
 /**
@@ -25,25 +32,56 @@ public class Cargo {
25 32
   
26 33
   @ManyToOne
27 34
   private Location finalDestination;
35
+  
36
+  @OneToMany
37
+  private final Set<HandlingEvent> events = new HashSet<HandlingEvent>();
28 38
 
29
-  private DeliveryHistory history;
30 39
 
31 40
   public Cargo(TrackingId trackingId, Location origin, Location finalDestination) {
32 41
     this.trackingId = trackingId;
33 42
     this.origin = origin;
34 43
     this.finalDestination = finalDestination;
35
-
36
-    this.history = new DeliveryHistory();
37 44
   }
38 45
 
39
-  public DeliveryHistory deliveryHistory() {
40
-    return history;
41
-  }
46
+//  
47
+//  public DeliveryHistory deliveryHistory() {
48
+//    return history;
49
+//  }
42 50
 
43 51
   public void handle(HandlingEvent event) {
44
-    history.addEvent(event);
52
+    events.add(event);
53
+  }
54
+
55
+  
56
+  /**
57
+   * @return An <b>unmodifiable</b> list of handling events, ordered by the time the events occured.
58
+   */
59
+  public List<HandlingEvent> eventsOrderedByTime() {
60
+    List<HandlingEvent> eventList = new ArrayList<HandlingEvent>(events);
61
+    Collections.sort(eventList, HandlingEvent.BY_TIMESTAMP_COMPARATOR);
62
+    return Collections.unmodifiableList(eventList);
45 63
   }
46 64
 
65
+  /**
66
+   * 
67
+   * @return The last handled event
68
+   */
69
+  public HandlingEvent lastEvent() {
70
+    if (events.isEmpty()) {
71
+      return null;
72
+    } else {
73
+      List<HandlingEvent> orderedEvents = eventsOrderedByTime();
74
+      return orderedEvents.get(orderedEvents.size() - 1);
75
+    }
76
+  }
77
+  
78
+  /**
79
+   * Checks if the Cargo's last event was reported at the same Location as the final destination. 
80
+   * 
81
+   * Note that this doesn't nessecary mean that the Cargo has been delivered. Possibly there are more handling to be done before the Cargo can be claimed at the final destination
82
+   * 
83
+   * @return true if Cargos is at final destination otherwise false.
84
+   */
47 85
   public boolean atFinalDestiation() {
48 86
     return currentLocation().equals(finalDestination);
49 87
   }
@@ -56,7 +94,7 @@ public class Cargo {
56 94
    * @return The last known location
57 95
    */
58 96
   public Location currentLocation() {
59
-    HandlingEvent lastEvent = history.lastEvent();
97
+    HandlingEvent lastEvent = lastEvent();
60 98
     
61 99
     // If we have no last event, we have not even received the package. Return unknown location
62 100
     if (lastEvent == null) {
@@ -109,5 +147,6 @@ public class Cargo {
109 147
   
110 148
   // Needed by Hibernate
111 149
   Cargo() {}
150
+
112 151
   
113 152
 }

+ 0
- 60
dddsample/src/main/java/se/citerus/dddsample/domain/DeliveryHistory.java Просмотреть файл

@@ -1,60 +0,0 @@
1
-package se.citerus.dddsample.domain;
2
-
3
-import org.apache.commons.lang.builder.ReflectionToStringBuilder;
4
-import org.apache.commons.lang.builder.ToStringStyle;
5
-
6
-import javax.persistence.Embeddable;
7
-import javax.persistence.OneToMany;
8
-import java.util.*;
9
-
10
-/**
11
- * The delivery history of a cargo. One cargo has exactly one delivery history.
12
- *
13
- */
14
-@Embeddable
15
-public class DeliveryHistory {
16
-
17
-  @OneToMany
18
-  private final Set<HandlingEvent> events = new HashSet<HandlingEvent>();
19
-
20
-  private static final HandlingEventByTimeComparator HANDLING_EVENT_COMPARATOR = new HandlingEventByTimeComparator();
21
-
22
-  /**
23
-   * @return An <b>unmodifiable</b> list of handling events, ordered by the time the events occured.
24
-   */
25
-  public List<HandlingEvent> eventsOrderedByTime() {
26
-    List<HandlingEvent> eventList = new ArrayList<HandlingEvent>(events);
27
-    Collections.sort(eventList, HANDLING_EVENT_COMPARATOR);
28
-    return Collections.unmodifiableList(eventList);
29
-  }
30
-
31
-  /**
32
-   * Adds the HandlingEvent to the sorted set.
33
-   * 
34
-   * @throws IllegalArgumentException if an event is not unique. Uniquness are evaluated by checking that compareTo() not returns 0.
35
-   * @param event
36
-   */
37
-  public void addEvent(HandlingEvent... event) {
38
-      events.addAll(Arrays.asList(event));
39
-  }
40
-
41
-  public HandlingEvent lastEvent() {
42
-    if (events.isEmpty()) {
43
-      return null;
44
-    } else {
45
-      List<HandlingEvent> orderedEvents = eventsOrderedByTime();
46
-      return orderedEvents.get(orderedEvents.size() - 1);
47
-    }
48
-  }
49
-
50
-  @Override
51
-  public String toString() {
52
-    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
53
-  }
54
-
55
-  private static class HandlingEventByTimeComparator implements Comparator<HandlingEvent> {
56
-    public int compare(HandlingEvent o1, HandlingEvent o2) {
57
-      return o1.timeOccurred().compareTo(o2.timeOccurred());
58
-    }
59
-  }
60
-}

+ 15
- 6
dddsample/src/main/java/se/citerus/dddsample/domain/HandlingEvent.java Просмотреть файл

@@ -1,25 +1,34 @@
1 1
 package se.citerus.dddsample.domain;
2 2
 
3
-import org.apache.commons.lang.builder.EqualsBuilder;
4
-
5
-import javax.persistence.*;
6
-
3
+import java.util.Comparator;
7 4
 import java.util.Date;
8 5
 import java.util.HashSet;
9 6
 import java.util.Set;
10 7
 import java.util.UUID;
11 8
 
9
+import javax.persistence.Entity;
10
+import javax.persistence.Enumerated;
11
+import javax.persistence.Id;
12
+import javax.persistence.ManyToOne;
13
+import javax.persistence.Transient;
14
+
15
+import org.apache.commons.lang.builder.EqualsBuilder;
16
+
12 17
 /**
13 18
  * HandlingEvent links the type of handling with a CarrierMovement.
14 19
  * 
15 20
  * Since HandlingEvents can be added in any order to a Cargo (or
16 21
  * DeliveryHistory), they need to implement Comparable to be able to be sorted
17 22
  * in correct order.
18
- *
19
- * TODO: build hierarchy of event types
20 23
  */
21 24
 @Entity
22 25
 public class HandlingEvent {
26
+  
27
+ public static final Comparator<HandlingEvent> BY_TIMESTAMP_COMPARATOR = new Comparator<HandlingEvent>(){
28
+  public int compare(HandlingEvent o1, HandlingEvent o2) {
29
+    return o1.timeOccurred().compareTo(o2.timeOccurred());
30
+  }
31
+ };
23 32
 
24 33
   @Id
25 34
   private UUID id;

+ 17
- 3
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryInMem.java Просмотреть файл

@@ -28,12 +28,12 @@ public class CargoRepositoryInMem implements CargoRepository {
28 28
   }
29 29
 
30 30
   public Cargo find(TrackingId trackingId) {
31
-    if (trackingId.toString().equalsIgnoreCase("DAE")){
32
-      throw new DataRetrievalFailureException("Network failure. Please try again");
33
-    }
31
+    simulateNetworkError(trackingId);
34 32
     
35 33
     return cargoDb.get(trackingId.toString());
36 34
   }
35
+
36
+
37 37
   
38 38
   public void save(Cargo cargo) {
39 39
     //No need to save anything with InMem
@@ -70,4 +70,18 @@ public class CargoRepositoryInMem implements CargoRepository {
70 70
   public void setHandlingEventRepository(HandlingEventRepository handlingEventRepository) {
71 71
     this.handlingEventRepository = handlingEventRepository;
72 72
   }
73
+  
74
+  /**
75
+   * Private helper method that simulates network error by thrwoing a DataDataRetrievalFailureException if tracking id equals "DAE".
76
+   * 
77
+   * Note that this method is only used for testing purposes.
78
+   * 
79
+   * @param trackingId
80
+   * @throws DataRetrievalFailureException
81
+   */
82
+  private void simulateNetworkError(TrackingId trackingId) {
83
+    if (trackingId.toString().equalsIgnoreCase("DAE")){
84
+      throw new DataRetrievalFailureException("Network failure. Please try again");
85
+    }
86
+  }
73 87
 }

+ 1
- 1
dddsample/src/main/java/se/citerus/dddsample/service/CargoServiceImpl.java Просмотреть файл

@@ -24,7 +24,7 @@ public class CargoServiceImpl implements CargoService {
24 24
             cargo.finalDestination().unlocode(),
25 25
             cargo.currentLocation().unlocode()
26 26
     );
27
-    final List<HandlingEvent> events = cargo.deliveryHistory().eventsOrderedByTime();
27
+    final List<HandlingEvent> events = cargo.eventsOrderedByTime();
28 28
     for (HandlingEvent event : events) {
29 29
       CarrierMovement cm = event.carrierMovement();
30 30
       String carrierIdString =

+ 59
- 2
dddsample/src/test/java/se/citerus/dddsample/domain/CargoTest.java Просмотреть файл

@@ -1,11 +1,13 @@
1 1
 package se.citerus.dddsample.domain;
2 2
 
3
-import junit.framework.TestCase;
4
-
5 3
 import java.text.DateFormat;
6 4
 import java.text.ParseException;
7 5
 import java.text.SimpleDateFormat;
6
+import java.util.Calendar;
8 7
 import java.util.Date;
8
+import java.util.List;
9
+
10
+import junit.framework.TestCase;
9 11
 
10 12
 public class CargoTest extends TestCase {
11 13
 
@@ -53,6 +55,36 @@ public class CargoTest extends TestCase {
53 55
     assertFalse(cargo.atFinalDestiation());
54 56
   }
55 57
   
58
+  public void testLastEvent() throws Exception {
59
+    Cargo cargo = populateCargoOutOfOrder();
60
+    
61
+    HandlingEvent lastEvent = cargo.lastEvent();
62
+    
63
+    assertEquals("SESTO", lastEvent.location().unlocode());
64
+    assertEquals(HandlingEvent.Type.LOAD, lastEvent.type());
65
+    assertEquals(getDate("2007-12-11"), lastEvent.timeOccurred());
66
+  }
67
+  
68
+  public void testLastEventWithNoEvents() throws Exception {
69
+    final Cargo cargo = new Cargo(new TrackingId("XYZ"), new Location("SESTO"), new Location("AUMEL"));
70
+    
71
+    HandlingEvent lastEvent = cargo.lastEvent();
72
+    assertNull(lastEvent);
73
+  }
74
+
75
+  public void testEventsOrderedByTime() throws Exception {
76
+    Cargo cargo = populateCargoOutOfOrder();
77
+    
78
+    List<HandlingEvent> events = cargo.eventsOrderedByTime();
79
+    
80
+    Date lastTime = new Date(0);
81
+    for (HandlingEvent event : events) {
82
+      Date time = event.timeOccurred();
83
+      assertTrue(time.compareTo(lastTime) > 0);
84
+      lastTime = time;
85
+    }
86
+  }
87
+  
56 88
   public void testEquality() throws Exception {
57 89
     Cargo c1 = new Cargo(new TrackingId("ABC"), new Location("A"), new Location("C"));
58 90
     Cargo c2 = new Cargo(new TrackingId("CBA"), new Location("A"), new Location("C"));
@@ -64,6 +96,9 @@ public class CargoTest extends TestCase {
64 96
     assertFalse("Cargos are not equal when Locations differ", c2.equals(c3));
65 97
   }
66 98
 
99
+  
100
+  
101
+  
67 102
   // TODO: Generate test data some better way
68 103
   private Cargo populateCargoReceivedStockholm() throws Exception {
69 104
     final Cargo cargo = new Cargo(new TrackingId("XYZ"), new Location("SESTO"), new Location("AUMEL"));
@@ -164,6 +199,28 @@ public class CargoTest extends TestCase {
164 199
     return cargo;
165 200
   }
166 201
 
202
+  private Cargo populateCargoOutOfOrder() throws Exception {
203
+    final Cargo cargo = new Cargo(new TrackingId("XYZ"), new Location("SESTO"), new Location("AUMEL"));
204
+
205
+    final CarrierMovement stockholmToHamburg = new CarrierMovement(
206
+            new CarrierId("CAR_001"), new Location("SESTO"), new Location("DEHAM"));
207
+
208
+    cargo.handle(new HandlingEvent(getDate("2007-12-11"), new Date(), HandlingEvent.Type.LOAD, new Location("SESTO"), stockholmToHamburg));
209
+    cargo.handle(new HandlingEvent(getDate("2007-12-02"), new Date(), HandlingEvent.Type.UNLOAD, new Location("DEHAM"), stockholmToHamburg));
210
+
211
+    final CarrierMovement hamburgToHongKong = new CarrierMovement(
212
+            new CarrierId("CAR_001"), new Location("DEHAM"), new Location("CNHGK"));
213
+
214
+    cargo.handle(new HandlingEvent(getDate("2007-12-03"), new Date(), HandlingEvent.Type.LOAD, new Location("DEHAM"), hamburgToHongKong));
215
+    cargo.handle(new HandlingEvent(getDate("2007-12-04"), new Date(), HandlingEvent.Type.UNLOAD, new Location("CNHGK"), hamburgToHongKong));
216
+
217
+    final CarrierMovement hongKongToMelbourne = new CarrierMovement(
218
+            new CarrierId("CAR_001"), new Location("CNHGK"), new Location("AUMEL"));
219
+
220
+    cargo.handle(new HandlingEvent(getDate("2001-12-05"), new Date(), HandlingEvent.Type.LOAD, new Location("CNHGK"), hongKongToMelbourne));
221
+
222
+    return cargo;
223
+  }
167 224
   /**
168 225
    * Parse an ISO 8601 (YYYY-MM-DD) String to Date
169 226
    *

+ 0
- 30
dddsample/src/test/java/se/citerus/dddsample/domain/DeliveryHistoryTest.java Просмотреть файл

@@ -1,30 +0,0 @@
1
-package se.citerus.dddsample.domain;
2
-
3
-import junit.framework.TestCase;
4
-
5
-import java.text.DateFormat;
6
-import java.text.SimpleDateFormat;
7
-import java.util.Date;
8
-import java.util.List;
9
-
10
-public class DeliveryHistoryTest extends TestCase {
11
-
12
-  public void testEvensOrderedByTimeOccured() throws Exception {
13
-    DeliveryHistory dh = new DeliveryHistory();
14
-    assertTrue(dh.eventsOrderedByTime().isEmpty());
15
-
16
-    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
17
-    HandlingEvent he1 = new HandlingEvent(df.parse("2010-01-03"), new Date(), HandlingEvent.Type.RECEIVE, new Location("a"));
18
-    HandlingEvent he2 = new HandlingEvent(df.parse("2010-01-01"), new Date(), HandlingEvent.Type.LOAD, new Location("b"));
19
-    HandlingEvent he3 = new HandlingEvent(df.parse("2010-01-04"), new Date(), HandlingEvent.Type.CLAIM, new Location("c"));
20
-    HandlingEvent he4 = new HandlingEvent(df.parse("2010-01-02"), new Date(), HandlingEvent.Type.UNLOAD, new Location("d"));
21
-    dh.addEvent(he1, he2, he3, he4);
22
-
23
-    List<HandlingEvent> orderEvents = dh.eventsOrderedByTime();
24
-    assertEquals(4, orderEvents.size());
25
-    assertSame(he2, orderEvents.get(0));
26
-    assertSame(he4, orderEvents.get(1));
27
-    assertSame(he1, orderEvents.get(2));
28
-    assertSame(he3, orderEvents.get(3));
29
-  }
30
-}

+ 9
- 6
dddsample/src/test/java/se/citerus/dddsample/domain/TrackingScenarioTest.java Просмотреть файл

@@ -14,13 +14,16 @@ public class TrackingScenarioTest extends TestCase {
14 14
 
15 15
     Cargo cargo = populateCargo();
16 16
 
17
-    DeliveryHistory deliveryHistory = cargo.deliveryHistory();
18
-
19
-    List<HandlingEvent> handlingEvents = deliveryHistory.eventsOrderedByTime();
20
-
17
+    final List<HandlingEvent> handlingEvents = cargo.eventsOrderedByTime();
18
+    final HandlingEvent event = cargo.lastEvent();
19
+
20
+//
21
+//    DeliveryHistory deliveryHistory = cargo.deliveryHistory();
22
+//
23
+//    List<HandlingEvent> handlingEvents = deliveryHistory.eventsOrderedByTime();
24
+//
21 25
     assertEquals(4, handlingEvents.size());
22
-    final HandlingEvent event = deliveryHistory.lastEvent();
23
-
26
+    
24 27
     assertSame(HandlingEvent.Type.UNLOAD, event.type());
25 28
     assertFalse(cargo.atFinalDestiation());
26 29
     assertEquals("CNHKG", cargo.currentLocation().unlocode());

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/service/CargoServiceTest.java Просмотреть файл

@@ -69,7 +69,7 @@ public class CargoServiceTest extends AbstractDependencyInjectionSpringContextTe
69 69
       public Cargo answerWithinTransaction() throws Throwable {
70 70
         Cargo cargo = new Cargo(new TrackingId("XYZ"), new Location("ORIG"), new Location("DEST"));
71 71
         CarrierMovement cm = new CarrierMovement(new CarrierId("CAR_001"), new Location("FROM"), new Location("TO"));
72
-        cargo.deliveryHistory().addEvent(
72
+        cargo.handle(
73 73
                 new HandlingEvent(new Date(10L), new Date(20L), HandlingEvent.Type.CLAIM, new Location("TO"), cm)
74 74
         );
75 75
         return cargo;

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/web/CargoTrackingControllerTest.java Просмотреть файл

@@ -45,7 +45,7 @@ public class CargoTrackingControllerTest extends TestCase {
45 45
       public CargoWithHistoryDTO find(String trackingId) {
46 46
         Cargo cargo = new Cargo(new TrackingId(trackingId), new Location("AAA"), new Location("BBB"));
47 47
         HandlingEvent event = new HandlingEvent(new Date(10L), new Date(20L), HandlingEvent.Type.RECEIVE, new Location("AAA"));
48
-        cargo.deliveryHistory().addEvent(event);
48
+        cargo.handle(event);
49 49
 
50 50
         // TODO: use DTO assemblers
51 51
         CargoWithHistoryDTO cargoDTO = new CargoWithHistoryDTO(

+ 0
- 1
dddsample/src/test/resources/test-context-persistence.xml Просмотреть файл

@@ -21,7 +21,6 @@
21 21
       <list>
22 22
         <value>se.citerus.dddsample.domain.Cargo</value>
23 23
         <value>se.citerus.dddsample.domain.Location</value>
24
-        <value>se.citerus.dddsample.domain.DeliveryHistory</value>
25 24
         <value>se.citerus.dddsample.domain.HandlingEvent</value>
26 25
         <value>se.citerus.dddsample.domain.CarrierMovement</value>
27 26
       </list>