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 public DaemonWrapper()
51 {
52 config = new DaemonConfiguration();
53 startup = new Invoker();
54 shutdown = new Invoker();
55 }
56
57
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 @Override
85 public void init(final DaemonContext context)
86 throws Exception
87 {
88 final String[] args = context.getArguments();
89
90 if (args != null) {
91 int i;
92
93
94
95 arguments:
96 for (i = 0; i < args.length; i++) {
97 if (args[i].equals("--")) {
98
99 break;
100 }
101 switch (args[i]) {
102 case "-daemon-properties":
103 if (++i == args.length) {
104 throw new IllegalArgumentException(args[i - 1]);
105 }
106 configFileName = args[i];
107 break;
108 case "-start":
109 if (++i == args.length) {
110 throw new IllegalArgumentException(args[i - 1]);
111 }
112 startup.setClassName(args[i]);
113 break;
114 case "-start-method":
115 if (++i == args.length) {
116 throw new IllegalArgumentException(args[i - 1]);
117 }
118 startup.setMethodName(args[i]);
119 break;
120 case "-stop":
121 if (++i == args.length) {
122 throw new IllegalArgumentException(args[i - 1]);
123 }
124 shutdown.setClassName(args[i]);
125 break;
126 case "-stop-method":
127 if (++i == args.length) {
128 throw new IllegalArgumentException(args[i - 1]);
129 }
130 shutdown.setMethodName(args[i]);
131 break;
132 case "-stop-argument":
133 if (++i == args.length) {
134 throw new IllegalArgumentException(args[i - 1]);
135 }
136 final String[] aa = new String[1];
137 aa[0] = args[i];
138 shutdown.addArguments(aa);
139 break;
140 default:
141
142
143 break arguments;
144 }
145 }
146 if (args.length > i) {
147 final String[] copy = new String[args.length - i];
148 System.arraycopy(args, i, copy, 0, copy.length);
149 startup.addArguments(copy);
150 }
151 }
152 if (config.load(configFileName)) {
153
154 startup.setClassName(config.getProperty(START_CLASS));
155 startup.setMethodName(config.getProperty(START_METHOD));
156
157 startup.addArguments(config.getPropertyArray(ARGS));
158
159 shutdown.setClassName(config.getProperty(STOP_CLASS));
160 shutdown.setMethodName(config.getProperty(STOP_METHOD));
161 shutdown.addArguments(config.getPropertyArray(STOP_ARGS));
162 }
163 startup.validate();
164 shutdown.validate();
165 }
166
167
168
169 @Override
170 public void start()
171 throws Exception
172 {
173 startup.invoke();
174 }
175
176
177
178 @Override
179 public void stop()
180 throws Exception
181 {
182 shutdown.invoke();
183 }
184
185
186
187 @Override
188 public void destroy()
189 {
190
191 System.err.println("DaemonWrapper: instance " + this.hashCode() + " destroy");
192 }
193
194
195 static class Invoker
196 {
197 private String name;
198 private String call;
199 private String[] args;
200 private Method inst;
201 private Class<?> main;
202
203 protected Invoker()
204 {
205 }
206
207 protected void setClassName(final String name)
208 {
209 if (this.name == null) {
210 this.name = name;
211 }
212 }
213 protected void setMethodName(final String name)
214 {
215 if (this.call == null) {
216 this.call = name;
217 }
218 }
219 protected void addArguments(final String[] args)
220 {
221 if (args != null) {
222 final ArrayList<String> aa = new ArrayList<>();
223 if (this.args != null) {
224 aa.addAll(Arrays.asList(this.args));
225 }
226 aa.addAll(Arrays.asList(args));
227 this.args = aa.toArray(DaemonConfiguration.EMPTY_STRING_ARRAY);
228 }
229 }
230
231 protected void invoke()
232 throws Exception
233 {
234 if (name.equals("System") && call.equals("exit")) {
235
236
237
238 System.exit(0);
239 }
240 else {
241 Object obj = null;
242 if ((inst.getModifiers() & Modifier.STATIC) == 0) {
243
244 obj = main.getConstructor().newInstance();
245 }
246 final Object[] arg = new Object[1];
247
248 arg[0] = args;
249 inst.invoke(obj, arg);
250 }
251 }
252
253 protected void validate()
254 throws Exception
255 {
256
257 if (name == null) {
258 name = "System";
259 call = "exit";
260 return;
261 }
262 if (args == null) {
263 args = new String[0];
264 }
265 if (call == null) {
266 call = "main";
267 }
268
269
270 final ClassLoader classLoader = DaemonWrapper.class.getClassLoader();
271 Objects.requireNonNull(classLoader, "classLoader");
272 final Class<?>[] ca = new Class[1];
273 ca[0] = args.getClass();
274
275 main = classLoader.loadClass(name);
276 if (main == null) {
277 throw new ClassNotFoundException(name);
278 }
279
280
281
282 inst = main.getMethod(call, ca);
283 }
284 }
285 }