View Javadoc

1   package se.citerus.dddsample.interfaces.tracking;
2   
3   import org.springframework.context.MessageSource;
4   import se.citerus.dddsample.domain.model.cargo.Cargo;
5   import se.citerus.dddsample.domain.model.cargo.Delivery;
6   import se.citerus.dddsample.domain.model.cargo.HandlingActivity;
7   import se.citerus.dddsample.domain.model.handling.HandlingEvent;
8   import se.citerus.dddsample.domain.model.location.Location;
9   import se.citerus.dddsample.domain.model.voyage.Voyage;
10  
11  import java.text.SimpleDateFormat;
12  import java.util.*;
13  
14  /**
15   * View adapter for displaying a cargo in a tracking context.
16   */
17  public final class CargoTrackingViewAdapter {
18  
19    private final Cargo cargo;
20    private final MessageSource messageSource;
21    private final Locale locale;
22    private final List<HandlingEventViewAdapter> events;
23    private final String FORMAT = "yyyy-MM-dd hh:mm";
24  
25    /**
26     * Constructor.
27     *
28     * @param cargo
29     * @param messageSource
30     * @param locale
31     * @param handlingEvents
32     */
33    public CargoTrackingViewAdapter(Cargo cargo, MessageSource messageSource, Locale locale, List<HandlingEvent> handlingEvents) {
34      this.messageSource = messageSource;
35      this.locale = locale;
36      this.cargo = cargo;
37  
38      this.events = new ArrayList<HandlingEventViewAdapter>(handlingEvents.size());
39      for (HandlingEvent handlingEvent : handlingEvents) {
40        events.add(new HandlingEventViewAdapter(handlingEvent));
41      }
42    }
43  
44    /**
45     * @param location a location
46     * @return A formatted string for displaying the location.
47     */
48    private String getDisplayText(Location location) {
49      return location.name();
50    }
51  
52    /**
53     * @return An unmodifiable list of handling event view adapters.
54     */
55    public List<HandlingEventViewAdapter> getEvents() {
56      return Collections.unmodifiableList(events);
57    }
58  
59    /**
60     * @return A translated string describing the cargo status. 
61     */
62    public String getStatusText() {
63      final Delivery delivery = cargo.delivery();
64      final String code = "cargo.status." + delivery.transportStatus().name();
65  
66      final Object[] args;
67      switch (delivery.transportStatus()) {
68        case IN_PORT:
69          args = new Object[] {getDisplayText(delivery.lastKnownLocation())};
70          break;
71        case ONBOARD_CARRIER:
72          args = new Object[] {delivery.currentVoyage().voyageNumber().idString()};
73          break;
74        case CLAIMED:
75        case NOT_RECEIVED:
76        case UNKNOWN:
77        default:
78          args = null;
79          break;
80      }
81      
82      return messageSource.getMessage(code, args, "[Unknown status]", locale);
83    }
84  
85    /**
86     * @return Cargo destination location.
87     */
88    public String getDestination() {
89      return getDisplayText(cargo.routeSpecification().destination());
90    }
91  
92    /**
93     * @return Cargo osigin location.
94     */
95    public String getOrigin() {
96      return getDisplayText(cargo.origin());
97    }
98  
99    /**
100    * @return Cargo tracking id.
101    */
102   public String getTrackingId() {
103     return cargo.trackingId().idString();
104   }
105 
106   public String getEta() {
107     Date eta = cargo.delivery().estimatedTimeOfArrival();
108 
109     if (eta == null) return "?";
110     else return new SimpleDateFormat(FORMAT).format(eta);
111   }
112 
113   public String getNextExpectedActivity() {
114       HandlingActivity activity = cargo.delivery().nextExpectedActivity();
115       if (activity == null) {
116         return "";
117       }
118 
119     String text = "Next expected activity is to ";
120     HandlingEvent.Type type = activity.type();
121     if (type.sameValueAs(HandlingEvent.Type.LOAD)) {
122         return
123           text + type.name().toLowerCase() + " cargo onto voyage " + activity.voyage().voyageNumber() +
124           " in " + activity.location().name();
125       } else if (type.sameValueAs(HandlingEvent.Type.UNLOAD)) {
126         return
127           text + type.name().toLowerCase() + " cargo off of " + activity.voyage().voyageNumber() +
128           " in " + activity.location().name();
129       } else {
130         return text + type.name().toLowerCase() + " cargo in " + activity.location().name();
131       }
132   }
133 
134   /**
135    * @return True if cargo is misdirected.
136    */
137   public boolean isMisdirected() {
138     return cargo.delivery().isMisdirected();
139   }
140 
141   /**
142    * Handling event view adapter component.
143    */
144   public final class HandlingEventViewAdapter {
145 
146     private final HandlingEvent handlingEvent;
147 
148     /**
149      * Constructor.
150      *
151      * @param handlingEvent handling event
152      */
153     public HandlingEventViewAdapter(HandlingEvent handlingEvent) {
154       this.handlingEvent = handlingEvent;
155     }
156 
157     /**
158      * @return Location where the event occurred.
159      */
160     public String getLocation() {
161       return handlingEvent.location().name();
162     }
163 
164     /**
165      * @return Time when the event was completed.
166      */
167     public String getTime() {
168       return new SimpleDateFormat(FORMAT).format(handlingEvent.completionTime());
169     }
170 
171     /**
172      * @return Type of event.
173      */
174     public String getType() {
175       return handlingEvent.type().toString();
176     }
177 
178     /**
179      * @return Voyage number, or empty string if not applicable.
180      */
181     public String getVoyageNumber() {
182       final Voyage voyage = handlingEvent.voyage();
183       return voyage.voyageNumber().idString();
184     }
185 
186     /**
187      * @return True if the event was expected, according to the cargo's itinerary.
188      */
189     public boolean isExpected() {
190       return cargo.itinerary().isExpected(handlingEvent);
191     }
192 
193     public String getDescription() {
194       Object[] args;
195 
196       switch (handlingEvent.type()) {
197         case LOAD:
198         case UNLOAD:
199           args = new Object[] {
200             handlingEvent.voyage().voyageNumber().idString(),
201             handlingEvent.location().name(),
202             handlingEvent.completionTime()
203           };
204           break;
205 
206         case RECEIVE:
207         case CLAIM:
208           args = new Object[] {
209             handlingEvent.location().name(),
210             handlingEvent.completionTime()
211           };
212           break;
213 
214         default:
215           args = new Object[] {};
216       }
217 
218       String key = "deliveryHistory.eventDescription." + handlingEvent.type().name();
219 
220       return messageSource.getMessage(key,args,locale);
221     }
222 
223   }
224   
225 }