1 18 19 package org.apache.tools.ant.taskdefs; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.util.Enumeration ; 24 import java.util.Vector ; 25 import java.util.Locale ; 26 27 import org.apache.tools.ant.BuildException; 28 import org.apache.tools.ant.Project; 29 import org.apache.tools.ant.Task; 30 import org.apache.tools.ant.taskdefs.condition.Os; 31 import org.apache.tools.ant.types.Commandline; 32 import org.apache.tools.ant.types.Environment; 33 import org.apache.tools.ant.types.Path; 34 import org.apache.tools.ant.types.RedirectorElement; 35 import org.apache.tools.ant.util.FileUtils; 36 37 44 public class ExecTask extends Task { 45 46 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 48 49 private String os; 50 private String osFamily; 51 52 private File dir; 53 protected boolean failOnError = false; 54 protected boolean newEnvironment = false; 55 private Long timeout = null; 56 private Environment env = new Environment(); 57 protected Commandline cmdl = new Commandline(); 58 private String resultProperty; 59 private boolean failIfExecFails = true; 60 private String executable; 61 private boolean resolveExecutable = false; 62 private boolean searchPath = false; 63 private boolean spawn = false; 64 private boolean incompatibleWithSpawn = false; 65 66 private String inputString; 68 private File input; 69 private File output; 70 private File error; 71 72 protected Redirector redirector = new Redirector(this); 73 protected RedirectorElement redirectorElement; 74 76 80 private boolean vmLauncher = true; 81 82 83 87 public ExecTask() { 88 } 89 90 96 public ExecTask(Task owner) { 97 bindToOwner(owner); 98 } 99 100 106 public void setSpawn(boolean spawn) { 107 this.spawn = spawn; 108 } 109 110 117 public void setTimeout(Long value) { 118 timeout = value; 119 incompatibleWithSpawn = true; 120 } 121 122 127 public void setTimeout(Integer value) { 128 setTimeout( 129 (Long ) ((value == null) ? null : new Long (value.intValue()))); 130 } 131 132 136 public void setExecutable(String value) { 137 this.executable = value; 138 cmdl.setExecutable(value); 139 } 140 141 145 public void setDir(File d) { 146 this.dir = d; 147 } 148 149 153 public void setOs(String os) { 154 this.os = os; 155 } 156 157 162 public void setCommand(Commandline cmdl) { 163 log("The command attribute is deprecated.\n" 164 + "Please use the executable attribute and nested arg elements.", 165 Project.MSG_WARN); 166 this.cmdl = cmdl; 167 } 168 169 175 public void setOutput(File out) { 176 this.output = out; 177 incompatibleWithSpawn = true; 178 } 179 180 185 public void setInput(File input) { 186 if (inputString != null) { 187 throw new BuildException("The \"input\" and \"inputstring\" " 188 + "attributes cannot both be specified"); 189 } 190 this.input = input; 191 incompatibleWithSpawn = true; 192 } 193 194 199 public void setInputString(String inputString) { 200 if (input != null) { 201 throw new BuildException("The \"input\" and \"inputstring\" " 202 + "attributes cannot both be specified"); 203 } 204 this.inputString = inputString; 205 incompatibleWithSpawn = true; 206 } 207 208 214 public void setLogError(boolean logError) { 215 redirector.setLogError(logError); 216 incompatibleWithSpawn |= logError; 217 } 218 219 226 public void setError(File error) { 227 this.error = error; 228 incompatibleWithSpawn = true; 229 } 230 231 237 public void setOutputproperty(String outputProp) { 238 redirector.setOutputProperty(outputProp); 239 incompatibleWithSpawn = true; 240 } 241 242 250 public void setErrorProperty(String errorProperty) { 251 redirector.setErrorProperty(errorProperty); 252 incompatibleWithSpawn = true; 253 } 254 255 260 public void setFailonerror(boolean fail) { 261 failOnError = fail; 262 incompatibleWithSpawn |= fail; 263 } 264 265 271 public void setNewenvironment(boolean newenv) { 272 newEnvironment = newenv; 273 } 274 275 281 public void setResolveExecutable(boolean resolveExecutable) { 282 this.resolveExecutable = resolveExecutable; 283 } 284 285 291 public void setSearchPath(boolean searchPath) { 292 this.searchPath = searchPath; 293 } 294 295 302 public boolean getResolveExecutable() { 303 return resolveExecutable; 304 } 305 306 311 public void addEnv(Environment.Variable var) { 312 env.addVariable(var); 313 } 314 315 320 public Commandline.Argument createArg() { 321 return cmdl.createArgument(); 322 } 323 324 332 public void setResultProperty(String resultProperty) { 333 this.resultProperty = resultProperty; 334 incompatibleWithSpawn = true; 335 } 336 337 343 protected void maybeSetResultPropertyValue(int result) { 344 if (resultProperty != null) { 345 String res = Integer.toString(result); 346 getProject().setNewProperty(resultProperty, res); 347 } 348 } 349 350 358 public void setFailIfExecutionFails(boolean flag) { 359 failIfExecFails = flag; 360 incompatibleWithSpawn = true; 361 } 362 363 371 public void setAppend(boolean append) { 372 redirector.setAppend(append); 373 incompatibleWithSpawn = true; 374 } 375 376 382 public void addConfiguredRedirector(RedirectorElement redirectorElement) { 383 if (this.redirectorElement != null) { 384 throw new BuildException("cannot have > 1 nested <redirector>s"); 385 } 386 this.redirectorElement = redirectorElement; 387 incompatibleWithSpawn = true; 388 } 389 390 391 395 public void setOsFamily(String osFamily) { 396 this.osFamily = osFamily.toLowerCase(Locale.US); 397 } 398 399 400 413 protected String resolveExecutable(String exec, boolean mustSearchPath) { 414 if (!resolveExecutable) { 415 return exec; 416 } 417 File executableFile = getProject().resolveFile(exec); 419 if (executableFile.exists()) { 420 return executableFile.getAbsolutePath(); 421 } 422 if (dir != null) { 424 executableFile = FILE_UTILS.resolveFile(dir, exec); 425 if (executableFile.exists()) { 426 return executableFile.getAbsolutePath(); 427 } 428 } 429 if (mustSearchPath) { 431 Path p = null; 432 String [] environment = env.getVariables(); 433 if (environment != null) { 434 for (int i = 0; i < environment.length; i++) { 435 if (isPath(environment[i])) { 436 p = new Path(getProject(), environment[i].substring(5)); 437 break; 438 } 439 } 440 } 441 if (p == null) { 442 Vector envVars = Execute.getProcEnvironment(); 443 Enumeration e = envVars.elements(); 444 while (e.hasMoreElements()) { 445 String line = (String ) e.nextElement(); 446 if (isPath(line)) { 447 p = new Path(getProject(), line.substring(5)); 448 break; 449 } 450 } 451 } 452 if (p != null) { 453 String [] dirs = p.list(); 454 for (int i = 0; i < dirs.length; i++) { 455 executableFile 456 = FILE_UTILS.resolveFile(new File (dirs[i]), exec); 457 if (executableFile.exists()) { 458 return executableFile.getAbsolutePath(); 459 } 460 } 461 } 462 } 463 return exec; 466 } 467 468 478 public void execute() throws BuildException { 479 if (!isValidOs()) { 481 return; 482 } 483 File savedDir = dir; cmdl.setExecutable(resolveExecutable(executable, searchPath)); 485 checkConfiguration(); 486 try { 487 runExec(prepareExec()); 488 } finally { 489 dir = savedDir; 490 } 491 } 492 493 497 protected void checkConfiguration() throws BuildException { 498 if (cmdl.getExecutable() == null) { 499 throw new BuildException("no executable specified", getLocation()); 500 } 501 if (dir != null && !dir.exists()) { 502 throw new BuildException("The directory " + dir + " does not exist"); 503 } 504 if (dir != null && !dir.isDirectory()) { 505 throw new BuildException(dir + " is not a directory"); 506 } 507 if (spawn && incompatibleWithSpawn) { 508 getProject().log("spawn does not allow attributes related to input, " 509 + "output, error, result", Project.MSG_ERR); 510 getProject().log("spawn also does not allow timeout", Project.MSG_ERR); 511 getProject().log("finally, spawn is not compatible " 512 + "with a nested I/O <redirector>", Project.MSG_ERR); 513 throw new BuildException("You have used an attribute " 514 + "or nested element which is not compatible with spawn"); 515 } 516 setupRedirector(); 517 } 518 519 522 protected void setupRedirector() { 523 redirector.setInput(input); 524 redirector.setInputString(inputString); 525 redirector.setOutput(output); 526 redirector.setError(error); 527 } 528 529 546 protected boolean isValidOs() { 547 if (osFamily != null && !Os.isOs(osFamily, null, null, null)) { 549 return false; 550 } 551 String myos = System.getProperty("os.name"); 555 log("Current OS is " + myos, Project.MSG_VERBOSE); 556 if ((os != null) && (os.indexOf(myos) < 0)) { 557 log("This OS, " + myos 559 + " was not found in the specified list of valid OSes: " + os, 560 Project.MSG_VERBOSE); 561 return false; 562 } 563 return true; 564 } 565 566 572 public void setVMLauncher(boolean vmLauncher) { 573 this.vmLauncher = vmLauncher; 574 } 575 576 583 protected Execute prepareExec() throws BuildException { 584 if (dir == null) { 586 dir = getProject().getBaseDir(); 587 } 588 if (redirectorElement != null) { 589 redirectorElement.configure(redirector); 590 } 591 Execute exe = new Execute(createHandler(), createWatchdog()); 592 exe.setAntRun(getProject()); 593 exe.setWorkingDirectory(dir); 594 exe.setVMLauncher(vmLauncher); 595 exe.setSpawn(spawn); 596 String [] environment = env.getVariables(); 597 if (environment != null) { 598 for (int i = 0; i < environment.length; i++) { 599 log("Setting environment variable: " + environment[i], 600 Project.MSG_VERBOSE); 601 } 602 } 603 exe.setNewenvironment(newEnvironment); 604 exe.setEnvironment(environment); 605 return exe; 606 } 607 608 617 protected final void runExecute(Execute exe) throws IOException { 618 int returnCode = -1; 620 if (!spawn) { 621 returnCode = exe.execute(); 622 623 if (exe.killedProcess()) { 625 String msg = "Timeout: killed the sub-process"; 626 if (failOnError) { 627 throw new BuildException(msg); 628 } else { 629 log(msg, Project.MSG_WARN); 630 } 631 } 632 maybeSetResultPropertyValue(returnCode); 633 redirector.complete(); 634 if (Execute.isFailure(returnCode)) { 635 if (failOnError) { 636 throw new BuildException(getTaskType() + " returned: " 637 + returnCode, getLocation()); 638 } else { 639 log("Result: " + returnCode, Project.MSG_ERR); 640 } 641 } 642 } else { 643 exe.spawn(); 644 } 645 } 646 647 656 protected void runExec(Execute exe) throws BuildException { 657 log(cmdl.describeCommand(), Project.MSG_VERBOSE); 659 660 exe.setCommandline(cmdl.getCommandline()); 661 try { 662 runExecute(exe); 663 } catch (IOException e) { 664 if (failIfExecFails) { 665 throw new BuildException("Execute failed: " + e.toString(), e, 666 getLocation()); 667 } else { 668 log("Execute failed: " + e.toString(), Project.MSG_ERR); 669 } 670 } finally { 671 logFlush(); 673 } 674 } 675 676 683 protected ExecuteStreamHandler createHandler() throws BuildException { 684 return redirector.createHandler(); 685 } 686 687 694 protected ExecuteWatchdog createWatchdog() throws BuildException { 695 return (timeout == null) 696 ? null : new ExecuteWatchdog(timeout.longValue()); 697 } 698 699 702 protected void logFlush() { 703 } 704 705 private boolean isPath(String line) { 706 return line.startsWith("PATH=") || line.startsWith("Path="); 707 } 708 709 } 710 | Popular Tags |