1 18 19 package org.apache.tools.ant.taskdefs; 20 21 import java.io.File ; 22 import java.io.FileOutputStream ; 23 import java.io.IOException ; 24 import java.io.PrintStream ; 25 import java.lang.reflect.Method ; 26 import java.util.Enumeration ; 27 import java.util.Hashtable ; 28 import java.util.Iterator ; 29 import java.util.Vector ; 30 import java.util.Set ; 31 import java.util.HashSet ; 32 import org.apache.tools.ant.BuildException; 33 import org.apache.tools.ant.BuildListener; 34 import org.apache.tools.ant.DefaultLogger; 35 import org.apache.tools.ant.Project; 36 import org.apache.tools.ant.ProjectComponent; 37 import org.apache.tools.ant.ProjectHelper; 38 import org.apache.tools.ant.Target; 39 import org.apache.tools.ant.Task; 40 import org.apache.tools.ant.MagicNames; 41 import org.apache.tools.ant.Main; 42 import org.apache.tools.ant.types.PropertySet; 43 import org.apache.tools.ant.util.FileUtils; 44 45 66 public class Ant extends Task { 67 68 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 69 70 71 private File dir = null; 72 73 77 private String antFile = null; 78 79 80 private String output = null; 81 82 83 private boolean inheritAll = true; 84 85 86 private boolean inheritRefs = false; 87 88 89 private Vector properties = new Vector (); 90 91 92 private Vector references = new Vector (); 93 94 95 private Project newProject; 96 97 98 private PrintStream out = null; 99 100 101 private Vector propertySets = new Vector (); 102 103 104 private Vector targets = new Vector (); 105 106 107 private boolean targetAttributeSet = false; 108 109 112 public Ant() { 113 } 115 116 120 public Ant(Task owner) { 121 bindToOwner(owner); 122 } 123 124 125 130 public void setInheritAll(boolean value) { 131 inheritAll = value; 132 } 133 134 139 public void setInheritRefs(boolean value) { 140 inheritRefs = value; 141 } 142 143 146 public void init() { 147 newProject = getProject().createSubProject(); 148 newProject.setJavaVersionProperty(); 149 } 150 151 161 private void reinit() { 162 init(); 163 } 164 165 172 private void initializeProject() { 173 newProject.setInputHandler(getProject().getInputHandler()); 174 175 Iterator iter = getBuildListeners(); 176 while (iter.hasNext()) { 177 newProject.addBuildListener((BuildListener) iter.next()); 178 } 179 180 if (output != null) { 181 File outfile = null; 182 if (dir != null) { 183 outfile = FILE_UTILS.resolveFile(dir, output); 184 } else { 185 outfile = getProject().resolveFile(output); 186 } 187 try { 188 out = new PrintStream (new FileOutputStream (outfile)); 189 DefaultLogger logger = new DefaultLogger(); 190 logger.setMessageOutputLevel(Project.MSG_INFO); 191 logger.setOutputPrintStream(out); 192 logger.setErrorPrintStream(out); 193 newProject.addBuildListener(logger); 194 } catch (IOException ex) { 195 log("Ant: Can't set output to " + output); 196 } 197 } 198 getProject().copyUserProperties(newProject); 200 201 if (!inheritAll) { 202 newProject.setSystemProperties(); 205 206 } else { 207 addAlmostAll(getProject().getProperties()); 209 } 210 211 Enumeration e = propertySets.elements(); 212 while (e.hasMoreElements()) { 213 PropertySet ps = (PropertySet) e.nextElement(); 214 addAlmostAll(ps.getProperties()); 215 } 216 } 217 218 226 public void handleOutput(String outputToHandle) { 227 if (newProject != null) { 228 newProject.demuxOutput(outputToHandle, false); 229 } else { 230 super.handleOutput(outputToHandle); 231 } 232 } 233 234 248 public int handleInput(byte[] buffer, int offset, int length) 249 throws IOException { 250 if (newProject != null) { 251 return newProject.demuxInput(buffer, offset, length); 252 } 253 return super.handleInput(buffer, offset, length); 254 } 255 256 264 public void handleFlush(String toFlush) { 265 if (newProject != null) { 266 newProject.demuxFlush(toFlush, false); 267 } else { 268 super.handleFlush(toFlush); 269 } 270 } 271 272 281 public void handleErrorOutput(String errorOutputToHandle) { 282 if (newProject != null) { 283 newProject.demuxOutput(errorOutputToHandle, true); 284 } else { 285 super.handleErrorOutput(errorOutputToHandle); 286 } 287 } 288 289 297 public void handleErrorFlush(String errorOutputToFlush) { 298 if (newProject != null) { 299 newProject.demuxFlush(errorOutputToFlush, true); 300 } else { 301 super.handleErrorFlush(errorOutputToFlush); 302 } 303 } 304 305 310 public void execute() throws BuildException { 311 File savedDir = dir; 312 String savedAntFile = antFile; 313 Vector locals = new Vector (targets); 314 try { 315 getNewProject(); 316 317 if (dir == null && inheritAll) { 318 dir = getProject().getBaseDir(); 319 } 320 321 initializeProject(); 322 323 if (dir != null) { 324 newProject.setBaseDir(dir); 325 if (savedDir != null) { 326 newProject.setInheritedProperty(MagicNames.PROJECT_BASEDIR, 328 dir.getAbsolutePath()); 329 } 330 } else { 331 dir = getProject().getBaseDir(); 332 } 333 334 overrideProperties(); 335 336 if (antFile == null) { 337 antFile = Main.DEFAULT_BUILD_FILENAME; 338 } 339 340 File file = FILE_UTILS.resolveFile(dir, antFile); 341 antFile = file.getAbsolutePath(); 342 343 log("calling target(s) " 344 + ((locals.size() > 0) ? locals.toString() : "[default]") 345 + " in build file " + antFile, Project.MSG_VERBOSE); 346 newProject.setUserProperty(MagicNames.ANT_FILE , antFile); 347 348 String thisAntFile = getProject().getProperty(MagicNames.ANT_FILE); 349 if (thisAntFile != null 352 && file.equals(getProject().resolveFile(thisAntFile)) 353 && getOwningTarget() != null) { 354 355 if (getOwningTarget().getName().equals("")) { 356 if (getTaskName().equals("antcall")) { 357 throw new BuildException("antcall must not be used at" 358 + " the top level."); 359 } 360 throw new BuildException(getTaskName() + " task at the" 361 + " top level must not invoke" 362 + " its own build file."); 363 } 364 } 365 366 try { 367 ProjectHelper.configureProject(newProject, file); 368 } catch (BuildException ex) { 369 throw ProjectHelper.addLocationToBuildException( 370 ex, getLocation()); 371 } 372 373 if (locals.size() == 0) { 374 String defaultTarget = newProject.getDefaultTarget(); 375 if (defaultTarget != null) { 376 locals.add(defaultTarget); 377 } 378 } 379 380 if (newProject.getProperty(MagicNames.ANT_FILE) 381 .equals(getProject().getProperty(MagicNames.ANT_FILE)) 382 && getOwningTarget() != null) { 383 384 String owningTargetName = getOwningTarget().getName(); 385 386 if (locals.contains(owningTargetName)) { 387 throw new BuildException(getTaskName() + " task calling " 388 + "its own parent target."); 389 } 390 boolean circular = false; 391 for (Iterator it = locals.iterator(); 392 !circular && it.hasNext();) { 393 Target other = 394 (Target) (getProject().getTargets().get(it.next())); 395 circular |= (other != null 396 && other.dependsOn(owningTargetName)); 397 } 398 if (circular) { 399 throw new BuildException(getTaskName() 400 + " task calling a target" 401 + " that depends on" 402 + " its parent target \'" 403 + owningTargetName 404 + "\'."); 405 } 406 } 407 408 addReferences(); 409 410 if (locals.size() > 0 && !(locals.size() == 1 411 && "".equals(locals.get(0)))) { 412 BuildException be = null; 413 try { 414 log("Entering " + antFile + "...", Project.MSG_VERBOSE); 415 newProject.fireSubBuildStarted(); 416 newProject.executeTargets(locals); 417 } catch (BuildException ex) { 418 be = ProjectHelper 419 .addLocationToBuildException(ex, getLocation()); 420 throw be; 421 } finally { 422 log("Exiting " + antFile + ".", Project.MSG_VERBOSE); 423 newProject.fireSubBuildFinished(be); 424 } 425 } 426 } finally { 427 newProject = null; 429 Enumeration e = properties.elements(); 430 while (e.hasMoreElements()) { 431 Property p = (Property) e.nextElement(); 432 p.setProject(null); 433 } 434 435 if (output != null && out != null) { 436 try { 437 out.close(); 438 } catch (final Exception ex) { 439 } 441 } 442 dir = savedDir; 443 antFile = savedAntFile; 444 } 445 } 446 447 452 private void overrideProperties() throws BuildException { 453 Set set = new HashSet (); 456 for (int i = properties.size() - 1; i >= 0; --i) { 457 Property p = (Property) properties.get(i); 458 if (p.getName() != null && !p.getName().equals("")) { 459 if (set.contains(p.getName())) { 460 properties.remove(i); 461 } else { 462 set.add(p.getName()); 463 } 464 } 465 } 466 Enumeration e = properties.elements(); 467 while (e.hasMoreElements()) { 468 Property p = (Property) e.nextElement(); 469 p.setProject(newProject); 470 p.execute(); 471 } 472 getProject().copyInheritedProperties(newProject); 473 } 474 475 482 private void addReferences() throws BuildException { 483 Hashtable thisReferences 484 = (Hashtable ) getProject().getReferences().clone(); 485 Hashtable newReferences = newProject.getReferences(); 486 Enumeration e; 487 if (references.size() > 0) { 488 for (e = references.elements(); e.hasMoreElements();) { 489 Reference ref = (Reference) e.nextElement(); 490 String refid = ref.getRefId(); 491 if (refid == null) { 492 throw new BuildException("the refid attribute is required" 493 + " for reference elements"); 494 } 495 if (!thisReferences.containsKey(refid)) { 496 log("Parent project doesn't contain any reference '" 497 + refid + "'", 498 Project.MSG_WARN); 499 continue; 500 } 501 502 thisReferences.remove(refid); 503 String toRefid = ref.getToRefid(); 504 if (toRefid == null) { 505 toRefid = refid; 506 } 507 copyReference(refid, toRefid); 508 } 509 } 510 511 if (inheritRefs) { 514 for (e = thisReferences.keys(); e.hasMoreElements();) { 515 String key = (String ) e.nextElement(); 516 if (newReferences.containsKey(key)) { 517 continue; 518 } 519 copyReference(key, key); 520 newProject.inheritIDReferences(getProject()); 521 } 522 } 523 } 524 525 534 private void copyReference(String oldKey, String newKey) { 535 Object orig = getProject().getReference(oldKey); 536 if (orig == null) { 537 log("No object referenced by " + oldKey + ". Can't copy to " 538 + newKey, 539 Project.MSG_WARN); 540 return; 541 } 542 543 Class c = orig.getClass(); 544 Object copy = orig; 545 try { 546 Method cloneM = c.getMethod("clone", new Class [0]); 547 if (cloneM != null) { 548 copy = cloneM.invoke(orig, new Object [0]); 549 log("Adding clone of reference " + oldKey, Project.MSG_DEBUG); 550 } 551 } catch (Exception e) { 552 } 554 555 556 if (copy instanceof ProjectComponent) { 557 ((ProjectComponent) copy).setProject(newProject); 558 } else { 559 try { 560 Method setProjectM = 561 c.getMethod("setProject", new Class [] {Project.class}); 562 if (setProjectM != null) { 563 setProjectM.invoke(copy, new Object [] {newProject}); 564 } 565 } catch (NoSuchMethodException e) { 566 } catch (Exception e2) { 569 String msg = "Error setting new project instance for " 570 + "reference with id " + oldKey; 571 throw new BuildException(msg, e2, getLocation()); 572 } 573 } 574 newProject.addReference(newKey, copy); 575 } 576 577 585 private void addAlmostAll(Hashtable props) { 586 Enumeration e = props.keys(); 587 while (e.hasMoreElements()) { 588 String key = e.nextElement().toString(); 589 if (MagicNames.PROJECT_BASEDIR.equals(key) || MagicNames.ANT_FILE.equals(key)) { 590 continue; 592 } 593 594 String value = props.get(key).toString(); 595 if (newProject.getProperty(key) == null) { 597 newProject.setNewProperty(key, value); 599 } 600 } 601 } 602 603 610 public void setDir(File dir) { 611 this.dir = dir; 612 } 613 614 619 public void setAntfile(String antFile) { 620 this.antFile = antFile; 624 } 625 626 631 public void setTarget(String targetToAdd) { 632 if (targetToAdd.equals("")) { 633 throw new BuildException("target attribute must not be empty"); 634 } 635 targets.add(targetToAdd); 636 targetAttributeSet = true; 637 } 638 639 645 public void setOutput(String outputFile) { 646 this.output = outputFile; 647 } 648 649 654 public Property createProperty() { 655 Property p = new Property(true, getProject()); 656 p.setProject(getNewProject()); 657 p.setTaskName("property"); 658 properties.addElement(p); 659 return p; 660 } 661 662 667 public void addReference(Reference ref) { 668 references.addElement(ref); 669 } 670 671 676 public void addConfiguredTarget(TargetElement t) { 677 if (targetAttributeSet) { 678 throw new BuildException( 679 "nested target is incompatible with the target attribute"); 680 } 681 String name = t.getName(); 682 if (name.equals("")) { 683 throw new BuildException("target name must not be empty"); 684 } 685 targets.add(name); 686 } 687 688 694 public void addPropertyset(PropertySet ps) { 695 propertySets.addElement(ps); 696 } 697 698 703 protected Project getNewProject() { 704 if (newProject == null) { 705 reinit(); 706 } 707 return newProject; 708 } 709 710 713 private Iterator getBuildListeners() { 714 return getProject().getBuildListeners().iterator(); 715 } 716 717 721 public static class Reference 722 extends org.apache.tools.ant.types.Reference { 723 724 725 public Reference() { 726 super(); 727 } 728 729 private String targetid = null; 730 731 737 public void setToRefid(String targetid) { 738 this.targetid = targetid; 739 } 740 741 747 public String getToRefid() { 748 return targetid; 749 } 750 } 751 752 757 public static class TargetElement { 758 private String name; 759 760 763 public TargetElement() { 764 } 766 767 771 public void setName(String name) { 772 this.name = name; 773 } 774 775 779 public String getName() { 780 return name; 781 } 782 } 783 } 784 | Popular Tags |