| /* ******************************************************************* |
| * Copyright (c) 1999-2001 Xerox Corporation, |
| * 2002 Palo Alto Research Center, Incorporated (PARC). |
| * All rights reserved. |
| * This program and the accompanying materials are made available |
| * under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Xerox/PARC initial implementation |
| * Mik Kersten port to AspectJ 1.1+ code base |
| * ******************************************************************/ |
| |
| package org.aspectj.tools.ajdoc; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileFilter; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.FileReader; |
| import java.io.FilenameFilter; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.StringTokenizer; |
| import java.util.Vector; |
| |
| import org.aspectj.asm.AsmManager; |
| import org.aspectj.bridge.IMessage; |
| import org.aspectj.bridge.Version; |
| import org.aspectj.util.FileUtil; |
| import org.aspectj.util.LangUtil; |
| |
| /** |
| * This is an old implementation of ajdoc that does not use an OO style. However, it does the job, and should serve to evolve a |
| * lightweight ajdoc implementation until we can make a properly extended javadoc implementation. |
| * |
| * @author Mik Kersten |
| */ |
| public class Main implements Config { |
| |
| private static final String FAIL_MESSAGE = "> compile failed, exiting ajdoc"; |
| |
| /** Command line options. */ |
| static Vector<String> options; |
| |
| /** Options to pass to ajc. */ |
| static Vector<String> ajcOptions; |
| |
| /** All of the files to be processed by ajdoc. */ |
| static Vector<String> filenames; |
| |
| /** List of files to pass to javadoc. */ |
| static Vector<String> fileList; |
| |
| /** List of packages to pass to javadoc. */ |
| static Vector<String> packageList; |
| |
| /** Default to package visiblity. */ |
| static String docModifier = "package"; |
| |
| static Vector<String> sourcepath; |
| |
| static boolean verboseMode = false; |
| static boolean packageMode = false; |
| static boolean authorStandardDocletSwitch = false; |
| static boolean versionStandardDocletSwitch = false; |
| static File rootDir = null; |
| static Hashtable declIDTable = new Hashtable(); |
| static String docDir = "."; |
| |
| private static boolean deleteTempFilesOnExit = true; |
| |
| private static boolean aborted = false; |
| private static IMessage[] errors; |
| private static boolean shownAjdocUsageMessage = false; |
| |
| // creating a local variable to enable us to create the ajdocworkingdir |
| // in a local sandbox during testing |
| private static String outputWorkingDir = Config.WORKING_DIR; |
| |
| public static void clearState() { |
| options = new Vector<String>(); |
| ajcOptions = new Vector<String>(); |
| filenames = new Vector<String>(); |
| fileList = new Vector<String>(); |
| packageList = new Vector<String>(); |
| docModifier = "package"; |
| sourcepath = new Vector<String>(); |
| verboseMode = false; |
| packageMode = false; |
| rootDir = null; |
| declIDTable = new Hashtable(); |
| docDir = "."; |
| aborted = false; |
| deleteTempFilesOnExit = true; |
| } |
| |
| public static void main(String[] args) { |
| clearState(); |
| if (!JavadocRunner.has14ToolsAvailable()) { |
| System.err.println("ajdoc requires a JDK 1.4 or later tools jar - exiting"); |
| aborted = true; |
| return; |
| } |
| |
| // STEP 1: parse the command line and do other global setup |
| sourcepath.addElement("."); // add the current directory to the classapth |
| parseCommandLine(args); |
| rootDir = getRootDir(); |
| File[] inputFiles = new File[filenames.size()]; |
| File[] signatureFiles = new File[filenames.size()]; |
| try { |
| // create the workingdir if it doesn't exist |
| if (!(new File(outputWorkingDir).isDirectory())) { |
| File dir = new File(outputWorkingDir); |
| dir.mkdir(); |
| if (deleteTempFilesOnExit) |
| dir.deleteOnExit(); |
| } |
| |
| for (int i = 0; i < filenames.size(); i++) { |
| inputFiles[i] = new File(filenames.elementAt(i)); |
| } |
| |
| // PHASE 0: call ajc |
| AsmManager model = callAjc(inputFiles); |
| if (CompilerWrapper.hasErrors()) { |
| System.out.println(FAIL_MESSAGE); |
| aborted = true; |
| errors = CompilerWrapper.getErrors(); |
| return; |
| } |
| |
| for (int ii = 0; ii < filenames.size(); ii++) { |
| signatureFiles[ii] = createSignatureFile(model, inputFiles[ii]); |
| } |
| |
| // PHASE 1: generate Signature files (Java with DeclIDs and no bodies). |
| System.out.println("> Building signature files..."); |
| try { |
| StubFileGenerator.doFiles(model, declIDTable, inputFiles, signatureFiles); |
| // Copy package.html and related files over |
| packageHTML(model, inputFiles); |
| } catch (DocException d) { |
| System.err.println(d.getMessage()); |
| return; |
| } |
| |
| // PHASE 2: let Javadoc generate HTML (with DeclIDs) |
| callJavadoc(signatureFiles); |
| |
| // PHASE 3: add AspectDoc specific stuff to the HTML (and remove the DeclIDS). |
| decorateHtmlFiles(model, inputFiles); |
| System.out.println("> Finished."); |
| } catch (Throwable e) { |
| handleInternalError(e); |
| exit(-2); |
| } |
| } |
| |
| /** |
| * Method to copy over any package.html files that may be part of the documentation so that javadoc generates the |
| * package-summary properly. |
| */ |
| private static void packageHTML(AsmManager model, File[] inputFiles) throws IOException { |
| ArrayList<String> dirList = new ArrayList<String>(); |
| for (int i = 0; i < inputFiles.length; i++) { |
| String packageName = StructureUtil.getPackageDeclarationFromFile(model, inputFiles[i]); |
| // Only copy the package.html file once. |
| if (dirList.contains(packageName)) |
| continue; |
| |
| // Check to see if there exist a package.html file for this package. |
| String dir = inputFiles[i].getAbsolutePath().substring(0, inputFiles[i].getAbsolutePath().lastIndexOf(File.separator)); |
| File input = new File(dir + Config.DIR_SEP_CHAR + "package.html"); |
| File inDir = new File(dir + Config.DIR_SEP_CHAR + "doc-files"); |
| // If it does not exist lets go to the next package. |
| if (!input.exists()) { |
| dirList.add(packageName); |
| continue; |
| } |
| |
| String filename = ""; |
| String docFiles = ""; |
| if (packageName != null) { |
| String pathName = outputWorkingDir + File.separator + packageName.replace('.', File.separatorChar); |
| File packageDir = new File(pathName); |
| if (!packageDir.exists()) { |
| dirList.add(packageName); |
| continue; |
| } |
| packageName = packageName.replace('.', '/'); // !!! |
| filename = outputWorkingDir + Config.DIR_SEP_CHAR + packageName + Config.DIR_SEP_CHAR + "package.html"; |
| docFiles = rootDir.getAbsolutePath() + Config.DIR_SEP_CHAR + packageName + Config.DIR_SEP_CHAR + "doc-files"; |
| } else { |
| filename = outputWorkingDir + Config.DIR_SEP_CHAR + "package.html"; |
| docFiles = rootDir.getAbsolutePath() + Config.DIR_SEP_CHAR + "doc-files"; |
| } |
| |
| File output = new File(filename); |
| FileUtil.copyFile(input, output);// Copy package.html |
| // javadoc doesn't do anything with the doc-files folder so |
| // we'll just copy it directly to the document location. |
| if (!inDir.exists()) |
| continue; |
| File outDir = new File(docFiles); |
| System.out.println("> Copying folder " + outDir); |
| FileUtil.copyFile(inDir, outDir);// Copy doc-files folder if it exist |
| } |
| } |
| |
| private static AsmManager callAjc(File[] inputFiles) { |
| ajcOptions.addElement("-noExit"); |
| ajcOptions.addElement("-XjavadocsInModel"); // TODO: wrong option to force model gen |
| ajcOptions.addElement("-d"); |
| ajcOptions.addElement(rootDir.getAbsolutePath()); |
| String[] argsToCompiler = new String[ajcOptions.size() + inputFiles.length]; |
| int i = 0; |
| for (; i < ajcOptions.size(); i++) { |
| argsToCompiler[i] = ajcOptions.elementAt(i); |
| } |
| for (int j = 0; j < inputFiles.length; j++) { |
| argsToCompiler[i] = inputFiles[j].getAbsolutePath(); |
| // System.out.println(">> file to ajc: " + inputFiles[j].getAbsolutePath()); |
| i++; |
| } |
| System.out.println("> Calling ajc..."); |
| return CompilerWrapper.executeMain(argsToCompiler); |
| } |
| |
| private static void callJavadoc(File[] signatureFiles) throws IOException { |
| System.out.println("> Calling javadoc..."); |
| String[] javadocargs = null; |
| |
| List<String> files = new ArrayList<String>(); |
| if (packageMode) { |
| int numExtraArgs = 2; |
| if (authorStandardDocletSwitch) |
| numExtraArgs++; |
| if (versionStandardDocletSwitch) |
| numExtraArgs++; |
| javadocargs = new String[numExtraArgs + options.size() + packageList.size() + fileList.size()]; |
| javadocargs[0] = "-sourcepath"; |
| javadocargs[1] = outputWorkingDir; |
| int argIndex = 2; |
| if (authorStandardDocletSwitch) { |
| javadocargs[argIndex] = "-author"; |
| argIndex++; |
| } |
| if (versionStandardDocletSwitch) { |
| javadocargs[argIndex] = "-version"; |
| } |
| // javadocargs[1] = getSourcepathAsString(); |
| for (int k = 0; k < options.size(); k++) { |
| javadocargs[numExtraArgs + k] = options.elementAt(k); |
| } |
| for (int k = 0; k < packageList.size(); k++) { |
| javadocargs[numExtraArgs + options.size() + k] = packageList.elementAt(k); |
| } |
| for (int k = 0; k < fileList.size(); k++) { |
| javadocargs[numExtraArgs + options.size() + packageList.size() + k] = fileList.elementAt(k); |
| } |
| if (LangUtil.is19VMOrGreater()) { |
| options = new Vector<String>(); |
| for (String a: javadocargs) { |
| options.add(a); |
| } |
| } |
| } else { |
| javadocargs = new String[options.size() + signatureFiles.length]; |
| for (int k = 0; k < options.size(); k++) { |
| javadocargs[k] = options.elementAt(k); |
| } |
| for (int k = 0; k < signatureFiles.length; k++) { |
| javadocargs[options.size() + k] = StructureUtil.translateAjPathName(signatureFiles[k].getCanonicalPath()); |
| } |
| for (int k = 0; k < signatureFiles.length; k++) { |
| files.add(StructureUtil.translateAjPathName(signatureFiles[k].getCanonicalPath())); |
| } |
| } |
| if (LangUtil.is19VMOrGreater()) { |
| JavadocRunner.callJavadocViaToolProvider(options, files); |
| } else { |
| JavadocRunner.callJavadoc(javadocargs); |
| } |
| } |
| |
| /** |
| * We start with the known HTML files (the ones that correspond directly to the input files.) As we go along, we may learn that |
| * Javadoc split one .java file into multiple .html files to handle inner classes or local classes. The html file decorator |
| * picks that up. |
| */ |
| private static void decorateHtmlFiles(AsmManager model, File[] inputFiles) throws IOException { |
| System.out.println("> Decorating html files..."); |
| HtmlDecorator.decorateHTMLFromInputFiles(model, declIDTable, rootDir, inputFiles, docModifier); |
| |
| System.out.println("> Removing generated tags..."); |
| removeDeclIDsFromFile("index-all.html", true); |
| removeDeclIDsFromFile("serialized-form.html", true); |
| if (packageList.size() > 0) { |
| for (int p = 0; p < packageList.size(); p++) { |
| removeDeclIDsFromFile(packageList.elementAt(p).replace('.', '/') + Config.DIR_SEP_CHAR |
| + "package-summary.html", true); |
| } |
| } else { |
| File[] files = rootDir.listFiles(); |
| if (files == null) { |
| System.err.println("Destination directory is not a directory: " + rootDir.toString()); |
| return; |
| } |
| files = FileUtil.listFiles(rootDir, new FileFilter() { |
| @Override |
| public boolean accept(File f) { |
| return f.getName().equals("package-summary.html"); |
| } |
| }); |
| for (int j = 0; j < files.length; j++) { |
| removeDeclIDsFromFile(files[j].getAbsolutePath(), false); |
| } |
| } |
| } |
| |
| private static void removeDeclIDsFromFile(String filename, boolean relativePath) { |
| // Remove the decl ids from "index-all.html" |
| File indexFile; |
| if (relativePath) { |
| indexFile = new File(docDir + Config.DIR_SEP_CHAR + filename); |
| } else { |
| indexFile = new File(filename); |
| } |
| try { |
| if (indexFile.exists()) { |
| BufferedReader indexFileReader = new BufferedReader(new FileReader(indexFile)); |
| // StringBuffer greatly reduces the time it takes to remove generated tags |
| StringBuffer indexFileBuffer = new StringBuffer((int) indexFile.length()); |
| String line = indexFileReader.readLine(); |
| while (line != null) { |
| int indexStart = line.indexOf(Config.DECL_ID_STRING); |
| int indexEnd = line.indexOf(Config.DECL_ID_TERMINATOR); |
| if (indexStart != -1 && indexEnd != -1) { |
| line = line.substring(0, indexStart) + line.substring(indexEnd + Config.DECL_ID_TERMINATOR.length()); |
| } |
| indexFileBuffer.append(line); |
| line = indexFileReader.readLine(); |
| } |
| FileOutputStream fos = new FileOutputStream(indexFile); |
| fos.write(indexFileBuffer.toString().getBytes()); |
| |
| indexFileReader.close(); |
| fos.close(); |
| } |
| } catch (IOException ioe) { |
| // be siltent |
| } |
| } |
| |
| static Vector<String> getSourcePath() { |
| Vector<String> sourcePath = new Vector<String>(); |
| boolean found = false; |
| for (int i = 0; i < options.size(); i++) { |
| String currOption = options.elementAt(i); |
| if (found && !currOption.startsWith("-")) { |
| sourcePath.add(currOption); |
| } |
| if (currOption.equals("-sourcepath")) { |
| found = true; |
| } |
| } |
| return sourcePath; |
| } |
| |
| static File getRootDir() { |
| File rootDir = new File("."); |
| for (int i = 0; i < options.size(); i++) { |
| if (options.elementAt(i).equals("-d")) { |
| rootDir = new File(options.elementAt(i + 1)); |
| if (!rootDir.exists()) { |
| rootDir.mkdir(); |
| // System.out.println( "Destination directory not found: " + |
| // (String)options.elementAt(i+1) ); |
| // System.exit( -1 ); |
| } |
| } |
| } |
| return rootDir; |
| } |
| |
| static File createSignatureFile(AsmManager model, File inputFile) throws IOException { |
| String packageName = StructureUtil.getPackageDeclarationFromFile(model, inputFile); |
| |
| String filename = ""; |
| if (packageName != null) { |
| String pathName = outputWorkingDir + '/' + packageName.replace('.', '/'); |
| File packageDir = new File(pathName); |
| if (!packageDir.exists()) { |
| packageDir.mkdirs(); |
| if (deleteTempFilesOnExit) |
| packageDir.deleteOnExit(); |
| } |
| // verifyPackageDirExists(packageName, null); |
| packageName = packageName.replace('.', '/'); // !!! |
| filename = outputWorkingDir + Config.DIR_SEP_CHAR + packageName + Config.DIR_SEP_CHAR + inputFile.getName(); |
| } else { |
| filename = outputWorkingDir + Config.DIR_SEP_CHAR + inputFile.getName(); |
| } |
| File signatureFile = new File(filename); |
| if (deleteTempFilesOnExit) |
| signatureFile.deleteOnExit(); |
| return signatureFile; |
| } |
| |
| // static void verifyPackageDirExists( String packageName, String offset ) { |
| // System.err.println(">>> name: " + packageName + ", offset: " + offset); |
| // if ( packageName.indexOf( "." ) != -1 ) { |
| // File tempFile = new File("c:/aspectj-test/d1/d2/d3"); |
| // tempFile.mkdirs(); |
| // String currPkgDir = packageName.substring( 0, packageName.indexOf( "." ) ); |
| // String remainingPkg = packageName.substring( packageName.indexOf( "." )+1 ); |
| // String filePath = null; |
| // if ( offset != null ) { |
| // filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + |
| // offset + Config.DIR_SEP_CHAR + currPkgDir ; |
| // } |
| // else { |
| // filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + currPkgDir; |
| // } |
| // File packageDir = new File( filePath ); |
| // if ( !packageDir.exists() ) { |
| // packageDir.mkdir(); |
| // if (deleteTempFilesOnExit) packageDir.deleteOnExit(); |
| // } |
| // if ( remainingPkg != "" ) { |
| // verifyPackageDirExists( remainingPkg, currPkgDir ); |
| // } |
| // } |
| // else { |
| // String filePath = null; |
| // if ( offset != null ) { |
| // filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + offset + Config.DIR_SEP_CHAR + packageName; |
| // } |
| // else { |
| // filePath = Config.WORKING_DIR + Config.DIR_SEP_CHAR + packageName; |
| // } |
| // File packageDir = new File( filePath ); |
| // if ( !packageDir.exists() ) { |
| // packageDir.mkdir(); |
| // if (deleteTempFilesOnExit) packageDir.deleteOnExit(); |
| // } |
| // } |
| // } |
| |
| /** |
| * Can read Eclipse-generated single-line arg |
| */ |
| static void parseCommandLine(String[] args) { |
| if (args.length == 0) { |
| displayHelpAndExit(null); |
| } else if (args.length == 1 && args[0].startsWith("@")) { |
| String argFile = args[0].substring(1); |
| System.out.println("> Using arg file: " + argFile); |
| BufferedReader br; |
| try { |
| br = new BufferedReader(new FileReader(argFile)); |
| String line = ""; |
| line = br.readLine(); |
| StringTokenizer st = new StringTokenizer(line, " "); |
| List<String> argList = new ArrayList<String>(); |
| while (st.hasMoreElements()) { |
| argList.add(st.nextToken()); |
| } |
| // System.err.println(argList); |
| args = new String[argList.size()]; |
| int counter = 0; |
| for (Iterator<String> it = argList.iterator(); it.hasNext();) { |
| args[counter] = it.next(); |
| counter++; |
| } |
| } catch (FileNotFoundException e) { |
| System.err.println("> could not read arg file: " + argFile); |
| e.printStackTrace(); |
| } catch (IOException ioe) { |
| System.err.println("> could not read arg file: " + argFile); |
| ioe.printStackTrace(); |
| } |
| } |
| List<String> vargs = new LinkedList<String>(Arrays.asList(args)); |
| vargs.add("-Xset:minimalModel=false"); |
| parseArgs(vargs, new File(".")); // !!! |
| |
| if (filenames.size() == 0) { |
| displayHelpAndExit("ajdoc: No packages or classes specified"); |
| } |
| } |
| |
| static void setSourcepath(String arg) { |
| sourcepath.clear(); |
| arg = arg + File.pathSeparator; // makes things easier for ourselves |
| StringTokenizer tokenizer = new StringTokenizer(arg, File.pathSeparator); |
| while (tokenizer.hasMoreElements()) { |
| sourcepath.addElement(tokenizer.nextToken()); |
| } |
| } |
| |
| static String getSourcepathAsString() { |
| String cPath = ""; |
| for (int i = 0; i < sourcepath.size(); i++) { |
| cPath += sourcepath.elementAt(i) + Config.DIR_SEP_CHAR + outputWorkingDir; |
| if (i != sourcepath.size() - 1) { |
| cPath += File.pathSeparator; |
| } |
| } |
| return cPath; |
| } |
| |
| static void parseArgs(List vargs, File currentWorkingDir) { |
| boolean addNextAsOption = false; |
| boolean addNextAsArgFile = false; |
| boolean addNextToAJCOptions = false; |
| boolean addNextAsDocDir = false; |
| boolean addNextAsClasspath = false; |
| boolean ignoreArg = false; // used for discrepancy betwen class/sourcepath in ajc/javadoc |
| boolean addNextAsSourcePath = false; |
| if (vargs.size() == 0) { |
| displayHelpAndExit(null); |
| } |
| for (int i = 0; i < vargs.size(); i++) { |
| String arg = (String) vargs.get(i); |
| ignoreArg = false; |
| if (addNextAsDocDir) { |
| docDir = arg; |
| addNextAsDocDir = false; |
| } |
| if (addNextAsClasspath) { |
| addNextAsClasspath = false; |
| } |
| if (addNextAsSourcePath) { |
| setSourcepath(arg); |
| addNextAsSourcePath = false; |
| ignoreArg = true; |
| } |
| |
| if (arg.startsWith("@")) { |
| expandAtSignFile(arg.substring(1), currentWorkingDir); |
| } else if (arg.equals("-argfile")) { |
| addNextAsArgFile = true; |
| } else if (addNextAsArgFile) { |
| expandAtSignFile(arg, currentWorkingDir); |
| addNextAsArgFile = false; |
| } else if (arg.equals("-d")) { |
| addNextAsOption = true; |
| options.addElement(arg); |
| addNextAsDocDir = true; |
| } else if (arg.equals("-bootclasspath")) { |
| addNextAsOption = true; |
| addNextToAJCOptions = true; |
| options.addElement(arg); |
| ajcOptions.addElement(arg); |
| } else if (arg.equals("-source")) { |
| addNextAsOption = true; |
| addNextToAJCOptions = true; |
| addNextAsClasspath = true; |
| options.addElement(arg); |
| ajcOptions.addElement(arg); |
| } else if (arg.equals("-classpath")) { |
| addNextAsOption = true; |
| addNextToAJCOptions = true; |
| addNextAsClasspath = true; |
| options.addElement(arg); |
| ajcOptions.addElement(arg); |
| } else if (arg.equals("-encoding")) { |
| addNextAsOption = true; |
| addNextToAJCOptions = false; |
| options.addElement(arg); |
| } else if (arg.equals("-docencoding")) { |
| addNextAsOption = true; |
| addNextToAJCOptions = false; |
| options.addElement(arg); |
| } else if (arg.equals("-charset")) { |
| addNextAsOption = true; |
| addNextToAJCOptions = false; |
| options.addElement(arg); |
| } else if (arg.equals("-sourcepath")) { |
| addNextAsSourcePath = true; |
| // options.addElement( arg ); |
| // ajcOptions.addElement( arg ); |
| } else if (arg.equals("-link")) { |
| addNextAsOption = true; |
| options.addElement(arg); |
| } else if (arg.equals("-bottom")) { |
| addNextAsOption = true; |
| options.addElement(arg); |
| } else if (arg.equals("-windowtitle")) { |
| addNextAsOption = true; |
| options.addElement(arg); |
| } else if (arg.equals("-XajdocDebug")) { |
| deleteTempFilesOnExit = false; |
| } else if (arg.equals("-use")) { |
| System.out.println("> Ignoring unsupported option: -use"); |
| } else if (arg.equals("-splitindex")) { |
| // passed to javadoc |
| } else if (arg.startsWith("-") || addNextAsOption || addNextToAJCOptions) { |
| if (arg.equals("-private")) { |
| docModifier = "private"; |
| } else if (arg.equals("-package")) { |
| docModifier = "package"; |
| } else if (arg.equals("-protected")) { |
| docModifier = "protected"; |
| } else if (arg.equals("-public")) { |
| docModifier = "public"; |
| } else if (arg.equals("-verbose")) { |
| verboseMode = true; |
| } else if (arg.equals("-author")) { |
| authorStandardDocletSwitch = true; |
| } else if (arg.equals("-version")) { |
| versionStandardDocletSwitch = true; |
| } else if (arg.equals("-v")) { |
| System.out.println(getVersion()); |
| exit(0); |
| } else if (arg.equals("-help")) { |
| displayHelpAndExit(null); |
| } else if (arg.equals("-doclet") || arg.equals("-docletpath")) { |
| System.out.println("The doclet and docletpath options are not currently supported \n" |
| + "since ajdoc makes assumptions about the behavior of the standard \n" |
| + "doclet. If you would find this option useful please email us at: \n" |
| + " \n" |
| + " aspectj-dev@eclipse.org \n" |
| + " \n"); |
| exit(0); |
| } else if (arg.equals("-nonavbar") || arg.equals("-noindex")) { |
| // pass through |
| // System.err.println("> ignoring unsupported option: " + arg); |
| } else if (addNextToAJCOptions || addNextAsOption) { |
| // deal with these two options together even though effectively |
| // just falling through if addNextAsOption is true. Otherwise |
| // will have to ensure check "addNextToAJCOptions" before |
| // "addNextAsOption" so as the options are added to the |
| // correct lists. |
| if (addNextToAJCOptions) { |
| ajcOptions.addElement(arg); |
| if (!arg.startsWith("-")) { |
| addNextToAJCOptions = false; |
| } |
| if (!addNextAsOption) { |
| continue; |
| } |
| } |
| } else if (arg.startsWith("-")) { |
| ajcOptions.addElement(arg); |
| addNextToAJCOptions = true; |
| continue; |
| } else { |
| System.err.println("> unrecognized argument: " + arg); |
| displayHelpAndExit(null); |
| } |
| options.addElement(arg); |
| addNextAsOption = false; |
| } else { |
| // check if this is a file or a package |
| // System.err.println(">>>>>>>> " + ); |
| // String entryName = arg.substring(arg.lastIndexOf(File.separator)+1); |
| if (FileUtil.hasSourceSuffix(arg) || arg.endsWith(".lst") && arg != null) { |
| File f = new File(arg); |
| if (f.isAbsolute()) { |
| filenames.addElement(arg); |
| } else { |
| filenames.addElement(currentWorkingDir + Config.DIR_SEP_CHAR + arg); |
| } |
| fileList.addElement(arg); |
| } |
| |
| // PACKAGE MODE STUFF |
| else if (!ignoreArg) { |
| |
| packageMode = true; |
| packageList.addElement(arg); |
| arg = arg.replace('.', '/'); // !!! |
| |
| // do this for every item in the classpath |
| for (int c = 0; c < sourcepath.size(); c++) { |
| String path = sourcepath.elementAt(c) + Config.DIR_SEP_CHAR + arg; |
| File pkg = new File(path); |
| if (pkg.isDirectory()) { |
| String[] files = pkg.list(new FilenameFilter() { |
| @Override |
| public boolean accept(File dir, String name) { |
| int index1 = name.lastIndexOf("."); |
| int index2 = name.length(); |
| if ((index1 >= 0 && index2 >= 0) |
| && (name.substring(index1, index2).equals(".java") || name.substring(index1, index2) |
| .equals(".aj"))) { |
| return true; |
| } else { |
| return false; |
| } |
| } |
| }); |
| for (int j = 0; j < files.length; j++) { |
| filenames.addElement(sourcepath.elementAt(c) + Config.DIR_SEP_CHAR + arg |
| + Config.DIR_SEP_CHAR + files[j]); |
| } |
| } else if (c == sourcepath.size()) { // last element on classpath |
| System.out.println("ajdoc: No package, class, or source file " + "found named " + arg + "."); |
| } else { |
| // didn't find it on that element of the classpath but that's ok |
| } |
| } |
| } |
| } |
| } |
| // set the default visibility as an option to javadoc option |
| if (!options.contains("-private") && !options.contains("-package") && !options.contains("-protected") |
| && !options.contains("-public")) { |
| options.addElement("-package"); |
| } |
| } |
| |
| static void expandAtSignFile(String filename, File currentWorkingDir) { |
| List<String> result = new LinkedList<String>(); |
| |
| File atFile = qualifiedFile(filename, currentWorkingDir); |
| String atFileParent = atFile.getParent(); |
| File myWorkingDir = null; |
| if (atFileParent != null) |
| myWorkingDir = new File(atFileParent); |
| |
| try { |
| BufferedReader stream = new BufferedReader(new FileReader(atFile)); |
| String line = null; |
| while ((line = stream.readLine()) != null) { |
| // strip out any comments of the form # to end of line |
| int commentStart = line.indexOf("//"); |
| if (commentStart != -1) { |
| line = line.substring(0, commentStart); |
| } |
| |
| // remove extra whitespace that might have crept in |
| line = line.trim(); |
| // ignore blank lines |
| if (line.length() == 0) |
| continue; |
| result.add(line); |
| } |
| stream.close(); |
| } catch (IOException e) { |
| System.err.println("Error while reading the @ file " + atFile.getPath() + ".\n" + e); |
| System.exit(-1); |
| } |
| |
| parseArgs(result, myWorkingDir); |
| } |
| |
| static File qualifiedFile(String name, File currentWorkingDir) { |
| name = name.replace('/', File.separatorChar); |
| File file = new File(name); |
| if (!file.isAbsolute() && currentWorkingDir != null) { |
| file = new File(currentWorkingDir, name); |
| } |
| return file; |
| } |
| |
| static void displayHelpAndExit(String message) { |
| shownAjdocUsageMessage = true; |
| if (message != null) { |
| System.err.println(message); |
| System.err.println(); |
| System.err.println(Config.USAGE); |
| } else { |
| System.out.println(Config.USAGE); |
| exit(0); |
| } |
| } |
| |
| static protected void exit(int value) { |
| System.out.flush(); |
| System.err.flush(); |
| System.exit(value); |
| } |
| |
| /* This section of code handles errors that occur during compilation */ |
| static final String internalErrorMessage = " \n" |
| + "If this has not already been logged as a bug raised please raise \n" |
| + "a new AspectJ bug at https://bugs.eclipse.org/bugs including the \n" |
| + "text below. To make the bug a priority, please also include a test\n" |
| + "program that can reproduce this problem.\n "; |
| |
| static public void handleInternalError(Throwable uncaughtThrowable) { |
| System.err.println("An internal error occured in ajdoc"); |
| System.err.println(internalErrorMessage); |
| System.err.println(uncaughtThrowable.toString()); |
| uncaughtThrowable.printStackTrace(); |
| System.err.println(); |
| } |
| |
| static String getVersion() { |
| return "ajdoc version " + Version.getText(); |
| } |
| |
| public static boolean hasAborted() { |
| return aborted; |
| } |
| |
| public static IMessage[] getErrors() { |
| return errors; |
| } |
| |
| public static boolean hasShownAjdocUsageMessage() { |
| return shownAjdocUsageMessage; |
| } |
| |
| /** |
| * Sets the output working dir to be <fullyQualifiedOutputDir>\ajdocworkingdir Useful in testing to redirect the ajdocworkingdir |
| * to the sandbox |
| */ |
| public static void setOutputWorkingDir(String fullyQulifiedOutputDir) { |
| if (fullyQulifiedOutputDir == null) { |
| resetOutputWorkingDir(); |
| } else { |
| outputWorkingDir = fullyQulifiedOutputDir + File.separatorChar + Config.WORKING_DIR; |
| } |
| } |
| |
| /** |
| * Resets the output working dir to be the default which is <the current directory>\ajdocworkingdir |
| */ |
| public static void resetOutputWorkingDir() { |
| outputWorkingDir = Config.WORKING_DIR; |
| } |
| } |