KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > quartz > jobs > NativeJob


1 /*
2  * Copyright 2004-2005 OpenSymphony
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  *
16  */

17
18 /*
19  * Previously Copyright (c) 2001-2004 James House
20  */

21
22 package org.quartz.jobs;
23
24 import java.io.BufferedReader JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.quartz.Job;
32 import org.quartz.JobDataMap;
33 import org.quartz.JobExecutionContext;
34 import org.quartz.JobExecutionException;
35
36 /*
37  * <p> Built in job for executing native executables in a separate process.</p>
38  *
39  * If PROP_WAIT_FOR_PROCESS is true, then the Integer exit value of the process
40  * will be saved as the job execution result in the JobExecutionContext.
41  *
42  * @see #PROP_COMMAND
43  * @see #PROP_PARAMETERS
44  * @see #PROP_WAIT_FOR_PROCESS
45  * @see #PROP_CONSUME_STREAMS
46  *
47  * @author Matthew Payne
48  * @author James House
49  * @author Steinar Overbeck Cook
50  * @date Sep 17, 2003 @Time: 11:27:13 AM
51  */

52 public class NativeJob implements Job {
53
54     private final Log log = LogFactory.getLog(getClass());
55
56     /*
57      *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58      *
59      * Constants.
60      *
61      *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62      */

63         
64     /**
65      * Required parameter that specifies the name of the command (executable)
66      * to be ran.
67      */

68     public static final String JavaDoc PROP_COMMAND = "command";
69     
70     /**
71      * Optional parameter that specifies the parameters to be passed to the
72      * executed command.
73      */

74     public static final String JavaDoc PROP_PARAMETERS = "parameters";
75     
76     
77     /**
78      * Optional parameter (value should be 'true' or 'false') that specifies
79      * whether the job should wait for the execution of the native process to
80      * complete before it completes.
81      *
82      * <p>Defaults to <code>true</code>.</p>
83      */

84     public static final String JavaDoc PROP_WAIT_FOR_PROCESS = "waitForProcess";
85     
86     /**
87      * Optional parameter (value should be 'true' or 'false') that specifies
88      * whether the spawned process's stdout and stderr streams should be
89      * consumed. If the process creates output, it is possible that it might
90      * 'hang' if the streams are not consumed.
91      *
92      * <p>Defaults to <code>false</code>.</p>
93      */

94     public static final String JavaDoc PROP_CONSUME_STREAMS = "consumeStreams";
95     
96     
97     /*
98      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99      *
100      * Interface.
101      *
102      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
103      */

104
105     public void execute(JobExecutionContext context)
106         throws JobExecutionException {
107
108         JobDataMap data = context.getMergedJobDataMap();
109         
110         String JavaDoc command = data.getString(PROP_COMMAND);
111
112         String JavaDoc parameters = data.getString(PROP_PARAMETERS);
113
114         if (parameters == null) {
115             parameters = "";
116         }
117
118         boolean wait = true;
119         if(data.containsKey(PROP_WAIT_FOR_PROCESS)) {
120             wait = data.getBooleanValue(PROP_WAIT_FOR_PROCESS);
121         }
122         boolean consumeStreams = false;
123         if(data.containsKey(PROP_CONSUME_STREAMS)) {
124             consumeStreams = data.getBooleanValue(PROP_CONSUME_STREAMS);
125         }
126             
127         Integer JavaDoc exitCode = this.runNativeCommand(command, parameters, wait, consumeStreams);
128         context.setResult(exitCode);
129         
130     }
131
132     protected Log getLog() {
133         return log;
134     }
135     
136     private Integer JavaDoc runNativeCommand(String JavaDoc command, String JavaDoc parameters, boolean wait, boolean consumeStreams) throws JobExecutionException {
137
138         String JavaDoc[] cmd = null;
139         String JavaDoc[] args = new String JavaDoc[2];
140         Integer JavaDoc result = null;
141         args[0] = command;
142         args[1] = parameters;
143
144         
145         try {
146             //with this variable will be done the swithcing
147
String JavaDoc osName = System.getProperty("os.name");
148
149             //only will work with Windows NT
150
if (osName.equals("Windows NT")) {
151                 if (cmd == null) {
152                     cmd = new String JavaDoc[args.length + 2];
153                 }
154                 cmd[0] = "cmd.exe";
155                 cmd[1] = "/C";
156                 for (int i = 0; i < args.length; i++) {
157                     cmd[i + 2] = args[i];
158                 }
159             } else if (osName.equals("Windows 95")) { //only will work with Windows 95
160
if (cmd == null) {
161                     cmd = new String JavaDoc[args.length + 2];
162                 }
163                 cmd[0] = "command.com";
164                 cmd[1] = "/C";
165                 for (int i = 0; i < args.length; i++) {
166                     cmd[i + 2] = args[i];
167                 }
168             } else if (osName.equals("Windows 2003")) { //only will work with Windows 2003
169
if (cmd == null) {
170                     cmd = new String JavaDoc[args.length + 2];
171                 }
172                 cmd[0] = "cmd.exe";
173                 cmd[1] = "/C";
174
175                 for (int i = 0; i < args.length; i++) {
176                     cmd[i + 2] = args[i];
177                 }
178             } else if (osName.equals("Windows 2000")) { //only will work with Windows 2000
179
if (cmd == null) {
180                     cmd = new String JavaDoc[args.length + 2];
181                 }
182                 cmd[0] = "cmd.exe";
183                 cmd[1] = "/C";
184
185                 for (int i = 0; i < args.length; i++) {
186                     cmd[i + 2] = args[i];
187                 }
188             } else if (osName.equals("Windows XP")) { //only will work with Windows XP
189
if (cmd == null) {
190                     cmd = new String JavaDoc[args.length + 2];
191                 }
192                 cmd[0] = "cmd.exe";
193                 cmd[1] = "/C";
194
195                 for (int i = 0; i < args.length; i++) {
196                     cmd[i + 2] = args[i];
197                 }
198             } else { //will work with the rest (including Linux)
199
cmd = args;
200             }
201
202             Runtime JavaDoc rt = Runtime.getRuntime();
203             // Executes the command
204
getLog().info("About to run" + cmd[0] + cmd[1]);
205             Process JavaDoc proc = rt.exec(cmd);
206             // Consumes the stdout from the process
207
StreamConsumer stdoutConsumer = new StreamConsumer(proc.getInputStream(), "stdout");
208
209             // Consumes the stderr from the process
210
if(consumeStreams) {
211                 StreamConsumer stderrConsumer = new StreamConsumer(proc.getErrorStream(), "stderr");
212                 stdoutConsumer.start();
213                 stderrConsumer.start();
214             }
215             
216             if(wait) {
217                 result = new Integer JavaDoc(proc.waitFor());
218             }
219             // any error message?
220

221         } catch (Exception JavaDoc x) {
222             throw new JobExecutionException("Error launching native command: ", x, false);
223         }
224         
225         return result;
226     }
227
228     /**
229      * Consumes data from the given input stream until EOF and prints the data to stdout
230      *
231      * @author cooste
232      * @author jhouse
233      */

234     class StreamConsumer extends Thread JavaDoc {
235         InputStream JavaDoc is;
236         String JavaDoc type;
237
238         /**
239          *
240          */

241         public StreamConsumer(InputStream JavaDoc inputStream, String JavaDoc type) {
242             this.is = inputStream;
243             this.type = type;
244         }
245
246         /**
247          * Runs this object as a separate thread, printing the contents of the InputStream
248          * supplied during instantiation, to either stdout or stderr
249          */

250         public void run() {
251             BufferedReader JavaDoc br = null;
252             try {
253                 br = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(is));
254                 String JavaDoc line = null;
255
256                 while ((line = br.readLine()) != null) {
257                     if(type.equalsIgnoreCase("stderr")) {
258                         getLog().warn(type + ">" + line);
259                     } else {
260                         getLog().info(type + ">" + line);
261                     }
262                 }
263             } catch (IOException JavaDoc ioe) {
264                 getLog().error("Error consuming " + type + " stream of spawned process.", ioe);
265             } finally {
266                 if(br != null) {
267                     try { br.close(); } catch(Exception JavaDoc ignore) {}
268                 }
269             }
270         }
271     }
272     
273 }
274
Popular Tags