View Javadoc

1   package com.atlassian.plugin.manager;
2   
3   import java.util.concurrent.atomic.AtomicReference;
4   
5   /**
6    * Simple thread-safe state machine that prevents illegal transitions.
7    * <p>
8    * Could be easily extended to allow custom workflows by interfacing 
9    * out the State type and having this class generified with that.
10   */
11  class StateTracker
12  {
13      enum State
14      {
15          NOT_STARTED,
16          STARTING,
17          STARTED,
18          SHUTTING_DOWN,
19          SHUTDOWN
20          {
21              @Override
22              void check(final State newState)
23              {
24                  if (newState != STARTING)
25                  {
26                      illegalState(newState);
27                  }
28              }
29          };
30  
31          void check(final State newState)
32          {
33              if ((ordinal() + 1) != newState.ordinal())
34              {
35                  illegalState(newState);
36              }
37          }
38  
39          void illegalState(final State newState)
40          {
41              throw new IllegalStateException("Cannot go from State: " + this + " to: " + newState);
42          }
43      }
44  
45      private final AtomicReference<State> state = new AtomicReference<State>(State.NOT_STARTED);
46  
47      public State get()
48      {
49          return state.get();
50      }
51  
52      StateTracker setState(final State newState) throws IllegalStateException
53      {
54          for (;;)
55          {
56              final State oldState = get();
57              oldState.check(newState);
58              if (state.compareAndSet(oldState, newState))
59              {
60                  return this;
61              }
62          }
63      }
64  
65      @Override
66      public String toString()
67      {
68          return get().toString();
69      }
70  }