View Javadoc
1   package ordertracker;
2   
3   import java.util.concurrent.TimeUnit;
4   
5   import com.google.common.base.Optional;
6   
7   import ordertracker.Order.Events.ArrivedDepot;
8   import ordertracker.Order.Events.ArrivedFinalDepot;
9   import ordertracker.Order.Events.Assign;
10  import ordertracker.Order.Events.CouldNotDeliver;
11  import ordertracker.Order.Events.Create;
12  import ordertracker.Order.Events.DeliverAgain;
13  import ordertracker.Order.Events.Delivered;
14  import ordertracker.Order.Events.DeliveredByPickup;
15  import ordertracker.Order.Events.Delivering;
16  import ordertracker.Order.Events.DeliveryFailed;
17  import ordertracker.Order.Events.NoMoreAttempts;
18  import ordertracker.Order.Events.PickedUp;
19  import ordertracker.Order.Events.ReturnToSender;
20  import ordertracker.Order.Events.Send;
21  import ordertracker.Order.State;
22  import scala.concurrent.duration.Duration;
23  
24  public class OrderBehaviour implements Order.Behaviour {
25  
26      private final Order self;
27  
28      public OrderBehaviour(Order self) {
29          this.self = self;
30      }
31  
32      @Override
33      public void onEntryPreparing(Create event) {
34          self.setAttempts(0);
35          self.setComment(event.getComment());
36          self.setDescription(event.getDescription());
37          self.setDestinationEmail(event.getDestinationEmail());
38          self.setFromAddress(event.getFromAddress());
39          self.setId(event.getOrderID());
40          self.setMaxAttempts(event.getMaxAttempts());
41          self.setSenderEmail(event.getSenderEmail());
42          self.setToAddress(event.getToAddress());
43          event(Order.State.PREPARING);
44      }
45  
46      @Override
47      public void onEntryReadyForDispatch(Send event) {
48          event(Order.State.READY_FOR_DISPATCH);
49      }
50  
51      @Override
52      public void onEntryCourierAssigned(Assign event) {
53          event(Order.State.COURIER_ASSIGNED);
54      }
55  
56      @Override
57      public void onEntryInTransit(PickedUp event) {
58          event(Order.State.IN_TRANSIT);
59      }
60  
61      @Override
62      public void onEntryInTransit(ArrivedDepot event) {
63          Optional<Depot> depot = Depot.find(event.getDepotID());
64          if (!depot.isPresent())
65              throw new RuntimeException("depot does not exist: " + event.getDepotID());
66          else {
67              self.setDepot_R1(depot.get());
68              event(Order.State.IN_TRANSIT);
69          }
70      }
71  
72      @Override
73      public void onEntryReadyForDelivery(ArrivedFinalDepot event) {
74          Optional<Depot> depot = Depot.find(event.getDepotID());
75          if (!depot.isPresent())
76              throw new RuntimeException("depot does not exist: " + event.getDepotID());
77          else {
78              self.setDepot_R1(depot.get());
79              event(Order.State.READY_FOR_DELIVERY);
80          }
81      }
82  
83      @Override
84      public void onEntryDelivering(Delivering event) {
85          self.setAttempts(self.getAttempts() + 1);
86          event(Order.State.DELIVERING);
87      }
88  
89      @Override
90      public void onEntryDelivered(Delivered event) {
91          // send email to destination email and sender email notifying of
92          // successful delivery
93          event(Order.State.DELIVERED);
94      }
95  
96      @Override
97      public void onEntryDeliveryFailed(DeliveryFailed event) {
98          event(Order.State.DELIVERY_FAILED);
99          if (self.getAttempts() >= self.getMaxAttempts())
100             self.signal(new Order.Events.NoMoreAttempts());
101         else
102             self.signal(new Order.Events.DeliverAgain());
103     }
104 
105     @Override
106     public void onEntryAwaitingNextDeliveryAttempt(DeliverAgain event) {
107         self.signal(new Order.Events.DeliverAgain(), Duration.create(12, TimeUnit.MILLISECONDS));
108         event(Order.State.AWAITING_NEXT_DELIVERY_ATTEMPT);
109     }
110 
111     @Override
112     public void onEntryHeldForPickup(NoMoreAttempts event) {
113         returnToSenderIfNotPickedUp();
114     }
115 
116     @Override
117     public void onEntryHeldForPickup(CouldNotDeliver event) {
118         returnToSenderIfNotPickedUp();
119     }
120 
121     private void returnToSenderIfNotPickedUp() {
122         self.signal(new Order.Events.ReturnToSender(), Duration.create(14, TimeUnit.MILLISECONDS));
123         event(Order.State.HELD_FOR_PICKUP);
124     }
125 
126     @Override
127     public void onEntryReturnToSender(ReturnToSender event) {
128         // at this point we might create another order for the return leg
129         event(Order.State.RETURN_TO_SENDER);
130     }
131 
132     @Override
133     public void onEntryDelivered(DeliveredByPickup event) {
134         event(Order.State.DELIVERED);
135     }
136 
137     private void event(State state) {
138         // send the state to the singleton event entity
139         SystemEvent.find("1").get().signal(new SystemEvent.Events.NewEvent(state.toString()));
140     }
141 
142     @Override
143     public void onEntryReadyForDelivery(DeliverAgain event) {
144         event(Order.State.READY_FOR_DELIVERY);
145     }
146 
147 }