1   package com.atlassian.pageobjects.elements.mock.clock;
2   
3   import java.util.SortedMap;
4   
5   import com.atlassian.pageobjects.elements.query.util.Clock;
6   
7   import com.google.common.collect.Maps;
8   
9   import static com.google.common.base.Preconditions.checkArgument;
10  import static com.google.common.base.Preconditions.checkNotNull;
11  
12  /**
13   * Composite clock that returns answer from one of the clocks it builds upon, depending on the number of times it
14   * was called already.
15   *
16   */
17  public class CompositeClock implements Clock
18  {
19      private final SortedMap<Integer, Clock> clocks = Maps.newTreeMap();
20      private int currentCall = 1;
21  
22  
23      public CompositeClock(Clock initialClock)
24      {
25          clocks.put(1, checkNotNull(initialClock, "initialClock"));
26      }
27  
28      public CompositeClock addClock(int startFromCall, Clock clock)
29      {
30          checkArgument(startFromCall > clocks.lastKey(), "startFromCall must be greater than the current last clock");
31          clocks.put(startFromCall, clock);
32          return this;
33      }
34  
35      public long currentTime()
36      {
37          long answer = findClock().currentTime();
38          currentCall++;
39          return answer;
40      }
41  
42      private Clock findClock()
43      {
44          Integer lastKey = clocks.lastKey();
45          if (currentCall >= lastKey)
46          {
47              return clocks.get(lastKey);
48          }
49          int clockKey = clocks.firstKey();
50          for (int startFromCall : clocks.keySet())
51          {
52              if (currentCall < startFromCall)
53              {
54                  break;
55              }
56              else
57              {
58                  clockKey = startFromCall;
59              }
60          }
61          return clocks.get(clockKey);
62      }
63  }