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

Main.java 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. /* *******************************************************************
  2. * Copyright (c) 1999-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC).
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Public License v1.0
  7. * which accompanies this distribution and is available at
  8. * http://www.eclipse.org/legal/epl-v10.html
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * Mik Kersten port to AspectJ 1.1+ code base
  13. * ******************************************************************/
  14. package org.aspectj.tools.ajdoc;
  15. import java.io.*;
  16. import java.util.*;
  17. import java.io.FileFilter;
  18. import org.aspectj.bridge.IMessage;
  19. import org.aspectj.bridge.Version;
  20. import org.aspectj.util.FileUtil;
  21. /**
  22. * This is an old implementation of ajdoc that does not use an OO style. However, it
  23. * does the job, and should serve to evolve a lightweight ajdoc implementation until
  24. * we can make a properly extended javadoc implementation.
  25. *
  26. * @author Mik Kersten
  27. */
  28. public class Main implements Config {
  29. private static final String FAIL_MESSAGE = "> compile failed, exiting ajdoc";
  30. /** Command line options. */
  31. static Vector options;
  32. /** Options to pass to ajc. */
  33. static Vector ajcOptions;
  34. /** All of the files to be processed by ajdoc. */
  35. static Vector filenames;
  36. /** List of files to pass to javadoc. */
  37. static Vector fileList;
  38. /** List of packages to pass to javadoc. */
  39. static Vector packageList;
  40. /** Default to package visiblity. */
  41. static String docModifier = "package";
  42. static Vector sourcepath;
  43. static boolean verboseMode = false;
  44. static boolean packageMode = false;
  45. static boolean authorStandardDocletSwitch = false;
  46. static boolean versionStandardDocletSwitch = false;
  47. static File rootDir = null;
  48. static Hashtable declIDTable = new Hashtable();
  49. static String docDir = ".";
  50. private static boolean deleteTempFilesOnExit = true;
  51. private static boolean aborted = false;
  52. private static IMessage[] errors;
  53. private static boolean shownAjdocUsageMessage = false;
  54. // creating a local variable to enable us to create the ajdocworkingdir
  55. // in a local sandbox during testing
  56. private static String outputWorkingDir = Config.WORKING_DIR;
  57. public static void clearState() {
  58. options = new Vector();
  59. ajcOptions = new Vector();
  60. filenames = new Vector();
  61. fileList= new Vector();
  62. packageList = new Vector();
  63. docModifier = "package";
  64. sourcepath = new Vector();
  65. verboseMode = false;
  66. packageMode = false;
  67. rootDir = null;
  68. declIDTable = new Hashtable();
  69. docDir = ".";
  70. aborted = false;
  71. deleteTempFilesOnExit = true;
  72. }
  73. public static void main(String[] args) {
  74. clearState();
  75. if (!JavadocRunner.has14ToolsAvailable()) {
  76. System.err.println("ajdoc requires a JDK 1.4 or later tools jar - exiting");
  77. aborted = true;
  78. return;
  79. }
  80. // STEP 1: parse the command line and do other global setup
  81. sourcepath.addElement("."); // add the current directory to the classapth
  82. parseCommandLine(args);
  83. rootDir = getRootDir();
  84. File[] inputFiles = new File[filenames.size()];
  85. File[] signatureFiles = new File[filenames.size()];
  86. try {
  87. // create the workingdir if it doesn't exist
  88. if ( !(new File( outputWorkingDir ).isDirectory()) ) {
  89. File dir = new File( outputWorkingDir );
  90. dir.mkdir();
  91. if (deleteTempFilesOnExit) dir.deleteOnExit();
  92. }
  93. for (int i = 0; i < filenames.size(); i++) {
  94. inputFiles[i] = new File((String)filenames.elementAt(i));
  95. }
  96. // PHASE 0: call ajc
  97. callAjc(inputFiles);
  98. if (CompilerWrapper.hasErrors()) {
  99. System.out.println(FAIL_MESSAGE);
  100. aborted = true;
  101. errors = CompilerWrapper.getErrors();
  102. return;
  103. }
  104. for (int ii = 0; ii < filenames.size(); ii++) {
  105. signatureFiles[ii] = createSignatureFile(inputFiles[ii]);
  106. }
  107. // PHASE 1: generate Signature files (Java with DeclIDs and no bodies).
  108. System.out.println( "> Building signature files..." );
  109. try{
  110. StubFileGenerator.doFiles(declIDTable, inputFiles, signatureFiles);
  111. } catch (DocException d){
  112. System.err.println(d.getMessage());
  113. return;
  114. }
  115. // PHASE 2: let Javadoc generate HTML (with DeclIDs)
  116. callJavadoc(signatureFiles);
  117. // PHASE 3: add AspectDoc specific stuff to the HTML (and remove the DeclIDS).
  118. decorateHtmlFiles(inputFiles);
  119. System.out.println( "> Finished." );
  120. } catch (Throwable e) {
  121. handleInternalError(e);
  122. exit(-2);
  123. }
  124. }
  125. private static void callAjc(File[] inputFiles) {
  126. ajcOptions.addElement("-noExit");
  127. ajcOptions.addElement("-XjavadocsInModel"); // TODO: wrong option to force model gen
  128. ajcOptions.addElement("-d");
  129. ajcOptions.addElement(rootDir.getAbsolutePath());
  130. String[] argsToCompiler = new String[ajcOptions.size() + inputFiles.length];
  131. int i = 0;
  132. for ( ; i < ajcOptions.size(); i++ ) {
  133. argsToCompiler[i] = (String)ajcOptions.elementAt(i);
  134. }
  135. for ( int j = 0; j < inputFiles.length; j++) {
  136. argsToCompiler[i] = inputFiles[j].getAbsolutePath();
  137. //System.out.println(">> file to ajc: " + inputFiles[j].getAbsolutePath());
  138. i++;
  139. }
  140. System.out.println( "> Calling ajc..." );
  141. CompilerWrapper.main(argsToCompiler);
  142. }
  143. private static void callJavadoc(File[] signatureFiles) throws IOException {
  144. System.out.println( "> Calling javadoc..." );
  145. String[] javadocargs = null;
  146. if ( packageMode ) {
  147. int numExtraArgs = 2;
  148. if (authorStandardDocletSwitch) numExtraArgs++;
  149. if (versionStandardDocletSwitch) numExtraArgs++;
  150. javadocargs = new String[numExtraArgs + options.size() + packageList.size() +
  151. fileList.size() ];
  152. javadocargs[0] = "-sourcepath";
  153. javadocargs[1] = outputWorkingDir;
  154. int argIndex = 2;
  155. if (authorStandardDocletSwitch) {
  156. javadocargs[argIndex] = "-author";
  157. argIndex++;
  158. }
  159. if (versionStandardDocletSwitch) {
  160. javadocargs[argIndex] = "-version";
  161. }
  162. //javadocargs[1] = getSourcepathAsString();
  163. for (int k = 0; k < options.size(); k++) {
  164. javadocargs[numExtraArgs+k] = (String)options.elementAt(k);
  165. }
  166. for (int k = 0; k < packageList.size(); k++) {
  167. javadocargs[numExtraArgs+options.size() + k] = (String)packageList.elementAt(k);
  168. }
  169. for (int k = 0; k < fileList.size(); k++) {
  170. javadocargs[numExtraArgs+options.size() + packageList.size() + k] = (String)fileList.elementAt(k);
  171. }
  172. }
  173. else {
  174. javadocargs = new String[options.size() + signatureFiles.length];
  175. for (int k = 0; k < options.size(); k++) {
  176. javadocargs[k] = (String)options.elementAt(k);
  177. }
  178. for (int k = 0; k < signatureFiles.length; k++) {
  179. javadocargs[options.size() + k] = StructureUtil.translateAjPathName(signatureFiles[k].getCanonicalPath());
  180. }
  181. }
  182. JavadocRunner.callJavadoc(javadocargs);
  183. }
  184. /**
  185. * We start with the known HTML files (the ones that correspond directly to the
  186. * input files.) As we go along, we may learn that Javadoc split one .java file
  187. * into multiple .html files to handle inner classes or local classes. The html
  188. * file decorator picks that up.
  189. */
  190. private static void decorateHtmlFiles(File[] inputFiles) throws IOException {
  191. System.out.println( "> Decorating html files..." );
  192. HtmlDecorator.decorateHTMLFromInputFiles(declIDTable,
  193. rootDir,
  194. inputFiles,
  195. docModifier);
  196. System.out.println( "> Removing generated tags (this may take a while)..." );
  197. removeDeclIDsFromFile("index-all.html", true);
  198. removeDeclIDsFromFile("serialized-form.html", true);
  199. if (packageList.size() > 0) {
  200. for (int p = 0; p < packageList.size(); p++) {
  201. removeDeclIDsFromFile(((String)packageList.elementAt(p)).replace('.','/') +
  202. Config.DIR_SEP_CHAR +
  203. "package-summary.html", true);
  204. }
  205. } else {
  206. File[] files = rootDir.listFiles();
  207. if (files == null){
  208. System.err.println("Destination directory is not a directory: " + rootDir.toString());
  209. return;
  210. }
  211. files = FileUtil.listFiles(rootDir, new FileFilter() {
  212. public boolean accept(File f) {
  213. return f.getName().equals("package-summary.html");
  214. }
  215. });
  216. for (int j = 0; j < files.length; j++) {
  217. removeDeclIDsFromFile(files[j].getAbsolutePath(), false);
  218. }
  219. }
  220. }
  221. private static void removeDeclIDsFromFile(String filename, boolean relativePath) {
  222. // Remove the decl ids from "index-all.html"
  223. File indexFile;
  224. if (relativePath) {
  225. indexFile = new File(docDir + Config.DIR_SEP_CHAR + filename);
  226. } else {
  227. indexFile = new File(filename);
  228. }
  229. try {
  230. if ( indexFile.exists() ) {
  231. BufferedReader indexFileReader = new BufferedReader( new FileReader( indexFile ) );
  232. String indexFileBuffer = "";
  233. String line = indexFileReader.readLine();
  234. while ( line != null ) {
  235. int indexStart = line.indexOf( Config.DECL_ID_STRING );
  236. int indexEnd = line.indexOf( Config.DECL_ID_TERMINATOR );
  237. if ( indexStart != -1 && indexEnd != -1 ) {
  238. line = line.substring( 0, indexStart ) +
  239. line.substring( indexEnd+Config.DECL_ID_TERMINATOR.length() );
  240. }
  241. indexFileBuffer += line;
  242. line = indexFileReader.readLine();
  243. }
  244. FileOutputStream fos = new FileOutputStream( indexFile );
  245. fos.write( indexFileBuffer.getBytes() );
  246. indexFileReader.close();
  247. fos.close();
  248. }
  249. }
  250. catch (IOException ioe) {
  251. // be siltent
  252. }
  253. }
  254. static Vector getSourcePath() {
  255. Vector sourcePath = new Vector();
  256. boolean found = false;
  257. for ( int i = 0; i < options.size(); i++ ) {
  258. String currOption = (String)options.elementAt(i);
  259. if (found && !currOption.startsWith("-")) {
  260. sourcePath.add(currOption);
  261. }
  262. if (currOption.equals("-sourcepath")) {
  263. found = true;
  264. }
  265. }
  266. return sourcePath;
  267. }
  268. static File getRootDir() {
  269. File rootDir = new File( "." );
  270. for ( int i = 0; i < options.size(); i++ ) {
  271. if ( ((String)options.elementAt(i)).equals( "-d" ) ) {
  272. rootDir = new File((String)options.elementAt(i+1));
  273. if ( !rootDir.exists() ) {
  274. rootDir.mkdir();
  275. // System.out.println( "Destination directory not found: " +
  276. // (String)options.elementAt(i+1) );
  277. // System.exit( -1 );
  278. }
  279. }
  280. }
  281. return rootDir;
  282. }
  283. static File createSignatureFile(File inputFile) throws IOException {
  284. String packageName = StructureUtil.getPackageDeclarationFromFile(inputFile);
  285. String filename = "";
  286. if ( packageName != null ) {
  287. String pathName = outputWorkingDir + '/' + packageName.replace('.', '/');
  288. File packageDir = new File(pathName);
  289. if ( !packageDir.exists() ) {
  290. packageDir.mkdirs();
  291. if (deleteTempFilesOnExit) packageDir.deleteOnExit();
  292. }
  293. //verifyPackageDirExists(packageName, null);
  294. packageName = packageName.replace( '.','/' ); // !!!
  295. filename = outputWorkingDir + Config.DIR_SEP_CHAR + packageName +
  296. Config.DIR_SEP_CHAR + inputFile.getName();
  297. }
  298. else {
  299. filename = outputWorkingDir + Config.DIR_SEP_CHAR + inputFile.getName();
  300. }
  301. File signatureFile = new File( filename );
  302. if (deleteTempFilesOnExit) signatureFile.deleteOnExit();
  303. return signatureFile;
  304. }
  305. // static void verifyPackageDirExists( String packageName, String offset ) {
  306. // System.err.println(">>> name: " + packageName + ", offset: " + offset);
  307. // if ( packageName.indexOf( "." ) != -1 ) {
  308. // File tempFile = new File("c:/aspectj-test/d1/d2/d3");
  309. // tempFile.mkdirs();
  310. // String currPkgDir = packageName.substring( 0, packageName.indexOf( "." ) );
  311. // String remainingPkg = packageName.substring( packageName.indexOf( "." )+1 );
  312. // String filePath = null;
  313. // if ( offset != null ) {
  314. // filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR +
  315. // offset + Config.DIR_SEP_CHAR + currPkgDir ;
  316. // }
  317. // else {
  318. // filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + currPkgDir;
  319. // }
  320. // File packageDir = new File( filePath );
  321. // if ( !packageDir.exists() ) {
  322. // packageDir.mkdir();
  323. // if (deleteTempFilesOnExit) packageDir.deleteOnExit();
  324. // }
  325. // if ( remainingPkg != "" ) {
  326. // verifyPackageDirExists( remainingPkg, currPkgDir );
  327. // }
  328. // }
  329. // else {
  330. // String filePath = null;
  331. // if ( offset != null ) {
  332. // filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + offset + Config.DIR_SEP_CHAR + packageName;
  333. // }
  334. // else {
  335. // filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + packageName;
  336. // }
  337. // File packageDir = new File( filePath );
  338. // if ( !packageDir.exists() ) {
  339. // packageDir.mkdir();
  340. // if (deleteTempFilesOnExit) packageDir.deleteOnExit();
  341. // }
  342. // }
  343. // }
  344. /**
  345. * Can read Eclipse-generated single-line arg
  346. */
  347. static void parseCommandLine(String[] args) {
  348. if (args.length == 0) {
  349. displayHelpAndExit( null );
  350. } else if (args.length == 1 && args[0].startsWith("@")) {
  351. String argFile = args[0].substring(1);
  352. System.out.println("> Using arg file: " + argFile);
  353. BufferedReader br;
  354. try {
  355. br = new BufferedReader(new FileReader(argFile));
  356. String line = "";
  357. line = br.readLine();
  358. StringTokenizer st = new StringTokenizer(line, " ");
  359. List argList = new ArrayList();
  360. while(st.hasMoreElements()) {
  361. argList.add((String)st.nextElement());
  362. }
  363. //System.err.println(argList);
  364. args = new String[argList.size()];
  365. int counter = 0;
  366. for (Iterator it = argList.iterator(); it.hasNext(); ) {
  367. args[counter] = (String)it.next();
  368. counter++;
  369. }
  370. } catch (FileNotFoundException e) {
  371. System.err.println("> could not read arg file: " + argFile);
  372. e.printStackTrace();
  373. } catch (IOException ioe) {
  374. System.err.println("> could not read arg file: " + argFile);
  375. ioe.printStackTrace();
  376. }
  377. }
  378. List vargs = new LinkedList(Arrays.asList(args));
  379. parseArgs(vargs, new File( "." )); // !!!
  380. if (filenames.size() == 0) {
  381. displayHelpAndExit( "ajdoc: No packages or classes specified" );
  382. }
  383. }
  384. static void setSourcepath(String arg) {
  385. sourcepath.clear();
  386. arg = arg + File.pathSeparator; // makes things easier for ourselves
  387. StringTokenizer tokenizer = new StringTokenizer(arg, File.pathSeparator);
  388. while (tokenizer.hasMoreElements()) {
  389. sourcepath.addElement(tokenizer.nextElement());
  390. }
  391. }
  392. static String getSourcepathAsString() {
  393. String cPath = "";
  394. for (int i = 0; i < sourcepath.size(); i++) {
  395. cPath += (String)sourcepath.elementAt(i) + Config.DIR_SEP_CHAR + outputWorkingDir;
  396. if (i != sourcepath.size()-1) {
  397. cPath += File.pathSeparator;
  398. }
  399. }
  400. return cPath;
  401. }
  402. static void parseArgs(List vargs, File currentWorkingDir) {
  403. boolean addNextAsOption = false;
  404. boolean addNextAsArgFile = false;
  405. boolean addNextToAJCOptions = false;
  406. boolean addNextAsDocDir = false;
  407. boolean addNextAsClasspath = false;
  408. boolean ignoreArg = false; // used for discrepancy betwen class/sourcepath in ajc/javadoc
  409. boolean addNextAsSourcePath = false;
  410. if ( vargs.size() == 0 ) {
  411. displayHelpAndExit( null );
  412. }
  413. for (int i = 0; i < vargs.size() ; i++) {
  414. String arg = (String)vargs.get(i);
  415. ignoreArg = false;
  416. if (addNextAsDocDir) {
  417. docDir = arg;
  418. addNextAsDocDir = false;
  419. }
  420. if (addNextAsClasspath) {
  421. addNextAsClasspath = false;
  422. }
  423. if (addNextAsSourcePath) {
  424. setSourcepath( arg );
  425. addNextAsSourcePath = false;
  426. ignoreArg = true;
  427. }
  428. if ( arg.startsWith("@") ) {
  429. expandAtSignFile(arg.substring(1), currentWorkingDir);
  430. } else if ( arg.equals( "-argfile" ) ) {
  431. addNextAsArgFile = true;
  432. } else if ( addNextAsArgFile ) {
  433. expandAtSignFile(arg, currentWorkingDir);
  434. addNextAsArgFile = false;
  435. } else if (arg.equals("-d") ) {
  436. addNextAsOption = true;
  437. options.addElement(arg);
  438. addNextAsDocDir = true;
  439. } else if ( arg.equals( "-bootclasspath" ) ) {
  440. addNextAsOption = true;
  441. addNextToAJCOptions = true;
  442. options.addElement( arg );
  443. ajcOptions.addElement( arg );
  444. } else if ( arg.equals( "-source" ) ) {
  445. addNextAsOption = true;
  446. addNextToAJCOptions = true;
  447. addNextAsClasspath = true;
  448. options.addElement(arg);
  449. ajcOptions.addElement(arg);
  450. } else if ( arg.equals( "-classpath" ) ) {
  451. addNextAsOption = true;
  452. addNextToAJCOptions = true;
  453. addNextAsClasspath = true;
  454. options.addElement( arg );
  455. ajcOptions.addElement( arg );
  456. } else if ( arg.equals( "-encoding" ) ) {
  457. addNextAsOption = true;
  458. addNextToAJCOptions = false;
  459. options.addElement( arg );
  460. } else if ( arg.equals( "-docencoding" ) ) {
  461. addNextAsOption = true;
  462. addNextToAJCOptions = false;
  463. options.addElement( arg );
  464. } else if ( arg.equals( "-charset" ) ) {
  465. addNextAsOption = true;
  466. addNextToAJCOptions = false;
  467. options.addElement( arg );
  468. } else if ( arg.equals( "-sourcepath" ) ) {
  469. addNextAsSourcePath = true;
  470. //options.addElement( arg );
  471. //ajcOptions.addElement( arg );
  472. } else if (arg.equals("-XajdocDebug")) {
  473. deleteTempFilesOnExit = false;
  474. } else if (arg.equals("-use")) {
  475. System.out.println("> Ignoring unsupported option: -use");
  476. } else if (arg.equals("-splitindex")) {
  477. // passed to javadoc
  478. } else if (arg.startsWith("-") || addNextAsOption || addNextToAJCOptions) {
  479. if ( arg.equals( "-private" ) ) {
  480. docModifier = "private";
  481. } else if ( arg.equals( "-package" ) ) {
  482. docModifier = "package";
  483. } else if ( arg.equals( "-protected" ) ) {
  484. docModifier = "protected";
  485. } else if ( arg.equals( "-public" ) ) {
  486. docModifier = "public";
  487. } else if ( arg.equals( "-verbose" ) ) {
  488. verboseMode = true;
  489. } else if ( arg.equals( "-author" ) ) {
  490. authorStandardDocletSwitch = true;
  491. } else if ( arg.equals( "-version" ) ) {
  492. versionStandardDocletSwitch = true;
  493. } else if ( arg.equals( "-v" ) ) {
  494. System.out.println(getVersion());
  495. exit(0);
  496. } else if ( arg.equals( "-help" ) ) {
  497. displayHelpAndExit( null );
  498. } else if ( arg.equals( "-doclet" ) || arg.equals( "-docletpath" ) ) {
  499. System.out.println( "The doclet and docletpath options are not currently supported \n" +
  500. "since ajdoc makes assumptions about the behavior of the standard \n" +
  501. "doclet. If you would find this option useful please email us at: \n" +
  502. " \n" +
  503. " aspectj-dev@eclipse.org \n" +
  504. " \n" );
  505. exit(0);
  506. } else if (arg.equals("-nonavbar")
  507. || arg.equals("-noindex")) {
  508. // pass through
  509. //System.err.println("> ignoring unsupported option: " + arg);
  510. } else if (addNextToAJCOptions || addNextAsOption) {
  511. // deal with these two options together even though effectively
  512. // just falling through if addNextAsOption is true. Otherwise
  513. // will have to ensure check "addNextToAJCOptions" before
  514. // "addNextAsOption" so as the options are added to the
  515. // correct lists.
  516. if (addNextToAJCOptions) {
  517. ajcOptions.addElement(arg);
  518. if (!arg.startsWith("-")) {
  519. addNextToAJCOptions = false;
  520. }
  521. if (!addNextAsOption) {
  522. continue;
  523. }
  524. }
  525. } else if (arg.startsWith("-")) {
  526. ajcOptions.addElement(arg);
  527. addNextToAJCOptions = true;
  528. continue;
  529. } else {
  530. System.err.println("> unrecognized argument: " + arg);
  531. displayHelpAndExit( null );
  532. }
  533. options.addElement(arg);
  534. addNextAsOption = false;
  535. } else {
  536. // check if this is a file or a package
  537. // System.err.println(">>>>>>>> " + );
  538. // String entryName = arg.substring(arg.lastIndexOf(File.separator)+1);
  539. if (FileUtil.hasSourceSuffix(arg) || arg.endsWith(".lst") && arg != null ) {
  540. File f = new File(arg);
  541. if (f.isAbsolute()) {
  542. filenames.addElement(arg);
  543. }
  544. else {
  545. filenames.addElement( currentWorkingDir + Config.DIR_SEP_CHAR + arg );
  546. }
  547. fileList.addElement( arg );
  548. }
  549. // PACKAGE MODE STUFF
  550. else if (!ignoreArg) {
  551. packageMode = true;
  552. packageList.addElement( arg );
  553. arg = arg.replace( '.', '/' ); // !!!
  554. // do this for every item in the classpath
  555. for ( int c = 0; c < sourcepath.size(); c++ ) {
  556. String path = (String)sourcepath.elementAt(c) + Config.DIR_SEP_CHAR + arg;
  557. File pkg = new File(path);
  558. if ( pkg.isDirectory() ) {
  559. String[] files = pkg.list( new FilenameFilter() {
  560. public boolean accept( File dir, String name ) {
  561. int index1 = name.lastIndexOf( "." );
  562. int index2 = name.length();
  563. if ( (index1 >= 0 && index2 >= 0 ) &&
  564. (name.substring(index1, index2).equals( ".java" )
  565. || name.substring(index1, index2).equals( ".aj" ))) {
  566. return true;
  567. }
  568. else {
  569. return false;
  570. }
  571. }
  572. } );
  573. for ( int j = 0; j < files.length; j++ ) {
  574. filenames.addElement( (String)sourcepath.elementAt(c) +
  575. Config.DIR_SEP_CHAR +
  576. arg + Config.DIR_SEP_CHAR + files[j] );
  577. }
  578. }
  579. else if (c == sourcepath.size() ) { // last element on classpath
  580. System.out.println( "ajdoc: No package, class, or source file " +
  581. "found named " + arg + "." );
  582. }
  583. else {
  584. // didn't find it on that element of the classpath but that's ok
  585. }
  586. }
  587. }
  588. }
  589. }
  590. // set the default visibility as an option to javadoc option
  591. if ( !options.contains( "-private" ) &&
  592. !options.contains( "-package" ) &&
  593. !options.contains( "-protected" ) &&
  594. !options.contains( "-public" ) ) {
  595. options.addElement( "-package" );
  596. }
  597. }
  598. static void expandAtSignFile(String filename, File currentWorkingDir) {
  599. List result = new LinkedList();
  600. File atFile = qualifiedFile(filename, currentWorkingDir);
  601. String atFileParent = atFile.getParent();
  602. File myWorkingDir = null;
  603. if (atFileParent != null) myWorkingDir = new File(atFileParent);
  604. try {
  605. BufferedReader stream = new BufferedReader(new FileReader(atFile));
  606. String line = null;
  607. while ( (line = stream.readLine()) != null) {
  608. // strip out any comments of the form # to end of line
  609. int commentStart = line.indexOf("//");
  610. if (commentStart != -1) {
  611. line = line.substring(0, commentStart);
  612. }
  613. // remove extra whitespace that might have crept in
  614. line = line.trim();
  615. // ignore blank lines
  616. if (line.length() == 0) continue;
  617. result.add(line);
  618. }
  619. } catch (IOException e) {
  620. System.err.println("Error while reading the @ file " + atFile.getPath() + ".\n"
  621. + e);
  622. System.exit( -1 );
  623. }
  624. parseArgs(result, myWorkingDir);
  625. }
  626. static File qualifiedFile(String name, File currentWorkingDir) {
  627. name = name.replace('/', File.separatorChar);
  628. File file = new File(name);
  629. if (!file.isAbsolute() && currentWorkingDir != null) {
  630. file = new File(currentWorkingDir, name);
  631. }
  632. return file;
  633. }
  634. static void displayHelpAndExit(String message) {
  635. shownAjdocUsageMessage = true;
  636. if (message != null) {
  637. System.err.println(message);
  638. System.err.println();
  639. System.err.println(Config.USAGE);
  640. } else {
  641. System.out.println(Config.USAGE);
  642. exit(0);
  643. }
  644. }
  645. static protected void exit(int value) {
  646. System.out.flush();
  647. System.err.flush();
  648. System.exit(value);
  649. }
  650. /* This section of code handles errors that occur during compilation */
  651. static final String internalErrorMessage =
  652. " \n"+
  653. "If this has not already been logged as a bug raised please raise \n"+
  654. "a new AspectJ bug at https://bugs.eclipse.org/bugs including the \n"+
  655. "text below. To make the bug a priority, please also include a test\n"+
  656. "program that can reproduce this problem.\n ";
  657. static public void handleInternalError(Throwable uncaughtThrowable) {
  658. System.err.println("An internal error occured in ajdoc");
  659. System.err.println(internalErrorMessage);
  660. System.err.println(uncaughtThrowable.toString());
  661. uncaughtThrowable.printStackTrace();
  662. System.err.println();
  663. }
  664. static String getVersion() {
  665. return "ajdoc version " + Version.text;
  666. }
  667. public static boolean hasAborted() {
  668. return aborted;
  669. }
  670. public static IMessage[] getErrors() {
  671. return errors;
  672. }
  673. public static boolean hasShownAjdocUsageMessage() {
  674. return shownAjdocUsageMessage;
  675. }
  676. /**
  677. * Sets the output working dir to be <fullyQualifiedOutputDir>\ajdocworkingdir
  678. * Useful in testing to redirect the ajdocworkingdir to the sandbox
  679. */
  680. public static void setOutputWorkingDir(String fullyQulifiedOutputDir) {
  681. if (fullyQulifiedOutputDir == null) {
  682. resetOutputWorkingDir();
  683. } else {
  684. outputWorkingDir = fullyQulifiedOutputDir + File.separatorChar +
  685. Config.WORKING_DIR;
  686. }
  687. }
  688. /**
  689. * Resets the output working dir to be the default which is
  690. * <the current directory>\ajdocworkingdir
  691. */
  692. public static void resetOutputWorkingDir() {
  693. outputWorkingDir = Config.WORKING_DIR;
  694. }
  695. }