1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.daemon.support;
19
20 import java.lang.reflect.Method;
21 import java.lang.reflect.Modifier;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Objects;
25
26 import org.apache.commons.daemon.Daemon;
27 import org.apache.commons.daemon.DaemonContext;
28
29
30
31
32
33
34
35 public class DaemonWrapper implements Daemon
36 {
37
38 private final static String ARGS = "args";
39 private final static String START_CLASS = "start";
40 private final static String START_METHOD = "start.method";
41 private final static String STOP_CLASS = "stop";
42 private final static String STOP_METHOD = "stop.method";
43 private final static String STOP_ARGS = "stop.args";
44 private String configFileName;
45 private final DaemonConfiguration config;
46
47 private final Invoker startup;
48 private final Invoker shutdown;
49
50
51
52
53 public DaemonWrapper()
54 {
55 config = new DaemonConfiguration();
56 startup = new Invoker();
57 shutdown = new Invoker();
58 }
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 @Override
88 public void init(final DaemonContext context)
89 throws Exception
90 {
91 final String[] args = context.getArguments();
92
93 if (args != null) {
94 int i;
95
96
97
98 arguments:
99 for (i = 0; i < args.length; i++) {
100 if (args[i].equals("--")) {
101
102 break;
103 }
104 switch (args[i]) {
105 case "-daemon-properties":
106 if (++i == args.length) {
107 throw new IllegalArgumentException(args[i - 1]);
108 }
109 configFileName = args[i];
110 break;
111 case "-start":
112 if (++i == args.length) {
113 throw new IllegalArgumentException(args[i - 1]);
114 }
115 startup.setClassName(args[i]);
116 break;
117 case "-start-method":
118 if (++i == args.length) {
119 throw new IllegalArgumentException(args[i - 1]);
120 }
121 startup.setMethodName(args[i]);
122 break;
123 case "-stop":
124 if (++i == args.length) {
125 throw new IllegalArgumentException(args[i - 1]);
126 }
127 shutdown.setClassName(args[i]);
128 break;
129 case "-stop-method":
130 if (++i == args.length) {
131 throw new IllegalArgumentException(args[i - 1]);
132 }
133 shutdown.setMethodName(args[i]);
134 break;
135 case "-stop-argument":
136 if (++i == args.length) {
137 throw new IllegalArgumentException(args[i - 1]);
138 }
139 final String[] aa = new String[1];
140 aa[0] = args[i];
141 shutdown.addArguments(aa);
142 break;
143 default:
144
145
146 break arguments;
147 }
148 }
149 if (args.length > i) {
150 final String[] copy = new String[args.length - i];
151 System.arraycopy(args, i, copy, 0, copy.length);
152 startup.addArguments(copy);
153 }
154 }
155 if (config.load(configFileName)) {
156
157 startup.setClassName(config.getProperty(START_CLASS));
158 startup.setMethodName(config.getProperty(START_METHOD));
159
160 startup.addArguments(config.getPropertyArray(ARGS));
161
162 shutdown.setClassName(config.getProperty(STOP_CLASS));
163 shutdown.setMethodName(config.getProperty(STOP_METHOD));
164 shutdown.addArguments(config.getPropertyArray(STOP_ARGS));
165 }
166 startup.validate();
167 shutdown.validate();
168 }
169
170
171
172 @Override
173 public void start()
174 throws Exception
175 {
176 startup.invoke();
177 }
178
179
180
181 @Override
182 public void stop()
183 throws Exception
184 {
185 shutdown.invoke();
186 }
187
188
189
190 @Override
191 public void destroy()
192 {
193
194 System.err.println("DaemonWrapper: instance " + hashCode() + " destroy");
195 }
196
197
198 static class Invoker
199 {
200 private String name;
201 private String call;
202 private String[] args;
203 private Method inst;
204 private Class<?> main;
205
206 protected Invoker()
207 {
208 }
209
210 protected void setClassName(final String name)
211 {
212 if (this.name == null) {
213 this.name = name;
214 }
215 }
216 protected void setMethodName(final String name)
217 {
218 if (this.call == null) {
219 this.call = name;
220 }
221 }
222 protected void addArguments(final String[] args)
223 {
224 if (args != null) {
225 final ArrayList<String> aa = new ArrayList<>();
226 if (this.args != null) {
227 aa.addAll(Arrays.asList(this.args));
228 }
229 aa.addAll(Arrays.asList(args));
230 this.args = aa.toArray(DaemonConfiguration.EMPTY_STRING_ARRAY);
231 }
232 }
233
234 protected void invoke()
235 throws Exception
236 {
237 if (name.equals("System") && call.equals("exit")) {
238
239
240
241 System.exit(0);
242 }
243 else {
244 Object obj = null;
245 if ((inst.getModifiers() & Modifier.STATIC) == 0) {
246
247 obj = main.getConstructor().newInstance();
248 }
249 final Object[] arg = new Object[1];
250
251 arg[0] = args;
252 inst.invoke(obj, arg);
253 }
254 }
255
256 protected void validate()
257 throws Exception
258 {
259
260 if (name == null) {
261 name = "System";
262 call = "exit";
263 return;
264 }
265 if (args == null) {
266 args = new String[0];
267 }
268 if (call == null) {
269 call = "main";
270 }
271
272
273 final ClassLoader classLoader = DaemonWrapper.class.getClassLoader();
274 Objects.requireNonNull(classLoader, "classLoader");
275 final Class<?>[] ca = new Class[1];
276 ca[0] = args.getClass();
277
278 main = classLoader.loadClass(name);
279 if (main == null) {
280 throw new ClassNotFoundException(name);
281 }
282
283
284
285 inst = main.getMethod(call, ca);
286 }
287 }
288 }