You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Javadoc.java 40 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177
  1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 1999 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowlegement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowlegement may appear in the software itself,
  24. * if and wherever such third-party acknowlegements normally appear.
  25. *
  26. * 4. The names "The Jakarta Project", "Ant", and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Group.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. */
  54. package org.apache.tools.ant.taskdefs;
  55. import java.io.*;
  56. import java.util.*;
  57. import org.apache.tools.ant.BuildException;
  58. import org.apache.tools.ant.DirectoryScanner;
  59. import org.apache.tools.ant.Project;
  60. import org.apache.tools.ant.ProjectHelper;
  61. import org.apache.tools.ant.Task;
  62. import org.apache.tools.ant.types.*;
  63. /**
  64. * This task makes it easy to generate Javadoc documentation for a collection
  65. * of source code.
  66. *
  67. * <P>Current known limitations are:
  68. *
  69. * <P><UL>
  70. * <LI>patterns must be of the form "xxx.*", every other pattern doesn't
  71. * work.
  72. * <LI>the java comment-stripper reader is horribly slow
  73. * <LI>there is no control on arguments sanity since they are left
  74. * to the javadoc implementation.
  75. * <LI>argument J in javadoc1 is not supported (what is that for anyway?)
  76. * </UL>
  77. *
  78. * <P>If no <CODE>doclet</CODE> is set, then the <CODE>version</CODE> and
  79. * <CODE>author</CODE> are by default <CODE>"yes"</CODE>.
  80. *
  81. * <P>Note: This task is run on another VM because the Javadoc code calls
  82. * <CODE>System.exit()</CODE> which would break Ant functionality.
  83. *
  84. * @author Jon S. Stevens <a href="mailto:jon@clearink.com">jon@clearink.com</a>
  85. * @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">stefano@apache.org</a>
  86. * @author Patrick Chanezon <a href="mailto:chanezon@netscape.com">chanezon@netscape.com</a>
  87. * @author Ernst de Haan <a href="mailto:ernst@jollem.com">ernst@jollem.com</a>
  88. * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
  89. */
  90. public class Javadoc extends Task {
  91. public class DocletParam {
  92. private String name;
  93. private String value;
  94. public void setName(String name) {
  95. this.name = name;
  96. }
  97. public String getName() {
  98. return name;
  99. }
  100. public void setValue(String value) {
  101. this.value = value;
  102. }
  103. public String getValue() {
  104. return value;
  105. }
  106. }
  107. public class DocletInfo {
  108. private String name;
  109. private Path path;
  110. private Vector params = new Vector();
  111. public void setName(String name) {
  112. this.name = name;
  113. }
  114. public String getName() {
  115. return name;
  116. }
  117. public void setPath(Path path) {
  118. if (this.path == null) {
  119. this.path = path;
  120. } else {
  121. this.path.append(path);
  122. }
  123. }
  124. public Path getPath() {
  125. return path;
  126. }
  127. public Path createPath() {
  128. if (path == null) {
  129. path = new Path(getProject());
  130. }
  131. return path.createPath();
  132. }
  133. /**
  134. * Adds a reference to a CLASSPATH defined elsewhere.
  135. */
  136. public void setPathRef(Reference r) {
  137. createPath().setRefid(r);
  138. }
  139. public DocletParam createParam() {
  140. DocletParam param = new DocletParam();
  141. params.addElement(param);
  142. return param;
  143. }
  144. public Enumeration getParams() {
  145. return params.elements();
  146. }
  147. }
  148. public static class PackageName {
  149. private String name;
  150. public void setName(String name) {
  151. this.name = name;
  152. }
  153. public String getName() {
  154. return name;
  155. }
  156. public String toString() {
  157. return getName();
  158. }
  159. }
  160. public static class SourceFile {
  161. private File file;
  162. public void setFile(File file) {
  163. this.file = file;
  164. }
  165. public File getFile() {
  166. return file;
  167. }
  168. }
  169. public static class Html {
  170. private StringBuffer text = new StringBuffer();
  171. public void addText(String t) {
  172. text.append(t);
  173. }
  174. public String getText() {
  175. return text.toString();
  176. }
  177. }
  178. public static class AccessType extends EnumeratedAttribute {
  179. public String[] getValues() {
  180. // Protected first so if any GUI tool offers a default
  181. // based on enum #0, it will be right.
  182. return new String[] {"protected", "public", "package", "private"};
  183. }
  184. }
  185. private Commandline cmd = new Commandline();
  186. private static boolean javadoc1 =
  187. (Project.getJavaVersion() == Project.JAVA_1_1);
  188. private void addArgIf(boolean b, String arg) {
  189. if (b) {
  190. cmd.createArgument().setValue(arg);
  191. }
  192. }
  193. private void add12ArgIfNotEmpty(String key, String value) {
  194. if (!javadoc1) {
  195. if (value != null && value.length() != 0) {
  196. cmd.createArgument().setValue(key);
  197. cmd.createArgument().setValue(value);
  198. } else {
  199. project.log(this,
  200. "Warning: Leaving out empty argument '" + key + "'",
  201. Project.MSG_WARN);
  202. }
  203. }
  204. }
  205. private void add11ArgIf(boolean b, String arg) {
  206. if (javadoc1 && b) {
  207. cmd.createArgument().setValue(arg);
  208. }
  209. }
  210. private void add12ArgIf(boolean b, String arg) {
  211. if (!javadoc1 && b) {
  212. cmd.createArgument().setValue(arg);
  213. }
  214. }
  215. private boolean foundJavaFile = false;
  216. private boolean failOnError = false;
  217. private Path sourcePath = null;
  218. private File destDir = null;
  219. private Vector sourceFiles = new Vector();
  220. private Vector packageNames = new Vector(5);
  221. private Vector excludePackageNames = new Vector(1);
  222. private boolean author = true;
  223. private boolean version = true;
  224. private DocletInfo doclet = null;
  225. private Path classpath = null;
  226. private Path bootclasspath = null;
  227. private String group = null;
  228. private Vector compileList = new Vector(10);
  229. private String packageList = null;
  230. private Vector links = new Vector(2);
  231. private Vector groups = new Vector(2);
  232. private boolean useDefaultExcludes = true;
  233. private Html doctitle = null;
  234. private Html header = null;
  235. private Html footer = null;
  236. private Html bottom = null;
  237. private boolean useExternalFile = false;
  238. private File tmpList = null;
  239. /**
  240. * Work around command line length limit by using an external file
  241. * for the sourcefiles.
  242. */
  243. public void setUseExternalFile(boolean b) {
  244. if (!javadoc1) {
  245. useExternalFile = b;
  246. }
  247. }
  248. /**
  249. * Sets whether default exclusions should be used or not.
  250. *
  251. * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions
  252. * should be used, "false"|"off"|"no" when they
  253. * shouldn't be used.
  254. */
  255. public void setDefaultexcludes(boolean useDefaultExcludes) {
  256. this.useDefaultExcludes = useDefaultExcludes;
  257. }
  258. public void setMaxmemory(String max){
  259. if(javadoc1){
  260. cmd.createArgument().setValue("-J-mx" + max);
  261. } else{
  262. cmd.createArgument().setValue("-J-Xmx" + max);
  263. }
  264. }
  265. public void setAdditionalparam(String add){
  266. cmd.createArgument().setLine(add);
  267. }
  268. public void setSourcepath(Path src) {
  269. if (sourcePath == null) {
  270. sourcePath = src;
  271. } else {
  272. sourcePath.append(src);
  273. }
  274. }
  275. public Path createSourcepath() {
  276. if (sourcePath == null) {
  277. sourcePath = new Path(project);
  278. }
  279. return sourcePath.createPath();
  280. }
  281. /**
  282. * Adds a reference to a CLASSPATH defined elsewhere.
  283. */
  284. public void setSourcepathRef(Reference r) {
  285. createSourcepath().setRefid(r);
  286. }
  287. public void setDestdir(File dir) {
  288. destDir = dir;
  289. cmd.createArgument().setValue("-d");
  290. cmd.createArgument().setFile(destDir);
  291. }
  292. public void setSourcefiles(String src) {
  293. StringTokenizer tok = new StringTokenizer(src, ",");
  294. while (tok.hasMoreTokens()) {
  295. String f = tok.nextToken();
  296. SourceFile sf = new SourceFile();
  297. sf.setFile(project.resolveFile(f));
  298. addSource(sf);
  299. }
  300. }
  301. public void addSource(SourceFile sf) {
  302. sourceFiles.addElement(sf);
  303. }
  304. public void setPackagenames(String src) {
  305. StringTokenizer tok = new StringTokenizer(src, ",");
  306. while (tok.hasMoreTokens()) {
  307. String p = tok.nextToken();
  308. PackageName pn = new PackageName();
  309. pn.setName(p);
  310. addPackage(pn);
  311. }
  312. }
  313. public void addPackage(PackageName pn) {
  314. packageNames.addElement(pn);
  315. }
  316. public void setExcludePackageNames(String src) {
  317. StringTokenizer tok = new StringTokenizer(src, ",");
  318. while (tok.hasMoreTokens()) {
  319. String p = tok.nextToken();
  320. PackageName pn = new PackageName();
  321. pn.setName(p);
  322. addExcludePackage(pn);
  323. }
  324. }
  325. public void addExcludePackage(PackageName pn) {
  326. excludePackageNames.addElement(pn);
  327. }
  328. public void setOverview(File f) {
  329. if (!javadoc1) {
  330. cmd.createArgument().setValue("-overview");
  331. cmd.createArgument().setFile(f);
  332. }
  333. }
  334. public void setPublic(boolean b) {
  335. addArgIf(b, "-public");
  336. }
  337. public void setProtected(boolean b) {
  338. addArgIf(b, "-protected");
  339. }
  340. public void setPackage(boolean b) {
  341. addArgIf(b, "-package");
  342. }
  343. public void setPrivate(boolean b) {
  344. addArgIf(b, "-private");
  345. }
  346. public void setAccess(AccessType at) {
  347. cmd.createArgument().setValue("-" + at.getValue());
  348. }
  349. public void setDoclet(String src) {
  350. if (doclet == null) {
  351. doclet = new DocletInfo();
  352. }
  353. doclet.setName(src);
  354. }
  355. public void setDocletPath(Path src) {
  356. if (doclet == null) {
  357. doclet = new DocletInfo();
  358. }
  359. doclet.setPath(src);
  360. }
  361. public void setDocletPathRef(Reference r) {
  362. if (doclet == null) {
  363. doclet = new DocletInfo();
  364. }
  365. doclet.createPath().setRefid(r);
  366. }
  367. public DocletInfo createDoclet() {
  368. doclet = new DocletInfo();
  369. return doclet;
  370. }
  371. public void setOld(boolean b) {
  372. add12ArgIf(b, "-1.1");
  373. }
  374. public void setClasspath(Path src) {
  375. if (classpath == null) {
  376. classpath = src;
  377. } else {
  378. classpath.append(src);
  379. }
  380. }
  381. public Path createClasspath() {
  382. if (classpath == null) {
  383. classpath = new Path(project);
  384. }
  385. return classpath.createPath();
  386. }
  387. /**
  388. * Adds a reference to a CLASSPATH defined elsewhere.
  389. */
  390. public void setClasspathRef(Reference r) {
  391. createClasspath().setRefid(r);
  392. }
  393. public void setBootclasspath(Path src) {
  394. if (bootclasspath == null) {
  395. bootclasspath = src;
  396. } else {
  397. bootclasspath.append(src);
  398. }
  399. }
  400. public Path createBootclasspath() {
  401. if (bootclasspath == null) {
  402. bootclasspath = new Path(project);
  403. }
  404. return bootclasspath.createPath();
  405. }
  406. /**
  407. * Adds a reference to a CLASSPATH defined elsewhere.
  408. */
  409. public void setBootClasspathRef(Reference r) {
  410. createBootclasspath().setRefid(r);
  411. }
  412. public void setExtdirs(String src) {
  413. if (!javadoc1) {
  414. cmd.createArgument().setValue("-extdirs");
  415. cmd.createArgument().setValue(src);
  416. }
  417. }
  418. public void setVerbose(boolean b) {
  419. add12ArgIf(b, "-verbose");
  420. }
  421. public void setLocale(String src) {
  422. if (!javadoc1) {
  423. cmd.createArgument().setValue("-locale");
  424. cmd.createArgument().setValue(src);
  425. }
  426. }
  427. public void setEncoding(String enc) {
  428. cmd.createArgument().setValue("-encoding");
  429. cmd.createArgument().setValue(enc);
  430. }
  431. public void setVersion(boolean src) {
  432. version = src;
  433. }
  434. public void setUse(boolean b) {
  435. add12ArgIf(b, "-use");
  436. }
  437. public void setAuthor(boolean src) {
  438. author = src;
  439. }
  440. public void setSplitindex(boolean b) {
  441. add12ArgIf(b, "-splitindex");
  442. }
  443. public void setWindowtitle(String src) {
  444. add12ArgIfNotEmpty("-windowtitle", src);
  445. }
  446. public void setDoctitle(String src) {
  447. Html h = new Html();
  448. h.addText(src);
  449. addDoctitle(h);
  450. }
  451. public void addDoctitle(Html text) {
  452. if (!javadoc1) {
  453. doctitle = text;
  454. }
  455. }
  456. public void setHeader(String src) {
  457. Html h = new Html();
  458. h.addText(src);
  459. addHeader(h);
  460. }
  461. public void addHeader(Html text) {
  462. if (!javadoc1) {
  463. header = text;
  464. }
  465. }
  466. public void setFooter(String src) {
  467. Html h = new Html();
  468. h.addText(src);
  469. addFooter(h);
  470. }
  471. public void addFooter(Html text) {
  472. if (!javadoc1) {
  473. footer = text;
  474. }
  475. }
  476. public void setBottom(String src) {
  477. Html h = new Html();
  478. h.addText(src);
  479. addBottom(h);
  480. }
  481. public void addBottom(Html text) {
  482. if (!javadoc1) {
  483. bottom = text;
  484. }
  485. }
  486. public void setLinkoffline(String src) {
  487. if (!javadoc1) {
  488. LinkArgument le = createLink();
  489. le.setOffline(true);
  490. String linkOfflineError = "The linkoffline attribute must include a URL and " +
  491. "a package-list file location separated by a space";
  492. if (src.trim().length() == 0) {
  493. throw new BuildException(linkOfflineError);
  494. }
  495. StringTokenizer tok = new StringTokenizer(src, " ", false);
  496. le.setHref(tok.nextToken());
  497. if (!tok.hasMoreTokens()) {
  498. throw new BuildException(linkOfflineError);
  499. }
  500. le.setPackagelistLoc(project.resolveFile(tok.nextToken()));
  501. }
  502. }
  503. public void setGroup(String src) {
  504. group = src;
  505. }
  506. public void setLink(String src) {
  507. if (!javadoc1) {
  508. createLink().setHref(src);
  509. }
  510. }
  511. public void setNodeprecated(boolean b) {
  512. addArgIf(b, "-nodeprecated");
  513. }
  514. public void setNodeprecatedlist(boolean b) {
  515. add12ArgIf(b, "-nodeprecatedlist");
  516. }
  517. public void setNotree(boolean b) {
  518. addArgIf(b, "-notree");
  519. }
  520. public void setNoindex(boolean b) {
  521. addArgIf(b, "-noindex");
  522. }
  523. public void setNohelp(boolean b) {
  524. add12ArgIf(b, "-nohelp");
  525. }
  526. public void setNonavbar(boolean b) {
  527. add12ArgIf(b, "-nonavbar");
  528. }
  529. public void setSerialwarn(boolean b) {
  530. add12ArgIf(b, "-serialwarn");
  531. }
  532. public void setStylesheetfile(File f) {
  533. if (!javadoc1) {
  534. cmd.createArgument().setValue("-stylesheetfile");
  535. cmd.createArgument().setFile(f);
  536. }
  537. }
  538. public void setHelpfile(File f) {
  539. if (!javadoc1) {
  540. cmd.createArgument().setValue("-helpfile");
  541. cmd.createArgument().setFile(f);
  542. }
  543. }
  544. public void setDocencoding(String enc) {
  545. cmd.createArgument().setValue("-docencoding");
  546. cmd.createArgument().setValue(enc);
  547. }
  548. public void setPackageList(String src) {
  549. packageList = src;
  550. }
  551. public LinkArgument createLink() {
  552. LinkArgument la = new LinkArgument();
  553. links.addElement(la);
  554. return la;
  555. }
  556. public class LinkArgument {
  557. private String href;
  558. private boolean offline = false;
  559. private File packagelistLoc;
  560. public LinkArgument() {
  561. }
  562. public void setHref(String hr) {
  563. href = hr;
  564. }
  565. public String getHref() {
  566. return href;
  567. }
  568. public void setPackagelistLoc(File src) {
  569. packagelistLoc = src;
  570. }
  571. public File getPackagelistLoc() {
  572. return packagelistLoc;
  573. }
  574. public void setOffline(boolean offline) {
  575. this.offline = offline;
  576. }
  577. public boolean isLinkOffline() {
  578. return offline;
  579. }
  580. }
  581. public GroupArgument createGroup() {
  582. GroupArgument ga = new GroupArgument();
  583. groups.addElement(ga);
  584. return ga;
  585. }
  586. public class GroupArgument {
  587. private Html title;
  588. private Vector packages = new Vector(3);
  589. public GroupArgument() {
  590. }
  591. public void setTitle(String src) {
  592. Html h = new Html();
  593. h.addText(src);
  594. addTitle(h);
  595. }
  596. public void addTitle(Html text) {
  597. title = text;
  598. }
  599. public String getTitle() {
  600. return title != null ? title.getText() : null;
  601. }
  602. public void setPackages(String src) {
  603. StringTokenizer tok = new StringTokenizer(src, ",");
  604. while (tok.hasMoreTokens()) {
  605. String p = tok.nextToken();
  606. PackageName pn = new PackageName();
  607. pn.setName(p);
  608. addPackage(pn);
  609. }
  610. }
  611. public void addPackage(PackageName pn) {
  612. packages.addElement(pn);
  613. }
  614. public String getPackages() {
  615. StringBuffer p = new StringBuffer();
  616. for (int i = 0; i < packages.size(); i++) {
  617. if ( i > 0 ) {
  618. p.append( ":" );
  619. }
  620. p.append( packages.elementAt(i).toString() );
  621. }
  622. return p.toString();
  623. }
  624. }
  625. public void setCharset(String src) {
  626. this.add12ArgIfNotEmpty("-charset", src);
  627. }
  628. /**
  629. * Should the build process fail if javadoc fails (as indicated by
  630. * a non zero return code)?
  631. *
  632. * <p>Default is false.</p>
  633. */
  634. public void setFailonerror(boolean b) {
  635. failOnError = b;
  636. }
  637. public void execute() throws BuildException {
  638. if ("javadoc2".equals(taskType)) {
  639. log("!! javadoc2 is deprecated. Use javadoc instead. !!");
  640. }
  641. if (sourcePath == null) {
  642. String msg = "sourcePath attribute must be set!";
  643. throw new BuildException(msg);
  644. }
  645. log("Generating Javadoc", Project.MSG_INFO);
  646. if (doctitle != null) {
  647. cmd.createArgument().setValue("-doctitle");
  648. cmd.createArgument().setValue(expand(doctitle.getText()));
  649. }
  650. if (header != null) {
  651. cmd.createArgument().setValue("-header");
  652. cmd.createArgument().setValue(expand(header.getText()));
  653. }
  654. if (footer != null) {
  655. cmd.createArgument().setValue("-footer");
  656. cmd.createArgument().setValue(expand(footer.getText()));
  657. }
  658. if (bottom != null) {
  659. cmd.createArgument().setValue("-bottom");
  660. cmd.createArgument().setValue(expand(bottom.getText()));
  661. }
  662. Commandline toExecute = (Commandline)cmd.clone();
  663. toExecute.setExecutable( getJavadocExecutableName() );
  664. // ------------------------------------------------ general javadoc arguments
  665. if (classpath == null)
  666. classpath = Path.systemClasspath;
  667. else
  668. classpath = classpath.concatSystemClasspath("ignore");
  669. if (!javadoc1) {
  670. toExecute.createArgument().setValue("-classpath");
  671. toExecute.createArgument().setPath(classpath);
  672. toExecute.createArgument().setValue("-sourcepath");
  673. toExecute.createArgument().setPath(sourcePath);
  674. } else {
  675. toExecute.createArgument().setValue("-classpath");
  676. toExecute.createArgument().setValue(sourcePath.toString() +
  677. System.getProperty("path.separator") + classpath.toString());
  678. }
  679. if (version && doclet == null)
  680. toExecute.createArgument().setValue("-version");
  681. if (author && doclet == null)
  682. toExecute.createArgument().setValue("-author");
  683. if (javadoc1 || doclet == null) {
  684. if (destDir == null) {
  685. String msg = "destDir attribute must be set!";
  686. throw new BuildException(msg);
  687. }
  688. }
  689. // --------------------------------- javadoc2 arguments for default doclet
  690. // XXX: how do we handle a custom doclet?
  691. if (!javadoc1) {
  692. if (doclet != null) {
  693. if (doclet.getName() == null) {
  694. throw new BuildException("The doclet name must be specified.", location);
  695. }
  696. else {
  697. toExecute.createArgument().setValue("-doclet");
  698. toExecute.createArgument().setValue(doclet.getName());
  699. if (doclet.getPath() != null) {
  700. toExecute.createArgument().setValue("-docletpath");
  701. toExecute.createArgument().setPath(doclet.getPath());
  702. }
  703. for (Enumeration e = doclet.getParams(); e.hasMoreElements();) {
  704. DocletParam param = (DocletParam)e.nextElement();
  705. if (param.getName() == null) {
  706. throw new BuildException("Doclet parameters must have a name");
  707. }
  708. toExecute.createArgument().setValue(param.getName());
  709. if (param.getValue() != null) {
  710. toExecute.createArgument().setValue(param.getValue());
  711. }
  712. }
  713. }
  714. }
  715. if (bootclasspath != null) {
  716. toExecute.createArgument().setValue("-bootclasspath");
  717. toExecute.createArgument().setPath(bootclasspath);
  718. }
  719. // add the links arguments
  720. if (links.size() != 0) {
  721. for (Enumeration e = links.elements(); e.hasMoreElements(); ) {
  722. LinkArgument la = (LinkArgument)e.nextElement();
  723. if (la.getHref() == null) {
  724. throw new BuildException("Links must provide the URL to the external class documentation.");
  725. }
  726. if (la.isLinkOffline()) {
  727. File packageListLocation = la.getPackagelistLoc();
  728. if (packageListLocation == null) {
  729. throw new BuildException("The package list location for link " + la.getHref() +
  730. " must be provided because the link is offline");
  731. }
  732. File packageList = new File(packageListLocation, "package-list");
  733. if (packageList.exists()) {
  734. toExecute.createArgument().setValue("-linkoffline");
  735. toExecute.createArgument().setValue(la.getHref());
  736. toExecute.createArgument().setValue(packageListLocation.getAbsolutePath());
  737. }
  738. else {
  739. log("Warning: No package list was found at " + packageListLocation,
  740. Project.MSG_VERBOSE);
  741. }
  742. }
  743. else {
  744. toExecute.createArgument().setValue("-link");
  745. toExecute.createArgument().setValue(la.getHref());
  746. }
  747. }
  748. }
  749. // add the single group arguments
  750. // Javadoc 1.2 rules:
  751. // Multiple -group args allowed.
  752. // Each arg includes 3 strings: -group [name] [packagelist].
  753. // Elements in [packagelist] are colon-delimited.
  754. // An element in [packagelist] may end with the * wildcard.
  755. // Ant javadoc task rules for group attribute:
  756. // Args are comma-delimited.
  757. // Each arg is 2 space-delimited strings.
  758. // E.g., group="XSLT_Packages org.apache.xalan.xslt*,XPath_Packages org.apache.xalan.xpath*"
  759. if (group != null) {
  760. StringTokenizer tok = new StringTokenizer(group, ",", false);
  761. while (tok.hasMoreTokens()) {
  762. String grp = tok.nextToken().trim();
  763. int space = grp.indexOf(" ");
  764. if (space > 0){
  765. String name = grp.substring(0, space);
  766. String pkgList = grp.substring(space + 1);
  767. toExecute.createArgument().setValue("-group");
  768. toExecute.createArgument().setValue(name);
  769. toExecute.createArgument().setValue(pkgList);
  770. }
  771. }
  772. }
  773. // add the group arguments
  774. if (groups.size() != 0) {
  775. for (Enumeration e = groups.elements(); e.hasMoreElements(); ) {
  776. GroupArgument ga = (GroupArgument)e.nextElement();
  777. String title = ga.getTitle();
  778. String packages = ga.getPackages();
  779. if (title == null || packages == null) {
  780. throw new BuildException("The title and packages must be specified for group elements.");
  781. }
  782. toExecute.createArgument().setValue("-group");
  783. toExecute.createArgument().setValue(expand(title));
  784. toExecute.createArgument().setValue(packages);
  785. }
  786. }
  787. }
  788. tmpList = null;
  789. if (packageNames.size() > 0) {
  790. Vector packages = new Vector();
  791. Enumeration enum = packageNames.elements();
  792. while (enum.hasMoreElements()) {
  793. PackageName pn = (PackageName) enum.nextElement();
  794. String name = pn.getName().trim();
  795. if (name.endsWith(".*")) {
  796. packages.addElement(name);
  797. } else {
  798. toExecute.createArgument().setValue(name);
  799. }
  800. }
  801. Vector excludePackages = new Vector();
  802. if (excludePackageNames.size() > 0) {
  803. enum = excludePackageNames.elements();
  804. while (enum.hasMoreElements()) {
  805. PackageName pn = (PackageName) enum.nextElement();
  806. excludePackages.addElement(pn.getName().trim());
  807. }
  808. }
  809. if (packages.size() > 0) {
  810. evaluatePackages(toExecute, sourcePath, packages, excludePackages);
  811. }
  812. }
  813. if (sourceFiles.size() > 0) {
  814. PrintWriter srcListWriter = null;
  815. try {
  816. /**
  817. * Write sourcefiles to a temporary file if requested.
  818. */
  819. if (useExternalFile) {
  820. if (tmpList == null) {
  821. tmpList = createTempFile();
  822. toExecute.createArgument().setValue("@" + tmpList.getAbsolutePath());
  823. }
  824. srcListWriter = new PrintWriter(new FileWriter(tmpList.getAbsolutePath(),
  825. true));
  826. }
  827. Enumeration enum = sourceFiles.elements();
  828. while (enum.hasMoreElements()) {
  829. SourceFile sf = (SourceFile) enum.nextElement();
  830. String sourceFileName = sf.getFile().getAbsolutePath();
  831. if (useExternalFile) {
  832. srcListWriter.println(sourceFileName);
  833. } else {
  834. toExecute.createArgument().setValue(sourceFileName);
  835. }
  836. }
  837. } catch (IOException e) {
  838. throw new BuildException("Error creating temporary file",
  839. e, location);
  840. } finally {
  841. if (srcListWriter != null) {
  842. srcListWriter.close();
  843. }
  844. }
  845. }
  846. if (packageList != null) {
  847. toExecute.createArgument().setValue("@" + packageList);
  848. }
  849. log("Javadoc args: " + toExecute, Project.MSG_VERBOSE);
  850. log("Javadoc execution", Project.MSG_INFO);
  851. JavadocOutputStream out = new JavadocOutputStream(Project.MSG_INFO);
  852. JavadocOutputStream err = new JavadocOutputStream(Project.MSG_WARN);
  853. Execute exe = new Execute(new PumpStreamHandler(out, err));
  854. exe.setAntRun(project);
  855. /*
  856. * No reason to change the working directory as all filenames and
  857. * path components have been resolved already.
  858. *
  859. * Avoid problems with command line length in some environments.
  860. */
  861. exe.setWorkingDirectory(null);
  862. try {
  863. exe.setCommandline(toExecute.getCommandline());
  864. int ret = exe.execute();
  865. if (ret != 0 && failOnError) {
  866. throw new BuildException("Javadoc returned "+ret, location);
  867. }
  868. } catch (IOException e) {
  869. throw new BuildException("Javadoc failed: " + e, e, location);
  870. } finally {
  871. if (tmpList != null) {
  872. tmpList.delete();
  873. tmpList = null;
  874. }
  875. out.logFlush();
  876. err.logFlush();
  877. try {
  878. out.close();
  879. err.close();
  880. } catch (IOException e) {}
  881. }
  882. }
  883. /**
  884. * Given a source path, a list of package patterns, fill the given list
  885. * with the packages found in that path subdirs matching one of the given
  886. * patterns.
  887. */
  888. private void evaluatePackages(Commandline toExecute, Path sourcePath,
  889. Vector packages, Vector excludePackages) {
  890. log("Source path = " + sourcePath.toString(), Project.MSG_VERBOSE);
  891. StringBuffer msg = new StringBuffer("Packages = ");
  892. for (int i=0; i<packages.size(); i++) {
  893. if (i > 0) {
  894. msg.append(",");
  895. }
  896. msg.append(packages.elementAt(i));
  897. }
  898. log(msg.toString(), Project.MSG_VERBOSE);
  899. msg.setLength(0);
  900. msg.append("Exclude Packages = ");
  901. for (int i=0; i<excludePackages.size(); i++) {
  902. if (i > 0) {
  903. msg.append(",");
  904. }
  905. msg.append(excludePackages.elementAt(i));
  906. }
  907. log(msg.toString(), Project.MSG_VERBOSE);
  908. Vector addedPackages = new Vector();
  909. String[] list = sourcePath.list();
  910. if (list == null) list = new String[0];
  911. FileSet fs = new FileSet();
  912. fs.setDefaultexcludes(useDefaultExcludes);
  913. Enumeration e = packages.elements();
  914. while (e.hasMoreElements()) {
  915. String pkg = (String)e.nextElement();
  916. pkg = pkg.replace('.','/');
  917. if (pkg.endsWith("*")) {
  918. pkg += "*";
  919. }
  920. fs.createInclude().setName(pkg);
  921. } // while
  922. e = excludePackages.elements();
  923. while (e.hasMoreElements()) {
  924. String pkg = (String)e.nextElement();
  925. pkg = pkg.replace('.','/');
  926. if (pkg.endsWith("*")) {
  927. pkg += "*";
  928. }
  929. fs.createExclude().setName(pkg);
  930. }
  931. PrintWriter packageListWriter = null;
  932. try {
  933. if (useExternalFile) {
  934. tmpList = createTempFile();
  935. toExecute.createArgument().setValue("@" + tmpList.getAbsolutePath());
  936. packageListWriter = new PrintWriter(new FileWriter(tmpList));
  937. }
  938. for (int j=0; j<list.length; j++) {
  939. File source = project.resolveFile(list[j]);
  940. fs.setDir(source);
  941. DirectoryScanner ds = fs.getDirectoryScanner(project);
  942. String[] packageDirs = ds.getIncludedDirectories();
  943. for (int i=0; i<packageDirs.length; i++) {
  944. File pd = new File(source, packageDirs[i]);
  945. String[] files = pd.list(new FilenameFilter () {
  946. public boolean accept(File dir1, String name) {
  947. if (name.endsWith(".java")) {
  948. return true;
  949. }
  950. return false; // ignore dirs
  951. }
  952. });
  953. if (files.length > 0) {
  954. String pkgDir = packageDirs[i].replace('/','.').replace('\\','.');
  955. if (!addedPackages.contains(pkgDir)) {
  956. if (useExternalFile) {
  957. packageListWriter.println(pkgDir);
  958. } else {
  959. toExecute.createArgument().setValue(pkgDir);
  960. }
  961. addedPackages.addElement(pkgDir);
  962. }
  963. }
  964. }
  965. }
  966. } catch (IOException ioex) {
  967. throw new BuildException("Error creating temporary file",
  968. ioex, location);
  969. } finally {
  970. if (packageListWriter != null) {
  971. packageListWriter.close();
  972. }
  973. }
  974. }
  975. private class JavadocOutputStream extends LogOutputStream {
  976. JavadocOutputStream(int level) {
  977. super(Javadoc.this, level);
  978. }
  979. //
  980. // Override the logging of output in order to filter out Generating
  981. // messages. Generating messages are set to a priority of VERBOSE
  982. // unless they appear after what could be an informational message.
  983. //
  984. private String queuedLine = null;
  985. protected void processLine(String line, int messageLevel) {
  986. if (messageLevel == Project.MSG_INFO && line.startsWith("Generating ")) {
  987. if (queuedLine != null) {
  988. super.processLine(queuedLine, Project.MSG_VERBOSE);
  989. }
  990. queuedLine = line;
  991. } else {
  992. if (queuedLine != null) {
  993. if (line.startsWith("Building "))
  994. super.processLine(queuedLine, Project.MSG_VERBOSE);
  995. else
  996. super.processLine(queuedLine, Project.MSG_INFO);
  997. queuedLine = null;
  998. }
  999. super.processLine(line, messageLevel);
  1000. }
  1001. }
  1002. protected void logFlush() {
  1003. if (queuedLine != null) {
  1004. super.processLine(queuedLine, Project.MSG_VERBOSE);
  1005. queuedLine = null;
  1006. }
  1007. }
  1008. }
  1009. /**
  1010. * Convenience method to expand properties.
  1011. */
  1012. protected String expand(String content) {
  1013. return ProjectHelper.replaceProperties(project, content,
  1014. project.getProperties());
  1015. }
  1016. /**
  1017. * Creates a temporary file.
  1018. */
  1019. private File createTempFile() {
  1020. return new File("javadoc" + (new Random(System.currentTimeMillis())).nextLong());
  1021. }
  1022. private String getJavadocExecutableName()
  1023. {
  1024. // This is the most common extension case - exe for windows and OS/2,
  1025. // nothing for *nix.
  1026. String os = System.getProperty("os.name").toLowerCase();
  1027. boolean dosBased =
  1028. os.indexOf("windows") >= 0 || os.indexOf("os/2") >= 0;
  1029. // for NetWare, we do not want an extension either, so we will be
  1030. // "non dosBased". If this variable is ever used for other logic
  1031. // besides the extension, we may need to revisit this code.
  1032. String extension = dosBased? ".exe" : "";
  1033. // Look for javadoc in the java.home/../bin directory. Unfortunately
  1034. // on Windows java.home doesn't always refer to the correct location,
  1035. // so we need to fall back to assuming javadoc is somewhere on the
  1036. // PATH.
  1037. File jdocExecutable = new File( System.getProperty("java.home") +
  1038. "/../bin/javadoc" + extension );
  1039. if (jdocExecutable.exists())
  1040. {
  1041. return jdocExecutable.getAbsolutePath();
  1042. }
  1043. else
  1044. {
  1045. log( "Unable to locate " + jdocExecutable.getAbsolutePath() +
  1046. ". Using \"javadoc\" instead.", Project.MSG_VERBOSE );
  1047. return "javadoc";
  1048. }
  1049. }
  1050. }