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 30 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  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.Task;
  61. import org.apache.tools.ant.types.Commandline;
  62. import org.apache.tools.ant.types.Path;
  63. import org.apache.tools.ant.types.Reference;
  64. /**
  65. * This task makes it easy to generate Javadoc documentation for a collection
  66. * of source code.
  67. *
  68. * <P>Current known limitations are:
  69. *
  70. * <P><UL>
  71. * <LI>patterns must be of the form "xxx.*", every other pattern doesn't
  72. * work.
  73. * <LI>the java comment-stripper reader is horribly slow
  74. * <LI>there is no control on arguments sanity since they are left
  75. * to the javadoc implementation.
  76. * <LI>argument J in javadoc1 is not supported (what is that for anyway?)
  77. * </UL>
  78. *
  79. * <P>If no <CODE>doclet</CODE> is set, then the <CODE>version</CODE> and
  80. * <CODE>author</CODE> are by default <CODE>"yes"</CODE>.
  81. *
  82. * <P>Note: This task is run on another VM because the Javadoc code calls
  83. * <CODE>System.exit()</CODE> which would break Ant functionality.
  84. *
  85. * @author Jon S. Stevens <a href="mailto:jon@clearink.com">jon@clearink.com</a>
  86. * @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">stefano@apache.org</a>
  87. * @author Patrick Chanezon <a href="mailto:chanezon@netscape.com">chanezon@netscape.com</a>
  88. * @author Ernst de Haan <a href="mailto:ernst@jollem.com">ernst@jollem.com</a>
  89. * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
  90. */
  91. public class Javadoc extends Task {
  92. public class DocletParam {
  93. private String name;
  94. private String value;
  95. public void setName(String name) {
  96. this.name = name;
  97. }
  98. public String getName() {
  99. return name;
  100. }
  101. public void setValue(String value) {
  102. this.value = value;
  103. }
  104. public String getValue() {
  105. return value;
  106. }
  107. }
  108. public class DocletInfo {
  109. private String name;
  110. private Path path;
  111. private Vector params = new Vector();
  112. public void setName(String name) {
  113. this.name = name;
  114. }
  115. public String getName() {
  116. return name;
  117. }
  118. public void setPath(Path path) {
  119. if (this.path == null) {
  120. this.path = path;
  121. } else {
  122. this.path.append(path);
  123. }
  124. }
  125. public Path getPath() {
  126. return path;
  127. }
  128. public Path createPath() {
  129. if (path == null) {
  130. path = new Path(getProject());
  131. }
  132. return path.createPath();
  133. }
  134. /**
  135. * Adds a reference to a CLASSPATH defined elsewhere.
  136. */
  137. public void setPathRef(Reference r) {
  138. createPath().setRefid(r);
  139. }
  140. public DocletParam createParam() {
  141. DocletParam param = new DocletParam();
  142. params.addElement(param);
  143. return param;
  144. }
  145. public Enumeration getParams() {
  146. return params.elements();
  147. }
  148. }
  149. private Commandline cmd = new Commandline();
  150. private static boolean javadoc1 =
  151. (Project.getJavaVersion() == Project.JAVA_1_1);
  152. private void addArgIf(boolean b, String arg) {
  153. if (b) {
  154. cmd.createArgument().setValue(arg);
  155. }
  156. }
  157. private void add11ArgIf(boolean b, String arg) {
  158. if (javadoc1 && b) {
  159. cmd.createArgument().setValue(arg);
  160. }
  161. }
  162. private void add12ArgIf(boolean b, String arg) {
  163. if (!javadoc1 && b) {
  164. cmd.createArgument().setValue(arg);
  165. }
  166. }
  167. private boolean foundJavaFile = false;
  168. private boolean failOnError = false;
  169. private Path sourcePath = null;
  170. private File destDir = null;
  171. private String sourceFiles = null;
  172. private String packageNames = null;
  173. private boolean author = true;
  174. private boolean version = true;
  175. private DocletInfo doclet = null;
  176. private Path classpath = null;
  177. private Path bootclasspath = null;
  178. private String group = null;
  179. private Vector compileList = new Vector(10);
  180. private String packageList = null;
  181. private Vector links = new Vector(2);
  182. private Vector groups = new Vector(2);
  183. public void setMaxmemory(String max){
  184. if(javadoc1){
  185. cmd.createArgument().setValue("-J-mx" + max);
  186. } else{
  187. cmd.createArgument().setValue("-J-Xmx" + max);
  188. }
  189. }
  190. public void setAdditionalparam(String add){
  191. cmd.createArgument().setValue(add);
  192. }
  193. public void setSourcepath(Path src) {
  194. if (sourcePath == null) {
  195. sourcePath = src;
  196. } else {
  197. sourcePath.append(src);
  198. }
  199. }
  200. public Path createSourcepath() {
  201. if (sourcePath == null) {
  202. sourcePath = new Path(project);
  203. }
  204. return sourcePath.createPath();
  205. }
  206. /**
  207. * Adds a reference to a CLASSPATH defined elsewhere.
  208. */
  209. public void setSourcepathRef(Reference r) {
  210. createSourcepath().setRefid(r);
  211. }
  212. public void setDestdir(File dir) {
  213. destDir = dir;
  214. cmd.createArgument().setValue("-d");
  215. cmd.createArgument().setFile(destDir);
  216. }
  217. public void setSourcefiles(String src) {
  218. sourceFiles = src;
  219. }
  220. public void setPackagenames(String src) {
  221. packageNames = src;
  222. }
  223. public void setOverview(File f) {
  224. if (!javadoc1) {
  225. cmd.createArgument().setValue("-overview");
  226. cmd.createArgument().setFile(f);
  227. }
  228. }
  229. public void setPublic(boolean b) {
  230. addArgIf(b, "-public");
  231. }
  232. public void setProtected(boolean b) {
  233. addArgIf(b, "-protected");
  234. }
  235. public void setPackage(boolean b) {
  236. addArgIf(b, "-package");
  237. }
  238. public void setPrivate(boolean b) {
  239. addArgIf(b, "-private");
  240. }
  241. public void setDoclet(String src) {
  242. if (doclet == null) {
  243. doclet = new DocletInfo();
  244. }
  245. doclet.setName(src);
  246. }
  247. public void setDocletPath(Path src) {
  248. if (doclet == null) {
  249. doclet = new DocletInfo();
  250. }
  251. doclet.setPath(src);
  252. }
  253. public void setDocletPathRef(Reference r) {
  254. if (doclet == null) {
  255. doclet = new DocletInfo();
  256. }
  257. doclet.createPath().setRefid(r);
  258. }
  259. public DocletInfo createDoclet() {
  260. doclet = new DocletInfo();
  261. return doclet;
  262. }
  263. public void setOld(boolean b) {
  264. add12ArgIf(b, "-1.1");
  265. }
  266. public void setClasspath(Path src) {
  267. if (classpath == null) {
  268. classpath = src;
  269. } else {
  270. classpath.append(src);
  271. }
  272. }
  273. public Path createClasspath() {
  274. if (classpath == null) {
  275. classpath = new Path(project);
  276. }
  277. return classpath.createPath();
  278. }
  279. /**
  280. * Adds a reference to a CLASSPATH defined elsewhere.
  281. */
  282. public void setClasspathRef(Reference r) {
  283. createClasspath().setRefid(r);
  284. }
  285. public void setBootclasspath(Path src) {
  286. if (bootclasspath == null) {
  287. bootclasspath = src;
  288. } else {
  289. bootclasspath.append(src);
  290. }
  291. }
  292. public Path createBootclasspath() {
  293. if (bootclasspath == null) {
  294. bootclasspath = new Path(project);
  295. }
  296. return bootclasspath.createPath();
  297. }
  298. /**
  299. * Adds a reference to a CLASSPATH defined elsewhere.
  300. */
  301. public void setBootClasspathRef(Reference r) {
  302. createBootclasspath().setRefid(r);
  303. }
  304. public void setExtdirs(String src) {
  305. if (!javadoc1) {
  306. cmd.createArgument().setValue("-extdirs");
  307. cmd.createArgument().setValue(src);
  308. }
  309. }
  310. public void setVerbose(boolean b) {
  311. add12ArgIf(b, "-verbose");
  312. }
  313. public void setLocale(String src) {
  314. if (!javadoc1) {
  315. cmd.createArgument().setValue("-locale");
  316. cmd.createArgument().setValue(src);
  317. }
  318. }
  319. public void setEncoding(String enc) {
  320. cmd.createArgument().setValue("-encoding");
  321. cmd.createArgument().setValue(enc);
  322. }
  323. public void setVersion(boolean src) {
  324. version = src;
  325. }
  326. public void setUse(boolean b) {
  327. add12ArgIf(b, "-use");
  328. }
  329. public void setAuthor(boolean src) {
  330. author = src;
  331. }
  332. public void setSplitindex(boolean b) {
  333. add12ArgIf(b, "-splitindex");
  334. }
  335. public void setWindowtitle(String src) {
  336. if (!javadoc1) {
  337. cmd.createArgument().setValue("-windowtitle");
  338. cmd.createArgument().setValue(src);
  339. }
  340. }
  341. public void setDoctitle(String src) {
  342. if (!javadoc1) {
  343. cmd.createArgument().setValue("-doctitle");
  344. cmd.createArgument().setValue(src);
  345. }
  346. }
  347. public void setHeader(String src) {
  348. if (!javadoc1) {
  349. cmd.createArgument().setValue("-header");
  350. cmd.createArgument().setValue(src);
  351. }
  352. }
  353. public void setFooter(String src) {
  354. if (!javadoc1) {
  355. cmd.createArgument().setValue("-footer");
  356. cmd.createArgument().setValue(src);
  357. }
  358. }
  359. public void setBottom(String src) {
  360. if (!javadoc1) {
  361. cmd.createArgument().setValue("-bottom");
  362. cmd.createArgument().setValue(src);
  363. }
  364. }
  365. public void setLinkoffline(String src) {
  366. if (!javadoc1) {
  367. LinkArgument le = createLink();
  368. le.setOffline(true);
  369. String linkOfflineError = "The linkoffline attribute must include a URL and " +
  370. "a package-list file location separated by a space";
  371. if (src.trim().length() == 0) {
  372. throw new BuildException(linkOfflineError);
  373. }
  374. StringTokenizer tok = new StringTokenizer(src, " ", false);
  375. le.setHref(tok.nextToken());
  376. if (!tok.hasMoreTokens()) {
  377. throw new BuildException(linkOfflineError);
  378. }
  379. le.setPackagelistLoc(tok.nextToken());
  380. }
  381. }
  382. public void setGroup(String src) {
  383. group = src;
  384. }
  385. public void setLink(String src) {
  386. if (!javadoc1) {
  387. createLink().setHref(src);
  388. }
  389. }
  390. public void setNodeprecated(boolean b) {
  391. addArgIf(b, "-nodeprecated");
  392. }
  393. public void setNodeprecatedlist(boolean b) {
  394. add12ArgIf(b, "-nodeprecatedlist");
  395. }
  396. public void setNotree(boolean b) {
  397. addArgIf(b, "-notree");
  398. }
  399. public void setNoindex(boolean b) {
  400. addArgIf(b, "-noindex");
  401. }
  402. public void setNohelp(boolean b) {
  403. add12ArgIf(b, "-nohelp");
  404. }
  405. public void setNonavbar(boolean b) {
  406. add12ArgIf(b, "-nonavbar");
  407. }
  408. public void setSerialwarn(boolean b) {
  409. add12ArgIf(b, "-serialwarn");
  410. }
  411. public void setStylesheetfile(File f) {
  412. if (!javadoc1) {
  413. cmd.createArgument().setValue("-stylesheetfile");
  414. cmd.createArgument().setFile(f);
  415. }
  416. }
  417. public void setHelpfile(File f) {
  418. if (!javadoc1) {
  419. cmd.createArgument().setValue("-helpfile");
  420. cmd.createArgument().setFile(f);
  421. }
  422. }
  423. public void setDocencoding(String enc) {
  424. cmd.createArgument().setValue("-docencoding");
  425. cmd.createArgument().setValue(enc);
  426. }
  427. public void setPackageList(String src) {
  428. packageList = src;
  429. }
  430. public LinkArgument createLink() {
  431. LinkArgument la = new LinkArgument();
  432. links.addElement(la);
  433. return la;
  434. }
  435. public class LinkArgument {
  436. private String href;
  437. private boolean offline = false;
  438. private String packagelistLoc;
  439. public LinkArgument() {
  440. }
  441. public void setHref(String hr) {
  442. href = hr;
  443. }
  444. public String getHref() {
  445. return href;
  446. }
  447. public void setPackagelistLoc(String src) {
  448. packagelistLoc = src;
  449. }
  450. public String getPackagelistLoc() {
  451. return packagelistLoc;
  452. }
  453. public void setOffline(boolean offline) {
  454. this.offline = offline;
  455. }
  456. public boolean isLinkOffline() {
  457. return offline;
  458. }
  459. }
  460. public GroupArgument createGroup() {
  461. GroupArgument ga = new GroupArgument();
  462. groups.addElement(ga);
  463. return ga;
  464. }
  465. public class GroupArgument {
  466. private String title;
  467. private String packages;
  468. public GroupArgument() {
  469. }
  470. public void setTitle(String src) {
  471. title = src;
  472. }
  473. public String getTitle() {
  474. return title;
  475. }
  476. public void setPackages(String src) {
  477. packages = src;
  478. }
  479. public String getPackages() {
  480. return packages;
  481. }
  482. }
  483. public void setCharset(String src) {
  484. if (!javadoc1) {
  485. cmd.createArgument().setValue("-charset");
  486. cmd.createArgument().setValue(src);
  487. }
  488. }
  489. /**
  490. * Should the build process fail if javadoc fails (as indicated by
  491. * a non zero return code)?
  492. *
  493. * <p>Default is false.</p>
  494. */
  495. public void setFailonerror(boolean b) {
  496. failOnError = b;
  497. }
  498. public void execute() throws BuildException {
  499. if ("javadoc2".equals(taskType)) {
  500. log("!! javadoc2 is deprecated. Use javadoc instead. !!");
  501. }
  502. if (sourcePath == null) {
  503. String msg = "sourcePath attribute must be set!";
  504. throw new BuildException(msg);
  505. }
  506. log("Generating Javadoc", Project.MSG_INFO);
  507. Commandline toExecute = (Commandline)cmd.clone();
  508. toExecute.setExecutable("javadoc");
  509. // ------------------------------------------------ general javadoc arguments
  510. if (classpath == null)
  511. classpath = Path.systemClasspath;
  512. else
  513. classpath = classpath.concatSystemClasspath("ignore");
  514. if (!javadoc1) {
  515. toExecute.createArgument().setValue("-classpath");
  516. toExecute.createArgument().setPath(classpath);
  517. toExecute.createArgument().setValue("-sourcepath");
  518. toExecute.createArgument().setPath(sourcePath);
  519. } else {
  520. toExecute.createArgument().setValue("-classpath");
  521. toExecute.createArgument().setValue(sourcePath.toString() +
  522. System.getProperty("path.separator") + classpath.toString());
  523. }
  524. if (version && doclet == null)
  525. toExecute.createArgument().setValue("-version");
  526. if (author && doclet == null)
  527. toExecute.createArgument().setValue("-author");
  528. if (javadoc1 || doclet == null) {
  529. if (destDir == null) {
  530. String msg = "destDir attribute must be set!";
  531. throw new BuildException(msg);
  532. }
  533. }
  534. // --------------------------------- javadoc2 arguments for default doclet
  535. // XXX: how do we handle a custom doclet?
  536. if (!javadoc1) {
  537. if (doclet != null) {
  538. if (doclet.getName() == null) {
  539. throw new BuildException("The doclet name must be specified.", location);
  540. }
  541. else {
  542. toExecute.createArgument().setValue("-doclet");
  543. toExecute.createArgument().setValue(doclet.getName());
  544. if (doclet.getPath() != null) {
  545. toExecute.createArgument().setValue("-docletpath");
  546. toExecute.createArgument().setPath(doclet.getPath());
  547. }
  548. for (Enumeration e = doclet.getParams(); e.hasMoreElements();) {
  549. DocletParam param = (DocletParam)e.nextElement();
  550. if (param.getName() == null) {
  551. throw new BuildException("Doclet parameters must have a name");
  552. }
  553. toExecute.createArgument().setValue(param.getName());
  554. if (param.getValue() != null) {
  555. toExecute.createArgument().setValue(param.getValue());
  556. }
  557. }
  558. }
  559. }
  560. if (bootclasspath != null) {
  561. toExecute.createArgument().setValue("-bootclasspath");
  562. toExecute.createArgument().setPath(bootclasspath);
  563. }
  564. // add the links arguments
  565. if (links.size() != 0) {
  566. for (Enumeration e = links.elements(); e.hasMoreElements(); ) {
  567. LinkArgument la = (LinkArgument)e.nextElement();
  568. if (la.getHref() == null) {
  569. throw new BuildException("Links must provide the URL to the external class documentation.");
  570. }
  571. if (la.isLinkOffline()) {
  572. String packageListLocation = la.getPackagelistLoc();
  573. if (packageListLocation == null) {
  574. throw new BuildException("The package list location for link " + la.getHref() +
  575. " must be provided because the link is offline");
  576. }
  577. toExecute.createArgument().setValue("-linkoffline");
  578. toExecute.createArgument().setValue(la.getHref());
  579. toExecute.createArgument().setValue(packageListLocation);
  580. }
  581. else {
  582. toExecute.createArgument().setValue("-link");
  583. toExecute.createArgument().setValue(la.getHref());
  584. }
  585. }
  586. }
  587. // add the single group arguments
  588. // Javadoc 1.2 rules:
  589. // Multiple -group args allowed.
  590. // Each arg includes 3 strings: -group [name] [packagelist].
  591. // Elements in [packagelist] are colon-delimited.
  592. // An element in [packagelist] may end with the * wildcard.
  593. // Ant javadoc task rules for group attribute:
  594. // Args are comma-delimited.
  595. // Each arg is 2 space-delimited strings.
  596. // E.g., group="XSLT_Packages org.apache.xalan.xslt*,XPath_Packages orgapache.xalan.xpath*"
  597. if (group != null) {
  598. StringTokenizer tok = new StringTokenizer(group, ",", false);
  599. while (tok.hasMoreTokens()) {
  600. String grp = tok.nextToken().trim();
  601. int space = grp.indexOf(" ");
  602. if (space > 0){
  603. String name = grp.substring(0, space);
  604. String pkgList = grp.substring(space + 1);
  605. toExecute.createArgument().setValue("-group");
  606. toExecute.createArgument().setValue(name);
  607. toExecute.createArgument().setValue(pkgList);
  608. }
  609. }
  610. }
  611. // add the group arguments
  612. if (groups.size() != 0) {
  613. for (Enumeration e = groups.elements(); e.hasMoreElements(); ) {
  614. GroupArgument ga = (GroupArgument)e.nextElement();
  615. String title = ga.getTitle();
  616. String packages = ga.getPackages();
  617. if (title == null || packages == null) {
  618. throw new BuildException("The title and packages must be specified for group elements.");
  619. }
  620. toExecute.createArgument().setValue("-group");
  621. toExecute.createArgument().setValue(title);
  622. toExecute.createArgument().setValue(packages);
  623. }
  624. }
  625. }
  626. if ((packageNames != null) && (packageNames.length() > 0)) {
  627. Vector packages = new Vector();
  628. StringTokenizer tok = new StringTokenizer(packageNames, ",", false);
  629. while (tok.hasMoreTokens()) {
  630. String name = tok.nextToken().trim();
  631. if (name.endsWith(".*")) {
  632. packages.addElement(name);
  633. } else {
  634. toExecute.createArgument().setValue(name);
  635. }
  636. }
  637. if (packages.size() > 0) {
  638. evaluatePackages(toExecute, sourcePath, packages);
  639. }
  640. }
  641. if ((sourceFiles != null) && (sourceFiles.length() > 0)) {
  642. StringTokenizer tok = new StringTokenizer(sourceFiles, ",", false);
  643. while (tok.hasMoreTokens()) {
  644. toExecute.createArgument().setValue(tok.nextToken().trim());
  645. }
  646. }
  647. if (packageList != null) {
  648. toExecute.createArgument().setValue("@" + packageList);
  649. }
  650. log("Javadoc args: " + toExecute, Project.MSG_VERBOSE);
  651. log("Javadoc execution", Project.MSG_INFO);
  652. JavadocOutputStream out = new JavadocOutputStream(Project.MSG_INFO);
  653. JavadocOutputStream err = new JavadocOutputStream(Project.MSG_WARN);
  654. Execute exe = new Execute(new PumpStreamHandler(out, err));
  655. exe.setAntRun(project);
  656. exe.setWorkingDirectory(project.getBaseDir());
  657. try {
  658. exe.setCommandline(toExecute.getCommandline());
  659. int ret = exe.execute();
  660. if (ret != 0 && failOnError) {
  661. throw new BuildException("Javadoc returned "+ret, location);
  662. }
  663. } catch (IOException e) {
  664. throw new BuildException("Javadoc failed: " + e, e, location);
  665. } finally {
  666. out.logFlush();
  667. err.logFlush();
  668. try {
  669. out.close();
  670. err.close();
  671. } catch (IOException e) {}
  672. }
  673. }
  674. /**
  675. * Given a source path, a list of package patterns, fill the given list
  676. * with the packages found in that path subdirs matching one of the given
  677. * patterns.
  678. */
  679. private void evaluatePackages(Commandline toExecute, Path sourcePath,
  680. Vector packages) {
  681. log("Source path = " + sourcePath.toString(), Project.MSG_VERBOSE);
  682. log("Packages = " + packages, Project.MSG_VERBOSE);
  683. Vector addedPackages = new Vector();
  684. String[] list = sourcePath.list();
  685. if (list == null) list = new String[0];
  686. for (int j=0; j<list.length; j++) {
  687. File source = project.resolveFile(list[j]);
  688. Vector foundPackages = findPackages(source);
  689. Enumeration e = foundPackages.elements();
  690. while (e.hasMoreElements()) {
  691. String pack = (String) e.nextElement();
  692. for (int i = 0; i < packages.size(); i++) {
  693. if (matches(pack, (String) packages.elementAt(i))) {
  694. if (!addedPackages.contains(pack)) {
  695. toExecute.createArgument().setValue(pack);
  696. addedPackages.addElement(pack);
  697. }
  698. break;
  699. }
  700. }
  701. }
  702. }
  703. }
  704. /**
  705. * Implements the pattern matching. For now it's only able to
  706. * guarantee that "aaa.bbb.ccc" matches "aaa.*" and "aaa.bbb.*"
  707. * FIXME: this code needs much improvement.
  708. */
  709. private boolean matches(String string, String pattern) {
  710. return string.startsWith(pattern.substring(0, pattern.length() - 2));
  711. }
  712. private class JavadocOutputStream extends LogOutputStream {
  713. JavadocOutputStream(int level) {
  714. super(Javadoc.this, level);
  715. }
  716. //
  717. // Override the logging of output in order to filter out Generating
  718. // messages. Generating messages are set to a priority of VERBOSE
  719. // unless they appear after what could be an informational message.
  720. //
  721. private String queuedLine = null;
  722. protected void processLine(String line, int messageLevel) {
  723. if (messageLevel == Project.MSG_INFO && line.startsWith("Generating ")) {
  724. if (queuedLine != null) {
  725. super.processLine(queuedLine, Project.MSG_VERBOSE);
  726. }
  727. queuedLine = line;
  728. } else {
  729. if (queuedLine != null) {
  730. if (line.startsWith("Building "))
  731. super.processLine(queuedLine, Project.MSG_VERBOSE);
  732. else
  733. super.processLine(queuedLine, Project.MSG_INFO);
  734. queuedLine = null;
  735. }
  736. super.processLine(line, messageLevel);
  737. }
  738. }
  739. protected void logFlush() {
  740. if (queuedLine != null) {
  741. super.processLine(queuedLine, Project.MSG_VERBOSE);
  742. queuedLine = null;
  743. }
  744. }
  745. }
  746. protected Vector findPackages(File srcDir) {
  747. Vector foundPkgs = new Vector();
  748. if ((srcDir != null) && (srcDir.isDirectory())) {
  749. scan(srcDir, "", foundPkgs);
  750. }
  751. return foundPkgs;
  752. }
  753. protected void scan(File srcDir, String vpath, Vector pkgs) {
  754. foundJavaFile = false;
  755. File dir = new File(srcDir, vpath);
  756. if (!dir.isDirectory()) {
  757. return;
  758. }
  759. String[] files = dir.list(new FilenameFilter () {
  760. public boolean accept(File dir1, String name) {
  761. if (name.endsWith(".java")) {
  762. foundJavaFile = true;
  763. return false;
  764. }
  765. File d = new File(dir1, name);
  766. if (d.isDirectory()
  767. && d.getName().indexOf("-") == -1) {
  768. return true;
  769. }
  770. return false;
  771. }
  772. });
  773. if (foundJavaFile && vpath.length() > 0) {
  774. String newPkg = vpath.substring(1).replace(File.separatorChar, '.');
  775. if (!pkgs.contains(newPkg)) {
  776. pkgs.addElement(newPkg);
  777. }
  778. }
  779. for (int i=0; i<files.length; i++) {
  780. scan(srcDir, vpath + File.separator + files[i], pkgs);
  781. }
  782. return;
  783. }
  784. }