Преглед на файлове

Started restructuring to make layering more clear

Patrik Fredriksson преди 18 години
родител
ревизия
f1445cfa82
променени са 49 файла, в които са добавени 328 реда и са изтрити 440 реда
  1. 4
    1
      dddsample/src/main/java/se/citerus/dddsample/application/BookingService.java
  2. 3
    1
      dddsample/src/main/java/se/citerus/dddsample/application/HandlingEventService.java
  3. 3
    2
      dddsample/src/main/java/se/citerus/dddsample/application/TrackingService.java
  4. 2
    2
      dddsample/src/main/java/se/citerus/dddsample/application/impl/HandlingEventServiceImpl.java
  5. 2
    2
      dddsample/src/main/java/se/citerus/dddsample/application/impl/TrackingServiceImpl.java
  6. 1
    1
      dddsample/src/main/java/se/citerus/dddsample/application/messaging/CargoHandledConsumer.java
  7. 2
    6
      dddsample/src/main/java/se/citerus/dddsample/application/messaging/HandlingEventRegistrationAttemptConsumer.java
  8. 0
    40
      dddsample/src/main/java/se/citerus/dddsample/application/persistence/CargoRepositoryHibernate.java
  9. 0
    28
      dddsample/src/main/java/se/citerus/dddsample/application/persistence/HandlingEventRepositoryHibernate.java
  10. 0
    23
      dddsample/src/main/java/se/citerus/dddsample/application/persistence/HibernateRepository.java
  11. 0
    24
      dddsample/src/main/java/se/citerus/dddsample/application/persistence/LocationRepositoryHibernate.java
  12. 0
    21
      dddsample/src/main/java/se/citerus/dddsample/application/persistence/VoyageRepositoryHibernate.java
  13. 0
    7
      dddsample/src/main/java/se/citerus/dddsample/application/persistence/package.html
  14. 1
    1
      dddsample/src/main/java/se/citerus/dddsample/application/remoting/BookingServiceFacadeImpl.java
  15. 2
    5
      dddsample/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingEventFactory.java
  16. 20
    0
      dddsample/src/main/java/se/citerus/dddsample/domain/model/handling/UnknownCargoException.java
  17. 17
    0
      dddsample/src/main/java/se/citerus/dddsample/domain/model/handling/UnknownLocationException.java
  18. 20
    0
      dddsample/src/main/java/se/citerus/dddsample/domain/model/handling/UnknownVoyageException.java
  19. 2
    1
      dddsample/src/main/java/se/citerus/dddsample/domain/model/package.html
  20. 0
    54
      dddsample/src/main/java/se/citerus/dddsample/domain/service/impl/BookingServiceImpl.java
  21. 4
    4
      dddsample/src/main/resources/context-persistence-hibernate.xml
  22. 3
    3
      dddsample/src/main/resources/context-service.xml
  23. 6
    6
      dddsample/src/main/resources/hibernate.cfg.xml
  24. 0
    40
      dddsample/src/main/resources/se/citerus/dddsample/application/persistence/Cargo.hbm.xml
  25. 0
    21
      dddsample/src/main/resources/se/citerus/dddsample/application/persistence/CarrierMovement.hbm.xml
  26. 0
    24
      dddsample/src/main/resources/se/citerus/dddsample/application/persistence/HandlingEvent.hbm.xml
  27. 0
    22
      dddsample/src/main/resources/se/citerus/dddsample/application/persistence/Leg.hbm.xml
  28. 0
    17
      dddsample/src/main/resources/se/citerus/dddsample/application/persistence/Location.hbm.xml
  29. 0
    27
      dddsample/src/main/resources/se/citerus/dddsample/application/persistence/Voyage.hbm.xml
  30. 1
    1
      dddsample/src/site/apt/characterization.apt
  31. 1
    28
      dddsample/src/site/apt/patterns-reference.apt
  32. 6
    6
      dddsample/src/test/java/se/citerus/dddsample/CargoHandlingScenarioTest.java
  33. 3
    2
      dddsample/src/test/java/se/citerus/dddsample/application/BookingServiceTest.java
  34. 140
    0
      dddsample/src/test/java/se/citerus/dddsample/application/HandlingEventServiceTest.java
  35. 68
    0
      dddsample/src/test/java/se/citerus/dddsample/application/TrackingScenarioTest.java
  36. 2
    2
      dddsample/src/test/java/se/citerus/dddsample/application/routing/ExternalRoutingServiceTest.java
  37. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/application/service/dto/assembler/ItineraryCandidateDTOAssemblerTest.java
  38. 2
    5
      dddsample/src/test/java/se/citerus/dddsample/domain/model/handling/HandlingEventFactoryTest.java
  39. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/domain/service/RoutingServiceTest.java
  40. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/AbstractRepositoryTest.java
  41. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/CargoRepositoryTest.java
  42. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/CarrierMovementRepositoryTest.java
  43. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/HandlingEventRepositoryTest.java
  44. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/LocationRepositoryTest.java
  45. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/CargoRepositoryInMem.java
  46. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/HandlingEventRepositoryInMem.java
  47. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/LocationRepositoryInMem.java
  48. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/VoyageRepositoryInMem.java
  49. 2
    2
      dddsample/src/test/java/se/citerus/dddsample/ui/CargoTrackingControllerTest.java

dddsample/src/main/java/se/citerus/dddsample/domain/service/BookingService.java → dddsample/src/main/java/se/citerus/dddsample/application/BookingService.java Целия файл

@@ -1,5 +1,6 @@
1
-package se.citerus.dddsample.domain.service;
1
+package se.citerus.dddsample.application;
2 2
 
3
+import org.springframework.transaction.annotation.Transactional;
3 4
 import se.citerus.dddsample.domain.model.cargo.Itinerary;
4 5
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
5 6
 import se.citerus.dddsample.domain.model.location.UnLocode;
@@ -18,6 +19,7 @@ public interface BookingService {
18 19
    * @param destination cargo destination
19 20
    * @return Cargo tracking id
20 21
    */
22
+  @Transactional
21 23
   TrackingId bookNewCargo(UnLocode origin, UnLocode destination);
22 24
 
23 25
   /**
@@ -26,6 +28,7 @@ public interface BookingService {
26 28
    * @param trackingId cargo tracking id
27 29
    * @return A list of possible itineraries for this cargo 
28 30
    */
31
+  @Transactional
29 32
   List<Itinerary> requestPossibleRoutesForCargo(TrackingId trackingId);
30 33
 
31 34
 }

dddsample/src/main/java/se/citerus/dddsample/domain/service/HandlingEventService.java → dddsample/src/main/java/se/citerus/dddsample/application/HandlingEventService.java Целия файл

@@ -1,5 +1,6 @@
1
-package se.citerus.dddsample.domain.service;
1
+package se.citerus.dddsample.application;
2 2
 
3
+import org.springframework.transaction.annotation.Transactional;
3 4
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
4 5
 
5 6
 
@@ -14,6 +15,7 @@ public interface HandlingEventService {
14 15
    *
15 16
    * @param event handling event to register
16 17
    */
18
+  @Transactional
17 19
   void register(HandlingEvent event);
18 20
 
19 21
 }

dddsample/src/main/java/se/citerus/dddsample/domain/service/TrackingService.java → dddsample/src/main/java/se/citerus/dddsample/application/TrackingService.java Целия файл

@@ -1,10 +1,10 @@
1
-package se.citerus.dddsample.domain.service;
1
+package se.citerus.dddsample.application;
2 2
 
3
+import org.springframework.transaction.annotation.Transactional;
3 4
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
4 5
 
5 6
 /**
6 7
  * Cargo tracking service.
7
- *
8 8
  */
9 9
 public interface TrackingService {
10 10
 
@@ -15,6 +15,7 @@ public interface TrackingService {
15 15
    *
16 16
    * @param trackingId cargo tracking id
17 17
    */
18
+  @Transactional
18 19
   void onCargoHandled(TrackingId trackingId);
19 20
 
20 21
 }

dddsample/src/main/java/se/citerus/dddsample/domain/service/impl/HandlingEventServiceImpl.java → dddsample/src/main/java/se/citerus/dddsample/application/impl/HandlingEventServiceImpl.java Целия файл

@@ -1,9 +1,9 @@
1
-package se.citerus.dddsample.domain.service.impl;
1
+package se.citerus.dddsample.application.impl;
2 2
 
3
+import se.citerus.dddsample.application.HandlingEventService;
3 4
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
4 5
 import se.citerus.dddsample.domain.model.handling.HandlingEventRepository;
5 6
 import se.citerus.dddsample.domain.service.DomainEventNotifier;
6
-import se.citerus.dddsample.domain.service.HandlingEventService;
7 7
 
8 8
 public final class HandlingEventServiceImpl implements HandlingEventService {
9 9
 

dddsample/src/main/java/se/citerus/dddsample/domain/service/impl/TrackingServiceImpl.java → dddsample/src/main/java/se/citerus/dddsample/application/impl/TrackingServiceImpl.java Целия файл

@@ -1,13 +1,13 @@
1
-package se.citerus.dddsample.domain.service.impl;
1
+package se.citerus.dddsample.application.impl;
2 2
 
3 3
 import org.apache.commons.lang.Validate;
4 4
 import org.apache.commons.logging.Log;
5 5
 import org.apache.commons.logging.LogFactory;
6
+import se.citerus.dddsample.application.TrackingService;
6 7
 import se.citerus.dddsample.domain.model.cargo.Cargo;
7 8
 import se.citerus.dddsample.domain.model.cargo.CargoRepository;
8 9
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
9 10
 import se.citerus.dddsample.domain.service.DomainEventNotifier;
10
-import se.citerus.dddsample.domain.service.TrackingService;
11 11
 
12 12
 public class TrackingServiceImpl implements TrackingService {
13 13
 

+ 1
- 1
dddsample/src/main/java/se/citerus/dddsample/application/messaging/CargoHandledConsumer.java Целия файл

@@ -3,8 +3,8 @@ package se.citerus.dddsample.application.messaging;
3 3
 import org.apache.commons.logging.Log;
4 4
 import org.apache.commons.logging.LogFactory;
5 5
 import org.springframework.transaction.annotation.Transactional;
6
+import se.citerus.dddsample.application.TrackingService;
6 7
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
7
-import se.citerus.dddsample.domain.service.TrackingService;
8 8
 
9 9
 import javax.jms.Message;
10 10
 import javax.jms.MessageListener;

+ 2
- 6
dddsample/src/main/java/se/citerus/dddsample/application/messaging/HandlingEventRegistrationAttemptConsumer.java Целия файл

@@ -3,15 +3,11 @@ package se.citerus.dddsample.application.messaging;
3 3
 import org.apache.commons.logging.Log;
4 4
 import org.apache.commons.logging.LogFactory;
5 5
 import org.springframework.transaction.annotation.Transactional;
6
+import se.citerus.dddsample.application.HandlingEventService;
6 7
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
7 8
 import se.citerus.dddsample.domain.model.carrier.VoyageNumber;
8
-import se.citerus.dddsample.domain.model.handling.HandlingEvent;
9
-import se.citerus.dddsample.domain.model.handling.HandlingEventFactory;
9
+import se.citerus.dddsample.domain.model.handling.*;
10 10
 import se.citerus.dddsample.domain.model.location.UnLocode;
11
-import se.citerus.dddsample.domain.service.HandlingEventService;
12
-import se.citerus.dddsample.domain.service.UnknownCargoException;
13
-import se.citerus.dddsample.domain.service.UnknownLocationException;
14
-import se.citerus.dddsample.domain.service.UnknownVoyageException;
15 11
 
16 12
 import javax.jms.JMSException;
17 13
 import javax.jms.Message;

+ 0
- 40
dddsample/src/main/java/se/citerus/dddsample/application/persistence/CargoRepositoryHibernate.java Целия файл

@@ -1,40 +0,0 @@
1
-package se.citerus.dddsample.application.persistence;
2
-
3
-import org.springframework.stereotype.Repository;
4
-import se.citerus.dddsample.domain.model.cargo.Cargo;
5
-import se.citerus.dddsample.domain.model.cargo.CargoRepository;
6
-import se.citerus.dddsample.domain.model.cargo.TrackingId;
7
-
8
-import java.util.List;
9
-import java.util.UUID;
10
-
11
-/**
12
- * Hibernate implementation of CargoRepository.
13
- */
14
-@Repository
15
-public class CargoRepositoryHibernate extends HibernateRepository implements CargoRepository {
16
-
17
-  public Cargo find(TrackingId tid) {
18
-    return (Cargo) getSession().
19
-      createQuery("from Cargo where trackingId = :tid").
20
-      setParameter("tid", tid).
21
-      uniqueResult();
22
-  }
23
-
24
-  public void save(Cargo cargo) {
25
-    getSession().persist(cargo);
26
-    getSession().createSQLQuery("delete from Leg where cargo_id = null").executeUpdate();
27
-  }
28
-
29
-  public TrackingId nextTrackingId() {
30
-    final String random = UUID.randomUUID().toString().toUpperCase();
31
-    return new TrackingId(
32
-      random.substring(0, random.indexOf("-"))
33
-    );
34
-  }
35
-
36
-  public List<Cargo> findAll() {
37
-    return getSession().createQuery("from Cargo").list();
38
-  }
39
-
40
-}

+ 0
- 28
dddsample/src/main/java/se/citerus/dddsample/application/persistence/HandlingEventRepositoryHibernate.java Целия файл

@@ -1,28 +0,0 @@
1
-package se.citerus.dddsample.application.persistence;
2
-
3
-import org.springframework.stereotype.Repository;
4
-import se.citerus.dddsample.domain.model.cargo.TrackingId;
5
-import se.citerus.dddsample.domain.model.handling.HandlingEvent;
6
-import se.citerus.dddsample.domain.model.handling.HandlingEventRepository;
7
-
8
-import java.util.List;
9
-
10
-/**
11
- * Hibernate implementation of HandlingEventRepository.
12
- *
13
- */
14
-@Repository
15
-public class HandlingEventRepositoryHibernate extends HibernateRepository implements HandlingEventRepository {
16
-
17
-  public void save(HandlingEvent event) {
18
-    getSession().save(event);
19
-  }
20
-
21
-  public List<HandlingEvent> findEventsForCargo(TrackingId tid) {
22
-    return getSession().createQuery(
23
-            "from HandlingEvent where cargo.trackingId = :tid order by completionTime").
24
-            setParameter("tid", tid).
25
-            list();
26
-  }
27
-
28
-}

+ 0
- 23
dddsample/src/main/java/se/citerus/dddsample/application/persistence/HibernateRepository.java Целия файл

@@ -1,23 +0,0 @@
1
-package se.citerus.dddsample.application.persistence;
2
-
3
-import org.hibernate.Session;
4
-import org.hibernate.SessionFactory;
5
-import org.springframework.beans.factory.annotation.Required;
6
-
7
-/**
8
- * Functionality common to all Hibernate repositories.
9
- */
10
-public abstract class HibernateRepository {
11
-
12
-  private SessionFactory sessionFactory;
13
-
14
-  @Required
15
-  public void setSessionFactory(final SessionFactory sessionFactory) {
16
-    this.sessionFactory = sessionFactory;
17
-  }
18
-
19
-  protected Session getSession() {
20
-    return sessionFactory.getCurrentSession();
21
-  }
22
-
23
-}

+ 0
- 24
dddsample/src/main/java/se/citerus/dddsample/application/persistence/LocationRepositoryHibernate.java Целия файл

@@ -1,24 +0,0 @@
1
-package se.citerus.dddsample.application.persistence;
2
-
3
-import org.springframework.stereotype.Repository;
4
-import se.citerus.dddsample.domain.model.location.Location;
5
-import se.citerus.dddsample.domain.model.location.LocationRepository;
6
-import se.citerus.dddsample.domain.model.location.UnLocode;
7
-
8
-import java.util.List;
9
-
10
-@Repository
11
-public final class LocationRepositoryHibernate extends HibernateRepository implements LocationRepository {
12
-
13
-  public Location find(final UnLocode unLocode) {
14
-    return (Location) getSession().
15
-      createQuery("from Location where unLocode = ?").
16
-      setParameter(0, unLocode).
17
-      uniqueResult();
18
-  }
19
-
20
-  public List<Location> findAll() {
21
-    return getSession().createQuery("from Location").list();
22
-  }
23
-
24
-}

+ 0
- 21
dddsample/src/main/java/se/citerus/dddsample/application/persistence/VoyageRepositoryHibernate.java Целия файл

@@ -1,21 +0,0 @@
1
-package se.citerus.dddsample.application.persistence;
2
-
3
-import org.springframework.stereotype.Repository;
4
-import se.citerus.dddsample.domain.model.carrier.Voyage;
5
-import se.citerus.dddsample.domain.model.carrier.VoyageNumber;
6
-import se.citerus.dddsample.domain.model.carrier.VoyageRepository;
7
-
8
-/**
9
- * Hibernate implementation of CarrierMovementRepository.
10
- */
11
-@Repository
12
-public final class VoyageRepositoryHibernate extends HibernateRepository implements VoyageRepository {
13
-
14
-  public Voyage find(final VoyageNumber voyageNumber) {
15
-    return (Voyage) getSession().
16
-      createQuery("from Voyage where voyageNumber = :vn").
17
-      setParameter("vn", voyageNumber).
18
-      uniqueResult();
19
-  }
20
-
21
-}

+ 0
- 7
dddsample/src/main/java/se/citerus/dddsample/application/persistence/package.html Целия файл

@@ -1,7 +0,0 @@
1
-<html>
2
-<body>
3
-<p>
4
-  Hibernate implementations of the repository interfaces. This is part of the infrastructure.
5
-</p>
6
-</body>
7
-</html>

+ 1
- 1
dddsample/src/main/java/se/citerus/dddsample/application/remoting/BookingServiceFacadeImpl.java Целия файл

@@ -2,6 +2,7 @@ package se.citerus.dddsample.application.remoting;
2 2
 
3 3
 import org.apache.log4j.Logger;
4 4
 import org.springframework.transaction.annotation.Transactional;
5
+import se.citerus.dddsample.application.BookingService;
5 6
 import se.citerus.dddsample.application.remoting.dto.CargoRoutingDTO;
6 7
 import se.citerus.dddsample.application.remoting.dto.ItineraryCandidateDTO;
7 8
 import se.citerus.dddsample.application.remoting.dto.LocationDTO;
@@ -16,7 +17,6 @@ import se.citerus.dddsample.domain.model.carrier.VoyageRepository;
16 17
 import se.citerus.dddsample.domain.model.location.Location;
17 18
 import se.citerus.dddsample.domain.model.location.LocationRepository;
18 19
 import se.citerus.dddsample.domain.model.location.UnLocode;
19
-import se.citerus.dddsample.domain.service.BookingService;
20 20
 
21 21
 import java.rmi.RemoteException;
22 22
 import java.util.ArrayList;

+ 2
- 5
dddsample/src/main/java/se/citerus/dddsample/domain/model/handling/HandlingEventFactory.java Целия файл

@@ -10,9 +10,6 @@ import se.citerus.dddsample.domain.model.carrier.VoyageRepository;
10 10
 import se.citerus.dddsample.domain.model.location.Location;
11 11
 import se.citerus.dddsample.domain.model.location.LocationRepository;
12 12
 import se.citerus.dddsample.domain.model.location.UnLocode;
13
-import se.citerus.dddsample.domain.service.UnknownCargoException;
14
-import se.citerus.dddsample.domain.service.UnknownLocationException;
15
-import se.citerus.dddsample.domain.service.UnknownVoyageException;
16 13
 
17 14
 import java.util.Date;
18 15
 
@@ -37,9 +34,9 @@ public class HandlingEventFactory {
37 34
    * @param voyageNumber      voyage number
38 35
    * @param unlocode          United Nations Location Code for the location of the event
39 36
    * @param type              type of event
40
-   * @throws se.citerus.dddsample.domain.service.UnknownVoyageException
37
+   * @throws UnknownVoyageException
41 38
    *                                    if there's not carrier movement with this id
42
-   * @throws se.citerus.dddsample.domain.service.UnknownCargoException if there's no cargo with this tracking id
39
+   * @throws UnknownCargoException if there's no cargo with this tracking id
43 40
    * @throws UnknownLocationException   if there's no location with this UN Locode
44 41
    * @return A handling event.
45 42
    */

+ 20
- 0
dddsample/src/main/java/se/citerus/dddsample/domain/model/handling/UnknownCargoException.java Целия файл

@@ -0,0 +1,20 @@
1
+package se.citerus.dddsample.domain.model.handling;
2
+
3
+import se.citerus.dddsample.domain.model.cargo.TrackingId;
4
+
5
+/**
6
+ * Thrown when trying to register an event with an unknown tracking id.
7
+ */
8
+public final class UnknownCargoException extends Exception {
9
+
10
+  private final TrackingId trackingId;
11
+
12
+  public UnknownCargoException(final TrackingId trackingId) {
13
+    this.trackingId = trackingId;
14
+  }
15
+
16
+  @Override
17
+  public String getMessage() {
18
+    return "No cargo with tracking id " + trackingId.idString() + " exists in the system";
19
+  }
20
+}

+ 17
- 0
dddsample/src/main/java/se/citerus/dddsample/domain/model/handling/UnknownLocationException.java Целия файл

@@ -0,0 +1,17 @@
1
+package se.citerus.dddsample.domain.model.handling;
2
+
3
+import se.citerus.dddsample.domain.model.location.UnLocode;
4
+
5
+public class UnknownLocationException extends Exception {
6
+
7
+  private final UnLocode unlocode;
8
+
9
+  public UnknownLocationException(final UnLocode unlocode) {
10
+    this.unlocode = unlocode;
11
+  }
12
+
13
+  @Override
14
+  public String getMessage() {
15
+    return "No location with UN locode " + unlocode.idString() + " exists in the system";
16
+  }
17
+}

+ 20
- 0
dddsample/src/main/java/se/citerus/dddsample/domain/model/handling/UnknownVoyageException.java Целия файл

@@ -0,0 +1,20 @@
1
+package se.citerus.dddsample.domain.model.handling;
2
+
3
+import se.citerus.dddsample.domain.model.carrier.VoyageNumber;
4
+
5
+/**
6
+ * Thrown when trying to register an event with an unknown carrier movement id.
7
+ */
8
+public class UnknownVoyageException extends Exception {
9
+
10
+  private final VoyageNumber voyageNumber;
11
+
12
+  public UnknownVoyageException(VoyageNumber voyageNumber) {
13
+    this.voyageNumber = voyageNumber;
14
+  }
15
+
16
+  @Override
17
+  public String getMessage() {
18
+    return "No voyage with number " + voyageNumber.idString() + " exists in the system";
19
+  }
20
+}

+ 2
- 1
dddsample/src/main/java/se/citerus/dddsample/domain/model/package.html Целия файл

@@ -2,7 +2,8 @@
2 2
 <body>
3 3
 <p>
4 4
   The domain model. This is the heart of the application. Each aggregate is contained in
5
-  its own subpackage, along with the repository interface.
5
+  its own subpackage, along with the repository interface, factories and exceptions where
6
+  applicable.
6 7
 </p>
7 8
 </body>
8 9
 </html>

+ 0
- 54
dddsample/src/main/java/se/citerus/dddsample/domain/service/impl/BookingServiceImpl.java Целия файл

@@ -1,54 +0,0 @@
1
-package se.citerus.dddsample.domain.service.impl;
2
-
3
-import org.apache.commons.lang.Validate;
4
-import org.apache.commons.logging.Log;
5
-import org.apache.commons.logging.LogFactory;
6
-import se.citerus.dddsample.domain.model.cargo.*;
7
-import se.citerus.dddsample.domain.model.location.Location;
8
-import se.citerus.dddsample.domain.model.location.LocationRepository;
9
-import se.citerus.dddsample.domain.model.location.UnLocode;
10
-import se.citerus.dddsample.domain.service.BookingService;
11
-import se.citerus.dddsample.domain.service.RoutingService;
12
-
13
-import java.util.Date;
14
-import java.util.List;
15
-
16
-public final class BookingServiceImpl implements BookingService {
17
-
18
-  private final CargoRepository cargoRepository;
19
-  private final LocationRepository locationRepository;
20
-  private final RoutingService routingService;
21
-  private final Log logger = LogFactory.getLog(getClass());
22
-
23
-  public BookingServiceImpl(CargoRepository cargoRepository, LocationRepository locationRepository, RoutingService routingService) {
24
-    this.cargoRepository = cargoRepository;
25
-    this.locationRepository = locationRepository;
26
-    this.routingService = routingService;
27
-  }
28
-
29
-  public TrackingId bookNewCargo(final UnLocode originUnLocode, final UnLocode destinationUnLocode) {
30
-    Validate.notNull(originUnLocode);
31
-    Validate.notNull(destinationUnLocode);
32
-
33
-    // TODO cargo factory? tracking id factory?
34
-    final TrackingId trackingId = cargoRepository.nextTrackingId();
35
-    final Location origin = locationRepository.find(originUnLocode);
36
-    final Location destination = locationRepository.find(destinationUnLocode);
37
-    Cargo cargo = new Cargo(trackingId, origin, destination);
38
-
39
-    cargoRepository.save(cargo);
40
-    logger.info("Registered new cargo with tracking id " + cargo.trackingId().idString());
41
-
42
-    return cargo.trackingId();
43
-  }
44
-
45
-  public List<Itinerary> requestPossibleRoutesForCargo(TrackingId trackingId) {
46
-    Validate.notNull(trackingId);
47
-    
48
-    final Cargo cargo = cargoRepository.find(trackingId);
49
-    final RouteSpecification routeSpecification = new RouteSpecification(cargo.origin(), cargo.destination(), new Date());
50
-
51
-    return routingService.fetchRoutesForSpecification(routeSpecification);
52
-  }
53
-
54
-}

+ 4
- 4
dddsample/src/main/resources/context-persistence-hibernate.xml Целия файл

@@ -26,19 +26,19 @@
26 26
     <property name="sessionFactory" ref="sessionFactory"/>
27 27
   </bean>
28 28
   
29
-  <bean id="cargoRepository" class="se.citerus.dddsample.application.persistence.CargoRepositoryHibernate">
29
+  <bean id="cargoRepository" class="se.citerus.dddsample.infrastructure.persistence.hibernate.CargoRepositoryHibernate">
30 30
     <property name="sessionFactory" ref="sessionFactory"/>
31 31
   </bean>
32 32
 
33
-  <bean id="handlingEventRepository" class="se.citerus.dddsample.application.persistence.HandlingEventRepositoryHibernate">
33
+  <bean id="handlingEventRepository" class="se.citerus.dddsample.infrastructure.persistence.hibernate.HandlingEventRepositoryHibernate">
34 34
     <property name="sessionFactory" ref="sessionFactory"/>
35 35
   </bean>
36 36
 
37
-  <bean id="voyageRepository" class="se.citerus.dddsample.application.persistence.VoyageRepositoryHibernate">
37
+  <bean id="voyageRepository" class="se.citerus.dddsample.infrastructure.persistence.hibernate.VoyageRepositoryHibernate">
38 38
     <property name="sessionFactory" ref="sessionFactory"/>
39 39
   </bean>
40 40
 
41
-  <bean id="locationRepository" class="se.citerus.dddsample.application.persistence.LocationRepositoryHibernate">
41
+  <bean id="locationRepository" class="se.citerus.dddsample.infrastructure.persistence.hibernate.LocationRepositoryHibernate">
42 42
     <property name="sessionFactory" ref="sessionFactory"/>
43 43
   </bean>
44 44
 </beans>

+ 3
- 3
dddsample/src/main/resources/context-service.xml Целия файл

@@ -7,18 +7,18 @@
7 7
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
8 8
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
9 9
 
10
-  <bean id="bookingService" class="se.citerus.dddsample.domain.service.impl.BookingServiceImpl">
10
+  <bean id="bookingService" class="se.citerus.dddsample.application.impl.BookingServiceImpl">
11 11
     <constructor-arg ref="cargoRepository"/>
12 12
     <constructor-arg ref="locationRepository"/>
13 13
     <constructor-arg ref="routingService"/>
14 14
   </bean>
15 15
 
16
-  <bean id="trackingService" class="se.citerus.dddsample.domain.service.impl.TrackingServiceImpl">
16
+  <bean id="trackingService" class="se.citerus.dddsample.application.impl.TrackingServiceImpl">
17 17
     <constructor-arg ref="cargoRepository"/>
18 18
     <constructor-arg ref="domainEventNotifier"/>
19 19
   </bean>
20 20
 
21
-  <bean id="handlingEventService" class="se.citerus.dddsample.domain.service.impl.HandlingEventServiceImpl">
21
+  <bean id="handlingEventService" class="se.citerus.dddsample.application.impl.HandlingEventServiceImpl">
22 22
     <constructor-arg ref="handlingEventRepository"/>
23 23
     <constructor-arg ref="domainEventNotifier"/>
24 24
   </bean>

+ 6
- 6
dddsample/src/main/resources/hibernate.cfg.xml Целия файл

@@ -10,12 +10,12 @@
10 10
     <!-- Properties defined here are shared between test and production -->
11 11
     <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
12 12
     
13
-    <mapping resource="se/citerus/dddsample/application/persistence/Cargo.hbm.xml" />
14
-    <mapping resource="se/citerus/dddsample/application/persistence/Voyage.hbm.xml" />
15
-    <mapping resource="se/citerus/dddsample/application/persistence/Leg.hbm.xml" />
16
-    <mapping resource="se/citerus/dddsample/application/persistence/Location.hbm.xml" />
17
-    <mapping resource="se/citerus/dddsample/application/persistence/CarrierMovement.hbm.xml" />
18
-    <mapping resource="se/citerus/dddsample/application/persistence/HandlingEvent.hbm.xml" />
13
+    <mapping resource="se/citerus/dddsample/infrastructure/persistence/hibernate/Cargo.hbm.xml" />
14
+    <mapping resource="se/citerus/dddsample/infrastructure/persistence/hibernate/Voyage.hbm.xml" />
15
+    <mapping resource="se/citerus/dddsample/infrastructure/persistence/hibernate/Leg.hbm.xml" />
16
+    <mapping resource="se/citerus/dddsample/infrastructure/persistence/hibernate/Location.hbm.xml" />
17
+    <mapping resource="se/citerus/dddsample/infrastructure/persistence/hibernate/CarrierMovement.hbm.xml" />
18
+    <mapping resource="se/citerus/dddsample/infrastructure/persistence/hibernate/HandlingEvent.hbm.xml" />
19 19
   </session-factory>
20 20
 
21 21
 </hibernate-configuration>

+ 0
- 40
dddsample/src/main/resources/se/citerus/dddsample/application/persistence/Cargo.hbm.xml Целия файл

@@ -1,40 +0,0 @@
1
-<?xml version="1.0"?>
2
-
3
-<!DOCTYPE hibernate-mapping PUBLIC
4
-  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
5
-  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
6
-
7
-<hibernate-mapping default-access="field">
8
-  <class name="se.citerus.dddsample.domain.model.cargo.Cargo" table="Cargo">
9
-
10
-    <id name="id" column="id">
11
-      <generator class="org.hibernate.id.IdentityGenerator"/>
12
-    </id>
13
-
14
-    <component name="trackingId" unique="true" update="false">
15
-      <property name="id" column="tracking_id"/>
16
-    </component>
17
-
18
-    <component name="delivery" lazy="true" update="false">
19
-      <set name="events" lazy="true" cascade="none">
20
-        <key column="cargo_id"/>
21
-        <one-to-many class="se.citerus.dddsample.domain.model.handling.HandlingEvent"/>
22
-      </set>
23
-    </component>
24
-
25
-    <component name="routeSpecification">
26
-      <many-to-one name="origin" column="origin_id" cascade="none" update="false" foreign-key="origin_fk"/>
27
-      <many-to-one name="destination" column="destination_id" cascade="none" foreign-key="destination_fk"/>
28
-      <property name="arrivalDeadline" column="arrival_deadline" not-null="true"/>
29
-    </component>
30
-
31
-    <component name="itinerary">
32
-      <list name="legs" lazy="true" cascade="all">
33
-        <key column="cargo_id" foreign-key="itinerary_fk"/>
34
-        <index column="leg_index"/>
35
-        <one-to-many class="se.citerus.dddsample.domain.model.cargo.Leg"/>
36
-      </list>
37
-    </component>
38
-
39
-  </class>
40
-</hibernate-mapping>

+ 0
- 21
dddsample/src/main/resources/se/citerus/dddsample/application/persistence/CarrierMovement.hbm.xml Целия файл

@@ -1,21 +0,0 @@
1
-<?xml version="1.0"?>
2
-
3
-<!DOCTYPE hibernate-mapping PUBLIC
4
-  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
5
-  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
6
-
7
-<hibernate-mapping default-access="field">
8
-  <class name="se.citerus.dddsample.domain.model.carrier.CarrierMovement" table="CarrierMovement" mutable="false">
9
-
10
-    <id name="id" column="id">
11
-      <generator class="org.hibernate.id.IdentityGenerator"/>
12
-    </id>
13
-
14
-    <many-to-one name="arrivalLocation" column="arrival_location_id" not-null="true" foreign-key="arrival_location_fk"/>
15
-    <property name="arrivalTime" column="arrival_time" not-null="true"/>
16
-
17
-    <many-to-one name="departureLocation" column="departure_location_id" not-null="true" foreign-key="departure_location_fk"/>
18
-    <property name="departureTime" column="departure_time" not-null="true"/>
19
-    
20
-  </class>
21
-</hibernate-mapping>

+ 0
- 24
dddsample/src/main/resources/se/citerus/dddsample/application/persistence/HandlingEvent.hbm.xml Целия файл

@@ -1,24 +0,0 @@
1
-<?xml version="1.0"?>
2
-
3
-<!DOCTYPE hibernate-mapping PUBLIC
4
-  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
5
-  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
6
-
7
-<hibernate-mapping default-access="field">
8
-  <class name="se.citerus.dddsample.domain.model.handling.HandlingEvent" table="HandlingEvent">
9
-    <id name="id" column="id">
10
-      <generator class="org.hibernate.id.IdentityGenerator"/>
11
-    </id>
12
-    <many-to-one name="voyage" column="voyage_id" not-null="false" cascade="none" foreign-key="voyage_fk"/>
13
-    <many-to-one name="location" column="location_id" not-null="true" cascade="none" foreign-key="location_fk"/>
14
-    <many-to-one name="cargo" column="cargo_id" not-null="true" cascade="none" foreign-key="cargo_fk"/>
15
-    <property name="completionTime" column="completionTime" not-null="true"/>
16
-    <property name="registrationTime" column="registrationTime" not-null="true"/>
17
-    <property name="type" column="type" not-null="true">
18
-      <type name="org.hibernate.type.EnumType">
19
-        <param name="enumClass">se.citerus.dddsample.domain.model.handling.HandlingEvent$Type</param>
20
-        <param name="type">12</param><!-- 12 is java.sql.Types.VARCHAR -->
21
-      </type>
22
-    </property>
23
-  </class>
24
-</hibernate-mapping>

+ 0
- 22
dddsample/src/main/resources/se/citerus/dddsample/application/persistence/Leg.hbm.xml Целия файл

@@ -1,22 +0,0 @@
1
-<?xml version="1.0"?>
2
-
3
-<!DOCTYPE hibernate-mapping PUBLIC
4
-  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
5
-  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
6
-
7
-<hibernate-mapping default-access="field">
8
-  <class name="se.citerus.dddsample.domain.model.cargo.Leg" table="Leg" mutable="false">
9
-    <id name="id" column="id">
10
-      <generator class="org.hibernate.id.IdentityGenerator"/>
11
-    </id>
12
-
13
-    <many-to-one name="voyage" column="voyage_id" cascade="none" foreign-key="voyage_fk"/>
14
-
15
-    <many-to-one name="loadLocation" column="load_location_id" cascade="none" foreign-key="load_location_fk"/>
16
-    <property name="loadTime" column="load_time" not-null="true"/>
17
-
18
-    <many-to-one name="unloadLocation" column="unload_location_id" cascade="none" foreign-key="unload_location_fk"/>
19
-    <property name="unloadTime" column="unload_time" not-null="true"/>
20
-    
21
-  </class>
22
-</hibernate-mapping>

+ 0
- 17
dddsample/src/main/resources/se/citerus/dddsample/application/persistence/Location.hbm.xml Целия файл

@@ -1,17 +0,0 @@
1
-<?xml version="1.0"?>
2
-
3
-<!DOCTYPE hibernate-mapping PUBLIC
4
-  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
5
-  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
6
-
7
-<hibernate-mapping default-access="field">
8
-  <class name="se.citerus.dddsample.domain.model.location.Location" table="Location">
9
-    <id name="id" column="id">
10
-      <generator class="org.hibernate.id.IdentityGenerator"/>
11
-    </id>
12
-    <component name="unLocode" unique="true" update="false">
13
-      <property name="unlocode" column="unlocode" not-null="true"/>
14
-    </component>
15
-    <property name="name" column="name" not-null="true"/>
16
-  </class>
17
-</hibernate-mapping>

+ 0
- 27
dddsample/src/main/resources/se/citerus/dddsample/application/persistence/Voyage.hbm.xml Целия файл

@@ -1,27 +0,0 @@
1
-<?xml version="1.0"?>
2
-
3
-<!DOCTYPE hibernate-mapping PUBLIC
4
-  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
5
-  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
6
-
7
-<hibernate-mapping default-access="field">
8
-  <class name="se.citerus.dddsample.domain.model.carrier.Voyage" table="Voyage">
9
-
10
-    <id name="id" column="id">
11
-      <generator class="org.hibernate.id.IdentityGenerator"/>
12
-    </id>
13
-
14
-    <component name="voyageNumber" unique="true" update="false">
15
-      <property name="number" column="voyage_number"/>
16
-    </component>
17
-
18
-    <component name="schedule" lazy="false">
19
-      <list name="carrierMovements" lazy="false" cascade="all-delete-orphan">
20
-        <key column="voyage_id" foreign-key="voyage_fk"/>
21
-        <index column="cm_index"/>
22
-        <one-to-many class="se.citerus.dddsample.domain.model.carrier.CarrierMovement"/>
23
-      </list>
24
-    </component>
25
-
26
-  </class>
27
-</hibernate-mapping>

+ 1
- 1
dddsample/src/site/apt/characterization.apt Целия файл

@@ -25,7 +25,7 @@
25 25
 
26 26
 {Domain Event}
27 27
 
28
-    Some things clearly have identity but no life-cycle, or an extremely limited life-cycle with just one state. We call these things <Domain Events> and they can be viewed as hybrid of <Entities> and <Value Objects>. In the sample application <<<{{{xref/se/citerus/dddsample/domain/model/handling/HandlingEvent.html}HandlingEvent}}>>> is a <Domain Event> that represent real-life event such as a <<<Cargo>>> being loaded or unloaded, customs cleared etc. They carry both a completion time and a registration time and a completion time. The completion time is the time when the event occurred and the registration time is the time when the event was received. The <<<HandlingEvent>>> id is composed of the cargo, carrier movement, completion time, location and type (<<<LOAD>>> or <<<UNLOAD>>>).
28
+    Some things clearly have identity but no life-cycle, or an extremely limited life-cycle with just one state. We call these things <Domain Events> and they can be viewed as hybrid of <Entities> and <Value Objects>. In the sample application <<<{{{xref/se/citerus/dddsample/domain/model/handling/HandlingEvent.html}HandlingEvent}}>>> is a <Domain Event> that represent real-life event such as a <<<Cargo>>> being loaded or unloaded, customs cleared etc. They carry both a completion time and a registration time. The completion time is the time when the event occurred and the registration time is the time when the event was received by the system. The <<<HandlingEvent>>> id is composed of the cargo, carrier movement, completion time, location and type (<<<LOAD>>> or <<<UNLOAD>>>).
29 29
 
30 30
 {Aggregates}
31 31
 

+ 1
- 28
dddsample/src/site/apt/patterns-reference.apt Целия файл

@@ -1,28 +1 @@
1
-  ------------------------------------
2
-  Patterns reference
3
-  ------------------------------------
4
-  Patrik Fredriksson
5
-  ------------------------------------
6
-  August 8, 2008
7
-  
8
-  In {{{http://www.domaindrivendesign.org/books/index.html#DDD}Eric Evans' book}} a number of patterns on Domain-Driven Design are presented. Many of these patterns are implemented in the sample application. Use this patterns reference to find out which patterns are implemented where!
9
-  
10
-  A patterns summary can be downloaded at {{{http://www.domaindrivendesign.org/discussion/index.html}domaindrivendesign.org}}.

Tactical Design Patterns

*Building Blocks of a Model-Driven Design

  Aggregate [{{{characterization.html#Aggregates}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/cargo/package-summary.html}code example}}]
11
-  
12
-  Domain Event [{{{characterization.html#Domain_Event}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/handling/HandlingEvent.html}code example}}]
  
13
-  Entity [{{{characterization.html#Entities}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/cargo/Cargo.html}code example}}]
  
14
-  Value Object [{{{characterization.html#Value_Objects}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/cargo/Leg.html}code example}}]
  
15
-  Repository [{{{characterization.html#Repositories}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/cargo/CargoRepository.html}code example}}]
  
16
-  Service [{{{characterization.html#Services}discussion}}] [{{{xref/se/citerus/dddsample/domain/service/RoutingService.html}code example}}]
  
17
-  Specification [{{{xref/se/citerus/dddsample/domain/model/Specification.html}code example}}]

  Layered Architecture [discussion]
18
-  
19
-  Service Layer [discussion]
20
-  
21
-*Supple Design
22
-
23
-  Intention-Revealing Interfaces [discussion] [{{{xref/se/citerus/dddsample/domain/model/cargo/Cargo.html}code example}}]
24
-  
25
-  Side-Effect-Free Functions [discussion] [{{{xref/se/citerus/dddsample/domain/model/cargo/Cargo.html}code example}}]
26
-  

Strategic Design Patterns
27
-
28
-*Maintaining Model Integrity

  Anti-corruption Layer [discussion]
1
+  ------------------------------------
  Patterns reference
  ------------------------------------
  Patrik Fredriksson
  ------------------------------------
  August 8, 2008
  
  In {{{http://www.domaindrivendesign.org/books/index.html#DDD}Eric Evans' book}} a number of patterns on Domain-Driven Design are presented. Many of these patterns are implemented in the sample application. Use this patterns reference to find out which patterns are implemented where!
  
  A patterns summary can be downloaded at {{{http://www.domaindrivendesign.org/discussion/index.html}domaindrivendesign.org}}.

Tactical Design Patterns

*Building Blocks of a Model-Driven Design

  Aggregate [{{{characterization.html#Aggregates}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/cargo/package-summary.html}code example}}]
  
  Domain Event [{{{characterization.html#Domain_Event}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/handling/HandlingEvent.html}code example}}]
  
  Entity [{{{characterization.html#Entities}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/cargo/Cargo.html}code example}}]
  
  Value Object [{{{characterization.html#Value_Objects}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/cargo/Leg.html}code example}}]
  
  Repository [{{{characterization.html#Repositories}discussion}}] [{{{xref/se/citerus/dddsample/domain/model/cargo/CargoRepository.html}code example}}]
  
  Service [{{{characterization.html#Services}discussion}}] [{{{xref/se/citerus/dddsample/domain/service/RoutingService.html}code example}}]
  
  Specification [{{{xref/se/citerus/dddsample/domain/model/Specification.html}code example}}]

  Layered Architecture [discussion]
  
  Service Layer [discussion]
  
*Supple Design

  Intention-Revealing Interfaces [discussion] [{{{xref/se/citerus/dddsample/domain/model/cargo/Cargo.html}code example}}]
  
  Side-Effect-Free Functions [discussion] [{{{xref/se/citerus/dddsample/domain/model/cargo/Cargo.html}code example}}]
  

Strategic Design Patterns

*Maintaining Model Integrity

  Anti-corruption Layer [discussion]

+ 6
- 6
dddsample/src/test/java/se/citerus/dddsample/CargoHandlingScenarioTest.java Целия файл

@@ -1,8 +1,10 @@
1 1
 package se.citerus.dddsample;
2 2
 
3 3
 import junit.framework.TestCase;
4
-import se.citerus.dddsample.application.persistence.LocationRepositoryInMem;
5
-import se.citerus.dddsample.application.persistence.VoyageRepositoryInMem;
4
+import se.citerus.dddsample.application.HandlingEventService;
5
+import se.citerus.dddsample.application.TrackingService;
6
+import se.citerus.dddsample.application.impl.HandlingEventServiceImpl;
7
+import se.citerus.dddsample.application.impl.TrackingServiceImpl;
6 8
 import se.citerus.dddsample.domain.model.cargo.*;
7 9
 import static se.citerus.dddsample.domain.model.carrier.SampleVoyages.*;
8 10
 import se.citerus.dddsample.domain.model.carrier.Voyage;
@@ -14,11 +16,9 @@ import se.citerus.dddsample.domain.model.location.Location;
14 16
 import se.citerus.dddsample.domain.model.location.LocationRepository;
15 17
 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
16 18
 import se.citerus.dddsample.domain.service.DomainEventNotifier;
17
-import se.citerus.dddsample.domain.service.HandlingEventService;
18 19
 import se.citerus.dddsample.domain.service.RoutingService;
19
-import se.citerus.dddsample.domain.service.TrackingService;
20
-import se.citerus.dddsample.domain.service.impl.HandlingEventServiceImpl;
21
-import se.citerus.dddsample.domain.service.impl.TrackingServiceImpl;
20
+import se.citerus.dddsample.infrastructure.persistence.inmemory.LocationRepositoryInMem;
21
+import se.citerus.dddsample.infrastructure.persistence.inmemory.VoyageRepositoryInMem;
22 22
 
23 23
 import java.util.*;
24 24
 

dddsample/src/test/java/se/citerus/dddsample/domain/service/BookingServiceTest.java → dddsample/src/test/java/se/citerus/dddsample/application/BookingServiceTest.java Целия файл

@@ -1,7 +1,8 @@
1
-package se.citerus.dddsample.domain.service;
1
+package se.citerus.dddsample.application;
2 2
 
3 3
 import junit.framework.TestCase;
4 4
 import static org.easymock.EasyMock.*;
5
+import se.citerus.dddsample.application.impl.BookingServiceImpl;
5 6
 import se.citerus.dddsample.domain.model.cargo.Cargo;
6 7
 import se.citerus.dddsample.domain.model.cargo.CargoRepository;
7 8
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
@@ -9,7 +10,7 @@ import se.citerus.dddsample.domain.model.location.LocationRepository;
9 10
 import static se.citerus.dddsample.domain.model.location.SampleLocations.CHICAGO;
10 11
 import static se.citerus.dddsample.domain.model.location.SampleLocations.STOCKHOLM;
11 12
 import se.citerus.dddsample.domain.model.location.UnLocode;
12
-import se.citerus.dddsample.domain.service.impl.BookingServiceImpl;
13
+import se.citerus.dddsample.domain.service.RoutingService;
13 14
 
14 15
 public class BookingServiceTest extends TestCase {
15 16
 

+ 140
- 0
dddsample/src/test/java/se/citerus/dddsample/application/HandlingEventServiceTest.java Целия файл

@@ -0,0 +1,140 @@
1
+package se.citerus.dddsample.application;
2
+
3
+import junit.framework.TestCase;
4
+import static org.easymock.EasyMock.*;
5
+import se.citerus.dddsample.application.impl.HandlingEventServiceImpl;
6
+import se.citerus.dddsample.domain.model.cargo.Cargo;
7
+import se.citerus.dddsample.domain.model.cargo.CargoRepository;
8
+import se.citerus.dddsample.domain.model.cargo.TrackingId;
9
+import se.citerus.dddsample.domain.model.carrier.SampleVoyages;
10
+import se.citerus.dddsample.domain.model.carrier.VoyageNumber;
11
+import se.citerus.dddsample.domain.model.carrier.VoyageRepository;
12
+import se.citerus.dddsample.domain.model.handling.*;
13
+import se.citerus.dddsample.domain.model.location.LocationRepository;
14
+import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
15
+import se.citerus.dddsample.domain.model.location.UnLocode;
16
+import se.citerus.dddsample.domain.service.DomainEventNotifier;
17
+
18
+import java.util.Date;
19
+
20
+public class HandlingEventServiceTest extends TestCase {
21
+  private HandlingEventServiceImpl service;
22
+  private DomainEventNotifier domainEventNotifier;
23
+  private CargoRepository cargoRepository;
24
+  private VoyageRepository voyageRepository;
25
+  private HandlingEventRepository handlingEventRepository;
26
+  private LocationRepository locationRepository;
27
+  private HandlingEventFactory handlingEventFactory;
28
+
29
+  private final Cargo cargoABC = new Cargo(new TrackingId("ABC"), HAMBURG, TOKYO);
30
+
31
+  private final Cargo cargoXYZ = new Cargo(new TrackingId("XYZ"), HONGKONG, HELSINKI);
32
+
33
+  protected void setUp() throws Exception{
34
+    cargoRepository = createMock(CargoRepository.class);
35
+    voyageRepository = createMock(VoyageRepository.class);
36
+    handlingEventRepository = createMock(HandlingEventRepository.class);
37
+    locationRepository = createMock(LocationRepository.class);
38
+    domainEventNotifier = createMock(DomainEventNotifier.class);
39
+    service = new HandlingEventServiceImpl(handlingEventRepository, domainEventNotifier);
40
+    handlingEventFactory = new HandlingEventFactory(cargoRepository, voyageRepository, locationRepository);
41
+  }
42
+
43
+  protected void tearDown() throws Exception {
44
+    verify(cargoRepository, voyageRepository, handlingEventRepository, domainEventNotifier);
45
+  }
46
+
47
+  public void testRegisterEvent() throws Exception {
48
+    final Date date = new Date();
49
+
50
+    final TrackingId trackingId = new TrackingId("ABC");
51
+    expect(cargoRepository.find(trackingId)).andReturn(cargoABC);
52
+
53
+    final VoyageNumber voyageNumber = new VoyageNumber("AAA_BBB");
54
+    expect(voyageRepository.find(voyageNumber)).andReturn(SampleVoyages.CM001);
55
+
56
+    final UnLocode unLocode = new UnLocode("SESTO");
57
+    expect(locationRepository.find(unLocode)).andReturn(STOCKHOLM);
58
+
59
+    // TODO: does not inspect the handling event instance in a sufficient way
60
+    handlingEventRepository.save(isA(HandlingEvent.class));
61
+    domainEventNotifier.cargoWasHandled(isA(HandlingEvent.class));
62
+
63
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
64
+
65
+    final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, voyageNumber, unLocode, HandlingEvent.Type.LOAD);
66
+    service.register(event);
67
+  }
68
+
69
+  public void testRegisterEventWithoutCarrierMovement() throws Exception {
70
+    final Date date = new Date();
71
+
72
+    final TrackingId trackingId = new TrackingId("ABC");
73
+    expect(cargoRepository.find(trackingId)).andReturn(cargoABC);
74
+
75
+    handlingEventRepository.save(isA(HandlingEvent.class));
76
+    domainEventNotifier.cargoWasHandled(isA(HandlingEvent.class));
77
+
78
+    expect(locationRepository.find(STOCKHOLM.unLocode())).andReturn(STOCKHOLM);
79
+
80
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
81
+
82
+    final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, null, STOCKHOLM.unLocode(), HandlingEvent.Type.CLAIM);
83
+    service.register(event);
84
+  }
85
+  
86
+
87
+  public void testRegisterEventInvalidCarrier() throws Exception {
88
+    final Date date = new Date();
89
+
90
+    final VoyageNumber voyageNumber = new VoyageNumber("AAA_BBB");
91
+    expect(voyageRepository.find(voyageNumber)).andReturn(null);
92
+
93
+    final TrackingId trackingId = new TrackingId("XYZ");
94
+    expect(cargoRepository.find(trackingId)).andReturn(new Cargo(trackingId, CHICAGO, STOCKHOLM));
95
+
96
+    expect(locationRepository.find(MELBOURNE.unLocode())).andReturn(MELBOURNE);
97
+    
98
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
99
+    
100
+    try {
101
+      final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, voyageNumber, MELBOURNE.unLocode(), HandlingEvent.Type.UNLOAD);
102
+      service.register(event);
103
+      fail("Should not be able to register an event with non-existing carrier movement");
104
+    } catch (UnknownVoyageException expected) {}
105
+  }
106
+  
107
+  public void testRegisterEventInvalidCargo() throws Exception {
108
+    final Date date = new Date();
109
+
110
+    final TrackingId trackingId = new TrackingId("XYZ");
111
+    expect(cargoRepository.find(trackingId)).andReturn(null);
112
+
113
+    expect(locationRepository.find(HONGKONG.unLocode())).andReturn(HONGKONG);
114
+    
115
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
116
+    
117
+    try {
118
+      final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, null, HONGKONG.unLocode(), HandlingEvent.Type.CLAIM);
119
+      service.register(event);
120
+      fail("Should not be able to register an event with non-existing cargo");
121
+    } catch (UnknownCargoException expected) {}
122
+  }
123
+  
124
+  public void testRegisterEventInvalidLocation() throws Exception {
125
+    final Date date = new Date();
126
+
127
+    final TrackingId trackingId = new TrackingId("XYZ");
128
+    expect(cargoRepository.find(trackingId)).andReturn(cargoXYZ);
129
+    UnLocode wayOff = new UnLocode("XXYYY");
130
+    expect(locationRepository.find(wayOff)).andReturn(null);
131
+    
132
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, domainEventNotifier);
133
+    
134
+    try {
135
+      final HandlingEvent event = handlingEventFactory.createHandlingEvent(date, trackingId, null, wayOff, HandlingEvent.Type.CLAIM);
136
+      service.register(event);
137
+      fail("Should not be able to register an event with non-existing Location");
138
+    } catch (UnknownLocationException expected) {}
139
+  }
140
+}

+ 68
- 0
dddsample/src/test/java/se/citerus/dddsample/application/TrackingScenarioTest.java Целия файл

@@ -0,0 +1,68 @@
1
+package se.citerus.dddsample.application;
2
+
3
+import junit.framework.TestCase;
4
+import se.citerus.dddsample.domain.model.cargo.Cargo;
5
+import se.citerus.dddsample.domain.model.cargo.CargoTestHelper;
6
+import se.citerus.dddsample.domain.model.cargo.Delivery;
7
+import se.citerus.dddsample.domain.model.cargo.TrackingId;
8
+import static se.citerus.dddsample.domain.model.carrier.SampleVoyages.CM001;
9
+import static se.citerus.dddsample.domain.model.carrier.SampleVoyages.CM002;
10
+import se.citerus.dddsample.domain.model.handling.HandlingEvent;
11
+import static se.citerus.dddsample.domain.model.handling.HandlingEvent.Type.LOAD;
12
+import static se.citerus.dddsample.domain.model.handling.HandlingEvent.Type.UNLOAD;
13
+import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
14
+
15
+import java.text.DateFormat;
16
+import java.text.ParseException;
17
+import java.text.SimpleDateFormat;
18
+import java.util.Arrays;
19
+import java.util.Date;
20
+import java.util.List;
21
+
22
+public class TrackingScenarioTest extends TestCase {
23
+
24
+  public void testTrackingScenarioStage1() throws Exception {
25
+
26
+    Cargo cargo = populateCargo();
27
+
28
+    Delivery delivery = cargo.delivery();
29
+
30
+    List<HandlingEvent> handlingEvents = delivery.history();
31
+
32
+    assertEquals(4, handlingEvents.size());
33
+    final HandlingEvent event = delivery.lastEvent();
34
+
35
+    assertEquals(UNLOAD, event.type());
36
+
37
+//    assertFalse(cargo.atFinalDestiation());
38
+//    assertEquals("CNHKG", cargo.currentLocation().unlocode());
39
+
40
+  }
41
+
42
+  private Cargo populateCargo() throws Exception {
43
+    final Cargo cargo = new Cargo(new TrackingId("XYZ"), STOCKHOLM, MELBOURNE);
44
+
45
+    final List<HandlingEvent> handlingEventList = Arrays.asList(
46
+      new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), LOAD, STOCKHOLM, CM001),
47
+      new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), UNLOAD, HAMBURG, CM001),
48
+      new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), LOAD, HAMBURG, CM002),
49
+      new HandlingEvent(cargo, getDate("2007-12-05"), new Date(), UNLOAD, HONGKONG, CM002)
50
+    );
51
+    CargoTestHelper.setDeliveryHistory(cargo, handlingEventList);
52
+
53
+    return cargo;
54
+  }
55
+
56
+  /**
57
+   * Parse an ISO 8601 (YYYY-MM-DD) String to Date
58
+   *
59
+   * @param isoFormat String to parse.
60
+   * @return Created date instance.
61
+   * @throws ParseException Thrown if parsing fails.
62
+   */
63
+  private Date getDate(String isoFormat) throws ParseException {
64
+    final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
65
+    return dateFormat.parse(isoFormat);
66
+  }
67
+
68
+}

+ 2
- 2
dddsample/src/test/java/se/citerus/dddsample/application/routing/ExternalRoutingServiceTest.java Целия файл

@@ -3,14 +3,14 @@ package se.citerus.dddsample.application.routing;
3 3
 import junit.framework.TestCase;
4 4
 import static org.easymock.EasyMock.*;
5 5
 import se.citerus.dddsample.DateTestUtil;
6
-import se.citerus.dddsample.application.persistence.LocationRepositoryInMem;
7
-import se.citerus.dddsample.application.persistence.VoyageRepositoryInMem;
8 6
 import se.citerus.dddsample.domain.model.cargo.Cargo;
9 7
 import se.citerus.dddsample.domain.model.cargo.Itinerary;
10 8
 import se.citerus.dddsample.domain.model.cargo.RouteSpecification;
11 9
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
12 10
 import static se.citerus.dddsample.domain.model.location.SampleLocations.HONGKONG;
13 11
 import static se.citerus.dddsample.domain.model.location.SampleLocations.STOCKHOLM;
12
+import se.citerus.dddsample.infrastructure.persistence.inmemory.LocationRepositoryInMem;
13
+import se.citerus.dddsample.infrastructure.persistence.inmemory.VoyageRepositoryInMem;
14 14
 import se.citerus.routingteam.GraphTraversalService;
15 15
 import se.citerus.routingteam.TransitEdge;
16 16
 import se.citerus.routingteam.TransitPath;

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/application/service/dto/assembler/ItineraryCandidateDTOAssemblerTest.java Целия файл

@@ -2,7 +2,6 @@ package se.citerus.dddsample.application.service.dto.assembler;
2 2
 
3 3
 import junit.framework.TestCase;
4 4
 import static org.easymock.EasyMock.*;
5
-import se.citerus.dddsample.application.persistence.VoyageRepositoryInMem;
6 5
 import se.citerus.dddsample.application.remoting.dto.ItineraryCandidateDTO;
7 6
 import se.citerus.dddsample.application.remoting.dto.LegDTO;
8 7
 import se.citerus.dddsample.application.remoting.dto.assembler.ItineraryCandidateDTOAssembler;
@@ -14,6 +13,7 @@ import se.citerus.dddsample.domain.model.location.Location;
14 13
 import se.citerus.dddsample.domain.model.location.LocationRepository;
15 14
 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
16 15
 import se.citerus.dddsample.domain.model.location.UnLocode;
16
+import se.citerus.dddsample.infrastructure.persistence.inmemory.VoyageRepositoryInMem;
17 17
 
18 18
 import java.util.ArrayList;
19 19
 import java.util.Arrays;

+ 2
- 5
dddsample/src/test/java/se/citerus/dddsample/domain/model/handling/HandlingEventFactoryTest.java Целия файл

@@ -2,8 +2,6 @@ package se.citerus.dddsample.domain.model.handling;
2 2
 
3 3
 import junit.framework.TestCase;
4 4
 import static org.easymock.EasyMock.*;
5
-import se.citerus.dddsample.application.persistence.LocationRepositoryInMem;
6
-import se.citerus.dddsample.application.persistence.VoyageRepositoryInMem;
7 5
 import se.citerus.dddsample.domain.model.cargo.Cargo;
8 6
 import se.citerus.dddsample.domain.model.cargo.CargoRepository;
9 7
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
@@ -15,9 +13,8 @@ import static se.citerus.dddsample.domain.model.handling.HandlingEvent.Type;
15 13
 import se.citerus.dddsample.domain.model.location.LocationRepository;
16 14
 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
17 15
 import se.citerus.dddsample.domain.model.location.UnLocode;
18
-import se.citerus.dddsample.domain.service.UnknownCargoException;
19
-import se.citerus.dddsample.domain.service.UnknownLocationException;
20
-import se.citerus.dddsample.domain.service.UnknownVoyageException;
16
+import se.citerus.dddsample.infrastructure.persistence.inmemory.LocationRepositoryInMem;
17
+import se.citerus.dddsample.infrastructure.persistence.inmemory.VoyageRepositoryInMem;
21 18
 
22 19
 import java.util.Date;
23 20
 

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/domain/service/RoutingServiceTest.java Целия файл

@@ -2,7 +2,6 @@ package se.citerus.dddsample.domain.service;
2 2
 
3 3
 import junit.framework.TestCase;
4 4
 import static org.easymock.EasyMock.*;
5
-import se.citerus.dddsample.application.persistence.LocationRepositoryInMem;
6 5
 import se.citerus.dddsample.application.routing.ExternalRoutingService;
7 6
 import se.citerus.dddsample.domain.model.cargo.*;
8 7
 import se.citerus.dddsample.domain.model.carrier.SampleVoyages;
@@ -11,6 +10,7 @@ import se.citerus.dddsample.domain.model.carrier.VoyageRepository;
11 10
 import se.citerus.dddsample.domain.model.location.Location;
12 11
 import se.citerus.dddsample.domain.model.location.LocationRepository;
13 12
 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
13
+import se.citerus.dddsample.infrastructure.persistence.inmemory.LocationRepositoryInMem;
14 14
 import se.citerus.routingteam.GraphTraversalService;
15 15
 import se.citerus.routingteam.internal.GraphDAO;
16 16
 import se.citerus.routingteam.internal.GraphTraversalServiceImpl;

dddsample/src/test/java/se/citerus/dddsample/application/persistence/AbstractRepositoryTest.java → dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/AbstractRepositoryTest.java Целия файл

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.persistence;
1
+package se.citerus.dddsample.infrastructure.persistence.hibernate;
2 2
 
3 3
 import org.hibernate.SessionFactory;
4 4
 import org.hibernate.classic.Session;

dddsample/src/test/java/se/citerus/dddsample/application/persistence/CargoRepositoryTest.java → dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/CargoRepositoryTest.java Целия файл

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.persistence;
1
+package se.citerus.dddsample.infrastructure.persistence.hibernate;
2 2
 
3 3
 import se.citerus.dddsample.application.util.SampleDataGenerator;
4 4
 import se.citerus.dddsample.domain.model.cargo.*;

dddsample/src/test/java/se/citerus/dddsample/application/persistence/CarrierMovementRepositoryTest.java → dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/CarrierMovementRepositoryTest.java Целия файл

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.persistence;
1
+package se.citerus.dddsample.infrastructure.persistence.hibernate;
2 2
 
3 3
 import se.citerus.dddsample.domain.model.carrier.Voyage;
4 4
 import se.citerus.dddsample.domain.model.carrier.VoyageNumber;

dddsample/src/test/java/se/citerus/dddsample/application/persistence/HandlingEventRepositoryTest.java → dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/HandlingEventRepositoryTest.java Целия файл

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.persistence;
1
+package se.citerus.dddsample.infrastructure.persistence.hibernate;
2 2
 
3 3
 import se.citerus.dddsample.domain.model.cargo.Cargo;
4 4
 import se.citerus.dddsample.domain.model.cargo.CargoRepository;

dddsample/src/test/java/se/citerus/dddsample/application/persistence/LocationRepositoryTest.java → dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/LocationRepositoryTest.java Целия файл

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.persistence;
1
+package se.citerus.dddsample.infrastructure.persistence.hibernate;
2 2
 
3 3
 import se.citerus.dddsample.domain.model.location.Location;
4 4
 import se.citerus.dddsample.domain.model.location.LocationRepository;

dddsample/src/test/java/se/citerus/dddsample/application/persistence/CargoRepositoryInMem.java → dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/CargoRepositoryInMem.java Целия файл

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.persistence;
1
+package se.citerus.dddsample.infrastructure.persistence.inmemory;
2 2
 
3 3
 import org.springframework.dao.DataRetrievalFailureException;
4 4
 import se.citerus.dddsample.domain.model.cargo.Cargo;

dddsample/src/test/java/se/citerus/dddsample/application/persistence/HandlingEventRepositoryInMem.java → dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/HandlingEventRepositoryInMem.java Целия файл

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.persistence;
1
+package se.citerus.dddsample.infrastructure.persistence.inmemory;
2 2
 
3 3
 import org.apache.commons.logging.Log;
4 4
 import org.apache.commons.logging.LogFactory;

dddsample/src/test/java/se/citerus/dddsample/application/persistence/LocationRepositoryInMem.java → dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/LocationRepositoryInMem.java Целия файл

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.persistence;
1
+package se.citerus.dddsample.infrastructure.persistence.inmemory;
2 2
 
3 3
 import se.citerus.dddsample.domain.model.location.Location;
4 4
 import se.citerus.dddsample.domain.model.location.LocationRepository;

dddsample/src/test/java/se/citerus/dddsample/application/persistence/VoyageRepositoryInMem.java → dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/VoyageRepositoryInMem.java Целия файл

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.persistence;
1
+package se.citerus.dddsample.infrastructure.persistence.inmemory;
2 2
 
3 3
 import se.citerus.dddsample.domain.model.carrier.SampleVoyages;
4 4
 import se.citerus.dddsample.domain.model.carrier.Voyage;

+ 2
- 2
dddsample/src/test/java/se/citerus/dddsample/ui/CargoTrackingControllerTest.java Целия файл

@@ -11,9 +11,9 @@ import org.springframework.validation.BindingResult;
11 11
 import org.springframework.validation.Errors;
12 12
 import org.springframework.validation.FieldError;
13 13
 import org.springframework.web.servlet.ModelAndView;
14
-import se.citerus.dddsample.application.persistence.CargoRepositoryInMem;
15
-import se.citerus.dddsample.application.persistence.HandlingEventRepositoryInMem;
16 14
 import se.citerus.dddsample.domain.model.cargo.CargoRepository;
15
+import se.citerus.dddsample.infrastructure.persistence.inmemory.CargoRepositoryInMem;
16
+import se.citerus.dddsample.infrastructure.persistence.inmemory.HandlingEventRepositoryInMem;
17 17
 import se.citerus.dddsample.ui.command.TrackCommand;
18 18
 
19 19
 public class CargoTrackingControllerTest extends TestCase {