1 28 29 package com.idaremedia.antx.flowcontrol.call; 30 31 import java.io.BufferedReader ; 32 import java.io.File ; 33 import java.util.List ; 34 import java.util.Iterator ; 35 import java.util.NoSuchElementException ; 36 37 import org.apache.tools.ant.BuildException; 38 import org.apache.tools.ant.DirectoryScanner; 39 import org.apache.tools.ant.Project; 40 import org.apache.tools.ant.types.DirSet; 41 import org.apache.tools.ant.types.FileSet; 42 import org.apache.tools.ant.types.Path; 43 import org.apache.tools.ant.types.Reference; 44 import org.apache.tools.ant.util.FileUtils; 45 46 import com.idaremedia.antx.AntX; 47 import com.idaremedia.antx.AntXFixture; 48 import com.idaremedia.antx.FlexString; 49 import com.idaremedia.antx.flowcontrol.HardLimitEnabled; 50 import com.idaremedia.antx.helpers.ArrayIterator; 51 import com.idaremedia.antx.helpers.Empties; 52 import com.idaremedia.antx.helpers.Tk; 53 import com.idaremedia.antx.parameters.TrimEnabled; 54 import com.idaremedia.antx.starters.ListFriendly; 55 56 72 73 public abstract class ForEachTask extends OnceTask implements TrimEnabled, HardLimitEnabled 74 { 75 78 protected ForEachTask() 79 { 80 super(AntX.flow+"foreach"); 81 } 82 83 84 88 protected ForEachTask(String iam) 89 { 90 super(iam); 91 } 92 93 94 100 public void setCursor(String cursorName) 101 { 102 require_(!Tk.isWhitespace(cursorName),"setCursor- nonwspc cursor"); 103 m_cursorName = cursorName; 104 } 105 106 107 110 public final void setI(String cursorName) 111 { 112 setCursor(cursorName); 113 } 114 115 116 120 public String getCursorName() 121 { 122 return m_cursorName; 123 } 124 125 126 130 136 public void setMaxLoops(int maxLoops) 137 { 138 m_maxLoops = maxLoops>=0 ? maxLoops : Integer.MAX_VALUE; 139 } 140 141 142 143 147 public final boolean hasMax() 148 { 149 return m_maxLoops!=Integer.MAX_VALUE; 150 } 151 152 153 154 159 public final int getMaxLoops() 160 { 161 return hasMax() ? m_maxLoops : -1; 162 } 163 164 165 166 172 public void setHaltIfMax(boolean halt) 173 { 174 m_haltIfMax = halt ? Boolean.TRUE : Boolean.FALSE; 175 } 176 177 178 179 186 public final Boolean getHaltIfMax() 187 { 188 return m_haltIfMax; 189 } 190 191 195 200 public void setList(String list) 201 { 202 require_(list!=null,"setList- nonzro list"); 203 m_byList = list; 204 resetCachedLoopInfo(); 205 } 206 207 208 212 public final String getListLoopControl() 213 { 214 return m_byList; 215 } 216 217 218 225 public void setDelim(String listDelim) 226 { 227 require_(listDelim!=null && listDelim.length()>0,"setDelim- nonzro delim"); 228 if ("[:space:]".equals(listDelim)) { 229 m_byListDelim = " \t\n\r"; } else { 231 m_byListDelim = listDelim; 232 } 233 } 234 235 236 240 public final String getListDelim() 241 { 242 return m_byListDelim; 243 } 244 245 246 251 public void setFiles(Reference filesetRef) 252 { 253 require_(filesetRef!=null && filesetRef.getRefId()!=null,"setfils- nonzro ref"); 254 m_byFilesRef= filesetRef; 255 resetCachedLoopInfo(); 256 } 257 258 259 263 public final Reference getFilesetLoopControl() 264 { 265 return m_byFilesRef; 266 } 267 268 269 274 public void setDirs(Reference dirsetRef) 275 { 276 require_(dirsetRef!=null && dirsetRef.getRefId()!=null,"setdirs- nonzro ref"); 277 m_byDirsRef= dirsetRef; 278 resetCachedLoopInfo(); 279 } 280 281 282 286 public final Reference getDirsetLoopControl() 287 { 288 return m_byDirsRef; 289 } 290 291 292 297 public void setBaseNameOnly(boolean only) 298 { 299 m_basenameOnly = only; 300 } 301 302 303 314 public void setInFile(File file) 315 { 316 require_(file!=null,"setInFil- nonzro file"); 317 m_byListFile = file; 318 resetCachedLoopInfo(); 319 } 320 321 322 326 public final File getFileContentsLoopControl() 327 { 328 return m_byListFile; 329 } 330 331 332 337 public void setTrim(boolean trim) 338 { 339 m_byfileModifiers.setTrim(trim); 340 } 341 342 343 349 public final boolean willTrim() 350 { 351 return m_byfileModifiers.isTrimmed(); 352 } 353 354 355 361 public void setIgnorePrefix(String prefix) 362 { 363 m_byfileModifiers.setIgnorePrefix(prefix); 364 } 365 366 367 374 public final String getFileContentsIgnorePrefix() 375 { 376 return m_byfileModifiers.getPrefixFilter(); 377 } 378 379 380 388 public void setIn(String loopDefn) 389 { 390 require_(loopDefn!=null,"setIn- nonzro lopvars"); 391 m_byIn = loopDefn; 392 resetCachedLoopInfo(); 393 } 394 395 396 400 public final String getForRangeLoopControl() 401 { 402 return m_byIn; 403 } 404 405 406 407 413 public void setPathList(Path path) 414 { 415 require_(path!=null,"setpathlst- nonzro path"); 416 m_byPath = path; 417 resetCachedLoopInfo(); 418 } 419 420 421 425 public final Path getPathListLoopControl() 426 { 427 return m_byPath; 428 } 429 430 431 437 public void setPath(Reference pathRef) 438 { 439 require_(pathRef!=null && pathRef.getRefId()!=null,"setpathRef- nonzro ref"); 440 m_byPathRef = pathRef; 441 resetCachedLoopInfo(); 442 } 443 444 445 449 public final Reference getPathLoopControl(Reference pathRef) 450 { 451 return m_byPathRef; 452 } 453 454 455 460 public void setItems(Reference itemsRef) 461 { 462 require_(itemsRef!=null && itemsRef.getRefId()!=null,"setItms- nonzro ref"); 463 m_byListRef = itemsRef; 464 resetCachedLoopInfo(); 465 } 466 467 468 473 public final Reference getItemsLoopControl() 474 { 475 return m_byListRef; 476 } 477 478 479 482 protected final void resetCachedLoopInfo() 483 { 484 if (m_foreachList!=null || m_byInStart!=Tk.NO_INT) { 485 m_foreachList= null; 486 m_byInStart= Tk.NO_INT; 487 m_byInEnd= Tk.NO_INT; 488 m_byInIncr= Tk.NO_INT; 489 } 490 } 491 492 496 private static final String BROKEN_CONTROL_MSG = "flow.foreach.err.bad.loopcontrol"; 497 private static final String BROKEN_SETUP_MSG = "flow.foreach.invalid.setup"; 498 499 500 505 protected boolean handleStringLists() 506 { 507 if (m_foreachList==null) { 508 if (m_byList!=null) { 509 if (!Tk.isWhitespace(m_byList)) { 510 List l= Tk.splitList(m_byList,m_byListDelim); 511 if (!l.isEmpty()) { 512 m_foreachList= (String [])l.toArray(Empties.EMPTY_STRING_ARRAY); 513 log("Will do "+l.size()+" items for foreach(list)",Project.MSG_DEBUG); 514 } else { 515 String ermsg= uistrs().get(BROKEN_CONTROL_MSG,"list",""); 516 log(ermsg,Project.MSG_ERR); 517 } 518 } else { 519 String ermsg= uistrs().get(BROKEN_CONTROL_MSG,"list",""); 520 log(ermsg,Project.MSG_WARN); 521 m_foreachList = new String [0]; 522 } 523 } 524 else if (m_byListRef!=null) { 525 Object o = getProject().getReference(m_byListRef.getRefId()); 526 if (!(o instanceof ListFriendly)) { 527 String ermsg = getAntXMsg("task.bad.refid",m_byListRef.getRefId(), 528 ListFriendly.class.getName(), 529 (o==null ? "NULL" : o.getClass().getName())); 530 log(ermsg,Project.MSG_ERR); 531 } else { 532 ListFriendly list = (ListFriendly)o; 533 String [] sl= new String [list.size()]; 534 if (sl.length>0) { 535 int i=0; 536 Iterator itr= list.readonlyStringIterator(getProject()); 537 while (itr.hasNext()) { 538 verify_(i<sl.length,"handlLst- no-concur-mods on roItr"); 539 sl[i++] = itr.next().toString(); 540 } 541 } 542 m_foreachList = sl; 543 log("Will do "+sl.length+" items for foreach(items)",Project.MSG_DEBUG); 544 } 545 } 546 } 547 return m_foreachList!=null; 548 } 549 550 551 555 protected boolean handleIn() 556 { 557 if (m_byInStart==Tk.NO_INT) { 558 if (!Tk.isWhitespace(m_byIn)) { 559 List l= Tk.splitList(m_byIn,","); 560 int istart=Tk.NO_INT,iend=Tk.NO_INT,iincr=Tk.NO_INT; 561 if (l.size()>=2) { 562 istart= Tk.integerFrom(l.get(0),Tk.NO_INT); 563 iend= Tk.integerFrom(l.get(1),Tk.NO_INT); 564 } 565 if (l.size()>=3) { 566 iincr = Tk.integerFrom(l.get(2),Tk.NO_INT); 567 if (iincr==Tk.NO_INT) { 568 String ermsg= uistrs().get("flow.foreach.err.in.incr",l.get(2)); 569 log(ermsg,Project.MSG_ERR); 570 return false; 571 } 572 } 573 if (istart!=Tk.NO_INT && iend!=Tk.NO_INT) { 574 m_byInStart = istart; 575 m_byInEnd = iend; 576 if (iincr!=Tk.NO_INT) { 577 m_byInIncr= iincr; 578 } else { 579 m_byInIncr= 1; 580 } 581 int N = (iend-istart)/iincr; 582 log("Will do "+N+" iterations for foreach(in)",Project.MSG_DEBUG); 583 } else { 584 String ermsg= uistrs().get(BROKEN_CONTROL_MSG,"in",""); 585 log(ermsg,Project.MSG_ERR); 586 } 587 } 588 } 589 return m_byInStart!=Tk.NO_INT; 590 } 591 592 593 597 protected boolean handleFiles() 598 { 599 if (m_foreachList==null) { 600 if (m_byFilesRef!=null) { 601 try { 602 FileSet fs = new FileSet(); 603 fs.setProject(getProject()); 604 fs.setRefid(m_byFilesRef); 605 DirectoryScanner dirscan = fs.getDirectoryScanner(getProject()); 606 m_foreachList= dirscan.getIncludedFiles(); 607 resolveAllFilesOrDirs(m_foreachList, dirscan); 608 log("Will do "+m_foreachList.length+" files for foreach(files)",Project.MSG_DEBUG); 609 } catch(BuildException bx) { 610 String ermsg= uistrs().get(BROKEN_CONTROL_MSG,"files",bx.getMessage()); 611 log(ermsg,Project.MSG_ERR); 612 } 613 } 614 } 615 return m_foreachList!=null; 616 } 617 618 619 623 protected boolean handleDirs() 624 { 625 if (m_foreachList==null) { 626 if (m_byDirsRef!=null) { 627 try { 628 DirSet ds = new DirSet(); 629 ds.setProject(getProject()); 630 ds.setRefid(m_byDirsRef); 631 DirectoryScanner dirscan = ds.getDirectoryScanner(getProject()); 632 m_foreachList= dirscan.getIncludedDirectories(); 633 resolveAllFilesOrDirs(m_foreachList, dirscan); 634 log("Will do "+m_foreachList.length+" dirs for foreach(dirs)",Project.MSG_DEBUG); 635 } catch(BuildException bx) { 636 String ermsg = uistrs().get(BROKEN_CONTROL_MSG,"dirs",bx.getMessage()); 637 log(ermsg,Project.MSG_ERR); 638 } 639 } 640 } 641 return m_foreachList!=null; 642 } 643 644 645 650 protected boolean handlePaths() 651 { 652 if (m_foreachList==null) { 653 if (m_byPath!=null) { 654 try { 655 m_foreachList = m_byPath.list(); 656 log("Will do "+m_foreachList.length+" elements for foreach(path)",Project.MSG_DEBUG); 657 } catch(BuildException bx) { 658 String ermsg = uistrs().get(BROKEN_CONTROL_MSG,"path",bx.getMessage()); 659 log(ermsg,Project.MSG_ERR); 660 } 661 } 662 else if (m_byPathRef!=null) { 663 try { 664 Path path = new Path(getProject()); 665 path.setRefid(m_byPathRef); 666 m_foreachList = path.list(); 667 log("Will do "+m_foreachList.length+" elements for foreach(pathref)",Project.MSG_DEBUG); 668 } catch(BuildException bx) { 669 String ermsg = uistrs().get(BROKEN_CONTROL_MSG,"pathref",bx.getMessage()); 670 log(ermsg,Project.MSG_ERR); 671 } 672 } 673 } 674 return m_foreachList!=null; 675 } 676 677 678 682 protected boolean handleFileContents() 683 { 684 if (m_foreachList==null) { 685 if (m_byListFile!=null && m_byListFile.canRead()) { 686 try { 687 BufferedReader fr = new BufferedReader (new java.io.FileReader (m_byListFile)); 688 List propList = AntXFixture.newList(10); 689 Project P= getProject(); 690 String next; 691 FlexString filter = (FlexString)m_byfileModifiers.clone(); 692 while ((next=fr.readLine())!=null) { 693 filter.set(next); 694 next = filter.getValue(); 695 if (next!=null) { 696 propList.add(Tk.resolveString(P,next)); 697 } 698 } 699 m_foreachList = (String [])propList.toArray(Empties.EMPTY_STRING_ARRAY); 700 log("Will do "+m_foreachList.length+" items for foreach(infile)",Project.MSG_DEBUG); 701 propList = null; 702 } catch(Exception ioxOrbuildX) { 703 String ermsg = uistrs().get(BROKEN_CONTROL_MSG,"infile",ioxOrbuildX.getMessage()); 704 log(ermsg,Project.MSG_ERR); 705 } 706 } 707 } 708 return m_foreachList!=null; 709 } 710 711 712 716 private void resolveAllFilesOrDirs(String [] filesOrDirs, DirectoryScanner dirscan) 717 { 718 FileUtils fileUtils = AntXFixture.fileUtils(); 719 File wrt = dirscan.getBasedir(); 720 for (int i=0;i<filesOrDirs.length;i++) { 721 File rf= fileUtils.resolveFile(wrt,filesOrDirs[i]); 722 if (m_basenameOnly) { 723 filesOrDirs[i]= rf.getName(); 724 } else { 725 filesOrDirs[i]= rf.getAbsolutePath(); 726 } 727 } 728 } 729 730 731 737 protected final String [] getForEachList() 738 { 739 return m_foreachList; 740 } 741 742 743 748 protected final void setForEachList(String [] newlist) 749 { 750 m_foreachList = newlist; 751 } 752 753 754 758 762 protected final boolean anyLoopControlsSpecified() 763 { 764 return (m_byList!=null || m_byListRef!=null || 765 m_byFilesRef!=null || m_byDirsRef!=null || 766 m_byListFile!=null || m_byPath!=null || 767 m_byPathRef!=null || m_byIn!=null 768 ); 769 } 770 771 772 776 protected final int getNumberLoopControlsSpecified() 777 { 778 int N=0; 779 if (m_byList!=null || m_byListRef!=null) { N++; } if (m_byIn!=null) { N++; } 781 if (m_byFilesRef!=null) { N++; } 782 if (m_byDirsRef!=null) { N++; } 783 if (m_byListFile!=null) { N++; } 784 if (m_byPath!=null || m_byPathRef!=null) { N++; } return N; 786 } 787 788 789 796 protected void verifyCanExecute_(String calr) 797 throws BuildException 798 { 799 super.verifyCanExecute_(calr); 800 801 int Nc= getNumberLoopControlsSpecified(); 802 803 if ((getCursorName()==null) || (Nc==0) || (Nc>1)) { 806 String ermsg = uistrs().get(BROKEN_SETUP_MSG); 807 log(ermsg,Project.MSG_ERR); 808 throw new BuildException(ermsg,getLocation()); 809 } 810 } 811 812 813 821 protected final void forEachRunTargetCallers(Iterator itr) 822 throws BuildException 823 { 824 final String cursorName = getCursorName(); 825 int ith=0; 826 final int Nth=m_maxLoops; 827 828 while (itr.hasNext() && ith<Nth) { 829 final String cursor = itr.next().toString(); 830 try { 831 runTargetCallers(new TargetCaller.RunSelector() { 832 public void run(TargetCaller caller) { 833 caller.run(cursorName, cursor); 834 } 835 }); 836 ith++; 837 } catch(RuntimeException rtX) { 838 log(uistrs().get("flow.cursor.failure",cursor), 839 Project.MSG_ERR); 840 throw rtX; 841 } 842 } 843 844 if (ith==Nth) { 845 String msg = getMsg(); 846 if (Tk.isWhitespace(msg)) { 847 msg = getAntXMsg("flow.loop.overflow",String.valueOf(ith)); 848 } 849 if (m_haltIfMax==Boolean.TRUE) { 850 log(msg, Project.MSG_ERR); 851 throw new BuildException(msg, getLocation()); 852 } 853 log(msg, Project.MSG_INFO); 854 } 855 } 856 857 858 869 protected void forEachRunTargetCallers() throws BuildException 870 { 871 if (!handleStringLists() && 872 !handleIn() && 873 !handleFileContents() && 874 !handleFiles() && 875 !handlePaths() && 876 !handleDirs()) { 877 878 String ermsg = uistrs().get(BROKEN_SETUP_MSG); 879 log(ermsg,Project.MSG_ERR); 880 throw new BuildException(ermsg,getLocation()); 881 } 882 883 if (m_foreachList!=null) { 884 forEachRunTargetCallers(new ArrayIterator(m_foreachList)); 885 } 886 else if (m_byInStart!=Tk.NO_INT) { 887 forEachRunTargetCallers 888 (new IntRangeIterator(m_byInStart,m_byInEnd,m_byInIncr)); 889 } 890 else { 891 String ermsg = uistrs().get(BROKEN_SETUP_MSG); 892 log(ermsg,Project.MSG_ERR); 893 throw new BuildException(ermsg,getLocation()); 894 } 895 } 896 897 898 904 public void execute() throws BuildException 905 { 906 verifyCanExecute_("execute"); 907 forEachRunTargetCallers(); 908 } 909 910 911 918 public static final class IntRangeIterator implements Iterator 919 { 920 private final int end, incr; 921 private int i; 922 public IntRangeIterator(int start, int end, int incr) { 923 this.i = start; 924 this.end= end; 925 this.incr = incr; 926 } 927 public void remove() { 928 throw new UnsupportedOperationException (); 929 } 930 public boolean hasNext() { 931 return i<end; 932 } 933 public Object next() { 934 if (i<end) { 935 Object iObject= String.valueOf(i); 936 i += incr; 937 return iObject; 938 } 939 throw new NoSuchElementException (); 940 } 941 } 942 943 945 private String m_cursorName; 947 948 private String [] m_foreachList; private int m_byInStart=Tk.NO_INT, m_byInEnd=Tk.NO_INT, m_byInIncr=Tk.NO_INT; 952 private String m_byList, m_byListDelim= AntX.DEFAULT_DELIMITER; 954 private String m_byIn; 955 private Reference m_byFilesRef, m_byDirsRef, m_byPathRef; 956 private File m_byListFile; 957 private FlexString m_byfileModifiers = new FlexString(); 958 private Path m_byPath; 959 private Reference m_byListRef; 960 private boolean m_basenameOnly; 961 962 private int m_maxLoops = Integer.MAX_VALUE; 964 private Boolean m_haltIfMax = null;} 966 967 968 | Popular Tags |