KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > common > Cmd


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: Cmd.java,v 1.11 2005/04/27 12:28:21 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.common;
27
28 import java.io.BufferedReader JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.InputStreamReader JavaDoc;
31 import java.io.PrintStream JavaDoc;
32 import java.util.Enumeration JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Vector JavaDoc;
36
37 import org.objectweb.util.monolog.api.BasicLevel;
38
39 /**
40  * This class allows to run a command in sub-process.
41  * @author Helene Joanin : Initial developer
42  * @author Christophe Ney : Fix to handle arguments containing white spaces.
43  * @author Nozomi Matsumura : GenIC i18n problem. GenIC invoke javac and javac's output has non asc-ii characters,
44  * javac's output did not show collectly.
45  * @author Guillaume Tulloup : Invoke directly the com.sun.tools.javac.Main.compile() method to work around a limitation on Windows.
46  * (See bug #100587)
47  * @author Helene Joanin : Invoke directly the com.sun.tools.rmic.Main.compile() method to work around a limitation on Windows.
48  */

49
50 public class Cmd {
51
52     /**
53      * Class name of the sun javac compiler
54      */

55     private static final String JavaDoc COMPILER_CLASS_NAME = "com.sun.tools.javac.Main";
56     /**
57      * Class name of the sun rmic compiler
58      */

59     private static final String JavaDoc RMICOMPILER_CLASS_NAME = "sun.rmi.rmic.Main";
60
61     /**
62      * Command arguments list (included the command name)
63      */

64     private Vector JavaDoc mCmd = new Vector JavaDoc();
65
66     /**
67      * Command environment variables
68      */

69     private String JavaDoc[] mEnv = null;
70
71     /**
72      * Invoke (or not) the compile method of the corresponding sun compiler class
73      */

74     private boolean tryToInvoke = false;
75
76     /**
77      * Construtor method of Cmd class.
78      * @param cmd command
79      * @param invoke try to invoke directly the method of the java class of the
80      * command
81      */

82     public Cmd(String JavaDoc cmd, boolean invoke) {
83         mCmd.addElement(cmd);
84         tryToInvoke = invoke;
85     }
86
87     /**
88      * Construtor method of Cmd class. Equivalent to Cmd(cmd, false).
89      * @param cmd command
90      */

91     public Cmd(String JavaDoc cmd) {
92         this(cmd, false);
93     }
94
95     /**
96      * Construtor method of Cmd class.
97      * @param cmd command
98      * @param env environment of the command
99      * @param invoke invoke the compile method of the class instead of execute the command
100      */

101     public Cmd(String JavaDoc cmd, String JavaDoc[] env, boolean invoke) {
102         mCmd.addElement(cmd);
103         mEnv = env;
104         tryToInvoke = invoke;
105     }
106
107     /**
108      * Add a new argument to the command.
109      * @param arg argument added to the tail of the command argument list
110      */

111     public void addArgument(String JavaDoc arg) {
112         mCmd.addElement(arg);
113     }
114
115     /**
116      * Add a new argument to the command.
117      * @param args argument added to the tail of the command argument list
118      */

119     public void addArguments(List JavaDoc args) {
120         for (Iterator JavaDoc it = args.iterator(); it.hasNext();) {
121             mCmd.addElement(it.next());
122         }
123     }
124
125     /**
126      * Execute the command. (In case of the exit value of the command is not 0,
127      * the output and error streams of the command is traced.)
128      * @return false if the command cannot be executed, or if its exit value is
129      * not 0.
130      */

131     public boolean run() {
132
133         if (tryToInvoke && (((String JavaDoc) mCmd.get(0)).endsWith("javac"))) {
134             // Bug #100587 fixed to work around a limitation on Windows
135
return compile();
136         }
137         if (tryToInvoke && (((String JavaDoc) mCmd.get(0)).endsWith("rmic"))) {
138             return rmicompile();
139         }
140
141         RunnableStreamListener out, err;
142         Process JavaDoc proc = null;
143         boolean val = true;
144         try {
145             String JavaDoc[] cmd = new String JavaDoc[mCmd.size()];
146             mCmd.copyInto(cmd);
147             proc = Runtime.getRuntime().exec(cmd, mEnv);
148         } catch (IOException JavaDoc e) {
149             TraceCore.logger.log(BasicLevel.ERROR, "exception", e);
150             return (false);
151         }
152         out = new RunnableStreamListener(new BufferedReader JavaDoc(new InputStreamReader JavaDoc(proc.getInputStream())), System.out);
153         new Thread JavaDoc(out, "stdout listener for " + this.toString()).start();
154         err = new RunnableStreamListener(new BufferedReader JavaDoc(new InputStreamReader JavaDoc(proc.getErrorStream())), System.err);
155         new Thread JavaDoc(err, "stderr listener for " + this.toString()).start();
156         try {
157             val = proc.waitFor() == 0;
158         } catch (InterruptedException JavaDoc e) {
159             TraceCore.logger.log(BasicLevel.ERROR, "exception", e);
160             val = false;
161         } finally {
162             // destroy the process
163
if (proc != null) {
164                 proc.destroy();
165             }
166         }
167
168         return (val);
169     }
170
171     /**
172      * invoke the compile method of the compiler javac class
173      * @return false in error case
174      */

175     private boolean compile() {
176         // first arg should not be added because it's the name of the command
177
String JavaDoc[] args = new String JavaDoc[mCmd.size() - 1];
178         for (int i = 0; i < mCmd.size() - 1; i++) {
179             args[i] = (String JavaDoc) mCmd.get(i + 1);
180         }
181
182         try {
183             // Use reflection
184
Class JavaDoc c = Class.forName(COMPILER_CLASS_NAME);
185             Object JavaDoc compiler = c.newInstance();
186             java.lang.reflect.Method JavaDoc compile = c.getMethod("compile", new Class JavaDoc[] {(new String JavaDoc[] {}).getClass()});
187             int result = ((Integer JavaDoc) compile.invoke(compiler, new Object JavaDoc[] {args})).intValue();
188             return (result == 0);
189         } catch (Exception JavaDoc e) {
190             TraceCore.logger.log(BasicLevel.ERROR, "exception", e);
191             return false;
192         }
193     }
194
195     /**
196      * invoke the main method of the rmi compiler rmic class
197      * @return false in error case
198      */

199     private boolean rmicompile() {
200         // first arg should not be added because it's the name of the command
201
String JavaDoc[] args = new String JavaDoc[mCmd.size() - 1];
202         for (int i = 0; i < mCmd.size() - 1; i++) {
203             args[i] = (String JavaDoc) mCmd.get(i + 1);
204         }
205
206         try {
207             // Use reflection
208
Class JavaDoc c = Class.forName(RMICOMPILER_CLASS_NAME);
209             Object JavaDoc compiler = c.newInstance();
210             java.lang.reflect.Method JavaDoc compile = c.getMethod("compile", new Class JavaDoc[] {(new String JavaDoc[] {}).getClass()});
211             int result = ((Integer JavaDoc) compile.invoke(compiler, new Object JavaDoc[] {args})).intValue();
212             return (result == 0);
213         } catch (Exception JavaDoc e) {
214             TraceCore.logger.log(BasicLevel.ERROR, "exception", e);
215             return false;
216         }
217     }
218
219     /**
220      * @return iterator over the command line
221      */

222     public Iterator JavaDoc getCommandLine() {
223         return mCmd.iterator();
224     }
225
226     /**
227      * @return the string representation of the object for UI purpose
228      */

229     public String JavaDoc toString() {
230         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
231         Enumeration JavaDoc e = mCmd.elements();
232         while (e.hasMoreElements()) {
233             String JavaDoc arg = (String JavaDoc) e.nextElement();
234             if (arg == null) {
235                 arg = "null";
236             }
237             for (int i = 0; i < arg.length(); i++) {
238                 if (Character.isWhitespace(arg.charAt(i))) {
239                     arg = "\"" + arg + "\"";
240                     break;
241                 }
242             }
243             buf.append(arg);
244             buf.append(' ');
245         }
246         return buf.toString().trim();
247     }
248
249 }
250
251 /**
252  * To run the command happily, and to swallow the stdout from the process
253  */

254 class RunnableStreamListener implements Runnable JavaDoc {
255
256     BufferedReader JavaDoc in_;
257
258     PrintStream JavaDoc stream_;
259
260     RunnableStreamListener(BufferedReader JavaDoc in, PrintStream JavaDoc stream) {
261         in_ = in;
262         stream_ = stream;
263     }
264
265     public void run() {
266         String JavaDoc line;
267         try {
268             while ((line = in_.readLine()) != null) {
269                 stream_.println(line);
270             }
271         } catch (IOException JavaDoc e) {
272             stream_.println(e.toString());
273         }
274
275     }
276 }
277
278
Popular Tags