Quellcode durchsuchen

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

jorgen_falk vor 18 Jahren
Ursprung
Commit
abf2f02137

+ 47
- 8
dddsample/src/main/java/se/citerus/dddsample/domain/Cargo.java Datei anzeigen

1
 package se.citerus.dddsample.domain;
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
 import org.apache.commons.lang.builder.EqualsBuilder;
9
 import org.apache.commons.lang.builder.EqualsBuilder;
4
 import org.apache.commons.lang.builder.HashCodeBuilder;
10
 import org.apache.commons.lang.builder.HashCodeBuilder;
5
 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
11
 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
8
 import javax.persistence.EmbeddedId;
14
 import javax.persistence.EmbeddedId;
9
 import javax.persistence.Entity;
15
 import javax.persistence.Entity;
10
 import javax.persistence.ManyToOne;
16
 import javax.persistence.ManyToOne;
17
+import javax.persistence.OneToMany;
11
 
18
 
12
 
19
 
13
 /**
20
 /**
25
   
32
   
26
   @ManyToOne
33
   @ManyToOne
27
   private Location finalDestination;
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
   public Cargo(TrackingId trackingId, Location origin, Location finalDestination) {
40
   public Cargo(TrackingId trackingId, Location origin, Location finalDestination) {
32
     this.trackingId = trackingId;
41
     this.trackingId = trackingId;
33
     this.origin = origin;
42
     this.origin = origin;
34
     this.finalDestination = finalDestination;
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
   public void handle(HandlingEvent event) {
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
   public boolean atFinalDestiation() {
85
   public boolean atFinalDestiation() {
48
     return currentLocation().equals(finalDestination);
86
     return currentLocation().equals(finalDestination);
49
   }
87
   }
56
    * @return The last known location
94
    * @return The last known location
57
    */
95
    */
58
   public Location currentLocation() {
96
   public Location currentLocation() {
59
-    HandlingEvent lastEvent = history.lastEvent();
97
+    HandlingEvent lastEvent = lastEvent();
60
     
98
     
61
     // If we have no last event, we have not even received the package. Return unknown location
99
     // If we have no last event, we have not even received the package. Return unknown location
62
     if (lastEvent == null) {
100
     if (lastEvent == null) {
109
   
147
   
110
   // Needed by Hibernate
148
   // Needed by Hibernate
111
   Cargo() {}
149
   Cargo() {}
150
+
112
   
151
   
113
 }
152
 }

+ 0
- 60
dddsample/src/main/java/se/citerus/dddsample/domain/DeliveryHistory.java Datei anzeigen

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 Datei anzeigen

1
 package se.citerus.dddsample.domain;
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
 import java.util.Date;
4
 import java.util.Date;
8
 import java.util.HashSet;
5
 import java.util.HashSet;
9
 import java.util.Set;
6
 import java.util.Set;
10
 import java.util.UUID;
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
  * HandlingEvent links the type of handling with a CarrierMovement.
18
  * HandlingEvent links the type of handling with a CarrierMovement.
14
  * 
19
  * 
15
  * Since HandlingEvents can be added in any order to a Cargo (or
20
  * Since HandlingEvents can be added in any order to a Cargo (or
16
  * DeliveryHistory), they need to implement Comparable to be able to be sorted
21
  * DeliveryHistory), they need to implement Comparable to be able to be sorted
17
  * in correct order.
22
  * in correct order.
18
- *
19
- * TODO: build hierarchy of event types
20
  */
23
  */
21
 @Entity
24
 @Entity
22
 public class HandlingEvent {
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
   @Id
33
   @Id
25
   private UUID id;
34
   private UUID id;

+ 17
- 3
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryInMem.java Datei anzeigen

28
   }
28
   }
29
 
29
 
30
   public Cargo find(TrackingId trackingId) {
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
     return cargoDb.get(trackingId.toString());
33
     return cargoDb.get(trackingId.toString());
36
   }
34
   }
35
+
36
+
37
   
37
   
38
   public void save(Cargo cargo) {
38
   public void save(Cargo cargo) {
39
     //No need to save anything with InMem
39
     //No need to save anything with InMem
70
   public void setHandlingEventRepository(HandlingEventRepository handlingEventRepository) {
70
   public void setHandlingEventRepository(HandlingEventRepository handlingEventRepository) {
71
     this.handlingEventRepository = handlingEventRepository;
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 Datei anzeigen

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

+ 59
- 2
dddsample/src/test/java/se/citerus/dddsample/domain/CargoTest.java Datei anzeigen

1
 package se.citerus.dddsample.domain;
1
 package se.citerus.dddsample.domain;
2
 
2
 
3
-import junit.framework.TestCase;
4
-
5
 import java.text.DateFormat;
3
 import java.text.DateFormat;
6
 import java.text.ParseException;
4
 import java.text.ParseException;
7
 import java.text.SimpleDateFormat;
5
 import java.text.SimpleDateFormat;
6
+import java.util.Calendar;
8
 import java.util.Date;
7
 import java.util.Date;
8
+import java.util.List;
9
+
10
+import junit.framework.TestCase;
9
 
11
 
10
 public class CargoTest extends TestCase {
12
 public class CargoTest extends TestCase {
11
 
13
 
53
     assertFalse(cargo.atFinalDestiation());
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
   public void testEquality() throws Exception {
88
   public void testEquality() throws Exception {
57
     Cargo c1 = new Cargo(new TrackingId("ABC"), new Location("A"), new Location("C"));
89
     Cargo c1 = new Cargo(new TrackingId("ABC"), new Location("A"), new Location("C"));
58
     Cargo c2 = new Cargo(new TrackingId("CBA"), new Location("A"), new Location("C"));
90
     Cargo c2 = new Cargo(new TrackingId("CBA"), new Location("A"), new Location("C"));
64
     assertFalse("Cargos are not equal when Locations differ", c2.equals(c3));
96
     assertFalse("Cargos are not equal when Locations differ", c2.equals(c3));
65
   }
97
   }
66
 
98
 
99
+  
100
+  
101
+  
67
   // TODO: Generate test data some better way
102
   // TODO: Generate test data some better way
68
   private Cargo populateCargoReceivedStockholm() throws Exception {
103
   private Cargo populateCargoReceivedStockholm() throws Exception {
69
     final Cargo cargo = new Cargo(new TrackingId("XYZ"), new Location("SESTO"), new Location("AUMEL"));
104
     final Cargo cargo = new Cargo(new TrackingId("XYZ"), new Location("SESTO"), new Location("AUMEL"));
164
     return cargo;
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
    * Parse an ISO 8601 (YYYY-MM-DD) String to Date
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 Datei anzeigen

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 Datei anzeigen

14
 
14
 
15
     Cargo cargo = populateCargo();
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
     assertEquals(4, handlingEvents.size());
25
     assertEquals(4, handlingEvents.size());
22
-    final HandlingEvent event = deliveryHistory.lastEvent();
23
-
26
+    
24
     assertSame(HandlingEvent.Type.UNLOAD, event.type());
27
     assertSame(HandlingEvent.Type.UNLOAD, event.type());
25
     assertFalse(cargo.atFinalDestiation());
28
     assertFalse(cargo.atFinalDestiation());
26
     assertEquals("CNHKG", cargo.currentLocation().unlocode());
29
     assertEquals("CNHKG", cargo.currentLocation().unlocode());

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/service/CargoServiceTest.java Datei anzeigen

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

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/web/CargoTrackingControllerTest.java Datei anzeigen

45
       public CargoWithHistoryDTO find(String trackingId) {
45
       public CargoWithHistoryDTO find(String trackingId) {
46
         Cargo cargo = new Cargo(new TrackingId(trackingId), new Location("AAA"), new Location("BBB"));
46
         Cargo cargo = new Cargo(new TrackingId(trackingId), new Location("AAA"), new Location("BBB"));
47
         HandlingEvent event = new HandlingEvent(new Date(10L), new Date(20L), HandlingEvent.Type.RECEIVE, new Location("AAA"));
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
         // TODO: use DTO assemblers
50
         // TODO: use DTO assemblers
51
         CargoWithHistoryDTO cargoDTO = new CargoWithHistoryDTO(
51
         CargoWithHistoryDTO cargoDTO = new CargoWithHistoryDTO(

+ 0
- 1
dddsample/src/test/resources/test-context-persistence.xml Datei anzeigen

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