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 enum State {
13 NOT_STARTED {
14 @Override
15 void check(final State newState) {
16 if (newState != STARTING && newState != SHUTTING_DOWN) {
17 illegalState(newState);
18 }
19 }
20 },
21 STARTING,
22 DELAYED {
23 @Override
24 void check(final State newState) {
25 if (newState != RESUMING && newState != SHUTTING_DOWN) {
26 illegalState(newState);
27 }
28 }
29 },
30 RESUMING,
31 STARTED {
32 @Override
33 void check(final State newState) {
34 if (newState != WARM_RESTARTING && newState != SHUTTING_DOWN) {
35 illegalState(newState);
36 }
37 }
38 },
39 WARM_RESTARTING {
40 @Override
41 void check(final State newState) {
42 if (newState != STARTED) {
43 illegalState(newState);
44 }
45 }
46 },
47 SHUTTING_DOWN,
48 SHUTDOWN {
49 @Override
50 void check(final State newState) {
51 if (newState != STARTING) {
52 illegalState(newState);
53 }
54 }
55 };
56
57 void check(final State newState) {
58 if ((ordinal() + 1) != newState.ordinal()) {
59 illegalState(newState);
60 }
61 }
62
63 void illegalState(final State newState) {
64 throw new IllegalStateException("Cannot go from State: " + this + " to: " + newState);
65 }
66 }
67
68 private final AtomicReference<State> state = new AtomicReference<>(State.NOT_STARTED);
69
70 public State get() {
71 return state.get();
72 }
73
74 StateTracker setState(final State newState) throws IllegalStateException {
75 for (; ; ) {
76 final State oldState = get();
77 oldState.check(newState);
78 if (state.compareAndSet(oldState, newState)) {
79 return this;
80 }
81 }
82 }
83
84 @Override
85 public String toString() {
86 return get().toString();
87 }
88 }