1 package org.apache.fulcrum.yaafi.service.shutdown;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.security.MessageDigest;
24
25 import org.apache.avalon.framework.activity.Disposable;
26 import org.apache.avalon.framework.activity.Initializable;
27 import org.apache.avalon.framework.activity.Startable;
28 import org.apache.avalon.framework.configuration.Configuration;
29 import org.apache.avalon.framework.configuration.ConfigurationException;
30 import org.apache.avalon.framework.configuration.Reconfigurable;
31 import org.apache.avalon.framework.context.Context;
32 import org.apache.avalon.framework.context.ContextException;
33 import org.apache.avalon.framework.context.Contextualizable;
34 import org.apache.avalon.framework.logger.AbstractLogEnabled;
35 import org.apache.avalon.framework.service.ServiceException;
36 import org.apache.avalon.framework.service.ServiceManager;
37 import org.apache.avalon.framework.service.Serviceable;
38
39
40
41
42
43
44
45
46 public class ShutdownServiceImpl extends AbstractLogEnabled implements ShutdownService, Serviceable, Contextualizable,
47 Reconfigurable, Initializable, Runnable, Startable, Disposable {
48
49 private int interval;
50
51
52 private boolean terminateNow;
53
54
55 private Thread workerThread;
56
57
58 private ServiceManager serviceManager;
59
60
61 private File applicationDir;
62
63
64 private ShutdownEntry shutdownEntry;
65
66
67
68
69
70
71
72
73 public ShutdownServiceImpl() {
74 this.terminateNow = false;
75 }
76
77
78
79
80 public void service(ServiceManager manager) throws ServiceException {
81 this.serviceManager = manager;
82 }
83
84
85
86
87 public void contextualize(Context context) throws ContextException {
88 this.applicationDir = (File) context.get("urn:avalon:home");
89 }
90
91
92
93
94 public void configure(Configuration configuration) throws ConfigurationException {
95
96
97 this.interval = Math.max(configuration.getAttributeAsInteger("interval", 5000), 1000);
98
99 this.getLogger().debug("Monitoring the resources every " + this.interval + " ms");
100
101 if (configuration.getChild("entry", false) != null) {
102 Configuration shutdownConfig = configuration.getChild("entry");
103
104 String shutdownEntryLocation = shutdownConfig.getChild("location").getValue();
105
106 this.shutdownEntry = new ShutdownEntry(this.getLogger(), this.applicationDir, shutdownEntryLocation,
107 shutdownConfig.getChild("useSystemExit").getValueAsBoolean(false));
108
109 this.getLogger().debug("Using a shutdown entry : " + shutdownEntryLocation);
110 } else {
111 this.shutdownEntry = null;
112 this.getLogger().debug("No shutdown entry defined");
113 }
114 }
115
116
117
118
119
120
121 public void initialize() throws Exception {
122
123
124 MessageDigest.getInstance("SHA1");
125
126
127 if (this.serviceManager instanceof Disposable == false) {
128 String msg = "The ServiceManager instance does not implement Disposable?!";
129 throw new IllegalArgumentException(msg);
130 }
131
132
133 this.workerThread = new Thread(this, "ShutdownService");
134 }
135
136
137
138
139
140
141 public void start() throws Exception {
142 this.getLogger().debug("Starting worker thread ...");
143 this.workerThread.start();
144 }
145
146
147
148
149 public void stop() throws Exception {
150 this.getLogger().debug("Stopping worker thread ...");
151 this.terminateNow = true;
152 this.workerThread.interrupt();
153 this.workerThread.join(10000);
154 }
155
156
157
158
159 public void dispose() {
160 this.terminateNow = false;
161 this.applicationDir = null;
162 this.workerThread = null;
163 this.serviceManager = null;
164 }
165
166
167
168
169 public void reconfigure(Configuration configuration) throws ConfigurationException {
170 this.configure(configuration);
171 }
172
173
174
175
176
177
178
179
180 public void run() {
181 while (this.terminateNow == false) {
182 try {
183 Thread.sleep(this.interval);
184 } catch (InterruptedException e) {
185
186 }
187
188 if (this.hasShutdownEntry() && this.getShutdownEntry().hasChanged()
189 && this.serviceManager instanceof Disposable) {
190
191 if (this.getShutdownEntry().isUseSystemExit()) {
192 this.getLogger().warn("Forcing a shutdown using System.exit() ...");
193 } else {
194 this.getLogger().warn("Forcing a shutdown ...");
195 }
196
197
198 Shutdown shutdown = new Shutdown((Disposable) this.serviceManager,
199 this.getShutdownEntry().isUseSystemExit());
200
201 Thread shutdownThread = new Thread(shutdown, "ShutdownServiceThread");
202 shutdownThread.setDaemon(true);
203 shutdownThread.start();
204 }
205 }
206 }
207
208
209
210
211
212
213
214
215 private ShutdownEntry getShutdownEntry() {
216 return this.shutdownEntry;
217 }
218
219
220
221
222 private boolean hasShutdownEntry() {
223 return (this.shutdownEntry != null ? true : false);
224 }
225 }