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

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