KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SimpleDaemon


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
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
17 /* @version $Id: SimpleDaemon.java 165001 2005-04-27 16:01:42Z jfclere $ */
18
19 import java.io.*;
20 import java.net.*;
21 import java.text.SimpleDateFormat JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Vector JavaDoc;
25 import org.apache.commons.daemon.Daemon;
26 import org.apache.commons.daemon.DaemonController;
27 import org.apache.commons.daemon.DaemonContext;
28
29 public class SimpleDaemon implements Daemon, Runnable JavaDoc {
30
31     private ServerSocket server=null;
32     private Thread JavaDoc thread=null;
33     private DaemonController controller=null;
34     private boolean stopping=false;
35     private String JavaDoc directory=null;
36     private Vector JavaDoc handlers=null;
37
38     public static native void toto();
39
40     public SimpleDaemon() {
41         super();
42         System.err.println("SimpleDaemon: instance "+this.hashCode()+
43                            " created");
44         this.handlers=new Vector JavaDoc();
45     }
46
47     protected void finalize() {
48         System.err.println("SimpleDaemon: instance "+this.hashCode()+
49                            " garbage collected");
50     }
51
52     /**
53      * init and destroy were added in jakarta-tomcat-daemon.
54      */

55     public void init(DaemonContext context)
56     throws Exception JavaDoc {
57         System.err.println("SimpleDaemon: instance "+this.hashCode()+
58                            " init");
59
60         int port=1200;
61
62         String JavaDoc[] a = context.getArguments();
63
64         if (a.length>0) port=Integer.parseInt(a[0]);
65         if (a.length>1) this.directory=a[1];
66         else this.directory="/tmp";
67
68         /* Dump a message */
69         System.err.println("SimpleDaemon: loading on port "+port);
70
71         /* Set up this simple daemon */
72         this.controller=context.getController();
73         this.server=new ServerSocket(port);
74         this.thread=new Thread JavaDoc(this);
75     }
76
77     public void start() {
78         /* Dump a message */
79         System.err.println("SimpleDaemon: starting");
80
81         /* Start */
82         this.thread.start();
83     }
84
85     public void stop()
86     throws IOException, InterruptedException JavaDoc {
87         /* Dump a message */
88         System.err.println("SimpleDaemon: stopping");
89
90         /* Close the ServerSocket. This will make our thread to terminate */
91         this.stopping=true;
92         this.server.close();
93
94         /* Wait for the main thread to exit and dump a message */
95         this.thread.join(5000);
96         System.err.println("SimpleDaemon: stopped");
97     }
98
99     public void destroy() {
100         System.err.println("SimpleDaemon: instance "+this.hashCode()+
101                            " destroy");
102     }
103
104     public void run() {
105         int number=0;
106
107         System.err.println("SimpleDaemon: started acceptor loop");
108         try {
109             while(!this.stopping) {
110                 Socket socket=this.server.accept();
111                 Handler handler=new Handler(socket,this,this.controller);
112                 handler.setConnectionNumber(number++);
113                 handler.setDirectoryName(this.directory);
114                 new Thread JavaDoc(handler).start();
115             }
116         } catch (IOException e) {
117             /* Don't dump any error message if we are stopping. A IOException
118                is generated when the ServerSocket is closed in stop() */

119             if (!this.stopping) e.printStackTrace(System.err);
120         }
121
122         /* Terminate all handlers that at this point are still open */
123         Enumeration JavaDoc openhandlers=this.handlers.elements();
124         while (openhandlers.hasMoreElements()) {
125             Handler handler=(Handler)openhandlers.nextElement();
126             System.err.println("SimpleDaemon: dropping connection "+
127                                handler.getConnectionNumber());
128             handler.close();
129         }
130
131         System.err.println("SimpleDaemon: exiting acceptor loop");
132     }
133
134     protected void addHandler(Handler handler) {
135         synchronized (handler) {
136             this.handlers.add(handler);
137         }
138     }
139
140     protected void removeHandler(Handler handler) {
141         synchronized (handler) {
142             this.handlers.remove(handler);
143         }
144     }
145
146     public static class Handler implements Runnable JavaDoc {
147
148         private DaemonController controller=null;
149         private SimpleDaemon parent=null;
150         private String JavaDoc directory=null;
151         private Socket socket=null;
152         private int number=0;
153
154         public Handler(Socket s, SimpleDaemon p, DaemonController c) {
155             super();
156             this.socket=s;
157             this.parent=p;
158             this.controller=c;
159         }
160
161         public void run() {
162             this.parent.addHandler(this);
163             System.err.println("SimpleDaemon: connection "+this.number+
164                                " opened from "+this.socket.getInetAddress());
165             try {
166                 InputStream in=this.socket.getInputStream();
167                 OutputStream out=this.socket.getOutputStream();
168                 handle(in,out);
169                 this.socket.close();
170             } catch (IOException e) {
171                 e.printStackTrace(System.err);
172             }
173             System.err.println("SimpleDaemon: connection "+this.number+
174                                " closed");
175             this.parent.removeHandler(this);
176         }
177
178         public void close() {
179             try {
180                 this.socket.close();
181             } catch (IOException e) {
182                 e.printStackTrace(System.err);
183             }
184         }
185
186         public void setConnectionNumber(int number) {
187             this.number=number;
188         }
189
190         public int getConnectionNumber() {
191             return(this.number);
192         }
193
194         public void setDirectoryName(String JavaDoc directory) {
195             this.directory=directory;
196         }
197
198         public String JavaDoc getDirectoryName() {
199             return(this.directory);
200         }
201
202         public void createFile(String JavaDoc name)
203         throws IOException {
204             OutputStream file=new FileOutputStream(name,true);
205             PrintStream out=new PrintStream(file);
206             SimpleDateFormat JavaDoc fmt=new SimpleDateFormat JavaDoc();
207
208             out.println(fmt.format(new Date JavaDoc()));
209             out.close();
210             file.close();
211         }
212
213         public void createDir(String JavaDoc name)
214         throws IOException {
215             File file = new File(name);
216             boolean ok = file.mkdirs();
217             if(! ok)
218                 throw new IOException("mkdirs for "+name+" failed");
219             createFile(name);
220         }
221
222         public void handle(InputStream in, OutputStream os) {
223             PrintStream out=null;
224             try {
225                 out=new PrintStream(os, true, "US-ASCII");
226             } catch (UnsupportedEncodingException ex) {
227                 out=new PrintStream(os);
228             }
229
230             while(true) {
231                 try {
232                     /* If we don't have data in the System InputStream, we want
233                        to ask to the user for an option. */

234                     if (in.available()==0) {
235                         out.println();
236                         out.println("Please select one of the following:");
237                         out.println(" 1) Shutdown");
238                         out.println(" 2) Reload");
239                         out.println(" 3) Create a file");
240                         out.println(" 4) Disconnect");
241                         out.println(" 5) Cause a core of the JVM");
242                         out.println(" 6) Create a directory");
243                         out.print("Your choiche: ");
244                     }
245
246                     /* Read an option from the client */
247                     int x=in.read();
248
249                     switch (x) {
250                         /* If the socket was closed, we simply return */
251                         case -1:
252                             return;
253
254                         /* Attempt to shutdown */
255                         case '1':
256                             out.println("Attempting a shutdown...");
257                             try {
258                                 this.controller.shutdown();
259                             } catch (IllegalStateException JavaDoc e) {
260                                 out.println();
261                                 out.println("Can't shutdown now");
262                                 e.printStackTrace(out);
263                             }
264                             break;
265
266                         /* Attempt to reload */
267                         case '2':
268                             out.println("Attempting a reload...");
269                             try {
270                                 this.controller.reload();
271                             } catch (IllegalStateException JavaDoc e) {
272                                 out.println();
273                                 out.println("Can't reload now");
274                                 e.printStackTrace(out);
275                             }
276                             break;
277
278                         /* Create a file */
279                         case '3':
280                             String JavaDoc name=this.getDirectoryName()+
281                                         "/SimpleDaemon."+
282                                         this.getConnectionNumber()+
283                                         ".tmp";
284                             try {
285                                 this.createFile(name);
286                                 out.println("File '"+name+"' created");
287                             } catch (IOException e) {
288                                 e.printStackTrace(out);
289                             }
290                             break;
291
292                         /* Disconnect */
293                         case '4':
294                             out.println("Disconnecting...");
295                             return;
296
297                         /* Crash JVM in a native call: It need an so file ;-) */
298                         case '5':
299                             System.load(System.getProperty("native.library", "./Native.so"));
300                             toto();
301                             break;
302
303                         /* Create a directory (PR 30177 with 1.4.x and 1.5.0 */
304                         case '6':
305                             String JavaDoc name1=this.getDirectoryName()+
306                                         "/a/b/c/d/e"+
307                                         "/SimpleDaemon."+
308                                         this.getConnectionNumber()+
309                                         ".tmp";
310                             try {
311                                 this.createDir(name1);
312                                 out.println("File '"+name1+"' created");
313                             } catch (IOException e) {
314                                 e.printStackTrace(out);
315                             }
316                             break;
317
318
319                         /* Discard any carriage return / newline characters */
320                         case '\r':
321                         case '\n':
322                             break;
323
324                         /* We got something that we weren't supposed to get */
325                         default:
326                             out.println("Unknown option '"+(char)x+"'");
327                             break;
328
329                     }
330
331                 /* If we get an IOException we return (disconnect) */
332                 } catch (IOException e) {
333                     System.err.println("SimpleDaemon: IOException in "+
334                                        "connection "+
335                                        this.getConnectionNumber());
336                     return;
337                 }
338             }
339         }
340     }
341 }
342
Popular Tags