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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175
  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. p.append( "\"" );
  623. return p.toString();
  624. }
  625. }
  626. public void setCharset(String src) {
  627. this.add12ArgIfNotEmpty("-charset", src);
  628. }
  629. /**
  630. * Should the build process fail if javadoc fails (as indicated by
  631. * a non zero return code)?
  632. *
  633. * <p>Default is false.</p>
  634. */
  635. public void setFailonerror(boolean b) {
  636. failOnError = b;
  637. }
  638. public void execute() throws BuildException {
  639. if ("javadoc2".equals(taskType)) {
  640. log("!! javadoc2 is deprecated. Use javadoc instead. !!");
  641. }
  642. if (sourcePath == null) {
  643. String msg = "sourcePath attribute must be set!";
  644. throw new BuildException(msg);
  645. }
  646. log("Generating Javadoc", Project.MSG_INFO);
  647. if (doctitle != null) {
  648. cmd.createArgument().setValue("-doctitle");
  649. cmd.createArgument().setValue(expand(doctitle.getText()));
  650. }
  651. if (header != null) {
  652. cmd.createArgument().setValue("-header");
  653. cmd.createArgument().setValue(expand(header.getText()));
  654. }
  655. if (footer != null) {
  656. cmd.createArgument().setValue("-footer");
  657. cmd.createArgument().setValue(expand(footer.getText()));
  658. }
  659. if (bottom != null) {
  660. cmd.createArgument().setValue("-bottom");
  661. cmd.createArgument().setValue(expand(bottom.getText()));
  662. }
  663. Commandline toExecute = (Commandline)cmd.clone();
  664. toExecute.setExecutable( getJavadocExecutableName() );
  665. // ------------------------------------------------ general javadoc arguments
  666. if (classpath == null)
  667. classpath = Path.systemClasspath;
  668. else
  669. classpath = classpath.concatSystemClasspath("ignore");
  670. if (!javadoc1) {
  671. toExecute.createArgument().setValue("-classpath");
  672. toExecute.createArgument().setPath(classpath);
  673. toExecute.createArgument().setValue("-sourcepath");
  674. toExecute.createArgument().setPath(sourcePath);
  675. } else {
  676. toExecute.createArgument().setValue("-classpath");
  677. toExecute.createArgument().setValue(sourcePath.toString() +
  678. System.getProperty("path.separator") + classpath.toString());
  679. }
  680. if (version && doclet == null)
  681. toExecute.createArgument().setValue("-version");
  682. if (author && doclet == null)
  683. toExecute.createArgument().setValue("-author");
  684. if (javadoc1 || doclet == null) {
  685. if (destDir == null) {
  686. String msg = "destDir attribute must be set!";
  687. throw new BuildException(msg);
  688. }
  689. }
  690. // --------------------------------- javadoc2 arguments for default doclet
  691. // XXX: how do we handle a custom doclet?
  692. if (!javadoc1) {
  693. if (doclet != null) {
  694. if (doclet.getName() == null) {
  695. throw new BuildException("The doclet name must be specified.", location);
  696. }
  697. else {
  698. toExecute.createArgument().setValue("-doclet");
  699. toExecute.createArgument().setValue(doclet.getName());
  700. if (doclet.getPath() != null) {
  701. toExecute.createArgument().setValue("-docletpath");
  702. toExecute.createArgument().setPath(doclet.getPath());
  703. }
  704. for (Enumeration e = doclet.getParams(); e.hasMoreElements();) {
  705. DocletParam param = (DocletParam)e.nextElement();
  706. if (param.getName() == null) {
  707. throw new BuildException("Doclet parameters must have a name");
  708. }
  709. toExecute.createArgument().setValue(param.getName());
  710. if (param.getValue() != null) {
  711. toExecute.createArgument().setValue(param.getValue());
  712. }
  713. }
  714. }
  715. }
  716. if (bootclasspath != null) {
  717. toExecute.createArgument().setValue("-bootclasspath");
  718. toExecute.createArgument().setPath(bootclasspath);
  719. }
  720. // add the links arguments
  721. if (links.size() != 0) {
  722. for (Enumeration e = links.elements(); e.hasMoreElements(); ) {
  723. LinkArgument la = (LinkArgument)e.nextElement();
  724. if (la.getHref() == null) {
  725. throw new BuildException("Links must provide the URL to the external class documentation.");
  726. }
  727. if (la.isLinkOffline()) {
  728. File packageListLocation = la.getPackagelistLoc();
  729. if (packageListLocation == null) {
  730. throw new BuildException("The package list location for link " + la.getHref() +
  731. " must be provided because the link is offline");
  732. }
  733. File packageList = new File(packageListLocation, "package-list");
  734. if (packageList.exists()) {
  735. toExecute.createArgument().setValue("-linkoffline");
  736. toExecute.createArgument().setValue(la.getHref());
  737. toExecute.createArgument().setValue(packageListLocation.getAbsolutePath());
  738. }
  739. else {
  740. log("Warning: No package list was found at " + packageListLocation,
  741. Project.MSG_VERBOSE);
  742. }
  743. }
  744. else {
  745. toExecute.createArgument().setValue("-link");
  746. toExecute.createArgument().setValue(la.getHref());
  747. }
  748. }
  749. }
  750. // add the single group arguments
  751. // Javadoc 1.2 rules:
  752. // Multiple -group args allowed.
  753. // Each arg includes 3 strings: -group [name] [packagelist].
  754. // Elements in [packagelist] are colon-delimited.
  755. // An element in [packagelist] may end with the * wildcard.
  756. // Ant javadoc task rules for group attribute:
  757. // Args are comma-delimited.
  758. // Each arg is 2 space-delimited strings.
  759. // E.g., group="XSLT_Packages org.apache.xalan.xslt*,XPath_Packages org.apache.xalan.xpath*"
  760. if (group != null) {
  761. StringTokenizer tok = new StringTokenizer(group, ",", false);
  762. while (tok.hasMoreTokens()) {
  763. String grp = tok.nextToken().trim();
  764. int space = grp.indexOf(" ");
  765. if (space > 0){
  766. String name = grp.substring(0, space);
  767. String pkgList = grp.substring(space + 1);
  768. toExecute.createArgument().setValue("-group");
  769. toExecute.createArgument().setValue(name);
  770. toExecute.createArgument().setValue(pkgList);
  771. }
  772. }
  773. }
  774. // add the group arguments
  775. if (groups.size() != 0) {
  776. for (Enumeration e = groups.elements(); e.hasMoreElements(); ) {
  777. GroupArgument ga = (GroupArgument)e.nextElement();
  778. String title = ga.getTitle();
  779. String packages = ga.getPackages();
  780. if (title == null || packages == null) {
  781. throw new BuildException("The title and packages must be specified for group elements.");
  782. }
  783. toExecute.createArgument().setValue("-group");
  784. toExecute.createArgument().setValue(expand(title));
  785. toExecute.createArgument().setValue(packages);
  786. }
  787. }
  788. }
  789. tmpList = null;
  790. if (packageNames.size() > 0) {
  791. Vector packages = new Vector();
  792. Enumeration enum = packageNames.elements();
  793. while (enum.hasMoreElements()) {
  794. PackageName pn = (PackageName) enum.nextElement();
  795. String name = pn.getName().trim();
  796. if (name.endsWith(".*")) {
  797. packages.addElement(name);
  798. } else {
  799. toExecute.createArgument().setValue(name);
  800. }
  801. }
  802. Vector excludePackages = new Vector();
  803. if (excludePackageNames.size() > 0) {
  804. enum = excludePackageNames.elements();
  805. while (enum.hasMoreElements()) {
  806. PackageName pn = (PackageName) enum.nextElement();
  807. excludePackages.addElement(pn.getName().trim());
  808. }
  809. }
  810. if (packages.size() > 0) {
  811. evaluatePackages(toExecute, sourcePath, packages, excludePackages);
  812. }
  813. }
  814. if (sourceFiles.size() > 0) {
  815. PrintWriter srcListWriter = null;
  816. try {
  817. /**
  818. * Write sourcefiles to a temporary file if requested.
  819. */
  820. if (useExternalFile) {
  821. if (tmpList == null) {
  822. tmpList = createTempFile();
  823. toExecute.createArgument().setValue("@" + tmpList.getAbsolutePath());
  824. }
  825. srcListWriter = new PrintWriter(new FileWriter(tmpList.getAbsolutePath(),
  826. true));
  827. }
  828. Enumeration enum = sourceFiles.elements();
  829. while (enum.hasMoreElements()) {
  830. SourceFile sf = (SourceFile) enum.nextElement();
  831. String sourceFileName = sf.getFile().getAbsolutePath();
  832. if (useExternalFile) {
  833. srcListWriter.println(sourceFileName);
  834. } else {
  835. toExecute.createArgument().setValue(sourceFileName);
  836. }
  837. }
  838. } catch (IOException e) {
  839. throw new BuildException("Error creating temporary file",
  840. e, location);
  841. } finally {
  842. if (srcListWriter != null) {
  843. srcListWriter.close();
  844. }
  845. }
  846. }
  847. if (packageList != null) {
  848. toExecute.createArgument().setValue("@" + packageList);
  849. }
  850. log("Javadoc args: " + toExecute, Project.MSG_VERBOSE);
  851. log("Javadoc execution", Project.MSG_INFO);
  852. JavadocOutputStream out = new JavadocOutputStream(Project.MSG_INFO);
  853. JavadocOutputStream err = new JavadocOutputStream(Project.MSG_WARN);
  854. Execute exe = new Execute(new PumpStreamHandler(out, err));
  855. exe.setAntRun(project);
  856. /*
  857. * No reason to change the working directory as all filenames and
  858. * path components have been resolved already.
  859. *
  860. * Avoid problems with command line length in some environments.
  861. */
  862. exe.setWorkingDirectory(null);
  863. try {
  864. exe.setCommandline(toExecute.getCommandline());
  865. int ret = exe.execute();
  866. if (ret != 0 && failOnError) {
  867. throw new BuildException("Javadoc returned "+ret, location);
  868. }
  869. } catch (IOException e) {
  870. throw new BuildException("Javadoc failed: " + e, e, location);
  871. } finally {
  872. if (tmpList != null) {
  873. tmpList.delete();
  874. tmpList = null;
  875. }
  876. out.logFlush();
  877. err.logFlush();
  878. try {
  879. out.close();
  880. err.close();
  881. } catch (IOException e) {}
  882. }
  883. }
  884. /**
  885. * Given a source path, a list of package patterns, fill the given list
  886. * with the packages found in that path subdirs matching one of the given
  887. * patterns.
  888. */
  889. private void evaluatePackages(Commandline toExecute, Path sourcePath,
  890. Vector packages, Vector excludePackages) {
  891. log("Source path = " + sourcePath.toString(), Project.MSG_VERBOSE);
  892. StringBuffer msg = new StringBuffer("Packages = ");
  893. for (int i=0; i<packages.size(); i++) {
  894. if (i > 0) {
  895. msg.append(",");
  896. }
  897. msg.append(packages.elementAt(i));
  898. }
  899. log(msg.toString(), Project.MSG_VERBOSE);
  900. msg.setLength(0);
  901. msg.append("Exclude Packages = ");
  902. for (int i=0; i<excludePackages.size(); i++) {
  903. if (i > 0) {
  904. msg.append(",");
  905. }
  906. msg.append(excludePackages.elementAt(i));
  907. }
  908. log(msg.toString(), Project.MSG_VERBOSE);
  909. Vector addedPackages = new Vector();
  910. String[] list = sourcePath.list();
  911. if (list == null) list = new String[0];
  912. FileSet fs = new FileSet();
  913. fs.setDefaultexcludes(useDefaultExcludes);
  914. Enumeration e = packages.elements();
  915. while (e.hasMoreElements()) {
  916. String pkg = (String)e.nextElement();
  917. pkg = pkg.replace('.','/');
  918. if (pkg.endsWith("*")) {
  919. pkg += "*";
  920. }
  921. fs.createInclude().setName(pkg);
  922. } // while
  923. e = excludePackages.elements();
  924. while (e.hasMoreElements()) {
  925. String pkg = (String)e.nextElement();
  926. pkg = pkg.replace('.','/');
  927. if (pkg.endsWith("*")) {
  928. pkg += "*";
  929. }
  930. fs.createExclude().setName(pkg);
  931. }
  932. PrintWriter packageListWriter = null;
  933. try {
  934. if (useExternalFile) {
  935. tmpList = createTempFile();
  936. toExecute.createArgument().setValue("@" + tmpList.getAbsolutePath());
  937. packageListWriter = new PrintWriter(new FileWriter(tmpList));
  938. }
  939. for (int j=0; j<list.length; j++) {
  940. File source = project.resolveFile(list[j]);
  941. fs.setDir(source);
  942. DirectoryScanner ds = fs.getDirectoryScanner(project);
  943. String[] packageDirs = ds.getIncludedDirectories();
  944. for (int i=0; i<packageDirs.length; i++) {
  945. File pd = new File(source, packageDirs[i]);
  946. String[] files = pd.list(new FilenameFilter () {
  947. public boolean accept(File dir1, String name) {
  948. if (name.endsWith(".java")) {
  949. return true;
  950. }
  951. return false; // ignore dirs
  952. }
  953. });
  954. if (files.length > 0) {
  955. String pkgDir = packageDirs[i].replace('/','.').replace('\\','.');
  956. if (!addedPackages.contains(pkgDir)) {
  957. if (useExternalFile) {
  958. packageListWriter.println(pkgDir);
  959. } else {
  960. toExecute.createArgument().setValue(pkgDir);
  961. }
  962. addedPackages.addElement(pkgDir);
  963. }
  964. }
  965. }
  966. }
  967. } catch (IOException ioex) {
  968. throw new BuildException("Error creating temporary file",
  969. ioex, location);
  970. } finally {
  971. if (packageListWriter != null) {
  972. packageListWriter.close();
  973. }
  974. }
  975. }
  976. private class JavadocOutputStream extends LogOutputStream {
  977. JavadocOutputStream(int level) {
  978. super(Javadoc.this, level);
  979. }
  980. //
  981. // Override the logging of output in order to filter out Generating
  982. // messages. Generating messages are set to a priority of VERBOSE
  983. // unless they appear after what could be an informational message.
  984. //
  985. private String queuedLine = null;
  986. protected void processLine(String line, int messageLevel) {
  987. if (messageLevel == Project.MSG_INFO && line.startsWith("Generating ")) {
  988. if (queuedLine != null) {
  989. super.processLine(queuedLine, Project.MSG_VERBOSE);
  990. }
  991. queuedLine = line;
  992. } else {
  993. if (queuedLine != null) {
  994. if (line.startsWith("Building "))
  995. super.processLine(queuedLine, Project.MSG_VERBOSE);
  996. else
  997. super.processLine(queuedLine, Project.MSG_INFO);
  998. queuedLine = null;
  999. }
  1000. super.processLine(line, messageLevel);
  1001. }
  1002. }
  1003. protected void logFlush() {
  1004. if (queuedLine != null) {
  1005. super.processLine(queuedLine, Project.MSG_VERBOSE);
  1006. queuedLine = null;
  1007. }
  1008. }
  1009. }
  1010. /**
  1011. * Convenience method to expand properties.
  1012. */
  1013. protected String expand(String content) {
  1014. return ProjectHelper.replaceProperties(project, content,
  1015. project.getProperties());
  1016. }
  1017. /**
  1018. * Creates a temporary file.
  1019. */
  1020. private File createTempFile() {
  1021. return new File("javadoc" + (new Random(System.currentTimeMillis())).nextLong());
  1022. }
  1023. private String getJavadocExecutableName()
  1024. {
  1025. // This is the most common extension case - exe for windows and OS/2,
  1026. // nothing for *nix.
  1027. String os = System.getProperty("os.name").toLowerCase();
  1028. boolean dosBased =
  1029. os.indexOf("windows") >= 0 || os.indexOf("os/2") >= 0;
  1030. String extension = dosBased? ".exe" : "";
  1031. // Look for javadoc in the java.home/../bin directory. Unfortunately
  1032. // on Windows java.home doesn't always refer to the correct location,
  1033. // so we need to fall back to assuming javadoc is somewhere on the
  1034. // PATH.
  1035. File jdocExecutable = new File( System.getProperty("java.home") +
  1036. "/../bin/javadoc" + extension );
  1037. if (jdocExecutable.exists())
  1038. {
  1039. return jdocExecutable.getAbsolutePath();
  1040. }
  1041. else
  1042. {
  1043. log( "Unable to locate " + jdocExecutable.getAbsolutePath() +
  1044. ". Using \"javadoc\" instead.", Project.MSG_VERBOSE );
  1045. return "javadoc";
  1046. }
  1047. }
  1048. }