View Javadoc

1   package se.citerus.dddsample.domain.model.voyage;
2   
3   import org.apache.commons.lang.Validate;
4   import se.citerus.dddsample.domain.model.location.Location;
5   import se.citerus.dddsample.domain.shared.Entity;
6   
7   import java.util.ArrayList;
8   import java.util.Date;
9   import java.util.List;
10  
11  /**
12   * A Voyage.
13   */
14  public class Voyage implements Entity<Voyage> {
15  
16    private VoyageNumber voyageNumber;
17    private Schedule schedule;
18  
19    // Null object pattern
20    public static final Voyage NONE = new Voyage(
21      new VoyageNumber(""), Schedule.EMPTY
22    );
23  
24    public Voyage(final VoyageNumber voyageNumber, final Schedule schedule) {
25      Validate.notNull(voyageNumber, "Voyage number is required");
26      Validate.notNull(schedule, "Schedule is required");
27  
28      this.voyageNumber = voyageNumber;
29      this.schedule = schedule;
30    }
31  
32    /**
33     * @return Voyage number.
34     */
35    public VoyageNumber voyageNumber() {
36      return voyageNumber;
37    }
38  
39    /**
40     * @return Schedule.
41     */
42    public Schedule schedule() {
43      return schedule;
44    }
45  
46    @Override
47    public int hashCode() {
48      return voyageNumber.hashCode();
49    }
50  
51    @Override
52    public boolean equals(Object o) {
53      if (this == o) return true;
54      if (o == null) return false;
55      if (!(o instanceof Voyage)) return false;
56  
57      final Voyage that = (Voyage) o;
58  
59      return sameIdentityAs(that);
60    }
61  
62    @Override
63    public boolean sameIdentityAs(Voyage other) {
64      return other != null && this.voyageNumber().sameValueAs(other.voyageNumber());
65    }
66  
67    @Override
68    public String toString() {
69      return "Voyage " + voyageNumber;
70    }
71  
72    Voyage() {
73      // Needed by Hibernate
74    }
75  
76    // Needed by Hibernate
77    private Long id;
78  
79    /**
80     * Builder pattern is used for incremental construction
81     * of a Voyage aggregate. This serves as an aggregate factory. 
82     */
83    public static final class Builder {
84  
85      private final List<CarrierMovement> carrierMovements = new ArrayList<CarrierMovement>();
86      private final VoyageNumber voyageNumber;
87      private Location departureLocation;
88  
89      public Builder(final VoyageNumber voyageNumber, final Location departureLocation) {
90        Validate.notNull(voyageNumber, "Voyage number is required");
91        Validate.notNull(departureLocation, "Departure location is required");
92  
93        this.voyageNumber = voyageNumber;
94        this.departureLocation = departureLocation;
95      }
96  
97      public Builder addMovement(Location arrivalLocation, Date departureTime, Date arrivalTime) {
98        carrierMovements.add(new CarrierMovement(departureLocation, arrivalLocation, departureTime, arrivalTime));
99        // Next departure location is the same as this arrival location
100       this.departureLocation = arrivalLocation;
101       return this;
102     }
103 
104     public Voyage build() {
105       return new Voyage(voyageNumber, new Schedule(carrierMovements));
106     }
107 
108   }
109 
110 }