• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aspectran / aspectran / #3971

08 Jan 2025 12:17PM CUT coverage: 35.017% (-0.009%) from 35.026%
#3971

push

github

topframe
Update

8 of 27 new or added lines in 6 files covered. (29.63%)

7 existing lines in 5 files now uncovered.

14188 of 40517 relevant lines covered (35.02%)

0.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/utils/src/main/java/com/aspectran/utils/lifecycle/AbstractLifeCycle.java
1
/*
2
 * Copyright (c) 2008-2025 The Aspectran Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.aspectran.utils.lifecycle;
17

18
import com.aspectran.utils.StringUtils;
19
import com.aspectran.utils.annotation.jsr305.NonNull;
20
import com.aspectran.utils.logging.Logger;
21
import com.aspectran.utils.logging.LoggerFactory;
22
import com.aspectran.utils.thread.AutoLock;
23

24
import java.util.concurrent.CopyOnWriteArrayList;
25

26
/**
27
 * Basic implementation of the life cycle interface for components.
28
 */
29
public abstract class AbstractLifeCycle implements LifeCycle {
×
30

31
    private static final Logger logger = LoggerFactory.getLogger(AbstractLifeCycle.class);
×
32

33
    private final CopyOnWriteArrayList<LifeCycle.Listener> listeners = new CopyOnWriteArrayList<>();
×
34

35
    private final AutoLock lock = new AutoLock();
×
36

37
    private static final int STATE_FAILED = -1;
38

39
    private static final int STATE_STOPPED = 0;
40

41
    private static final int STATE_STARTING = 1;
42

43
    private static final int STATE_STARTED = 2;
44

45
    private static final int STATE_STOPPING = 3;
46

47
    private volatile int state = STATE_STOPPED;
×
48

49
    protected void doStart() throws Exception {
50
    }
×
51

52
    protected void doStop() throws Exception {
53
    }
×
54

55
    @Override
56
    public final void start() throws Exception {
57
        try (AutoLock ignored = lock.lock()) {
×
58
            try {
59
                if (state == STATE_STARTED || state == STATE_STARTING) {
×
60
                    return;
×
61
                }
62
                setStarting();
×
63
                doStart();
×
64
                setStarted();
×
65
            } catch (Throwable e) {
×
66
                setFailed(e);
×
67
                throw e;
×
68
            }
×
69
        }
×
70
    }
×
71

72
    @Override
73
    public final void stop() throws Exception {
74
        try (AutoLock ignored = lock.lock()) {
×
75
            try {
76
                if (state == STATE_STOPPING || state == STATE_STOPPED) {
×
77
                    return;
×
78
                }
79
                setStopping();
×
80
                doStop();
×
81
                setStopped();
×
82
            } catch (Throwable e) {
×
83
                setFailed(e);
×
84
                throw e;
×
85
            }
×
86
        }
×
87
    }
×
88

89
    @Override
90
    public boolean isRunning() {
91
        final int state = this.state;
×
92
        return (state == STATE_STARTED || state == STATE_STARTING);
×
93
    }
94

95
    @Override
96
    public boolean isStarted() {
97
        return (state == STATE_STARTED);
×
98
    }
99

100
    @Override
101
    public boolean isStarting() {
102
        return (state == STATE_STARTING);
×
103
    }
104

105
    @Override
106
    public boolean isStopping() {
107
        return (state == STATE_STOPPING);
×
108
    }
109

110
    @Override
111
    public boolean isStopped() {
112
        return (state == STATE_STOPPED);
×
113
    }
114

115
    @Override
116
    public boolean isFailed() {
117
        return (state == STATE_FAILED);
×
118
    }
119

120
    @Override
121
    public void addLifeCycleListener(LifeCycle.Listener listener) {
122
        listeners.add(listener);
×
123
    }
×
124

125
    @Override
126
    public void removeLifeCycleListener(LifeCycle.Listener listener) {
127
        listeners.remove(listener);
×
128
    }
×
129

130
    @Override
131
    public String getState() {
132
        return switch (state) {
×
133
            case STATE_FAILED -> FAILED;
×
134
            case STATE_STARTING -> STARTING;
×
135
            case STATE_STARTED -> STARTED;
×
136
            case STATE_STOPPING -> STOPPING;
×
137
            case STATE_STOPPED -> STOPPED;
×
138
            default -> null;
×
139
        };
140
    }
141

142
    public static String getState(@NonNull LifeCycle lc) {
143
        if (lc.isStarting()) {
×
144
            return STARTING;
×
145
        }
146
        if (lc.isStarted()) {
×
147
            return STARTED;
×
148
        }
149
        if (lc.isStopping()) {
×
150
            return STOPPING;
×
151
        }
152
        if (lc.isStopped()) {
×
153
            return STOPPED;
×
154
        }
155
        return FAILED;
×
156
    }
157

158
    private void setStarted() {
159
        state = STATE_STARTED;
×
160
        if (logger.isDebugEnabled()) {
×
161
            logger.debug("Started " + this);
×
162
        }
163
        for (Listener listener : listeners) {
×
164
            listener.lifeCycleStarted(this);
×
165
        }
×
166
    }
×
167

168
    private void setStarting() {
169
        if (logger.isDebugEnabled()) {
×
170
            logger.debug("Starting " + this);
×
171
        }
172
        state = STATE_STARTING;
×
173
        for (Listener listener : listeners) {
×
174
            listener.lifeCycleStarting(this);
×
175
        }
×
176
    }
×
177

178
    private void setStopping() {
179
        if (logger.isDebugEnabled()) {
×
180
            logger.debug("Stopping " + this);
×
181
        }
182
        state = STATE_STOPPING;
×
183
        for (Listener listener : listeners) {
×
184
            listener.lifeCycleStopping(this);
×
185
        }
×
186
    }
×
187

188
    private void setStopped() {
189
        state = STATE_STOPPED;
×
190
        if (logger.isDebugEnabled()) {
×
191
            logger.debug("Stopped " + this);
×
192
        }
193
        for (Listener listener : listeners) {
×
194
            listener.lifeCycleStopped(this);
×
195
        }
×
196
    }
×
197

198
    private void setFailed(Throwable th) {
199
        state = STATE_FAILED;
×
NEW
200
        logger.warn(this + " - " + th, th);
×
201
        for (Listener listener : listeners) {
×
202
            listener.lifeCycleFailure(this, th);
×
203
        }
×
204
    }
×
205

206
    @Override
207
    public String toString() {
208
        return String.format("%s@%x{%s}", myName(), hashCode(), getState());
×
209
    }
210

211
    private String myName() {
212
        Class<?> type = getClass();
×
213
        String name = type.getSimpleName();
×
214
        if (StringUtils.isEmpty(name) && type.getSuperclass() != null) {
×
215
            name = type.getSuperclass().getSimpleName();
×
216
        }
217
        return name;
×
218
    }
219

220
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc