You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Exec.java 8.8 kB

8 years ago
8 years ago
8 years ago
8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * https://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.taskdefs;
  19. import java.io.BufferedReader;
  20. import java.io.File;
  21. import java.io.FileWriter;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.io.InputStreamReader;
  25. import java.io.PrintWriter;
  26. import java.util.Locale;
  27. import org.apache.tools.ant.BuildException;
  28. import org.apache.tools.ant.MagicNames;
  29. import org.apache.tools.ant.Project;
  30. import org.apache.tools.ant.Task;
  31. /**
  32. * Executes a given command if the os platform is appropriate.
  33. *
  34. * <p><strong>As of Ant 1.2, this class is no longer the
  35. * implementation of Ant's &lt;exec&gt; task - it is considered to be
  36. * dead code by the Ant developers and is unmaintained. Don't use
  37. * it.</strong></p>
  38. *
  39. * @deprecated since 1.2.
  40. * delegate to {@link org.apache.tools.ant.taskdefs.Execute Execute}
  41. * instead.
  42. */
  43. @Deprecated
  44. public class Exec extends Task {
  45. private String os;
  46. private String out;
  47. private File dir;
  48. private String command;
  49. // CheckStyle:VisibilityModifier OFF - bc
  50. protected PrintWriter fos = null;
  51. // CheckStyle:VisibilityModifier ON
  52. private boolean failOnError = false;
  53. /**
  54. * Constructor for Exec.
  55. * Prints a warning message to std error.
  56. */
  57. public Exec() {
  58. System.err.println("As of Ant 1.2 released in October 2000, "
  59. + "the Exec class");
  60. System.err.println("is considered to be dead code by the Ant "
  61. + "developers and is unmaintained.");
  62. System.err.println("Don't use it!");
  63. }
  64. /**
  65. * Execute the task.
  66. * @throws BuildException on error
  67. */
  68. @Override
  69. public void execute() throws BuildException {
  70. run(command);
  71. }
  72. /**
  73. * Execute the command.
  74. * @param command the command to exec
  75. * @return the exit value of the command
  76. * @throws BuildException on error
  77. */
  78. protected int run(String command) throws BuildException {
  79. int err = -1; // assume the worst
  80. // test if os match
  81. String myos = System.getProperty("os.name");
  82. log("Myos = " + myos, Project.MSG_VERBOSE);
  83. if (os != null && !os.contains(myos)) {
  84. // this command will be executed only on the specified OS
  85. log("Not found in " + os, Project.MSG_VERBOSE);
  86. return 0;
  87. }
  88. // default directory to the project's base directory
  89. if (dir == null) {
  90. dir = getProject().getBaseDir();
  91. }
  92. if (myos.toLowerCase(Locale.ENGLISH).contains("windows")) {
  93. if (!dir.equals(getProject().resolveFile("."))) {
  94. if (myos.toLowerCase(Locale.ENGLISH).contains("nt")) {
  95. command = "cmd /c cd " + dir + " && " + command;
  96. } else {
  97. String ant = getProject().getProperty(MagicNames.ANT_HOME);
  98. if (ant == null) {
  99. throw new BuildException("Property '" + MagicNames.ANT_HOME + "' not "
  100. + "found", getLocation());
  101. }
  102. String antRun = getProject().resolveFile(ant + "/bin/antRun.bat").toString();
  103. command = antRun + " " + dir + " " + command;
  104. }
  105. }
  106. } else {
  107. String ant = getProject().getProperty(MagicNames.ANT_HOME);
  108. if (ant == null) {
  109. throw new BuildException("Property '" + MagicNames.ANT_HOME + "' not found",
  110. getLocation());
  111. }
  112. String antRun = getProject().resolveFile(ant + "/bin/antRun").toString();
  113. command = antRun + " " + dir + " " + command;
  114. }
  115. try {
  116. // show the command
  117. log(command, Project.MSG_VERBOSE);
  118. // exec command on system runtime
  119. Process proc = Runtime.getRuntime().exec(command);
  120. if (out != null) {
  121. fos = new PrintWriter(new FileWriter(out));
  122. log("Output redirected to " + out, Project.MSG_VERBOSE);
  123. }
  124. // copy input and error to the output stream
  125. StreamPumper inputPumper =
  126. new StreamPumper(proc.getInputStream(), Project.MSG_INFO);
  127. StreamPumper errorPumper =
  128. new StreamPumper(proc.getErrorStream(), Project.MSG_WARN);
  129. // starts pumping away the generated output/error
  130. inputPumper.start();
  131. errorPumper.start();
  132. // Wait for everything to finish
  133. proc.waitFor();
  134. inputPumper.join();
  135. errorPumper.join();
  136. proc.destroy();
  137. // close the output file if required
  138. logFlush();
  139. // check its exit value
  140. err = proc.exitValue();
  141. if (err != 0) {
  142. if (failOnError) {
  143. throw new BuildException("Exec returned: " + err, getLocation());
  144. }
  145. log("Result: " + err, Project.MSG_ERR);
  146. }
  147. } catch (IOException ioe) {
  148. throw new BuildException("Error exec: " + command, ioe, getLocation());
  149. } catch (InterruptedException ex) {
  150. //ignore
  151. }
  152. return err;
  153. }
  154. /**
  155. * Set the directory.
  156. * @param d a <code>String</code> value
  157. */
  158. public void setDir(String d) {
  159. this.dir = getProject().resolveFile(d);
  160. }
  161. /**
  162. * Set the Operating System that this exec is to run in.
  163. * @param os a <code>String</code> value
  164. */
  165. public void setOs(String os) {
  166. this.os = os;
  167. }
  168. /**
  169. * Set the command to exec.
  170. * @param command a <code>String</code> value
  171. */
  172. public void setCommand(String command) {
  173. this.command = command;
  174. }
  175. /**
  176. * Set the output filename.
  177. * @param out a <code>String</code> value
  178. */
  179. public void setOutput(String out) {
  180. this.out = out;
  181. }
  182. /**
  183. * Set the failOnError attribute.
  184. * Default is false.
  185. * @param fail a <code>boolean</code> value
  186. */
  187. public void setFailonerror(boolean fail) {
  188. failOnError = fail;
  189. }
  190. /**
  191. * Log an output message.
  192. * @param line the line to putput
  193. * @param messageLevel the level of logging - ignored
  194. * if output is going to a file
  195. */
  196. protected void outputLog(String line, int messageLevel) {
  197. if (fos == null) {
  198. log(line, messageLevel);
  199. } else {
  200. fos.println(line);
  201. }
  202. }
  203. /**
  204. * Close output.
  205. */
  206. protected void logFlush() {
  207. if (fos != null) {
  208. fos.close();
  209. }
  210. }
  211. // Inner class for continually pumping the input stream during
  212. // Process's runtime.
  213. class StreamPumper extends Thread {
  214. private BufferedReader din;
  215. private int messageLevel;
  216. private boolean endOfStream = false;
  217. private static final int SLEEP_TIME = 5;
  218. public StreamPumper(InputStream is, int messageLevel) {
  219. this.din = new BufferedReader(new InputStreamReader(is));
  220. this.messageLevel = messageLevel;
  221. }
  222. public void pumpStream() throws IOException {
  223. if (!endOfStream) {
  224. String line = din.readLine();
  225. if (line != null) {
  226. outputLog(line, messageLevel);
  227. } else {
  228. endOfStream = true;
  229. }
  230. }
  231. }
  232. @Override
  233. public void run() {
  234. try {
  235. try {
  236. while (!endOfStream) {
  237. pumpStream();
  238. sleep(SLEEP_TIME);
  239. }
  240. } catch (InterruptedException ie) {
  241. //ignore
  242. }
  243. din.close();
  244. } catch (IOException ioe) {
  245. // ignore
  246. }
  247. }
  248. }
  249. }