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 STARTED
28 {
29 @Override
30 void check(final State newState)
31 {
32 if (newState != WARM_RESTARTING && newState != SHUTTING_DOWN)
33 {
34 illegalState(newState);
35 }
36 }
37 },
38 WARM_RESTARTING
39 {
40 @Override
41 void check(final State newState)
42 {
43 if (newState != STARTED)
44 {
45 illegalState(newState);
46 }
47 }
48 },
49 SHUTTING_DOWN,
50 SHUTDOWN
51 {
52 @Override
53 void check(final State newState)
54 {
55 if (newState != STARTING)
56 {
57 illegalState(newState);
58 }
59 }
60 };
61
62 void check(final State newState)
63 {
64 if ((ordinal() + 1) != newState.ordinal())
65 {
66 illegalState(newState);
67 }
68 }
69
70 void illegalState(final State newState)
71 {
72 throw new IllegalStateException("Cannot go from State: " + this + " to: " + newState);
73 }
74 }
75
76 private final AtomicReference<State> state = new AtomicReference<State>(State.NOT_STARTED);
77
78 public State get()
79 {
80 return state.get();
81 }
82
83 StateTracker setState(final State newState) throws IllegalStateException
84 {
85 for (;;)
86 {
87 final State oldState = get();
88 oldState.check(newState);
89 if (state.compareAndSet(oldState, newState))
90 {
91 return this;
92 }
93 }
94 }
95
96 @Override
97 public String toString()
98 {
99 return get().toString();
100 }
101 }