Pārlūkot izejas kodu

Implement Itinerary in scala

Dan Eidmark 10 gadus atpakaļ
vecāks
revīzija
4996797d17

+ 13
- 2
pom.xml Parādīt failu

@@ -76,6 +76,8 @@
76 76
     <maven-assembly-plugin.version>2.5.5</maven-assembly-plugin.version>
77 77
   </properties>
78 78
   <build>
79
+    <sourceDirectory>src/main/scala</sourceDirectory>
80
+    <testSourceDirectory>src/test/scala</testSourceDirectory>
79 81
     <plugins>
80 82
       <!-- Compiler -->
81 83
       <plugin>
@@ -87,7 +89,11 @@
87 89
           <encoding>${project.build.sourceEncoding}</encoding>
88 90
         </configuration>
89 91
       </plugin>
90
-
92
+      <plugin>
93
+        <groupId>net.alchim31.maven</groupId>
94
+        <artifactId>scala-maven-plugin</artifactId>
95
+        <version>3.2.1</version>
96
+      </plugin>
91 97
       <!-- Jetty plugin -->
92 98
       <plugin>
93 99
         <groupId>org.mortbay.jetty</groupId>
@@ -130,11 +136,16 @@
130 136
           </descriptorRefs>
131 137
         </configuration>
132 138
       </plugin>
133
-      
139
+
134 140
     </plugins>
135 141
   </build>
136 142
   <dependencies>
137 143
     <dependency>
144
+      <groupId>org.scala-lang</groupId>
145
+      <artifactId>scala-library</artifactId>
146
+      <version>2.11.8</version>
147
+    </dependency>
148
+    <dependency>
138 149
       <groupId>junit</groupId>
139 150
       <artifactId>junit</artifactId>
140 151
       <version>4.12</version>

+ 2
- 1
src/main/java/se/citerus/dddsample/domain/model/cargo/Cargo.java Parādīt failu

@@ -1,5 +1,6 @@
1 1
 package se.citerus.dddsample.domain.model.cargo;
2 2
 
3
+import java.util.Collections;
3 4
 import org.apache.commons.lang.Validate;
4 5
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
5 6
 import se.citerus.dddsample.domain.model.handling.HandlingHistory;
@@ -93,7 +94,7 @@ public class Cargo implements Entity<Cargo> {
93 94
    * @return The itinerary. Never null.
94 95
    */
95 96
   public Itinerary itinerary() {
96
-    return DomainObjectUtils.nullSafe(this.itinerary, Itinerary.EMPTY_ITINERARY);
97
+    return DomainObjectUtils.nullSafe(this.itinerary, new Itinerary(Collections.emptyList()));
97 98
   }
98 99
 
99 100
   /**

+ 0
- 165
src/main/java/se/citerus/dddsample/domain/model/cargo/Itinerary.java Parādīt failu

@@ -1,165 +0,0 @@
1
-package se.citerus.dddsample.domain.model.cargo;
2
-
3
-import org.apache.commons.lang.Validate;
4
-import se.citerus.dddsample.domain.model.handling.HandlingEvent;
5
-import se.citerus.dddsample.domain.model.location.Location;
6
-import se.citerus.dddsample.domain.shared.ValueObject;
7
-
8
-import java.util.Collections;
9
-import java.util.Date;
10
-import java.util.List;
11
-
12
-/**
13
- * An itinerary.
14
- *
15
- */
16
-public class Itinerary implements ValueObject<Itinerary> {
17
-
18
-  private List<Leg> legs = Collections.emptyList();
19
-
20
-  static final Itinerary EMPTY_ITINERARY = new Itinerary();
21
-  private static final Date END_OF_DAYS = new Date(Long.MAX_VALUE);
22
-
23
-  /**
24
-   * Constructor.
25
-   *
26
-   * @param legs List of legs for this itinerary.
27
-   */
28
-  public Itinerary(final List<Leg> legs) {
29
-    Validate.notEmpty(legs);
30
-    Validate.noNullElements(legs);
31
-
32
-    this.legs = legs;
33
-  }
34
-
35
-  /**
36
-   * @return the legs of this itinerary, as an <b>immutable</b> list.
37
-   */
38
-  public List<Leg> legs() {
39
-    return Collections.unmodifiableList(legs);
40
-  }
41
-
42
-  /**
43
-   * Test if the given handling event is expected when executing this itinerary.
44
-   *
45
-   * @param event Event to test.
46
-   * @return <code>true</code> if the event is expected
47
-   */
48
-  public boolean isExpected(final HandlingEvent event) {
49
-    if (legs.isEmpty()) {
50
-      return true;
51
-    }
52
-
53
-    if (event.type() == HandlingEvent.Type.RECEIVE) {
54
-      //Check that the first leg's origin is the event's location
55
-      final Leg leg = legs.get(0);
56
-      return (leg.loadLocation().equals(event.location()));
57
-    }
58
-
59
-    if (event.type() == HandlingEvent.Type.LOAD) {
60
-      //Check that the there is one leg with same load location and voyage
61
-      for (Leg leg : legs) {
62
-        if (leg.loadLocation().sameIdentityAs(event.location()) &&
63
-            leg.voyage().sameIdentityAs(event.voyage()))
64
-          return true;
65
-      }
66
-      return false;
67
-    }
68
-
69
-    if (event.type() == HandlingEvent.Type.UNLOAD) {
70
-      //Check that the there is one leg with same unload location and voyage
71
-      for (Leg leg : legs) {
72
-        if (leg.unloadLocation().equals(event.location()) &&
73
-            leg.voyage().equals(event.voyage()))
74
-          return true;
75
-      }
76
-      return false;
77
-    }
78
-
79
-    if (event.type() == HandlingEvent.Type.CLAIM) {
80
-      //Check that the last leg's destination is from the event's location
81
-      final Leg leg = lastLeg();
82
-      return (leg.unloadLocation().equals(event.location()));
83
-    }
84
-
85
-    //HandlingEvent.Type.CUSTOMS;
86
-    return true;
87
-  }
88
-
89
-  /**
90
-   * @return The initial departure location.
91
-   */
92
-  Location initialDepartureLocation() {
93
-     if (legs.isEmpty()) {
94
-       return Location.UNKNOWN;
95
-     } else {
96
-       return legs.get(0).loadLocation();
97
-     }
98
-  }
99
-
100
-  /**
101
-   * @return The final arrival location.
102
-   */
103
-  Location finalArrivalLocation() {
104
-    if (legs.isEmpty()) {
105
-      return Location.UNKNOWN;
106
-    } else {
107
-      return lastLeg().unloadLocation();
108
-    }
109
-  }
110
-
111
-  /**
112
-   * @return Date when cargo arrives at final destination.
113
-   */
114
-  Date finalArrivalDate() {
115
-    final Leg lastLeg = lastLeg();
116
-
117
-    if (lastLeg == null) {
118
-      return new Date(END_OF_DAYS.getTime());
119
-    } else {
120
-      return new Date(lastLeg.unloadTime().getTime());
121
-    }
122
-  }
123
-
124
-  /**
125
-   * @return The last leg on the itinerary.
126
-   */
127
-  Leg lastLeg() {
128
-    if (legs.isEmpty()) {
129
-      return null;
130
-    } else {
131
-      return legs.get(legs.size() - 1);
132
-    }
133
-  }
134
-
135
-  /**
136
-   * @param other itinerary to compare
137
-   * @return <code>true</code> if the legs in this and the other itinerary are all equal.
138
-   */
139
-  @Override
140
-  public boolean sameValueAs(final Itinerary other) {
141
-    return other != null && legs.equals(other.legs);
142
-  }
143
-
144
-  @Override
145
-  public boolean equals(final Object o) {
146
-    if (this == o) return true;
147
-    if (o == null || getClass() != o.getClass()) return false;
148
-
149
-    final Itinerary itinerary = (Itinerary) o;
150
-
151
-    return sameValueAs(itinerary);
152
-  }
153
-
154
-  @Override
155
-  public int hashCode() {
156
-    return legs.hashCode();
157
-  }
158
-
159
-  Itinerary() {
160
-    // Needed by Hibernate
161
-  }
162
-
163
-  // Auto-generated surrogate key
164
-  private Long id;
165
-}

+ 62
- 0
src/main/scala/se/citerus/dddsample/domain/model/cargo/Itinerary.scala Parādīt failu

@@ -0,0 +1,62 @@
1
+package se.citerus.dddsample.domain.model.cargo
2
+
3
+import java.util.{Collections, Date}
4
+
5
+import se.citerus.dddsample.domain.model.handling.HandlingEvent
6
+import se.citerus.dddsample.domain.model.handling.HandlingEvent.Type._
7
+import se.citerus.dddsample.domain.model.location.Location
8
+
9
+import scala.collection.JavaConverters._
10
+
11
+/**
12
+  * Created by dan on 2016-09-23.
13
+  */
14
+
15
+
16
+case class Itinerary(legs: java.util.List[Leg]) {
17
+  private val END_OF_DAYS: Date = new Date(Long.MaxValue)
18
+
19
+  require(legs != null, "Legs cannot be null")
20
+  require(!legs.contains(null), "Legs cannot have null elements")
21
+
22
+  def this() {
23
+    this(Collections.emptyList())
24
+  }
25
+
26
+  def isExpected(event: HandlingEvent): Boolean = {
27
+    if (legs.isEmpty) return true
28
+
29
+    event.`type`() match {
30
+      case RECEIVE =>
31
+        legs.get(0).loadLocation == event.location
32
+      case LOAD =>
33
+        legs.asScala.exists(leg => leg.loadLocation.sameIdentityAs(event.location) && leg.voyage.sameIdentityAs(event.voyage))
34
+      case UNLOAD =>
35
+        legs.asScala.exists(leg => leg.unloadLocation.sameIdentityAs(event.location) && leg.voyage.sameIdentityAs(event.voyage))
36
+      case CLAIM =>
37
+        legs.asScala.last.unloadLocation.sameIdentityAs(event.location)
38
+      case _ => true
39
+    }
40
+  }
41
+
42
+  private[cargo]  def initialDepartureLocation: Location = {
43
+    if (legs.isEmpty) Location.UNKNOWN
44
+    else legs.asScala.head.loadLocation
45
+  }
46
+
47
+  private[cargo]  def finalArrivalLocation: Location = {
48
+    if (legs.isEmpty) Location.UNKNOWN
49
+    else legs.asScala.last.unloadLocation
50
+  }
51
+
52
+  private[cargo]  def finalArrivalDate: Date = {
53
+    if (legs.isEmpty) {
54
+      new Date(Long.MaxValue)
55
+    }
56
+    else {
57
+      new Date(legs.asScala.last.unloadTime.getTime)
58
+    }
59
+  }
60
+
61
+  private val id: Long = 0L
62
+}

+ 5
- 5
src/test/java/se/citerus/dddsample/domain/model/cargo/CargoTest.java Parādīt failu

@@ -48,11 +48,11 @@ public class CargoTest extends TestCase {
48 48
 
49 49
   public void testRoutingStatus() throws Exception {
50 50
     final Cargo cargo = new Cargo(new TrackingId("XYZ"), new RouteSpecification(STOCKHOLM, MELBOURNE, new Date()));
51
-    final Itinerary good = new Itinerary();
52
-    final Itinerary bad = new Itinerary();
51
+    final ItineraryScala good = new ItineraryScala();
52
+    final ItineraryScala bad = new ItineraryScala();
53 53
     final RouteSpecification acceptOnlyGood = new RouteSpecification(cargo.origin(), cargo.routeSpecification().destination(), new Date()) {
54 54
       @Override
55
-      public boolean isSatisfiedBy(Itinerary itinerary) {
55
+      public boolean isSatisfiedBy(ItineraryScala itinerary) {
56 56
         return itinerary == good;
57 57
       }
58 58
     };
@@ -60,7 +60,7 @@ public class CargoTest extends TestCase {
60 60
     cargo.specifyNewRoute(acceptOnlyGood);
61 61
 
62 62
     assertEquals(NOT_ROUTED, cargo.delivery().routingStatus());
63
-    
63
+
64 64
     cargo.assignToRoute(bad);
65 65
     assertEquals(MISROUTED, cargo.delivery().routingStatus());
66 66
 
@@ -289,7 +289,7 @@ public class CargoTest extends TestCase {
289 289
   private Cargo setUpCargoWithItinerary(Location origin, Location midpoint, Location destination) {
290 290
     Cargo cargo = new Cargo(new TrackingId("CARGO1"), new RouteSpecification(origin, destination, new Date()));
291 291
 
292
-    Itinerary itinerary = new Itinerary(
292
+    ItineraryScala itinerary = new ItineraryScala(
293 293
       Arrays.asList(
294 294
         new Leg(voyage, origin, midpoint, new Date(), new Date()),
295 295
         new Leg(voyage, midpoint, destination, new Date(), new Date())

+ 2
- 23
src/test/java/se/citerus/dddsample/domain/model/cargo/ItineraryTest.java Parādīt failu

@@ -1,6 +1,7 @@
1 1
 package se.citerus.dddsample.domain.model.cargo;
2 2
 
3 3
 import junit.framework.TestCase;
4
+import org.junit.Ignore;
4 5
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
5 6
 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
6 7
 import se.citerus.dddsample.domain.model.voyage.CarrierMovement;
@@ -82,28 +83,6 @@ public class ItineraryTest extends TestCase {
82 83
 
83 84
     event = new HandlingEvent(cargo, new Date(), new Date(), HandlingEvent.Type.CLAIM, ROTTERDAM);
84 85
     assertFalse(itinerary.isExpected(event));
85
-
86
-  }
87
-
88
-  public void testNextExpectedEvent() throws Exception {
89
-
90
-  }
91
-
92
-  public void testCreateItinerary() throws Exception {
93
-    try {
94
-      new Itinerary(new ArrayList<Leg>());
95
-      fail("An empty itinerary is not OK");
96
-    } catch (IllegalArgumentException iae) {
97
-      //Expected
98
-    }
99
-
100
-    try {
101
-      List<Leg> legs = null;
102
-      new Itinerary(legs);
103
-      fail("Null itinerary is not OK");
104
-    } catch (IllegalArgumentException iae) {
105
-      //Expected
106
-    }
107 86
   }
108 87
 
109
-}
88
+}