1 18 package org.apache.tools.ant.taskdefs; 19 20 import java.io.File ; 21 import java.io.FileWriter ; 22 import java.io.FilenameFilter ; 23 import java.io.IOException ; 24 import java.io.PrintWriter ; 25 import java.io.BufferedReader ; 26 import java.io.FileReader ; 27 import java.net.MalformedURLException ; 28 import java.net.URL ; 29 import java.util.ArrayList ; 30 import java.util.Enumeration ; 31 import java.util.Iterator ; 32 import java.util.Locale ; 33 import java.util.StringTokenizer ; 34 import java.util.Vector ; 35 import org.apache.tools.ant.BuildException; 36 import org.apache.tools.ant.DirectoryScanner; 37 import org.apache.tools.ant.MagicNames; 38 import org.apache.tools.ant.Project; 39 import org.apache.tools.ant.ProjectComponent; 40 import org.apache.tools.ant.Task; 41 import org.apache.tools.ant.types.Commandline; 42 import org.apache.tools.ant.types.DirSet; 43 import org.apache.tools.ant.types.EnumeratedAttribute; 44 import org.apache.tools.ant.types.FileSet; 45 import org.apache.tools.ant.types.Path; 46 import org.apache.tools.ant.types.PatternSet; 47 import org.apache.tools.ant.types.Reference; 48 import org.apache.tools.ant.types.ResourceCollection; 49 import org.apache.tools.ant.types.resources.FileResource; 50 import org.apache.tools.ant.util.FileUtils; 51 import org.apache.tools.ant.util.JavaEnvUtils; 52 53 76 public class Javadoc extends Task { 77 80 public class DocletParam { 81 82 private String name; 83 84 85 private String value; 86 87 92 public void setName(String name) { 93 this.name = name; 94 } 95 96 101 public String getName() { 102 return name; 103 } 104 105 113 public void setValue(String value) { 114 this.value = value; 115 } 116 117 122 public String getValue() { 123 return value; 124 } 125 } 126 127 132 public static class ExtensionInfo extends ProjectComponent { 133 134 private String name; 135 136 137 private Path path; 138 139 144 public void setName(String name) { 145 this.name = name; 146 } 147 148 153 public String getName() { 154 return name; 155 } 156 157 162 public void setPath(Path path) { 163 if (this.path == null) { 164 this.path = path; 165 } else { 166 this.path.append(path); 167 } 168 } 169 170 176 public Path getPath() { 177 return path; 178 } 179 180 186 public Path createPath() { 187 if (path == null) { 188 path = new Path(getProject()); 189 } 190 return path.createPath(); 191 } 192 193 198 public void setPathRef(Reference r) { 199 createPath().setRefid(r); 200 } 201 } 202 203 207 public class DocletInfo extends ExtensionInfo { 208 209 210 private Vector params = new Vector (); 211 212 217 public DocletParam createParam() { 218 DocletParam param = new DocletParam(); 219 params.addElement(param); 220 221 return param; 222 } 223 224 229 public Enumeration getParams() { 230 return params.elements(); 231 } 232 } 233 234 237 public static class PackageName { 238 239 private String name; 240 241 246 public void setName(String name) { 247 this.name = name.trim(); 248 } 249 250 255 public String getName() { 256 return name; 257 } 258 259 263 public String toString() { 264 return getName(); 265 } 266 } 267 268 271 public static class SourceFile { 272 273 private File file; 274 275 278 public SourceFile() { 279 } 281 282 287 public SourceFile(File file) { 288 this.file = file; 289 } 290 291 296 public void setFile(File file) { 297 this.file = file; 298 } 299 300 305 public File getFile() { 306 return file; 307 } 308 } 309 310 316 public static class Html { 317 318 private StringBuffer text = new StringBuffer (); 319 320 325 public void addText(String t) { 326 text.append(t); 327 } 328 329 334 public String getText() { 335 return text.substring(0); 336 } 337 } 338 339 343 public static class AccessType extends EnumeratedAttribute { 344 347 public String [] getValues() { 348 return new String [] {"protected", "public", "package", "private"}; 351 } 352 } 353 354 361 public class ResourceCollectionContainer { 362 private ArrayList rcs = new ArrayList (); 363 367 public void add(ResourceCollection rc) { 368 rcs.add(rc); 369 } 370 371 375 private Iterator iterator() { 376 return rcs.iterator(); 377 } 378 } 379 380 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 381 382 383 private Commandline cmd = new Commandline(); 384 385 392 private void addArgIf(boolean b, String arg) { 393 if (b) { 394 cmd.createArgument().setValue(arg); 395 } 396 } 397 398 404 private void addArgIfNotEmpty(String key, String value) { 405 if (value != null && value.length() != 0) { 406 cmd.createArgument().setValue(key); 407 cmd.createArgument().setValue(value); 408 } else { 409 log("Warning: Leaving out empty argument '" + key + "'", 410 Project.MSG_WARN); 411 } 412 } 413 414 418 private boolean failOnError = false; 419 private Path sourcePath = null; 420 private File destDir = null; 421 private Vector sourceFiles = new Vector (); 422 private Vector packageNames = new Vector (); 423 private Vector excludePackageNames = new Vector (1); 424 private boolean author = true; 425 private boolean version = true; 426 private DocletInfo doclet = null; 427 private Path classpath = null; 428 private Path bootclasspath = null; 429 private String group = null; 430 private String packageList = null; 431 private Vector links = new Vector (); 432 private Vector groups = new Vector (); 433 private Vector tags = new Vector (); 434 private boolean useDefaultExcludes = true; 435 private Html doctitle = null; 436 private Html header = null; 437 private Html footer = null; 438 private Html bottom = null; 439 private boolean useExternalFile = false; 440 private String source = null; 441 private boolean linksource = false; 442 private boolean breakiterator = false; 443 private String noqualifier; 444 private boolean includeNoSourcePackages = false; 445 private boolean old = false; 446 private String executable = null; 447 448 private ResourceCollectionContainer nestedSourceFiles 449 = new ResourceCollectionContainer(); 450 private Vector packageSets = new Vector (); 451 452 458 public void setUseExternalFile(boolean b) { 459 useExternalFile = b; 460 } 461 462 469 public void setDefaultexcludes(boolean useDefaultExcludes) { 470 this.useDefaultExcludes = useDefaultExcludes; 471 } 472 473 479 public void setMaxmemory(String max) { 480 cmd.createArgument().setValue("-J-Xmx" + max); 481 } 482 483 488 public void setAdditionalparam(String add) { 489 cmd.createArgument().setLine(add); 490 } 491 492 497 public Commandline.Argument createArg() { 498 return cmd.createArgument(); 499 } 500 501 506 public void setSourcepath(Path src) { 507 if (sourcePath == null) { 508 sourcePath = src; 509 } else { 510 sourcePath.append(src); 511 } 512 } 513 514 520 public Path createSourcepath() { 521 if (sourcePath == null) { 522 sourcePath = new Path(getProject()); 523 } 524 return sourcePath.createPath(); 525 } 526 527 532 public void setSourcepathRef(Reference r) { 533 createSourcepath().setRefid(r); 534 } 535 536 541 public void setDestdir(File dir) { 542 destDir = dir; 543 cmd.createArgument().setValue("-d"); 544 cmd.createArgument().setFile(destDir); 545 } 546 547 552 public void setSourcefiles(String src) { 553 StringTokenizer tok = new StringTokenizer (src, ","); 554 while (tok.hasMoreTokens()) { 555 String f = tok.nextToken(); 556 SourceFile sf = new SourceFile(); 557 sf.setFile(getProject().resolveFile(f.trim())); 558 addSource(sf); 559 } 560 } 561 562 567 public void addSource(SourceFile sf) { 568 sourceFiles.addElement(sf); 569 } 570 571 579 public void setPackagenames(String packages) { 580 StringTokenizer tok = new StringTokenizer (packages, ","); 581 while (tok.hasMoreTokens()) { 582 String p = tok.nextToken(); 583 PackageName pn = new PackageName(); 584 pn.setName(p); 585 addPackage(pn); 586 } 587 } 588 589 597 public void addPackage(PackageName pn) { 598 packageNames.addElement(pn); 599 } 600 601 607 public void setExcludePackageNames(String packages) { 608 StringTokenizer tok = new StringTokenizer (packages, ","); 609 while (tok.hasMoreTokens()) { 610 String p = tok.nextToken(); 611 PackageName pn = new PackageName(); 612 pn.setName(p); 613 addExcludePackage(pn); 614 } 615 } 616 617 622 public void addExcludePackage(PackageName pn) { 623 excludePackageNames.addElement(pn); 624 } 625 626 632 public void setOverview(File f) { 633 cmd.createArgument().setValue("-overview"); 634 cmd.createArgument().setFile(f); 635 } 636 637 643 public void setPublic(boolean b) { 644 addArgIf(b, "-public"); 645 } 646 647 653 public void setProtected(boolean b) { 654 addArgIf(b, "-protected"); 655 } 656 657 663 public void setPackage(boolean b) { 664 addArgIf(b, "-package"); 665 } 666 667 673 public void setPrivate(boolean b) { 674 addArgIf(b, "-private"); 675 } 676 677 684 public void setAccess(AccessType at) { 685 cmd.createArgument().setValue("-" + at.getValue()); 686 } 687 688 694 public void setDoclet(String docletName) { 695 if (doclet == null) { 696 doclet = new DocletInfo(); 697 doclet.setProject(getProject()); 698 } 699 doclet.setName(docletName); 700 } 701 702 707 public void setDocletPath(Path docletPath) { 708 if (doclet == null) { 709 doclet = new DocletInfo(); 710 doclet.setProject(getProject()); 711 } 712 doclet.setPath(docletPath); 713 } 714 715 721 public void setDocletPathRef(Reference r) { 722 if (doclet == null) { 723 doclet = new DocletInfo(); 724 doclet.setProject(getProject()); 725 } 726 doclet.createPath().setRefid(r); 727 } 728 729 734 public DocletInfo createDoclet() { 735 if (doclet == null) { 736 doclet = new DocletInfo(); 737 } 738 return doclet; 739 } 740 741 746 public void addTaglet(ExtensionInfo tagletInfo) { 747 tags.addElement(tagletInfo); 748 } 749 750 758 public void setOld(boolean b) { 759 old = b; 760 } 761 762 768 public void setClasspath(Path path) { 769 if (classpath == null) { 770 classpath = path; 771 } else { 772 classpath.append(path); 773 } 774 } 775 776 781 public Path createClasspath() { 782 if (classpath == null) { 783 classpath = new Path(getProject()); 784 } 785 return classpath.createPath(); 786 } 787 788 793 public void setClasspathRef(Reference r) { 794 createClasspath().setRefid(r); 795 } 796 797 802 public void setBootclasspath(Path path) { 803 if (bootclasspath == null) { 804 bootclasspath = path; 805 } else { 806 bootclasspath.append(path); 807 } 808 } 809 810 815 public Path createBootclasspath() { 816 if (bootclasspath == null) { 817 bootclasspath = new Path(getProject()); 818 } 819 return bootclasspath.createPath(); 820 } 821 822 827 public void setBootClasspathRef(Reference r) { 828 createBootclasspath().setRefid(r); 829 } 830 831 838 public void setExtdirs(String path) { 839 cmd.createArgument().setValue("-extdirs"); 840 cmd.createArgument().setValue(path); 841 } 842 843 848 public void setExtdirs(Path path) { 849 cmd.createArgument().setValue("-extdirs"); 850 cmd.createArgument().setPath(path); 851 } 852 853 858 public void setVerbose(boolean b) { 859 addArgIf(b, "-verbose"); 860 } 861 862 867 public void setLocale(String locale) { 868 cmd.createArgument(true).setValue(locale); 871 cmd.createArgument(true).setValue("-locale"); 872 } 873 874 879 public void setEncoding(String enc) { 880 cmd.createArgument().setValue("-encoding"); 881 cmd.createArgument().setValue(enc); 882 } 883 884 889 public void setVersion(boolean b) { 890 this.version = b; 891 } 892 893 898 public void setUse(boolean b) { 899 addArgIf(b, "-use"); 900 } 901 902 903 908 public void setAuthor(boolean b) { 909 author = b; 910 } 911 912 917 public void setSplitindex(boolean b) { 918 addArgIf(b, "-splitindex"); 919 } 920 921 927 public void setWindowtitle(String title) { 928 addArgIfNotEmpty("-windowtitle", title); 929 } 930 931 936 public void setDoctitle(String doctitle) { 937 Html h = new Html(); 938 h.addText(doctitle); 939 addDoctitle(h); 940 } 941 942 947 public void addDoctitle(Html text) { 948 doctitle = text; 949 } 950 951 956 public void setHeader(String header) { 957 Html h = new Html(); 958 h.addText(header); 959 addHeader(h); 960 } 961 962 967 public void addHeader(Html text) { 968 header = text; 969 } 970 971 976 public void setFooter(String footer) { 977 Html h = new Html(); 978 h.addText(footer); 979 addFooter(h); 980 } 981 982 987 public void addFooter(Html text) { 988 footer = text; 989 } 990 991 996 public void setBottom(String bottom) { 997 Html h = new Html(); 998 h.addText(bottom); 999 addBottom(h); 1000 } 1001 1002 1007 public void addBottom(Html text) { 1008 bottom = text; 1009 } 1010 1011 1017 public void setLinkoffline(String src) { 1018 LinkArgument le = createLink(); 1019 le.setOffline(true); 1020 String linkOfflineError = "The linkoffline attribute must include" 1021 + " a URL and a package-list file location separated by a" 1022 + " space"; 1023 if (src.trim().length() == 0) { 1024 throw new BuildException(linkOfflineError); 1025 } 1026 StringTokenizer tok = new StringTokenizer (src, " ", false); 1027 le.setHref(tok.nextToken()); 1028 1029 if (!tok.hasMoreTokens()) { 1030 throw new BuildException(linkOfflineError); 1031 } 1032 le.setPackagelistLoc(getProject().resolveFile(tok.nextToken())); 1033 } 1034 1035 1042 public void setGroup(String src) { 1043 group = src; 1044 } 1045 1046 1050 public void setLink(String src) { 1051 createLink().setHref(src); 1052 } 1053 1054 1059 public void setNodeprecated(boolean b) { 1060 addArgIf(b, "-nodeprecated"); 1061 } 1062 1063 1068 public void setNodeprecatedlist(boolean b) { 1069 addArgIf(b, "-nodeprecatedlist"); 1070 } 1071 1072 1077 public void setNotree(boolean b) { 1078 addArgIf(b, "-notree"); 1079 } 1080 1081 1086 public void setNoindex(boolean b) { 1087 addArgIf(b, "-noindex"); 1088 } 1089 1090 1095 public void setNohelp(boolean b) { 1096 addArgIf(b, "-nohelp"); 1097 } 1098 1099 1104 public void setNonavbar(boolean b) { 1105 addArgIf(b, "-nonavbar"); 1106 } 1107 1108 1113 public void setSerialwarn(boolean b) { 1114 addArgIf(b, "-serialwarn"); 1115 } 1116 1117 1122 public void setStylesheetfile(File f) { 1123 cmd.createArgument().setValue("-stylesheetfile"); 1124 cmd.createArgument().setFile(f); 1125 } 1126 1127 1132 public void setHelpfile(File f) { 1133 cmd.createArgument().setValue("-helpfile"); 1134 cmd.createArgument().setFile(f); 1135 } 1136 1137 1142 public void setDocencoding(String enc) { 1143 cmd.createArgument().setValue("-docencoding"); 1144 cmd.createArgument().setValue(enc); 1145 } 1146 1147 1152 public void setPackageList(String src) { 1153 packageList = src; 1154 } 1155 1156 1161 public LinkArgument createLink() { 1162 LinkArgument la = new LinkArgument(); 1163 links.addElement(la); 1164 return la; 1165 } 1166 1167 1171 public class LinkArgument { 1172 private String href; 1173 private boolean offline = false; 1174 private File packagelistLoc; 1175 private boolean resolveLink = false; 1176 1177 1178 public LinkArgument() { 1179 } 1181 1182 1186 public void setHref(String hr) { 1187 href = hr; 1188 } 1189 1190 1194 public String getHref() { 1195 return href; 1196 } 1197 1198 1202 public void setPackagelistLoc(File src) { 1203 packagelistLoc = src; 1204 } 1205 1206 1210 public File getPackagelistLoc() { 1211 return packagelistLoc; 1212 } 1213 1214 1218 public void setOffline(boolean offline) { 1219 this.offline = offline; 1220 } 1221 1222 1226 public boolean isLinkOffline() { 1227 return offline; 1228 } 1229 1230 1235 public void setResolveLink(boolean resolve) { 1236 this.resolveLink = resolve; 1237 } 1238 1239 1244 public boolean shouldResolveLink() { 1245 return resolveLink; 1246 } 1247 1248 } 1249 1250 1257 public TagArgument createTag() { 1258 TagArgument ta = new TagArgument(); 1259 tags.addElement (ta); 1260 return ta; 1261 } 1262 1263 1268 static final String [] SCOPE_ELEMENTS = { 1269 "overview", "packages", "types", "constructors", 1270 "methods", "fields" 1271 }; 1272 1273 1276 public class TagArgument extends FileSet { 1277 1278 private String name = null; 1279 1280 private boolean enabled = true; 1281 1286 private String scope = "a"; 1287 1288 1289 public TagArgument () { 1290 } 1292 1293 1299 public void setName (String name) { 1300 this.name = name; 1301 } 1302 1303 1319 public void setScope (String verboseScope) throws BuildException { 1320 verboseScope = verboseScope.toLowerCase(Locale.US); 1321 1322 boolean[] elements = new boolean[SCOPE_ELEMENTS.length]; 1323 1324 boolean gotAll = false; 1325 boolean gotNotAll = false; 1326 1327 StringTokenizer tok = new StringTokenizer (verboseScope, ","); 1330 while (tok.hasMoreTokens()) { 1331 String next = tok.nextToken().trim(); 1332 if (next.equals("all")) { 1333 if (gotAll) { 1334 getProject().log ("Repeated tag scope element: all", 1335 Project.MSG_VERBOSE); 1336 } 1337 gotAll = true; 1338 } else { 1339 int i; 1340 for (i = 0; i < SCOPE_ELEMENTS.length; i++) { 1341 if (next.equals (SCOPE_ELEMENTS[i])) { 1342 break; 1343 } 1344 } 1345 if (i == SCOPE_ELEMENTS.length) { 1346 throw new BuildException ("Unrecognised scope element: " 1347 + next); 1348 } else { 1349 if (elements[i]) { 1350 getProject().log ("Repeated tag scope element: " 1351 + next, Project.MSG_VERBOSE); 1352 } 1353 elements[i] = true; 1354 gotNotAll = true; 1355 } 1356 } 1357 } 1358 1359 if (gotNotAll && gotAll) { 1360 throw new BuildException ("Mixture of \"all\" and other scope " 1361 + "elements in tag parameter."); 1362 } 1363 if (!gotNotAll && !gotAll) { 1364 throw new BuildException ("No scope elements specified in tag " 1365 + "parameter."); 1366 } 1367 if (gotAll) { 1368 this.scope = "a"; 1369 } else { 1370 StringBuffer buff = new StringBuffer (elements.length); 1371 for (int i = 0; i < elements.length; i++) { 1372 if (elements[i]) { 1373 buff.append (SCOPE_ELEMENTS[i].charAt(0)); 1374 } 1375 } 1376 this.scope = buff.toString(); 1377 } 1378 } 1379 1380 1385 public void setEnabled (boolean enabled) { 1386 this.enabled = enabled; 1387 } 1388 1389 1395 public String getParameter() throws BuildException { 1396 if (name == null || name.equals("")) { 1397 throw new BuildException ("No name specified for custom tag."); 1398 } 1399 if (getDescription() != null) { 1400 return name + ":" + (enabled ? "" : "X") 1401 + scope + ":" + getDescription(); 1402 } else { 1403 return name + ":" + (enabled ? "" : "X") 1404 + scope + ":" + name; 1405 } 1406 } 1407 } 1408 1409 1414 public GroupArgument createGroup() { 1415 GroupArgument ga = new GroupArgument(); 1416 groups.addElement(ga); 1417 return ga; 1418 } 1419 1420 1421 1424 public class GroupArgument { 1425 private Html title; 1426 private Vector packages = new Vector (); 1427 1428 1429 public GroupArgument() { 1430 } 1432 1433 1437 public void setTitle(String src) { 1438 Html h = new Html(); 1439 h.addText(src); 1440 addTitle(h); 1441 } 1442 1446 public void addTitle(Html text) { 1447 title = text; 1448 } 1449 1450 1454 public String getTitle() { 1455 return title != null ? title.getText() : null; 1456 } 1457 1458 1462 public void setPackages(String src) { 1463 StringTokenizer tok = new StringTokenizer (src, ","); 1464 while (tok.hasMoreTokens()) { 1465 String p = tok.nextToken(); 1466 PackageName pn = new PackageName(); 1467 pn.setName(p); 1468 addPackage(pn); 1469 } 1470 } 1471 1475 public void addPackage(PackageName pn) { 1476 packages.addElement(pn); 1477 } 1478 1479 1483 public String getPackages() { 1484 StringBuffer p = new StringBuffer (); 1485 for (int i = 0; i < packages.size(); i++) { 1486 if (i > 0) { 1487 p.append(":"); 1488 } 1489 p.append(packages.elementAt(i).toString()); 1490 } 1491 return p.toString(); 1492 } 1493 } 1494 1495 1499 public void setCharset(String src) { 1500 this.addArgIfNotEmpty("-charset", src); 1501 } 1502 1503 1510 public void setFailonerror(boolean b) { 1511 failOnError = b; 1512 } 1513 1514 1520 public void setSource(String source) { 1521 this.source = source; 1522 } 1523 1524 1530 public void setExecutable(String executable) { 1531 this.executable = executable; 1532 } 1533 1534 1542 public void addPackageset(DirSet packageSet) { 1543 packageSets.addElement(packageSet); 1544 } 1545 1546 1556 public void addFileset(FileSet fs) { 1557 createSourceFiles().add(fs); 1558 } 1559 1560 1567 public ResourceCollectionContainer createSourceFiles() { 1568 return nestedSourceFiles; 1569 } 1570 1571 1577 public void setLinksource(boolean b) { 1578 this.linksource = b; 1579 } 1580 1581 1587 public void setBreakiterator(boolean b) { 1588 this.breakiterator = b; 1589 } 1590 1591 1597 public void setNoqualifier(String noqualifier) { 1598 this.noqualifier = noqualifier; 1599 } 1600 1601 1607 public void setIncludeNoSourcePackages(boolean b) { 1608 this.includeNoSourcePackages = b; 1609 } 1610 1611 1615 public void execute() throws BuildException { 1616 if ("javadoc2".equals(getTaskType())) { 1617 log("Warning: the task name <javadoc2> is deprecated. Use <javadoc> instead.", 1618 Project.MSG_WARN); 1619 } 1620 1621 boolean javadoc4 = 1623 !JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2) 1624 && !JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_3); 1625 boolean javadoc5 = javadoc4 1626 && !JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4); 1627 1628 Vector packagesToDoc = new Vector (); 1629 Path sourceDirs = new Path(getProject()); 1630 1631 if (packageList != null && sourcePath == null) { 1632 String msg = "sourcePath attribute must be set when " 1633 + "specifying packagelist."; 1634 throw new BuildException(msg); 1635 } 1636 1637 if (sourcePath != null) { 1638 sourceDirs.addExisting(sourcePath); 1639 } 1640 1641 parsePackages(packagesToDoc, sourceDirs); 1642 1643 if (packagesToDoc.size() != 0 && sourceDirs.size() == 0) { 1644 String msg = "sourcePath attribute must be set when " 1645 + "specifying package names."; 1646 throw new BuildException(msg); 1647 } 1648 1649 Vector sourceFilesToDoc = (Vector ) sourceFiles.clone(); 1650 addSourceFiles(sourceFilesToDoc); 1651 1652 if (packageList == null && packagesToDoc.size() == 0 1653 && sourceFilesToDoc.size() == 0) { 1654 throw new BuildException("No source files and no packages have " 1655 + "been specified."); 1656 } 1657 1658 log("Generating Javadoc", Project.MSG_INFO); 1659 1660 Commandline toExecute = (Commandline) cmd.clone(); 1661 if (executable != null) { 1662 toExecute.setExecutable(executable); 1663 } else { 1664 toExecute.setExecutable(JavaEnvUtils.getJdkExecutable("javadoc")); 1665 } 1666 1667 if (doctitle != null) { 1669 toExecute.createArgument().setValue("-doctitle"); 1670 toExecute.createArgument().setValue(expand(doctitle.getText())); 1671 } 1672 if (header != null) { 1673 toExecute.createArgument().setValue("-header"); 1674 toExecute.createArgument().setValue(expand(header.getText())); 1675 } 1676 if (footer != null) { 1677 toExecute.createArgument().setValue("-footer"); 1678 toExecute.createArgument().setValue(expand(footer.getText())); 1679 } 1680 if (bottom != null) { 1681 toExecute.createArgument().setValue("-bottom"); 1682 toExecute.createArgument().setValue(expand(bottom.getText())); 1683 } 1684 1685 if (classpath == null) { 1686 classpath = (new Path(getProject())).concatSystemClasspath("last"); 1687 } else { 1688 classpath = classpath.concatSystemClasspath("ignore"); 1689 } 1690 1691 if (classpath.size() > 0) { 1692 toExecute.createArgument().setValue("-classpath"); 1693 toExecute.createArgument().setPath(classpath); 1694 } 1695 if (sourceDirs.size() > 0) { 1696 toExecute.createArgument().setValue("-sourcepath"); 1697 toExecute.createArgument().setPath(sourceDirs); 1698 } 1699 1700 if (version && doclet == null) { 1701 toExecute.createArgument().setValue("-version"); 1702 } 1703 if (author && doclet == null) { 1704 toExecute.createArgument().setValue("-author"); 1705 } 1706 1707 if (doclet == null && destDir == null) { 1708 throw new BuildException("destdir attribute must be set!"); 1709 } 1710 1711 1713 if (doclet != null) { 1714 if (doclet.getName() == null) { 1715 throw new BuildException("The doclet name must be " 1716 + "specified.", getLocation()); 1717 } else { 1718 toExecute.createArgument().setValue("-doclet"); 1719 toExecute.createArgument().setValue(doclet.getName()); 1720 if (doclet.getPath() != null) { 1721 Path docletPath 1722 = doclet.getPath().concatSystemClasspath("ignore"); 1723 if (docletPath.size() != 0) { 1724 toExecute.createArgument().setValue("-docletpath"); 1725 toExecute.createArgument().setPath(docletPath); 1726 } 1727 } 1728 for (Enumeration e = doclet.getParams(); 1729 e.hasMoreElements();) { 1730 DocletParam param = (DocletParam) e.nextElement(); 1731 if (param.getName() == null) { 1732 throw new BuildException("Doclet parameters must " 1733 + "have a name"); 1734 } 1735 1736 toExecute.createArgument().setValue(param.getName()); 1737 if (param.getValue() != null) { 1738 toExecute.createArgument() 1739 .setValue(param.getValue()); 1740 } 1741 } 1742 } 1743 } 1744 Path bcp = new Path(getProject()); 1745 if (bootclasspath != null) { 1746 bcp.append(bootclasspath); 1747 } 1748 bcp = bcp.concatSystemBootClasspath("ignore"); 1749 if (bcp.size() > 0) { 1750 toExecute.createArgument().setValue("-bootclasspath"); 1751 toExecute.createArgument().setPath(bcp); 1752 } 1753 1754 if (links.size() != 0) { 1756 for (Enumeration e = links.elements(); e.hasMoreElements();) { 1757 LinkArgument la = (LinkArgument) e.nextElement(); 1758 1759 if (la.getHref() == null || la.getHref().length() == 0) { 1760 log("No href was given for the link - skipping", 1761 Project.MSG_VERBOSE); 1762 continue; 1763 } 1764 String link = null; 1765 if (la.shouldResolveLink()) { 1766 File hrefAsFile = 1767 getProject().resolveFile(la.getHref()); 1768 if (hrefAsFile.exists()) { 1769 try { 1770 link = FILE_UTILS.getFileURL(hrefAsFile) 1771 .toExternalForm(); 1772 } catch (MalformedURLException ex) { 1773 log("Warning: link location was invalid " 1775 + hrefAsFile, Project.MSG_WARN); 1776 } 1777 } 1778 } 1779 if (link == null) { 1780 try { 1782 URL base = new URL ("file://."); 1783 new URL (base, la.getHref()); 1784 link = la.getHref(); 1785 } catch (MalformedURLException mue) { 1786 log("Link href \"" + la.getHref() 1788 + "\" is not a valid url - skipping link", 1789 Project.MSG_WARN); 1790 continue; 1791 } 1792 } 1793 1794 if (la.isLinkOffline()) { 1795 File packageListLocation = la.getPackagelistLoc(); 1796 if (packageListLocation == null) { 1797 throw new BuildException("The package list" 1798 + " location for link " 1799 + la.getHref() 1800 + " must be provided " 1801 + "because the link is " 1802 + "offline"); 1803 } 1804 File packageListFile = 1805 new File (packageListLocation, "package-list"); 1806 if (packageListFile.exists()) { 1807 try { 1808 String packageListURL = 1809 FILE_UTILS.getFileURL(packageListLocation) 1810 .toExternalForm(); 1811 toExecute.createArgument() 1812 .setValue("-linkoffline"); 1813 toExecute.createArgument() 1814 .setValue(link); 1815 toExecute.createArgument() 1816 .setValue(packageListURL); 1817 } catch (MalformedURLException ex) { 1818 log("Warning: Package list location was " 1819 + "invalid " + packageListLocation, 1820 Project.MSG_WARN); 1821 } 1822 } else { 1823 log("Warning: No package list was found at " 1824 + packageListLocation, Project.MSG_VERBOSE); 1825 } 1826 } else { 1827 toExecute.createArgument().setValue("-link"); 1828 toExecute.createArgument().setValue(link); 1829 } 1830 } 1831 } 1832 1833 1840 if (group != null) { 1846 StringTokenizer tok = new StringTokenizer (group, ",", false); 1847 while (tok.hasMoreTokens()) { 1848 String grp = tok.nextToken().trim(); 1849 int space = grp.indexOf(" "); 1850 if (space > 0) { 1851 String name = grp.substring(0, space); 1852 String pkgList = grp.substring(space + 1); 1853 toExecute.createArgument().setValue("-group"); 1854 toExecute.createArgument().setValue(name); 1855 toExecute.createArgument().setValue(pkgList); 1856 } 1857 } 1858 } 1859 1860 if (groups.size() != 0) { 1862 for (Enumeration e = groups.elements(); e.hasMoreElements();) { 1863 GroupArgument ga = (GroupArgument) e.nextElement(); 1864 String title = ga.getTitle(); 1865 String packages = ga.getPackages(); 1866 if (title == null || packages == null) { 1867 throw new BuildException("The title and packages must " 1868 + "be specified for group " 1869 + "elements."); 1870 } 1871 toExecute.createArgument().setValue("-group"); 1872 toExecute.createArgument().setValue(expand(title)); 1873 toExecute.createArgument().setValue(packages); 1874 } 1875 } 1876 1877 if (javadoc4 || executable != null) { 1879 for (Enumeration e = tags.elements(); e.hasMoreElements();) { 1880 Object element = e.nextElement(); 1881 if (element instanceof TagArgument) { 1882 TagArgument ta = (TagArgument) element; 1883 File tagDir = ta.getDir(getProject()); 1884 if (tagDir == null) { 1885 toExecute.createArgument().setValue ("-tag"); 1888 toExecute.createArgument() 1889 .setValue (ta.getParameter()); 1890 } else { 1891 DirectoryScanner tagDefScanner = 1895 ta.getDirectoryScanner(getProject()); 1896 String [] files = tagDefScanner.getIncludedFiles(); 1897 for (int i = 0; i < files.length; i++) { 1898 File tagDefFile = new File (tagDir, files[i]); 1899 try { 1900 BufferedReader in 1901 = new BufferedReader ( 1902 new FileReader (tagDefFile) 1903 ); 1904 String line = null; 1905 while ((line = in.readLine()) != null) { 1906 toExecute.createArgument() 1907 .setValue("-tag"); 1908 toExecute.createArgument() 1909 .setValue(line); 1910 } 1911 in.close(); 1912 } catch (IOException ioe) { 1913 throw new BuildException("Couldn't read " 1914 + " tag file from " 1915 + tagDefFile.getAbsolutePath(), ioe); 1916 } 1917 } 1918 } 1919 } else { 1920 ExtensionInfo tagletInfo = (ExtensionInfo) element; 1921 toExecute.createArgument().setValue("-taglet"); 1922 toExecute.createArgument().setValue(tagletInfo 1923 .getName()); 1924 if (tagletInfo.getPath() != null) { 1925 Path tagletPath = tagletInfo.getPath() 1926 .concatSystemClasspath("ignore"); 1927 if (tagletPath.size() != 0) { 1928 toExecute.createArgument() 1929 .setValue("-tagletpath"); 1930 toExecute.createArgument().setPath(tagletPath); 1931 } 1932 } 1933 } 1934 } 1935 1936 String sourceArg = source != null ? source 1937 : getProject().getProperty(MagicNames.BUILD_JAVAC_SOURCE); 1938 if (sourceArg != null) { 1939 toExecute.createArgument().setValue("-source"); 1940 toExecute.createArgument().setValue(sourceArg); 1941 } 1942 1943 if (linksource && doclet == null) { 1944 toExecute.createArgument().setValue("-linksource"); 1945 } 1946 if (breakiterator && (doclet == null || javadoc5)) { 1947 toExecute.createArgument().setValue("-breakiterator"); 1948 } 1949 if (noqualifier != null && doclet == null) { 1950 toExecute.createArgument().setValue("-noqualifier"); 1951 toExecute.createArgument().setValue(noqualifier); 1952 } 1953 } else { 1954 if (!tags.isEmpty()) { 1956 log("-tag and -taglet options not supported on Javadoc < 1.4", 1957 Project.MSG_VERBOSE); 1958 } 1959 if (source != null) { 1960 log("-source option not supported on Javadoc < 1.4", 1961 Project.MSG_VERBOSE); 1962 } 1963 if (linksource) { 1964 log("-linksource option not supported on Javadoc < 1.4", 1965 Project.MSG_VERBOSE); 1966 } 1967 if (breakiterator) { 1968 log("-breakiterator option not supported on Javadoc < 1.4", 1969 Project.MSG_VERBOSE); 1970 } 1971 if (noqualifier != null) { 1972 log("-noqualifier option not supported on Javadoc < 1.4", 1973 Project.MSG_VERBOSE); 1974 } 1975 } 1976 if (!javadoc4 || executable != null) { 1978 if (old) { 1979 toExecute.createArgument().setValue("-1.1"); 1980 } 1981 } else { 1982 if (old) { 1983 log("Javadoc 1.4 doesn't support the -1.1 switch anymore", 1984 Project.MSG_WARN); 1985 } 1986 } 1987 if (useExternalFile && javadoc4) { 1989 writeExternalArgs(toExecute); 1990 } 1991 1992 File tmpList = null; 1993 PrintWriter srcListWriter = null; 1994 1995 try { 1996 1997 2001 if (useExternalFile) { 2002 if (tmpList == null) { 2003 tmpList = FILE_UTILS.createTempFile("javadoc", "", null); 2004 tmpList.deleteOnExit(); 2005 toExecute.createArgument() 2006 .setValue("@" + tmpList.getAbsolutePath()); 2007 } 2008 srcListWriter = new PrintWriter ( 2009 new FileWriter (tmpList.getAbsolutePath(), 2010 true)); 2011 } 2012 2013 Enumeration e = packagesToDoc.elements(); 2014 while (e.hasMoreElements()) { 2015 String packageName = (String ) e.nextElement(); 2016 if (useExternalFile) { 2017 srcListWriter.println(packageName); 2018 } else { 2019 toExecute.createArgument().setValue(packageName); 2020 } 2021 } 2022 2023 e = sourceFilesToDoc.elements(); 2024 while (e.hasMoreElements()) { 2025 SourceFile sf = (SourceFile) e.nextElement(); 2026 String sourceFileName = sf.getFile().getAbsolutePath(); 2027 if (useExternalFile) { 2028 if (javadoc4 && sourceFileName.indexOf(" ") > -1) { 2031 String name = sourceFileName; 2032 if (File.separatorChar == '\\') { 2033 name = sourceFileName.replace(File.separatorChar, '/'); 2034 } 2035 srcListWriter.println("\"" + name + "\""); 2036 } else { 2037 srcListWriter.println(sourceFileName); 2038 } 2039 } else { 2040 toExecute.createArgument().setValue(sourceFileName); 2041 } 2042 } 2043 2044 } catch (IOException e) { 2045 tmpList.delete(); 2046 throw new BuildException("Error creating temporary file", 2047 e, getLocation()); 2048 } finally { 2049 if (srcListWriter != null) { 2050 srcListWriter.close(); 2051 } 2052 } 2053 2054 if (packageList != null) { 2055 toExecute.createArgument().setValue("@" + packageList); 2056 } 2057 log(toExecute.describeCommand(), Project.MSG_VERBOSE); 2058 2059 log("Javadoc execution", Project.MSG_INFO); 2060 2061 JavadocOutputStream out = new JavadocOutputStream(Project.MSG_INFO); 2062 JavadocOutputStream err = new JavadocOutputStream(Project.MSG_WARN); 2063 Execute exe = new Execute(new PumpStreamHandler(out, err)); 2064 exe.setAntRun(getProject()); 2065 2066 2072 exe.setWorkingDirectory(null); 2073 try { 2074 exe.setCommandline(toExecute.getCommandline()); 2075 int ret = exe.execute(); 2076 if (ret != 0 && failOnError) { 2077 throw new BuildException("Javadoc returned " + ret, 2078 getLocation()); 2079 } 2080 } catch (IOException e) { 2081 throw new BuildException("Javadoc failed: " + e, e, getLocation()); 2082 } finally { 2083 if (tmpList != null) { 2084 tmpList.delete(); 2085 tmpList = null; 2086 } 2087 2088 out.logFlush(); 2089 err.logFlush(); 2090 try { 2091 out.close(); 2092 err.close(); 2093 } catch (IOException e) { 2094 } 2096 } 2097 } 2098 2099 private void writeExternalArgs(Commandline toExecute) { 2100 File optionsTmpFile = null; 2102 PrintWriter optionsListWriter = null; 2103 try { 2104 optionsTmpFile = FILE_UTILS.createTempFile( 2105 "javadocOptions", "", null); 2106 optionsTmpFile.deleteOnExit(); 2107 String [] listOpt = toExecute.getArguments(); 2108 toExecute.clearArgs(); 2109 toExecute.createArgument().setValue( 2110 "@" + optionsTmpFile.getAbsolutePath()); 2111 optionsListWriter = new PrintWriter ( 2112 new FileWriter (optionsTmpFile.getAbsolutePath(), true)); 2113 for (int i = 0; i < listOpt.length; i++) { 2114 String string = listOpt[i]; 2115 if (string.startsWith("-J-")) { 2116 toExecute.createArgument().setValue(string); 2117 } else { 2118 if (string.startsWith("-")) { 2119 optionsListWriter.print(string); 2120 optionsListWriter.print(" "); 2121 } else { 2122 optionsListWriter.println(quoteString(string)); 2123 } 2124 } 2125 } 2126 optionsListWriter.close(); 2127 } catch (IOException ex) { 2128 if (optionsTmpFile != null) { 2129 optionsTmpFile.delete(); 2130 } 2131 throw new BuildException( 2132 "Error creating or writing temporary file for javadoc options", 2133 ex, getLocation()); 2134 } finally { 2135 FILE_UTILS.close(optionsListWriter); 2136 } 2137 } 2138 2139 2145 private String quoteString(String str) { 2146 if (str.indexOf(' ') == -1 2147 && str.indexOf('\'') == -1 2148 && str.indexOf('"') == -1) { 2149 return str; 2150 } 2151 if (str.indexOf('\'') == -1) { 2152 return quoteString(str, '\''); 2153 } else { 2154 return quoteString(str, '"'); 2155 } 2156 } 2157 2158 private String quoteString(String str, char delim) { 2159 StringBuffer buf = new StringBuffer (str.length() * 2); 2160 buf.append(delim); 2161 if (str.indexOf('\\') != -1) { 2162 str = replace(str, '\\', "\\\\"); 2163 } 2164 if (str.indexOf(delim) != -1) { 2165 str = replace(str, delim, "\\" + delim); 2166 } 2167 buf.append(str); 2168 buf.append(delim); 2169 return buf.toString(); 2170 } 2171 2172 private String replace(String str, char fromChar, String toString) { 2173 StringBuffer buf = new StringBuffer (str.length() * 2); 2174 for (int i = 0; i < str.length(); ++i) { 2175 char ch = str.charAt(i); 2176 if (ch == fromChar) { 2177 buf.append(toString); 2178 } else { 2179 buf.append(ch); 2180 } 2181 } 2182 return buf.toString(); 2183 } 2184 2185 2191 private void addSourceFiles(Vector sf) { 2192 Iterator e = nestedSourceFiles.iterator(); 2193 while (e.hasNext()) { 2194 ResourceCollection rc = (ResourceCollection) e.next(); 2195 if (!rc.isFilesystemOnly()) { 2196 throw new BuildException("only file system based resources are" 2197 + " supported by javadoc"); 2198 } 2199 if (rc instanceof FileSet) { 2200 FileSet fs = (FileSet) rc; 2201 if (!fs.hasPatterns() && !fs.hasSelectors()) { 2202 fs = (FileSet) fs.clone(); 2203 fs.createInclude().setName("**/*.java"); 2204 if (includeNoSourcePackages) { 2205 fs.createInclude().setName("**/package.html"); 2206 } 2207 } 2208 } 2209 Iterator iter = rc.iterator(); 2210 while (iter.hasNext()) { 2211 sf.addElement(new SourceFile(((FileResource) iter.next()) 2212 .getFile())); 2213 } 2214 } 2215 } 2216 2217 2225 private void parsePackages(Vector pn, Path sp) { 2226 Vector addedPackages = new Vector (); 2227 Vector dirSets = (Vector ) packageSets.clone(); 2228 2229 if (sourcePath != null) { 2234 PatternSet ps = new PatternSet(); 2235 if (packageNames.size() > 0) { 2236 Enumeration e = packageNames.elements(); 2237 while (e.hasMoreElements()) { 2238 PackageName p = (PackageName) e.nextElement(); 2239 String pkg = p.getName().replace('.', '/'); 2240 if (pkg.endsWith("*")) { 2241 pkg += "*"; 2242 } 2243 ps.createInclude().setName(pkg); 2244 } 2245 } else { 2246 ps.createInclude().setName("**"); 2247 } 2248 2249 Enumeration e = excludePackageNames.elements(); 2250 while (e.hasMoreElements()) { 2251 PackageName p = (PackageName) e.nextElement(); 2252 String pkg = p.getName().replace('.', '/'); 2253 if (pkg.endsWith("*")) { 2254 pkg += "*"; 2255 } 2256 ps.createExclude().setName(pkg); 2257 } 2258 2259 2260 String [] pathElements = sourcePath.list(); 2261 for (int i = 0; i < pathElements.length; i++) { 2262 File dir = new File (pathElements[i]); 2263 if (dir.isDirectory()) { 2264 DirSet ds = new DirSet(); 2265 ds.setDefaultexcludes(useDefaultExcludes); 2266 ds.setDir(dir); 2267 ds.createPatternSet().addConfiguredPatternset(ps); 2268 dirSets.addElement(ds); 2269 } else { 2270 log("Skipping " + pathElements[i] 2271 + " since it is no directory.", Project.MSG_WARN); 2272 } 2273 } 2274 } 2275 2276 Enumeration e = dirSets.elements(); 2277 while (e.hasMoreElements()) { 2278 DirSet ds = (DirSet) e.nextElement(); 2279 File baseDir = ds.getDir(getProject()); 2280 log("scanning " + baseDir + " for packages.", Project.MSG_DEBUG); 2281 DirectoryScanner dsc = ds.getDirectoryScanner(getProject()); 2282 String [] dirs = dsc.getIncludedDirectories(); 2283 boolean containsPackages = false; 2284 for (int i = 0; i < dirs.length; i++) { 2285 File pd = new File (baseDir, dirs[i]); 2287 String [] files = pd.list(new FilenameFilter () { 2288 public boolean accept(File dir1, String name) { 2289 return name.endsWith(".java") 2290 || (includeNoSourcePackages 2291 && name.equals("package.html")); 2292 } 2293 }); 2294 2295 if (files.length > 0) { 2296 if ("".equals(dirs[i])) { 2297 log(baseDir 2298 + " contains source files in the default package," 2299 + " you must specify them as source files" 2300 + " not packages.", 2301 Project.MSG_WARN); 2302 } else { 2303 containsPackages = true; 2304 String packageName = 2305 dirs[i].replace(File.separatorChar, '.'); 2306 if (!addedPackages.contains(packageName)) { 2307 addedPackages.addElement(packageName); 2308 pn.addElement(packageName); 2309 } 2310 } 2311 } 2312 } 2313 if (containsPackages) { 2314 sp.createPathElement().setLocation(baseDir); 2317 } else { 2318 log(baseDir + " doesn\'t contain any packages, dropping it.", 2319 Project.MSG_VERBOSE); 2320 } 2321 } 2322 } 2323 2324 private class JavadocOutputStream extends LogOutputStream { 2325 JavadocOutputStream(int level) { 2326 super(Javadoc.this, level); 2327 } 2328 2329 private String queuedLine = null; 2335 protected void processLine(String line, int messageLevel) { 2336 if (messageLevel == Project.MSG_INFO 2337 && line.startsWith("Generating ")) { 2338 if (queuedLine != null) { 2339 super.processLine(queuedLine, Project.MSG_VERBOSE); 2340 } 2341 queuedLine = line; 2342 } else { 2343 if (queuedLine != null) { 2344 if (line.startsWith("Building ")) { 2345 super.processLine(queuedLine, Project.MSG_VERBOSE); 2346 } else { 2347 super.processLine(queuedLine, Project.MSG_INFO); 2348 } 2349 queuedLine = null; 2350 } 2351 super.processLine(line, messageLevel); 2352 } 2353 } 2354 2355 2356 protected void logFlush() { 2357 if (queuedLine != null) { 2358 super.processLine(queuedLine, Project.MSG_VERBOSE); 2359 queuedLine = null; 2360 } 2361 } 2362 } 2363 2364 2369 protected String expand(String content) { 2370 return getProject().replaceProperties(content); 2371 } 2372 2373} 2374 | Popular Tags |