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