KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > launcher > ChildMain


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 package org.apache.commons.launcher;
18
19 import java.awt.Frame JavaDoc;
20 import java.awt.Image JavaDoc;
21 import java.awt.Rectangle JavaDoc;
22 import java.awt.Toolkit JavaDoc;
23 import java.awt.event.WindowAdapter JavaDoc;
24 import java.awt.event.WindowEvent JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.PrintStream JavaDoc;
27 import java.lang.reflect.Method JavaDoc;
28
29 /**
30  * A wrapper class that invokes another class'
31  * <code>main(String[])</code>. This particular class uses several system
32  * properties to control features:
33  * <ul>
34  * <li>Redirecting System.out and System.err.
35  * <li>Displaying a minimized window in the Windows taskbar.
36  * </ul>
37  * This class is normally not invoked directly. Instead, it is invoked by the
38  * {@link LaunchTask} class.
39  *
40  * @author Patrick Luby
41  */

42 public class ChildMain extends Thread JavaDoc {
43
44     //----------------------------------------------------------- Static Fields
45

46     /**
47      * The appendOutput system property name.
48      */

49     public final static String JavaDoc APPEND_OUTPUT_PROP_NAME =
50         "org.apache.commons.launcher.appendOutput";
51
52     /**
53      * The displayMiminizedWindow system property name.
54      */

55     public final static String JavaDoc DISPLAY_MINIMIZED_WINDOW_PROP_NAME =
56         "org.apache.commons.launcher.displayMinimizedWindow";
57
58     /**
59      * The disposeMiminizedWindow system property name.
60      */

61     public final static String JavaDoc DISPOSE_MINIMIZED_WINDOW_PROP_NAME =
62         "org.apache.commons.launcher.disposeMinimizedWindow";
63
64     /**
65      * The executableName system property name.
66      */

67     public final static String JavaDoc EXECUTABLE_PROP_NAME =
68         "org.apache.commons.launcher.executableName";
69
70     /**
71      * The heartbeatFile system property name.
72      */

73     public final static String JavaDoc HEARTBEAT_FILE_PROP_NAME =
74         "org.apache.commons.launcher.heartbeatFile";
75
76     /**
77      * The miminizedWindowTitle system property name.
78      */

79     public final static String JavaDoc MINIMIZED_WINDOW_TITLE_PROP_NAME =
80         "org.apache.commons.launcher.minimizedWindowTitle";
81
82     /**
83      * The miminizedWindowIcon system property name.
84      */

85     public final static String JavaDoc MINIMIZED_WINDOW_ICON_PROP_NAME=
86         "org.apache.commons.launcher.minimizedWindowIcon";
87
88     /**
89      * The outputFile system property name.
90      */

91     public final static String JavaDoc OUTPUT_FILE_PROP_NAME =
92         "org.apache.commons.launcher.outputFile";
93
94     /**
95      * The waitForChild system property name.
96      */

97     public final static String JavaDoc WAIT_FOR_CHILD_PROP_NAME =
98         "org.apache.commons.launcher.waitForChild";
99
100     //------------------------------------------------------------------ Fields
101

102     /**
103      * Cached command line arguments
104      */

105     private String JavaDoc[] args = null;
106
107     //------------------------------------------------------------ Constructors
108

109     /**
110      * Construct an instance of this {@link Thread} subclass and cache the
111      * args parameter for use by the {@link #run()} method.
112      *
113      * @param group the ThreadGroup to use for this thread
114      * @param args the command line arguments
115      */

116     private ChildMain(ThreadGroup JavaDoc group, String JavaDoc[] args) {
117
118         super(group, ChildMain.class.getName());
119         this.args = args;
120
121     }
122
123     //---------------------------------------------------------- Static Methods
124

125     /**
126      * Main entry point for the child process. This method should only be
127      * invoked by the {@link LaunchTask} class.
128      *
129      * @param args command line arguments
130      */

131     public static void main(String JavaDoc[] args) {
132
133         // Invoke the target application in a separate thread so that we
134
// caught any uncaught errors thrown by the target application
135
Thread JavaDoc mainThread = new ChildMain(new ExitOnErrorThreadGroup(ChildMain.class.getName()), args);
136         mainThread.start();
137
138     }
139
140     //----------------------------------------------------------------- Methods
141

142     /**
143      * Invoke the target application.
144      *
145      * @param args command line arguments
146      */

147     public void run() {
148
149         // If there are no arguments, do nothing
150
if (args == null || args.length == 0)
151             return;
152
153         // Invoke the target application
154
try {
155
156             // Start the thread to check if the parent JVM exits.
157
boolean waitForChild = false;
158             if (System.getProperty(ChildMain.WAIT_FOR_CHILD_PROP_NAME) != null) {
159                 waitForChild = true;
160                 String JavaDoc heartbeatFile = System.getProperty(ChildMain.HEARTBEAT_FILE_PROP_NAME);
161                 ParentListener heartbeat = new ParentListener(heartbeatFile);
162                 // Make the thread a daemon thread so that it does not
163
// prevent this process from exiting when all of the
164
// appliation's threads finish.
165
heartbeat.setDaemon(true);
166                 heartbeat.start();
167             }
168
169             // If applicable, redirect output and error streams
170
String JavaDoc outputPath = System.getProperty(ChildMain.OUTPUT_FILE_PROP_NAME);
171             if (outputPath != null) {
172                 boolean appendOutput = false;
173                 if (System.getProperty(ChildMain.APPEND_OUTPUT_PROP_NAME) != null)
174                     appendOutput = true;
175                 PrintStream JavaDoc ps = new PrintStream JavaDoc(new FileOutputStream JavaDoc(outputPath, appendOutput), true);
176                 System.setOut(ps);
177                 System.setErr(ps);
178             }
179
180             // The first argument should be the class that we really want to
181
// invoke. Try to load the class and invoke its main(String[])
182
// method with the first argument shifted out.
183
Class JavaDoc mainClass = Class.forName(args[0]);
184             Class JavaDoc[] paramTypes = new Class JavaDoc[1];
185             Object JavaDoc[] paramValues = new Object JavaDoc[1];
186             String JavaDoc[] params = new String JavaDoc[args.length - 1];
187             // Shift args[0] out of the arguments
188
for (int i = 0; i < params.length; i++)
189                 params[i] = args[i + 1];
190             paramTypes[0] = params.getClass();
191             paramValues[0] = params;
192
193             // Create the icon window if this is a waitForChild task
194
Frame JavaDoc frame = null;
195             boolean displayMinimizedWindow = false;
196             if (System.getProperty(ChildMain.DISPLAY_MINIMIZED_WINDOW_PROP_NAME) != null)
197                 displayMinimizedWindow = true;
198             String JavaDoc osname = System.getProperty("os.name").toLowerCase();
199             if (displayMinimizedWindow && osname.indexOf("windows") >= 0) {
200                 try {
201                     frame = new Frame JavaDoc();
202                     String JavaDoc title = System.getProperty(ChildMain.MINIMIZED_WINDOW_TITLE_PROP_NAME);
203                     if (title != null)
204                         frame.setTitle(title);
205                     frame.setState(Frame.ICONIFIED);
206                     String JavaDoc icon = System.getProperty(ChildMain.MINIMIZED_WINDOW_TITLE_PROP_NAME);
207                     if (icon != null) {
208                         Image JavaDoc iconImage = Toolkit.getDefaultToolkit().createImage(icon);
209                         if (iconImage != null)
210                             frame.setIconImage(iconImage);
211                     }
212
213                     // Ensure that window always remains minimized
214
frame.addWindowListener(new ChildWindowAdapter());
215                     Rectangle JavaDoc bounds = frame.getGraphicsConfiguration().getBounds();
216                     int width = (int)frame.getBounds().getWidth();
217                     int height = frame.getInsets().top + frame.getInsets().bottom;
218                     int x = (int)bounds.getWidth() - width;
219                     int y = (int)bounds.getHeight() - height;
220                     frame.setBounds(x, y, width, height);
221                     frame.setResizable(false);
222                     frame.setVisible(true);
223                 } catch(Exception JavaDoc fe) {}
224             }
225
226             // Invoke the main() method
227
Method JavaDoc mainMethod = mainClass.getDeclaredMethod("main", paramTypes);
228             mainMethod.invoke(null, paramValues);
229
230             // Close the frame if it exists
231
if (frame != null && System.getProperty(ChildMain.DISPOSE_MINIMIZED_WINDOW_PROP_NAME) != null) {
232                 // Exit this process. Closing or disposing of the window is not
233
// enough to allow the process to exit.
234
System.exit(0);
235             }
236
237         } catch (Throwable JavaDoc t) {
238             String JavaDoc message = t.getMessage();
239             t.printStackTrace();
240             System.exit(1);
241         }
242
243     }
244
245     /**
246      * A WindowAdapter subclass that causes the application to exit when its
247      * {@link #windowClosing(WindowEvent)} method is invoked.
248      */

249     private static class ChildWindowAdapter extends WindowAdapter JavaDoc {
250
251         /**
252          * Invoked when a window is in the process of being closed.
253          *
254          * @param e the event
255          */

256         public void windowClosing(WindowEvent JavaDoc e) {
257
258             System.exit(0);
259
260         }
261
262     }
263
264 }
265
Popular Tags