Kaynağa Gözat

Changed persistence layer to point to the InMem repositories

Added test-context-persistence.xml to still be able to test hibernate repositories
Added HandlingEventService (first lab version...)
Added HandlingEvent- and Carrier-Repository.
Modified some equality operators to fit better with HandlingEventRepository (Maybe unneccessary after all, but it's working...)
jorgen_falk 18 yıl önce
ebeveyn
işleme
7ec3437e26
21 değiştirilmiş dosya ile 622 ekleme ve 64 silme
  1. 29
    0
      dddsample/src/main/java/se/citerus/dddsample/domain/Cargo.java
  2. 26
    1
      dddsample/src/main/java/se/citerus/dddsample/domain/HandlingEvent.java
  3. 1
    1
      dddsample/src/main/java/se/citerus/dddsample/domain/Location.java
  4. 1
    0
      dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepository.java
  5. 4
    0
      dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryHibernate.java
  6. 18
    58
      dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryInMem.java
  7. 9
    0
      dddsample/src/main/java/se/citerus/dddsample/repository/CarrierRepository.java
  8. 36
    0
      dddsample/src/main/java/se/citerus/dddsample/repository/CarrierRepositoryInMem.java
  9. 12
    0
      dddsample/src/main/java/se/citerus/dddsample/repository/HandlingEventRepository.java
  10. 142
    0
      dddsample/src/main/java/se/citerus/dddsample/repository/HandlingEventRepositoryInMem.java
  11. 20
    0
      dddsample/src/main/java/se/citerus/dddsample/service/HandlingEventService.java
  12. 74
    0
      dddsample/src/main/java/se/citerus/dddsample/service/HandlingEventServiceImpl.java
  13. 12
    2
      dddsample/src/main/resources/context-persistence.xml
  14. 5
    0
      dddsample/src/main/resources/context-service.xml
  15. 8
    0
      dddsample/src/main/webapp/style.css
  16. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/domain/CargoRepositoryTest.java
  17. 11
    0
      dddsample/src/test/java/se/citerus/dddsample/domain/CargoTest.java
  18. 57
    0
      dddsample/src/test/java/se/citerus/dddsample/domain/HandlingEventTest.java
  19. 102
    0
      dddsample/src/test/java/se/citerus/dddsample/service/HandlingEventServiceTest.java
  20. 6
    1
      dddsample/src/test/resources/mock-context-persistence.xml
  21. 48
    0
      dddsample/src/test/resources/test-context-persistence.xml

+ 29
- 0
dddsample/src/main/java/se/citerus/dddsample/domain/Cargo.java Dosyayı Görüntüle

1
 package se.citerus.dddsample.domain;
1
 package se.citerus.dddsample.domain;
2
 
2
 
3
+import org.apache.commons.lang.builder.EqualsBuilder;
4
+import org.apache.commons.lang.builder.HashCodeBuilder;
3
 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
5
 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
4
 import org.apache.commons.lang.builder.ToStringStyle;
6
 import org.apache.commons.lang.builder.ToStringStyle;
5
 
7
 
88
   public String toString() {
90
   public String toString() {
89
     return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
91
     return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
90
   }
92
   }
93
+
94
+  @Override
95
+  public boolean equals(Object obj) {
96
+    if (obj instanceof Cargo == false) {
97
+      return false;
98
+    }
99
+    if (this == obj) {
100
+      return true;
101
+    }
102
+    Cargo rhs = (Cargo) obj;
103
+    return new EqualsBuilder()
104
+      .append(trackingId, rhs.trackingId)
105
+      .append(origin, rhs.origin)
106
+      .append(finalDestination, rhs.finalDestination)
107
+      .isEquals();
108
+  }
109
+
110
+  @Override
111
+  public int hashCode() {
112
+    return new HashCodeBuilder(7, 39)
113
+    .append(trackingId)
114
+    .append(origin)
115
+    .append(finalDestination)
116
+    .toHashCode();
117
+  }
118
+  
119
+  
91
 }
120
 }

+ 26
- 1
dddsample/src/main/java/se/citerus/dddsample/domain/HandlingEvent.java Dosyayı Görüntüle

5
 
5
 
6
 import javax.persistence.*;
6
 import javax.persistence.*;
7
 import java.util.Date;
7
 import java.util.Date;
8
+import java.util.HashSet;
9
+import java.util.Set;
8
 
10
 
9
 /**
11
 /**
10
  * HandlingEvent links the type of handling with a CarrierMovement.
12
  * HandlingEvent links the type of handling with a CarrierMovement.
32
   @Column(name = "time")
34
   @Column(name = "time")
33
   private Date time;
35
   private Date time;
34
 
36
 
37
+  @Transient /*TODO: Change to many-to-many if we decide on that approach*/
38
+  private Set<Cargo> cargos;
39
+  
35
   public enum Type {
40
   public enum Type {
36
     LOAD, UNLOAD, RECEIVE, CLAIM
41
     LOAD, UNLOAD, RECEIVE, CLAIM
37
   }
42
   }
46
     this.time = time;
51
     this.time = time;
47
     this.type = type;
52
     this.type = type;
48
     this.carrierMovement = carrierMovement;
53
     this.carrierMovement = carrierMovement;
54
+    this.cargos = new HashSet<Cargo>();
49
   }
55
   }
50
 
56
 
51
   public Type getType() {
57
   public Type getType() {
92
     
98
     
93
     return location;
99
     return location;
94
   }
100
   }
101
+
102
+
103
+  /**
104
+   * Register a set of Cargos
105
+   * 
106
+   * @param cargos
107
+   */
108
+  public void register(Set<Cargo> cargosToRegister) {
109
+    this.cargos.addAll(cargosToRegister);
110
+  }
111
+  
112
+  public Set<Cargo> getRegisterdCargos(){
113
+    return cargos;
114
+  }
95
   
115
   
96
   
116
   
97
   @Override
117
   @Override
101
 
121
 
102
   @Override
122
   @Override
103
   public int hashCode() {
123
   public int hashCode() {
104
-    return HashCodeBuilder.reflectionHashCode(this, excludedFields);
124
+    return HashCodeBuilder.reflectionHashCode(this);
105
   }
125
   }
106
 
126
 
107
   public int compareTo(HandlingEvent o) {
127
   public int compareTo(HandlingEvent o) {
108
     return time.compareTo(o.getTime());
128
     return time.compareTo(o.getTime());
109
   }
129
   }
130
+
131
+  public static Type parseType(String type) {
132
+    return Type.valueOf(type);
133
+  }
134
+
110
 }
135
 }

+ 1
- 1
dddsample/src/main/java/se/citerus/dddsample/domain/Location.java Dosyayı Görüntüle

14
   /**
14
   /**
15
    * The NULL Location object
15
    * The NULL Location object
16
    */
16
    */
17
-  public static final Location NULL = new Location(Location.class.getName() + ".NULL");
17
+  public static final Location NULL = new Location("Unknown");
18
 
18
 
19
   @Id
19
   @Id
20
   private Long id;
20
   private Long id;

+ 1
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepository.java Dosyayı Görüntüle

5
 
5
 
6
 public interface CargoRepository {
6
 public interface CargoRepository {
7
   Cargo find(TrackingId trackingId);
7
   Cargo find(TrackingId trackingId);
8
+  void save(Cargo cargo);
8
 }
9
 }

+ 4
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryHibernate.java Dosyayı Görüntüle

18
     return (Cargo) sessionFactory.getCurrentSession().
18
     return (Cargo) sessionFactory.getCurrentSession().
19
             get(Cargo.class, trackingId);
19
             get(Cargo.class, trackingId);
20
   }
20
   }
21
+
22
+  public void save(Cargo cargo) {
23
+    sessionFactory.getCurrentSession().saveOrUpdate(cargo);
24
+  }
21
 }
25
 }

+ 18
- 58
dddsample/src/main/java/se/citerus/dddsample/repository/CargoRepositoryInMem.java Dosyayı Görüntüle

1
 package se.citerus.dddsample.repository;
1
 package se.citerus.dddsample.repository;
2
 
2
 
3
-import java.text.DateFormat;
4
-import java.text.ParseException;
5
-import java.text.SimpleDateFormat;
6
-import java.util.Date;
7
 import java.util.HashMap;
3
 import java.util.HashMap;
8
 import java.util.Map;
4
 import java.util.Map;
9
 
5
 
10
 import org.springframework.dao.DataRetrievalFailureException;
6
 import org.springframework.dao.DataRetrievalFailureException;
11
 
7
 
12
 import se.citerus.dddsample.domain.Cargo;
8
 import se.citerus.dddsample.domain.Cargo;
13
-import se.citerus.dddsample.domain.CarrierMovement;
14
 import se.citerus.dddsample.domain.HandlingEvent;
9
 import se.citerus.dddsample.domain.HandlingEvent;
15
 import se.citerus.dddsample.domain.Location;
10
 import se.citerus.dddsample.domain.Location;
16
 import se.citerus.dddsample.domain.TrackingId;
11
 import se.citerus.dddsample.domain.TrackingId;
27
  */
22
  */
28
 public class CargoRepositoryInMem implements CargoRepository {
23
 public class CargoRepositoryInMem implements CargoRepository {
29
   private Map<String, Cargo> cargoDb;
24
   private Map<String, Cargo> cargoDb;
25
+  private HandlingEventRepository handlingEventRepository;
30
 
26
 
31
   public CargoRepositoryInMem() throws Exception {
27
   public CargoRepositoryInMem() throws Exception {
32
     cargoDb = new HashMap<String, Cargo>();
28
     cargoDb = new HashMap<String, Cargo>();
33
-    setup();
34
   }
29
   }
35
 
30
 
36
   public Cargo find(TrackingId trackingId) {
31
   public Cargo find(TrackingId trackingId) {
40
     
35
     
41
     return cargoDb.get(trackingId.getId());
36
     return cargoDb.get(trackingId.getId());
42
   }
37
   }
38
+  
39
+  public void save(Cargo cargo) {
40
+    //No need to save anything with InMem
41
+  }
43
 
42
 
44
-  private void setup() throws Exception {
43
+  /**
44
+   * 
45
+   * @throws Exception
46
+   */
47
+  public void init() throws Exception {
45
     String trackIdXYZ = "XYZ";
48
     String trackIdXYZ = "XYZ";
46
     final Cargo cargoXYZ = new Cargo(new TrackingId(trackIdXYZ), new Location("SESTO"), new Location("AUMEL"));
49
     final Cargo cargoXYZ = new Cargo(new TrackingId(trackIdXYZ), new Location("SESTO"), new Location("AUMEL"));
47
-    
48
-    cargoXYZ.handle(new HandlingEvent(getDate("2007-11-30"), HandlingEvent.Type.RECEIVE, null));
49
-
50
-    final CarrierMovement stockholmToHamburg = new CarrierMovement(new Location("SESTO"), new Location("DEHAM"));
51
-
52
-    cargoXYZ.handle(new HandlingEvent(getDate("2007-12-01"), HandlingEvent.Type.LOAD, stockholmToHamburg));
53
-    cargoXYZ.handle(new HandlingEvent(getDate("2007-12-02"), HandlingEvent.Type.UNLOAD, stockholmToHamburg));
54
-
55
-    final CarrierMovement hamburgToHongKong = new CarrierMovement(new Location("DEHAM"), new Location("CNHKG"));
56
-
57
-    cargoXYZ.handle(new HandlingEvent(getDate("2007-12-03"), HandlingEvent.Type.LOAD, hamburgToHongKong));
58
-    cargoXYZ.handle(new HandlingEvent(getDate("2007-12-05"), HandlingEvent.Type.UNLOAD, hamburgToHongKong));
59
-
60
     cargoDb.put(trackIdXYZ, cargoXYZ);
50
     cargoDb.put(trackIdXYZ, cargoXYZ);
61
     
51
     
62
-    
63
     String trackIdZYX = "ZYX";
52
     String trackIdZYX = "ZYX";
64
     final Cargo cargoZYX = new Cargo(new TrackingId(trackIdZYX), new Location("AUMEL"), new Location("SESTO"));
53
     final Cargo cargoZYX = new Cargo(new TrackingId(trackIdZYX), new Location("AUMEL"), new Location("SESTO"));
65
-    
66
-    cargoZYX.handle(new HandlingEvent(getDate("2007-12-09"), HandlingEvent.Type.RECEIVE, null));
67
-    
68
-    final CarrierMovement melbourneToTokyo = new CarrierMovement(new Location("AUMEL"), new Location("JPTOK"));
69
-
70
-    cargoZYX.handle(new HandlingEvent(getDate("2007-12-10"), HandlingEvent.Type.LOAD, melbourneToTokyo));
71
-    cargoZYX.handle(new HandlingEvent(getDate("2007-12-12"), HandlingEvent.Type.UNLOAD, melbourneToTokyo));
72
-
73
-    final CarrierMovement tokyoToLosAngeles = new CarrierMovement(new Location("JPTOK"), new Location("USLA"));
74
-
75
-    cargoZYX.handle(new HandlingEvent(getDate("2007-12-13"), HandlingEvent.Type.LOAD, tokyoToLosAngeles));
76
-
77
     cargoDb.put(trackIdZYX, cargoZYX);
54
     cargoDb.put(trackIdZYX, cargoZYX);
78
     
55
     
79
     String trackIdABC = "ABC";
56
     String trackIdABC = "ABC";
80
     final Cargo cargoABC = new Cargo(new TrackingId(trackIdABC), new Location("SESTO"), new Location("FIHEL"));
57
     final Cargo cargoABC = new Cargo(new TrackingId(trackIdABC), new Location("SESTO"), new Location("FIHEL"));
81
-    
82
-    cargoABC.handle(new HandlingEvent(getDate("2008-01-01"), HandlingEvent.Type.RECEIVE, null));
83
-
84
-    final CarrierMovement stockholmToHelsinki = new CarrierMovement(new Location("SESTO"), new Location("FIHEL"));
85
-
86
-    cargoABC.handle(new HandlingEvent(getDate("2008-01-02"), HandlingEvent.Type.LOAD, stockholmToHelsinki));
87
-    cargoABC.handle(new HandlingEvent(getDate("2008-01-03"), HandlingEvent.Type.UNLOAD, stockholmToHelsinki));
88
-    cargoABC.handle(new HandlingEvent(getDate("2008-01-05"), HandlingEvent.Type.CLAIM, null));
89
-    
90
     cargoDb.put(trackIdABC, cargoABC);
58
     cargoDb.put(trackIdABC, cargoABC);
91
     
59
     
92
     String trackIdCBA = "CBA";
60
     String trackIdCBA = "CBA";
93
     final Cargo cargoCBA = new Cargo(new TrackingId(trackIdCBA), new Location("FIHEL"), new Location("SESTO"));
61
     final Cargo cargoCBA = new Cargo(new TrackingId(trackIdCBA), new Location("FIHEL"), new Location("SESTO"));
94
-    
95
-    cargoCBA.handle(new HandlingEvent(getDate("2008-01-10"), HandlingEvent.Type.RECEIVE, null));
96
-
97
-    
98
     cargoDb.put(trackIdCBA, cargoCBA);
62
     cargoDb.put(trackIdCBA, cargoCBA);
63
+    
64
+    for (Cargo cargo : cargoDb.values()) {
65
+      for (HandlingEvent event : handlingEventRepository.findByTrackingId(cargo.trackingId())) {
66
+        cargo.handle(event);
67
+      }   
68
+    }
99
   }
69
   }
100
 
70
 
101
-  /**
102
-   * Parse an ISO 8601 (YYYY-MM-DD) String to Date
103
-   * 
104
-   * @param isoFormat
105
-   *            String to parse.
106
-   * @return Created date instance.
107
-   * @throws ParseException
108
-   *             Thrown if parsing fails.
109
-   */
110
-  private Date getDate(String isoFormat) throws ParseException {
111
-    final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
112
-    return dateFormat.parse(isoFormat);
71
+  public void setHandlingEventRepository(HandlingEventRepository handlingEventRepository) {
72
+    this.handlingEventRepository = handlingEventRepository;
113
   }
73
   }
114
 }
74
 }

+ 9
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/CarrierRepository.java Dosyayı Görüntüle

1
+package se.citerus.dddsample.repository;
2
+
3
+import se.citerus.dddsample.domain.CarrierMovement;
4
+
5
+public interface CarrierRepository {
6
+
7
+  CarrierMovement find(String carrierId);
8
+
9
+}

+ 36
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/CarrierRepositoryInMem.java Dosyayı Görüntüle

1
+package se.citerus.dddsample.repository;
2
+
3
+import java.util.HashMap;
4
+
5
+import se.citerus.dddsample.domain.CarrierMovement;
6
+import se.citerus.dddsample.domain.Location;
7
+
8
+public class CarrierRepositoryInMem implements CarrierRepository {
9
+  private HashMap<String, CarrierMovement> carriers;
10
+
11
+  public CarrierRepositoryInMem() {
12
+    carriers = new HashMap<String, CarrierMovement>();
13
+    setup();
14
+  }
15
+
16
+  private void setup() {
17
+    final CarrierMovement stockholmToHamburg = new CarrierMovement(new Location("SESTO"), new Location("DEHAM"));
18
+    final CarrierMovement hamburgToHongKong = new CarrierMovement(new Location("DEHAM"), new Location("CNHKG"));
19
+    final CarrierMovement melbourneToTokyo = new CarrierMovement(new Location("AUMEL"), new Location("JPTOK"));
20
+    final CarrierMovement tokyoToLosAngeles = new CarrierMovement(new Location("JPTOK"), new Location("USLA"));
21
+    final CarrierMovement stockholmToHelsinki = new CarrierMovement(new Location("SESTO"), new Location("FIHEL"));
22
+    
23
+    carriers.put("SESTO_DEHAM", stockholmToHamburg);
24
+    carriers.put("DEHAM_CNHKG", hamburgToHongKong);
25
+    carriers.put("AUMEL_JPTOK", melbourneToTokyo);
26
+    carriers.put("JPTOK_USLA", tokyoToLosAngeles);
27
+    carriers.put("SESTO_FIHEL", stockholmToHelsinki);
28
+  }
29
+
30
+  public CarrierMovement find(String carrierId) {
31
+    return carriers.get(carrierId);
32
+  }
33
+  
34
+  
35
+
36
+}

+ 12
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/HandlingEventRepository.java Dosyayı Görüntüle

1
+package se.citerus.dddsample.repository;
2
+
3
+import java.util.Set;
4
+
5
+import se.citerus.dddsample.domain.HandlingEvent;
6
+import se.citerus.dddsample.domain.TrackingId;
7
+
8
+public interface HandlingEventRepository {
9
+  HandlingEvent find(String handlingEventId);
10
+  void save(HandlingEvent event);
11
+  Set<HandlingEvent> findByTrackingId(final TrackingId trackingId);
12
+}

+ 142
- 0
dddsample/src/main/java/se/citerus/dddsample/repository/HandlingEventRepositoryInMem.java Dosyayı Görüntüle

1
+package se.citerus.dddsample.repository;
2
+
3
+import java.text.DateFormat;
4
+import java.text.ParseException;
5
+import java.text.SimpleDateFormat;
6
+import java.util.Date;
7
+import java.util.HashMap;
8
+import java.util.HashSet;
9
+import java.util.Set;
10
+
11
+import org.apache.commons.logging.Log;
12
+import org.apache.commons.logging.LogFactory;
13
+
14
+import se.citerus.dddsample.domain.Cargo;
15
+import se.citerus.dddsample.domain.CarrierMovement;
16
+import se.citerus.dddsample.domain.HandlingEvent;
17
+import se.citerus.dddsample.domain.Location;
18
+import se.citerus.dddsample.domain.TrackingId;
19
+import se.citerus.dddsample.domain.HandlingEvent.Type;
20
+
21
+public class HandlingEventRepositoryInMem implements HandlingEventRepository{
22
+  private HashMap<String, HandlingEvent> eventDB;
23
+  private CarrierRepository carrierRepository;
24
+  
25
+  private final Log logger = LogFactory.getLog(getClass());
26
+
27
+  public HandlingEventRepositoryInMem() throws ParseException {
28
+    eventDB = new HashMap<String, HandlingEvent>();
29
+  }
30
+
31
+  /**
32
+   * Initilaze the in mem repository.
33
+   * 
34
+   * SpringIoC will call this init-method after the bean has bean created and properties has been set.
35
+   * 
36
+   * @throws ParseException
37
+   */
38
+  public void init() throws ParseException {
39
+    
40
+    // CargoXYZ
41
+    final Cargo cargoXYZ = new Cargo(new TrackingId("XYZ"), new Location("SESTO"), new Location("AUMEL"));
42
+    registerEvent(cargoXYZ, "2007-11-30", HandlingEvent.Type.RECEIVE, null);
43
+
44
+    final CarrierMovement stockholmToHamburg = carrierRepository.find("SESTO_DEHAM");
45
+    registerEvent(cargoXYZ, "2007-12-01", HandlingEvent.Type.LOAD, stockholmToHamburg);
46
+    registerEvent(cargoXYZ, "2007-12-02", HandlingEvent.Type.UNLOAD, stockholmToHamburg);
47
+    
48
+    final CarrierMovement hamburgToHongKong = carrierRepository.find("DEHAM_CNHKG");
49
+    registerEvent(cargoXYZ, "2007-12-03", HandlingEvent.Type.LOAD, hamburgToHongKong);
50
+    registerEvent(cargoXYZ, "2007-12-05", HandlingEvent.Type.UNLOAD, hamburgToHongKong);
51
+    
52
+    //CargoZYX
53
+    final Cargo cargoZYX = new Cargo(new TrackingId("ZYX"), new Location("AUMEL"), new Location("SESTO"));
54
+    registerEvent(cargoZYX, "2007-12-09", HandlingEvent.Type.RECEIVE, null);
55
+    
56
+    final CarrierMovement melbourneToTokyo = carrierRepository.find("AUMEL_JPTOK");
57
+    registerEvent(cargoZYX, "2007-12-10", HandlingEvent.Type.LOAD, melbourneToTokyo);
58
+    registerEvent(cargoZYX, "2007-12-12", HandlingEvent.Type.UNLOAD, melbourneToTokyo);
59
+    
60
+    final CarrierMovement tokyoToLosAngeles = carrierRepository.find("JPTOK_USLA");
61
+    registerEvent(cargoZYX, "2007-12-13", HandlingEvent.Type.LOAD, tokyoToLosAngeles);
62
+ 
63
+    //CargoABC
64
+    final Cargo cargoABC = new Cargo(new TrackingId("ABC"), new Location("SESTO"), new Location("FIHEL"));
65
+    registerEvent(cargoABC, "2008-01-01", HandlingEvent.Type.RECEIVE, null);
66
+    
67
+    final CarrierMovement stockholmToHelsinki = new CarrierMovement(new Location("SESTO"), new Location("FIHEL"));
68
+    registerEvent(cargoABC, "2008-01-02", HandlingEvent.Type.LOAD, stockholmToHelsinki);
69
+    registerEvent(cargoABC, "2008-01-03", HandlingEvent.Type.UNLOAD, stockholmToHelsinki);
70
+    registerEvent(cargoABC, "2008-01-05", HandlingEvent.Type.CLAIM, null);
71
+
72
+    //CargoCBA
73
+    final Cargo cargoCBA = new Cargo(new TrackingId("CBA"), new Location("FIHEL"), new Location("SESTO"));
74
+    registerEvent(cargoCBA, "2008-01-10", HandlingEvent.Type.RECEIVE, null);
75
+  }
76
+
77
+  
78
+  private void registerEvent(Cargo cargo, String date, Type type, CarrierMovement carrierMovement) throws ParseException{
79
+    HandlingEvent ev= new HandlingEvent(getDate(date), type, carrierMovement);
80
+    ev.register(toSet(cargo));
81
+    String id = cargo.trackingId() + "_" + type + "_" + date;
82
+    
83
+    logger.debug("Adding event " + id + "(" + ev + ")");
84
+    eventDB.put(id, ev);
85
+  }
86
+  
87
+  
88
+  private Set<Cargo> toSet(Cargo... cargoArgs) {
89
+    Set<Cargo> cargos = new HashSet<Cargo>();
90
+    for (Cargo cargo : cargoArgs) {
91
+      cargos.add(cargo);
92
+    }
93
+    
94
+    return cargos;
95
+  }
96
+
97
+  /**
98
+   * Parse an ISO 8601 (YYYY-MM-DD) String to Date
99
+   * 
100
+   * @param isoFormat
101
+   *            String to parse.
102
+   * @return Created date instance.
103
+   * @throws ParseException
104
+   *             Thrown if parsing fails.
105
+   */
106
+  private Date getDate(String isoFormat) throws ParseException {
107
+    final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
108
+    return dateFormat.parse(isoFormat);
109
+  }
110
+  
111
+  public HandlingEvent find(String handlingEventId){
112
+    return eventDB.get(handlingEventId);
113
+  }
114
+
115
+  public void save(HandlingEvent event) {
116
+    // Mimmick saving to database
117
+    for (Cargo cargo : event.getRegisterdCargos()) {
118
+      cargo.handle(event);
119
+    }
120
+  }
121
+
122
+  @SuppressWarnings("unchecked")
123
+  public Set<HandlingEvent> findByTrackingId(final TrackingId trackingId) {
124
+    Set<HandlingEvent> events = new HashSet<HandlingEvent>();
125
+    for (HandlingEvent event : eventDB.values()) {
126
+      for (Cargo cargo : event.getRegisterdCargos()) {
127
+        if (cargo.trackingId().equals(trackingId)) {
128
+          events.add(event);
129
+          break;
130
+        }
131
+      }   
132
+    }
133
+    
134
+    logger.debug("findByTrackingId " + trackingId + " finds " + events);
135
+    
136
+    return events;
137
+  }
138
+
139
+  public void setCarrierRepository(CarrierRepository carrierRepository) {
140
+    this.carrierRepository = carrierRepository;
141
+  }
142
+}

+ 20
- 0
dddsample/src/main/java/se/citerus/dddsample/service/HandlingEventService.java Dosyayı Görüntüle

1
+package se.citerus.dddsample.service;
2
+
3
+import java.util.Date;
4
+
5
+
6
+public interface HandlingEventService {
7
+
8
+  /**
9
+   * Regster an event with the EventHandling service
10
+   * 
11
+   * TODO: Fix javadoc when we know more about the relation between Cargo and HandlingEvent...
12
+   * 
13
+   * @param date
14
+   * @param type
15
+   * @param carrierId
16
+   * @param trackIds
17
+   */
18
+  public abstract void register(Date date, String type, String carrierId, String[] trackIds);
19
+
20
+}

+ 74
- 0
dddsample/src/main/java/se/citerus/dddsample/service/HandlingEventServiceImpl.java Dosyayı Görüntüle

1
+package se.citerus.dddsample.service;
2
+
3
+import java.util.Date;
4
+import java.util.HashSet;
5
+import java.util.Set;
6
+
7
+import org.apache.commons.lang.Validate;
8
+
9
+import se.citerus.dddsample.domain.Cargo;
10
+import se.citerus.dddsample.domain.CarrierMovement;
11
+import se.citerus.dddsample.domain.HandlingEvent;
12
+import se.citerus.dddsample.domain.TrackingId;
13
+import se.citerus.dddsample.repository.CargoRepository;
14
+import se.citerus.dddsample.repository.CarrierRepository;
15
+import se.citerus.dddsample.repository.HandlingEventRepository;
16
+
17
+public class HandlingEventServiceImpl implements HandlingEventService {
18
+  private CargoRepository cargoRepository;
19
+  private CarrierRepository carrierRepository;
20
+  private HandlingEventRepository handlingEventRepository;
21
+
22
+
23
+  public void register(Date date, String type, String carrierId, String[] trackingIds) {
24
+    HandlingEvent event = new HandlingEvent(date, HandlingEvent.parseType(type), findCarrier(carrierId));
25
+    Set<Cargo> cargos = findCargos(trackingIds);
26
+    event.register(cargos);
27
+    
28
+    handlingEventRepository.save(event);
29
+  }
30
+
31
+
32
+  private Set<Cargo> findCargos(String[] trackingIds) {
33
+    Set<Cargo> cargos = new HashSet<Cargo>();
34
+    
35
+    for (String trackingId : trackingIds) {
36
+      cargos.add(findCargo(trackingId));
37
+    }
38
+    
39
+    return cargos;
40
+  }
41
+
42
+
43
+  private Cargo findCargo(String trackingId) {
44
+    Cargo cargo = cargoRepository.find(new TrackingId(trackingId));
45
+    Validate.notNull(cargo, "Cargo is not found. Tracking ID=" + trackingId);
46
+    
47
+    return cargo;
48
+  }
49
+
50
+  private CarrierMovement findCarrier(String carrierId) {
51
+    if (carrierId == null){
52
+      return null;
53
+    }
54
+    CarrierMovement carrier = carrierRepository.find(carrierId);
55
+    Validate.notNull(carrier, "Carrier is not found: Carrier ID=" + carrierId);
56
+    
57
+    return carrier;
58
+  }
59
+
60
+  public void setCargoRepository(CargoRepository cargoRepository) {
61
+    this.cargoRepository = cargoRepository;
62
+  }
63
+
64
+  public void setCarrierRepository(CarrierRepository carrierRepository) {
65
+    this.carrierRepository = carrierRepository;
66
+  }
67
+
68
+  public void setHandlingEventRepository(HandlingEventRepository handlingEventRepository) {
69
+    this.handlingEventRepository = handlingEventRepository;
70
+  }
71
+
72
+
73
+
74
+}

+ 12
- 2
dddsample/src/main/resources/context-persistence.xml Dosyayı Görüntüle

39
     <property name="sessionFactory" ref="sessionFactory"/>
39
     <property name="sessionFactory" ref="sessionFactory"/>
40
   </bean>
40
   </bean>
41
 
41
 
42
-  <bean id="cargoRepository" class="se.citerus.dddsample.repository.CargoRepositoryHibernate">
43
-    <property name="sessionFactory" ref="sessionFactory"/>
42
+  <bean id="cargoRepository" class="se.citerus.dddsample.repository.CargoRepositoryInMem" init-method="init">
43
+    <property name="handlingEventRepository" ref="handlingEventRepository"/>
44
+  </bean>
45
+  
46
+  <bean id="handlingEventRepository" class="se.citerus.dddsample.repository.HandlingEventRepositoryInMem" init-method="init">
47
+    <property name="carrierRepository" ref="carrierRepository"/>
44
   </bean>
48
   </bean>
49
+  
50
+  <bean id="carrierRepository" class="se.citerus.dddsample.repository.CarrierRepositoryInMem" />
51
+  
52
+  <!--bean id="cargoRepository" class="se.citerus.dddsample.repository.CargoRepositoryHibernate">
53
+    <property name="sessionFactory" ref="sessionFactory"/>
54
+  </bean-->
45
 
55
 
46
 </beans>
56
 </beans>

+ 5
- 0
dddsample/src/main/resources/context-service.xml Dosyayı Görüntüle

13
     <property name="cargoRepository" ref="cargoRepository"/>
13
     <property name="cargoRepository" ref="cargoRepository"/>
14
   </bean>
14
   </bean>
15
 
15
 
16
+  <bean id="handlingEventService" class="se.citerus.dddsample.service.HandlingEventServiceImpl">
17
+    <property name="cargoRepository" ref="cargoRepository"/>
18
+    <property name="handlingEventRepository" ref="handlingEventRepository"/>
19
+    <property name="carrierRepository" ref="carrierRepository"/>
20
+  </bean>
16
 </beans>
21
 </beans>

+ 8
- 0
dddsample/src/main/webapp/style.css Dosyayı Görüntüle

187
 /**************************************************************
187
 /**************************************************************
188
    Custom div and span
188
    Custom div and span
189
  **************************************************************/
189
  **************************************************************/
190
+#apptitle h1{
191
+  font-size: 1.6em;
192
+  margin-left: 200px;
193
+  margin-bottom: 10px;
194
+  border-bottom: 0px
195
+  
196
+}
197
+
190
 #container {
198
 #container {
191
   text-align: left;
199
   text-align: left;
192
   width: 500px;
200
   width: 500px;

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/domain/CargoRepositoryTest.java Dosyayı Görüntüle

12
   }
12
   }
13
 
13
 
14
   protected String[] getConfigLocations() {
14
   protected String[] getConfigLocations() {
15
-    return new String[]{"context-persistence.xml"};
15
+    return new String[]{"test-context-persistence.xml"};
16
   }
16
   }
17
 
17
 
18
   protected void onSetUpInTransaction() throws Exception {
18
   protected void onSetUpInTransaction() throws Exception {

+ 11
- 0
dddsample/src/test/java/se/citerus/dddsample/domain/CargoTest.java Dosyayı Görüntüle

52
 
52
 
53
     assertFalse(cargo.atFinalDestiation());
53
     assertFalse(cargo.atFinalDestiation());
54
   }
54
   }
55
+  
56
+  public void testEquality() throws Exception {
57
+    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"));
59
+    Cargo c3 = new Cargo(new TrackingId("ABC"), new Location("A"), new Location("X"));
60
+    Cargo c4 = new Cargo(new TrackingId("ABC"), new Location("A"), new Location("C"));
61
+
62
+    assertTrue("TrackingID, origin and finalDestnation should be equal if Cargos are considered equal", c1.equals(c4));
63
+    assertFalse("Cargos are not equal when TrackingID differ", c1.equals(c2));
64
+    assertFalse("Cargos are not equal when Locations differ", c2.equals(c3));
65
+  }
55
 
66
 
56
   // TODO: Generate test data some better way
67
   // TODO: Generate test data some better way
57
   private Cargo populateCargoReceivedStockholm() throws Exception {
68
   private Cargo populateCargoReceivedStockholm() throws Exception {

+ 57
- 0
dddsample/src/test/java/se/citerus/dddsample/domain/HandlingEventTest.java Dosyayı Görüntüle

1
 package se.citerus.dddsample.domain;
1
 package se.citerus.dddsample.domain;
2
 
2
 
3
+import java.util.Calendar;
4
+import java.util.Date;
5
+import java.util.HashSet;
6
+import java.util.Set;
7
+
8
+import se.citerus.dddsample.domain.HandlingEvent.Type;
3
 import junit.framework.TestCase;
9
 import junit.framework.TestCase;
4
 
10
 
5
 public class HandlingEventTest extends TestCase {
11
 public class HandlingEventTest extends TestCase {
33
 
39
 
34
     assertEquals(Location.NULL, ev.getLocation());
40
     assertEquals(Location.NULL, ev.getLocation());
35
   }
41
   }
42
+  
43
+  public void testParseType() throws Exception {
44
+    assertEquals(Type.CLAIM, HandlingEvent.parseType("CLAIM"));
45
+    assertEquals(Type.LOAD, HandlingEvent.parseType("LOAD"));
46
+    assertEquals(Type.UNLOAD, HandlingEvent.parseType("UNLOAD"));
47
+    assertEquals(Type.RECEIVE, HandlingEvent.parseType("RECEIVE"));
48
+  }
49
+  
50
+  public void testParseTypeIllegal() throws Exception {
51
+    try {
52
+      HandlingEvent.parseType("NOT_A_HANDLING_EVENT_TYPE");
53
+      assertTrue("Expected IllegaArgumentException to be thrown", false);
54
+    } catch (IllegalArgumentException e) {
55
+      // All's well
56
+    }
57
+  }
58
+  
59
+  public void testEquality() throws Exception {
60
+    Date date = Calendar.getInstance().getTime();
61
+    Location locationAAA = new Location("AAA");
62
+    Location locationBBB = new Location("BBB");
63
+    CarrierMovement cm = new CarrierMovement(locationAAA, locationBBB);
64
+    
65
+    Cargo cargo1 = new Cargo(new TrackingId("ABC"), new Location("A"), new Location("C"));
66
+    Cargo cargo2 = new Cargo(new TrackingId("CBA"), new Location("C"), new Location("A"));
67
+    Cargo cargo3 = new Cargo(new TrackingId("CBA"), new Location("C"), new Location("A")); //Identical to cargo2
68
+    
69
+    Set<Cargo> cargos1 = new HashSet<Cargo>();
70
+    cargos1.add(cargo1);
71
+    
72
+    Set<Cargo> cargos2 = new HashSet<Cargo>();
73
+    cargos2.add(cargo1);
74
+    cargos2.add(cargo2);
75
+    
76
+    Set<Cargo> cargos3 = new HashSet<Cargo>();
77
+    cargos3.add(cargo1);
78
+    cargos3.add(cargo3);
79
+    
80
+    
81
+    HandlingEvent ev1 = new HandlingEvent(date, HandlingEvent.Type.LOAD, cm);
82
+    ev1.register(cargos1);
83
+    
84
+    HandlingEvent ev2 = new HandlingEvent(date, HandlingEvent.Type.LOAD, cm);
85
+    ev2.register(cargos2);
86
+    
87
+    HandlingEvent ev3 = new HandlingEvent(date, HandlingEvent.Type.LOAD, cm);
88
+    ev3.register(cargos2);  
89
+    
90
+    assertFalse("HandlingEvents should not be considered equal if the Set of Cargo is not equal", ev1.equals(ev2));
91
+    assertTrue("HandlingEvents should be considered equal if the Set of Cargo is equal", ev2.equals(ev3));
92
+  }
36
 }
93
 }

+ 102
- 0
dddsample/src/test/java/se/citerus/dddsample/service/HandlingEventServiceTest.java Dosyayı Görüntüle

1
+package se.citerus.dddsample.service;
2
+
3
+import java.util.Calendar;
4
+import java.util.Date;
5
+import java.util.HashSet;
6
+import java.util.Set;
7
+
8
+import junit.framework.TestCase;
9
+import se.citerus.dddsample.domain.Cargo;
10
+import se.citerus.dddsample.domain.CarrierMovement;
11
+import se.citerus.dddsample.domain.HandlingEvent;
12
+import se.citerus.dddsample.domain.Location;
13
+import se.citerus.dddsample.domain.TrackingId;
14
+import se.citerus.dddsample.repository.CargoRepository;
15
+import se.citerus.dddsample.repository.CarrierRepository;
16
+import se.citerus.dddsample.repository.HandlingEventRepository;
17
+import static org.easymock.EasyMock.*;
18
+
19
+public class HandlingEventServiceTest extends TestCase {
20
+  private HandlingEventServiceImpl service;
21
+  private CargoRepository cargoRepository;
22
+  private CarrierRepository carrierRepository;
23
+  private HandlingEventRepository handlingEventRepository;
24
+  
25
+  private final Cargo cargoABC = new Cargo(new TrackingId("ABC"), new Location("ABCFROM"), new Location("ABCTO"));
26
+  private final Cargo cargoXYZ = new Cargo(new TrackingId("XYZ"), new Location("XYZFROM"), new Location("XYZTO"));
27
+  private final CarrierMovement cmAAA_BBB = new CarrierMovement(new Location("AAA"), new Location("BBB"));
28
+
29
+  protected void setUp() throws Exception{
30
+    service = new HandlingEventServiceImpl();
31
+    cargoRepository = createMock(CargoRepository.class);
32
+    carrierRepository = createMock(CarrierRepository.class);
33
+    handlingEventRepository = createMock(HandlingEventRepository.class);
34
+    
35
+    service.setCargoRepository(cargoRepository);
36
+    service.setCarrierRepository(carrierRepository);
37
+    service.setHandlingEventRepository(handlingEventRepository);
38
+  }
39
+
40
+  public void testRegisterEvent() throws Exception {
41
+    String carrierId = "AAA_BBB";
42
+    final String[] trackIds = { "ABC", "XYZ" };
43
+    Date date = Calendar.getInstance().getTime();
44
+    String type = "UNLOAD";
45
+    
46
+    expect(cargoRepository.find(new TrackingId("ABC"))).andReturn(cargoABC);
47
+    expect(cargoRepository.find(new TrackingId("XYZ"))).andReturn(cargoXYZ);
48
+    expect(carrierRepository.find("AAA_BBB")).andReturn(cmAAA_BBB);
49
+    
50
+    HandlingEvent event = new HandlingEvent(date, HandlingEvent.parseType(type), cmAAA_BBB);
51
+    Set<Cargo> cargos = new HashSet<Cargo>();
52
+    cargos.add(cargoABC);
53
+    cargos.add(cargoXYZ);
54
+    event.register(cargos);
55
+    
56
+    handlingEventRepository.save(event);
57
+    
58
+    replay(cargoRepository, carrierRepository, handlingEventRepository);
59
+    
60
+    service.register(date, type, carrierId, trackIds);
61
+    
62
+    verify(cargoRepository, carrierRepository, handlingEventRepository);
63
+  }
64
+  
65
+  public void testRegisterEventInvalidCarrier() throws Exception {
66
+    final String[] trackIds = { "ABC", "XYZ" };
67
+    Date date = Calendar.getInstance().getTime();
68
+    String type = "UNLOAD";
69
+    
70
+    expect(cargoRepository.find(new TrackingId("ABC"))).andReturn(cargoABC);
71
+    expect(cargoRepository.find(new TrackingId("XYZ"))).andReturn(cargoXYZ);
72
+    expect(carrierRepository.find("AAA_BBB")).andReturn(null);
73
+    
74
+    replay(cargoRepository, carrierRepository, handlingEventRepository);
75
+    
76
+    try {
77
+      service.register(date, type, "AAA_BBB", trackIds);
78
+      assertFalse(true);
79
+    } catch (IllegalArgumentException e) {
80
+      // Expected IllegalArgumentExecption
81
+    }
82
+  }
83
+  
84
+  public void testRegisterEventInvalidCargo() throws Exception {
85
+    final String[] trackIds = { "ABC", "XYZ" };
86
+    Date date = Calendar.getInstance().getTime();
87
+    String type = "UNLOAD";
88
+    
89
+    expect(cargoRepository.find(new TrackingId("ABC"))).andReturn(cargoABC);
90
+    expect(cargoRepository.find(new TrackingId("XYZ"))).andReturn(null);
91
+    expect(carrierRepository.find("AAA_BBB")).andReturn(cmAAA_BBB);
92
+    
93
+    replay(cargoRepository, carrierRepository, handlingEventRepository);
94
+    
95
+    try {
96
+      service.register(date, type, "AAA_BBB", trackIds);
97
+      assertFalse(true);
98
+    } catch (IllegalArgumentException e) {
99
+      // Expected IllegalArgumentExecption
100
+    }
101
+  }
102
+}

+ 6
- 1
dddsample/src/test/resources/mock-context-persistence.xml Dosyayı Görüntüle

11
   <bean id="cargoRepository" class="org.easymock.EasyMock" factory-method="createMock">
11
   <bean id="cargoRepository" class="org.easymock.EasyMock" factory-method="createMock">
12
     <constructor-arg value="se.citerus.dddsample.repository.CargoRepository"/>
12
     <constructor-arg value="se.citerus.dddsample.repository.CargoRepository"/>
13
   </bean>
13
   </bean>
14
-
14
+  
15
+  <bean id="handlingEventRepository" class="se.citerus.dddsample.repository.HandlingEventRepositoryInMem" init-method="init">
16
+    <property name="carrierRepository" ref="carrierRepository"/>
17
+  </bean>
18
+  
19
+  <bean id="carrierRepository" class="se.citerus.dddsample.repository.CarrierRepositoryInMem" />
15
 </beans>
20
 </beans>

+ 48
- 0
dddsample/src/test/resources/test-context-persistence.xml Dosyayı Görüntüle

1
+<?xml version="1.0" encoding="UTF-8"?>
2
+
3
+<beans  xmlns="http://www.springframework.org/schema/beans"
4
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
6
+
7
+  <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
8
+    <property name="location" value="classpath:jdbc.properties"/>
9
+  </bean>
10
+
11
+  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
12
+    <property name="url" value="${jdbc.url}"/>
13
+    <property name="driverClassName" value="${jdbc.driverClassName}"/>
14
+    <property name="username" value="${jdbc.username}"/>
15
+    <property name="password" value="${jdbc.password}"/>
16
+  </bean>
17
+
18
+  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
19
+    <property name="dataSource" ref="dataSource"/>
20
+    <property name="annotatedClasses">
21
+      <list>
22
+        <value>se.citerus.dddsample.domain.Cargo</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>
26
+        <value>se.citerus.dddsample.domain.CarrierMovement</value>
27
+      </list>
28
+    </property>
29
+    <property name="hibernateProperties">
30
+      <props>
31
+        <!-- These are properties that are common for test and production -->
32
+        <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
33
+        <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
34
+      </props>
35
+    </property>
36
+  </bean>
37
+
38
+  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
39
+    <property name="sessionFactory" ref="sessionFactory"/>
40
+  </bean>
41
+
42
+  <!--  bean id="cargoRepository" class="se.citerus.dddsample.repository.CargoRepositoryInMem" / -->
43
+
44
+  <bean id="cargoRepository" class="se.citerus.dddsample.repository.CargoRepositoryHibernate">
45
+    <property name="sessionFactory" ref="sessionFactory"/>
46
+  </bean>
47
+
48
+</beans>