1 package com.atlassian.plugin.manager;
2
3 import java.util.concurrent.atomic.AtomicReference;
4
5
6
7
8
9
10
11 class StateTracker
12 {
13 enum State
14 {
15 NOT_STARTED
16 {
17 @Override
18 void check(final State newState)
19 {
20 if (newState != STARTING && newState != SHUTTING_DOWN)
21 {
22 illegalState(newState);
23 }
24 }
25 },
26 STARTING,
27 DELAYED,
28 RESUMING,
29 STARTED
30 {
31 @Override
32 void check(final State newState)
33 {
34 if (newState != WARM_RESTARTING && newState != SHUTTING_DOWN)
35 {
36 illegalState(newState);
37 }
38 }
39 },
40 WARM_RESTARTING
41 {
42 @Override
43 void check(final State newState)
44 {
45 if (newState != STARTED)
46 {
47 illegalState(newState);
48 }
49 }
50 },
51 SHUTTING_DOWN,
52 SHUTDOWN
53 {
54 @Override
55 void check(final State newState)
56 {
57 if (newState != STARTING)
58 {
59 illegalState(newState);
60 }
61 }
62 };
63
64 void check(final State newState)
65 {
66 if ((ordinal() + 1) != newState.ordinal())
67 {
68 illegalState(newState);
69 }
70 }
71
72 void illegalState(final State newState)
73 {
74 throw new IllegalStateException("Cannot go from State: " + this + " to: " + newState);
75 }
76 }
77
78 private final AtomicReference<State> state = new AtomicReference<State>(State.NOT_STARTED);
79
80 public State get()
81 {
82 return state.get();
83 }
84
85 StateTracker setState(final State newState) throws IllegalStateException
86 {
87 for (;;)
88 {
89 final State oldState = get();
90 oldState.check(newState);
91 if (state.compareAndSet(oldState, newState))
92 {
93 return this;
94 }
95 }
96 }
97
98 @Override
99 public String toString()
100 {
101 return get().toString();
102 }
103 }