1. /*
  2. * Copyright 2000,2002,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.tools.ant.taskdefs;
  18. import java.io.BufferedReader;
  19. import java.io.File;
  20. import java.io.FileWriter;
  21. import java.io.IOException;
  22. import java.io.InputStream;
  23. import java.io.InputStreamReader;
  24. import java.io.PrintWriter;
  25. import org.apache.tools.ant.BuildException;
  26. import org.apache.tools.ant.Project;
  27. import org.apache.tools.ant.Task;
  28. /**
  29. * Executes a given command if the os platform is appropriate.
  30. *
  31. * <p><strong>As of Ant 1.2, this class is no longer the
  32. * implementation of Ant's <exec> task - it is considered to be
  33. * dead code by the Ant developers and is unmaintained. Don't use
  34. * it.</strong></p>
  35. *
  36. * @deprecated delegate to {@link org.apache.tools.ant.taskdefs.Execute Execute}
  37. * instead.
  38. */
  39. public class Exec extends Task {
  40. private String os;
  41. private String out;
  42. private File dir;
  43. private String command;
  44. protected PrintWriter fos = null;
  45. private boolean failOnError = false;
  46. public Exec() {
  47. System.err.println("As of Ant 1.2 released in October 2000, "
  48. + "the Exec class");
  49. System.err.println("is considered to be dead code by the Ant "
  50. + "developers and is unmaintained.");
  51. System.err.println("Don\'t use it!");
  52. }
  53. public void execute() throws BuildException {
  54. run(command);
  55. }
  56. protected int run(String command) throws BuildException {
  57. int err = -1; // assume the worst
  58. // test if os match
  59. String myos = System.getProperty("os.name");
  60. log("Myos = " + myos, Project.MSG_VERBOSE);
  61. if ((os != null) && (os.indexOf(myos) < 0)) {
  62. // this command will be executed only on the specified OS
  63. log("Not found in " + os, Project.MSG_VERBOSE);
  64. return 0;
  65. }
  66. // default directory to the project's base directory
  67. if (dir == null) {
  68. dir = getProject().getBaseDir();
  69. }
  70. if (myos.toLowerCase().indexOf("windows") >= 0) {
  71. if (!dir.equals(getProject().resolveFile("."))) {
  72. if (myos.toLowerCase().indexOf("nt") >= 0) {
  73. command = "cmd /c cd " + dir + " && " + command;
  74. } else {
  75. String ant = getProject().getProperty("ant.home");
  76. if (ant == null) {
  77. throw new BuildException("Property 'ant.home' not "
  78. + "found", getLocation());
  79. }
  80. String antRun = getProject().resolveFile(ant + "/bin/antRun.bat").toString();
  81. command = antRun + " " + dir + " " + command;
  82. }
  83. }
  84. } else {
  85. String ant = getProject().getProperty("ant.home");
  86. if (ant == null) {
  87. throw new BuildException("Property 'ant.home' not found",
  88. getLocation());
  89. }
  90. String antRun = getProject().resolveFile(ant + "/bin/antRun").toString();
  91. command = antRun + " " + dir + " " + command;
  92. }
  93. try {
  94. // show the command
  95. log(command, Project.MSG_VERBOSE);
  96. // exec command on system runtime
  97. Process proc = Runtime.getRuntime().exec(command);
  98. if (out != null) {
  99. fos = new PrintWriter(new FileWriter(out));
  100. log("Output redirected to " + out, Project.MSG_VERBOSE);
  101. }
  102. // copy input and error to the output stream
  103. StreamPumper inputPumper =
  104. new StreamPumper(proc.getInputStream(), Project.MSG_INFO);
  105. StreamPumper errorPumper =
  106. new StreamPumper(proc.getErrorStream(), Project.MSG_WARN);
  107. // starts pumping away the generated output/error
  108. inputPumper.start();
  109. errorPumper.start();
  110. // Wait for everything to finish
  111. proc.waitFor();
  112. inputPumper.join();
  113. errorPumper.join();
  114. proc.destroy();
  115. // close the output file if required
  116. logFlush();
  117. // check its exit value
  118. err = proc.exitValue();
  119. if (err != 0) {
  120. if (failOnError) {
  121. throw new BuildException("Exec returned: " + err, getLocation());
  122. } else {
  123. log("Result: " + err, Project.MSG_ERR);
  124. }
  125. }
  126. } catch (IOException ioe) {
  127. throw new BuildException("Error exec: " + command, ioe, getLocation());
  128. } catch (InterruptedException ex) {
  129. //ignore
  130. }
  131. return err;
  132. }
  133. public void setDir(String d) {
  134. this.dir = getProject().resolveFile(d);
  135. }
  136. public void setOs(String os) {
  137. this.os = os;
  138. }
  139. public void setCommand(String command) {
  140. this.command = command;
  141. }
  142. public void setOutput(String out) {
  143. this.out = out;
  144. }
  145. public void setFailonerror(boolean fail) {
  146. failOnError = fail;
  147. }
  148. protected void outputLog(String line, int messageLevel) {
  149. if (fos == null) {
  150. log(line, messageLevel);
  151. } else {
  152. fos.println(line);
  153. }
  154. }
  155. protected void logFlush() {
  156. if (fos != null) {
  157. fos.close();
  158. }
  159. }
  160. // Inner class for continually pumping the input stream during
  161. // Process's runtime.
  162. class StreamPumper extends Thread {
  163. private BufferedReader din;
  164. private int messageLevel;
  165. private boolean endOfStream = false;
  166. private int SLEEP_TIME = 5;
  167. public StreamPumper(InputStream is, int messageLevel) {
  168. this.din = new BufferedReader(new InputStreamReader(is));
  169. this.messageLevel = messageLevel;
  170. }
  171. public void pumpStream() throws IOException {
  172. if (!endOfStream) {
  173. String line = din.readLine();
  174. if (line != null) {
  175. outputLog(line, messageLevel);
  176. } else {
  177. endOfStream = true;
  178. }
  179. }
  180. }
  181. public void run() {
  182. try {
  183. try {
  184. while (!endOfStream) {
  185. pumpStream();
  186. sleep(SLEEP_TIME);
  187. }
  188. } catch (InterruptedException ie) {
  189. //ignore
  190. }
  191. din.close();
  192. } catch (IOException ioe) {
  193. // ignore
  194. }
  195. }
  196. }
  197. }