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