/****************************************************************************** * Copyright (c) 2005 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation ****************************************************************************/ package org.eclipse.gmf.runtime.doclet; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.text.Collator; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.TreeSet; import org.eclipse.gmf.runtime.doclet.proxies.ProxyFactory; import org.eclipse.gmf.runtime.doclet.utils.AliasRegistry; import org.eclipse.gmf.runtime.doclet.utils.MapsGenerator; import org.eclipse.gmf.runtime.doclet.utils.NamespaceChecker; import com.sun.javadoc.ClassDoc; import com.sun.javadoc.DocErrorReporter; import com.sun.javadoc.PackageDoc; import com.sun.javadoc.RootDoc; import com.sun.tools.doclets.standard.Standard; /** * Main entry point of the Aurora doclet, this doclet offers support for the * special namespace-based accessibility rules and generates Eclipse TOC for * exported packages */ public class AuroraDoclet extends Standard { private static final String CMDLINE_OPTION_CLIENT_CONTEXT = "-clientContext"; //$NON-NLS-1$ private static final String CMDLINE_OPTION_NAMESPACE_ALIAS = "-namespaceAlias"; //$NON-NLS-1$ private static final String CMDLINE_OPTION_NAMESPACE_ALIASES = "-namespaceAliases"; //$NON-NLS-1$ private static final String CMDLINE_OPTION_TOC_FILENAME = "-tocFilename"; //$NON-NLS-1$ private static final String CMDLINE_OPTION_TOC_REF_PREFIX = "-tocRefPrefix"; //$NON-NLS-1$ private static final String CMDLINE_OPTION_TOC_TITLE = "-tocTitle"; //$NON-NLS-1$ private static final String CMDLINE_OPTION_TOC_LINK_TO = "-tocLinkTo"; //$NON-NLS-1$ private static String clientContext = ""; //$NON-NLS-1$ private static NamespaceChecker namespaceChecker = null; private static AliasRegistry aliasRegistry = null; private static File tocFile = null; private static String tocRefPrefix = "reference/api/"; //$NON-NLS-1$ private static String tocTitle = ""; //$NON-NLS-1$ private static String tocLinkTo = ""; //$NON-NLS-1$ public static boolean start(RootDoc root) throws IOException { readOptions(root.options(), root); RootDoc rootDocProxy = getRootDocProxy(root); boolean startRet = Standard.start(rootDocProxy); outputToc(rootDocProxy); return startRet; } public static int optionLength(String option) { if (option.equals(CMDLINE_OPTION_CLIENT_CONTEXT)) { return 2; } if (option.equals(CMDLINE_OPTION_NAMESPACE_ALIAS)) { return 2; } if (option.equals(CMDLINE_OPTION_NAMESPACE_ALIASES)) { return 2; } if (option.equals(CMDLINE_OPTION_TOC_FILENAME)) { return 2; } if (option.equals(CMDLINE_OPTION_TOC_REF_PREFIX)) { return 2; } if (option.equals(CMDLINE_OPTION_TOC_TITLE)) { return 2; } if (option.equals(CMDLINE_OPTION_TOC_LINK_TO)) { return 2; } return Standard.optionLength(option); } public static boolean validOptions(String options[][], DocErrorReporter reporter) throws IOException { boolean foundClientContextOption = false; for (int i = 0; i < options.length; i++) { String[] opt = options[i]; if (opt[0].equals(CMDLINE_OPTION_CLIENT_CONTEXT)) { if (foundClientContextOption) { reporter .printError("Only one " + CMDLINE_OPTION_CLIENT_CONTEXT + " option allowed."); //$NON-NLS-1$ //$NON-NLS-2$ return false; } else { foundClientContextOption = true; } } else if (opt[0].equals(CMDLINE_OPTION_NAMESPACE_ALIAS)) { String arg = opt[1]; int equalPos = arg.indexOf('='); if (equalPos <= 0 || equalPos >= arg.length() - 2) { reporter .printError("Invalid " + CMDLINE_OPTION_NAMESPACE_ALIAS + ": " + arg); //$NON-NLS-1$ //$NON-NLS-2$ return false; } } else if (opt[0].equals(CMDLINE_OPTION_NAMESPACE_ALIASES)) { String arg = opt[1]; File file = new File(arg); if (!file.exists()) { reporter .printError("No such file in " + CMDLINE_OPTION_NAMESPACE_ALIASES + ": " + arg); //$NON-NLS-1$ //$NON-NLS-2$ return false; } } else if (opt[0].equals(CMDLINE_OPTION_TOC_FILENAME)) { String arg = opt[1]; if (arg == null || arg.length() == 0) { reporter .printError("Unable to create TOC file: \"" + arg + "\""); //$NON-NLS-1$ //$NON-NLS-2$ return false; } else { File file = new File(arg); if (file.isDirectory()) { reporter .printError("Unable to create TOC file: \"" + arg + "\" is a directory"); //$NON-NLS-1$ //$NON-NLS-2$ return false; } } } else if (opt[0].equals(CMDLINE_OPTION_TOC_REF_PREFIX)) { String arg = opt[1]; if (arg == null || arg.length() == 0) { reporter .printError("Invalid " + CMDLINE_OPTION_TOC_REF_PREFIX + ": " + arg); //$NON-NLS-1$ //$NON-NLS-2$ return false; } } else if (opt[0].equals(CMDLINE_OPTION_TOC_TITLE)) { String arg = opt[1]; if (arg == null || arg.length() == 0) { reporter .printError("Invalid " + CMDLINE_OPTION_TOC_TITLE + ": " + arg); //$NON-NLS-1$ //$NON-NLS-2$ return false; } } } return Standard.validOptions(options, reporter); } private static void readOptions(String[][] options, DocErrorReporter reporter) { aliasRegistry = new AliasRegistry(); for (int i = 0; i < options.length; i++) { String[] opt = options[i]; if (opt[0].equals(CMDLINE_OPTION_CLIENT_CONTEXT)) { clientContext = opt[1]; } else if (opt[0].equals(CMDLINE_OPTION_NAMESPACE_ALIAS)) { String arg = opt[1]; int equalPos = arg.indexOf('='); if (equalPos > 0 && equalPos < arg.length() - 2) { String alias = arg.substring(0, equalPos); String value = arg.substring(equalPos + 1); aliasRegistry.registerAlias(alias, value); } } else if (opt[0].equals(CMDLINE_OPTION_NAMESPACE_ALIASES)) { readNamespaceAliases(opt[1], reporter); } else if (opt[0].equals(CMDLINE_OPTION_TOC_FILENAME)) { String arg = opt[1]; File file = new File(arg); try { file.delete(); if (file.createNewFile()) { tocFile = file; reporter .printNotice("TOC Pathname: " + file.getAbsolutePath()); //$NON-NLS-1$ } } catch (IOException e) { reporter .printError("Could not create TOC file: \"" + arg + "\""); //$NON-NLS-1$ //$NON-NLS-2$ } } else if (opt[0].equals(CMDLINE_OPTION_TOC_REF_PREFIX)) { tocRefPrefix = opt[1]; reporter.printNotice("TOC REF Prefix: " + tocRefPrefix); //$NON-NLS-1$ } else if (opt[0].equals(CMDLINE_OPTION_TOC_TITLE)) { tocTitle = opt[1]; reporter.printNotice("TOC Title: " + tocTitle); //$NON-NLS-1$ } else if (opt[0].equals(CMDLINE_OPTION_TOC_LINK_TO)) { tocLinkTo = opt[1].trim(); reporter.printNotice("TOC Link To: " + tocLinkTo); //$NON-NLS-1$ } } /* Check for alias for the client context */ String aliasValue = getAliasRegistry().getAliasValue(clientContext); if (aliasValue != null) { clientContext = aliasValue; } } private static void readNamespaceAliases(String fileName, DocErrorReporter reporter) { Properties namespaceAliases = new Properties(); try { FileInputStream fis = new FileInputStream(fileName); namespaceAliases.load(fis); fis.close(); for (Iterator iter = namespaceAliases.entrySet().iterator(); iter .hasNext();) { Map.Entry next = (Map.Entry) iter.next(); aliasRegistry.registerAlias((String) next.getKey(), (String) next.getValue()); } } catch (IOException e) { reporter .printError("Could not read namespace aliases from " + fileName //$NON-NLS-1$ + ": " + e.getLocalizedMessage()); //$NON-NLS-1$ } } public static NamespaceChecker getNamespaceChecker() { return namespaceChecker; } public static AliasRegistry getAliasRegistry() { return aliasRegistry; } private static RootDoc getRootDocProxy(RootDoc root) { MapsGenerator mapGenerator = new MapsGenerator(root, getAliasRegistry()); namespaceChecker = new NamespaceChecker(clientContext, mapGenerator .getCanBeSeeByMap()); RootDoc retRootDoc = ProxyFactory.getInstance() .createRootDocProxy(root); // printOptions(retRootDoc.options()); return retRootDoc; } private static void outputToc(RootDoc rootDoc) { if (tocFile == null) return; try { FileOutputStream fos = new FileOutputStream(tocFile); PrintWriter pw = new PrintWriter(fos); pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$ pw.println("<?NLS TYPE=\"org.eclipse.help.toc\"?>"); //$NON-NLS-1$ pw.println(); String linkToText = ""; //$NON-NLS-1$ if (tocLinkTo.length() > 0) { linkToText = " link_to=\"" + tocLinkTo + "\""; //$NON-NLS-1$ //$NON-NLS-2$ } String tocText = "<toc" + linkToText + " label=\"" + tocTitle + "\" href=\"" + tocRefPrefix + "overview-summary.html\">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ pw.println(tocText); pw.println("\t<topic label=\"" + tocTitle + "\" href=\"" + tocRefPrefix + "overview-summary.html\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ /* Gather list of packages and sort by name */ TreeSet treeSet = new TreeSet(Collator.getInstance()); ClassDoc classDocs[] = rootDoc.classes(); if (classDocs != null) { for (int i = 0; i < classDocs.length; i++) { ClassDoc classDoc = classDocs[i]; PackageDoc packageDoc = classDoc.containingPackage(); if (packageDoc != null) { treeSet.add(packageDoc.name()); } } } /* Iterate over each package name and output a topic entry */ for (Iterator iter = treeSet.iterator(); iter.hasNext();) { String packageName = (String) iter.next(); String packagePath = packageName.replace('.', '/'); pw .println("\t\t<topic label=\"" + packageName + "\" href=\"" + tocRefPrefix + packagePath + "/package-summary.html\" />"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } pw.println("\t</topic>"); //$NON-NLS-1$ pw.println("</toc>"); //$NON-NLS-1$ pw.close(); } catch (FileNotFoundException e) { rootDoc .printError("Cannot find tocFile: " + tocFile.getAbsolutePath()); //$NON-NLS-1$ } } // private static void printOptions(String options[][]) { // System.out.println(); // System.out // .println("************************* START Options // ***************************"); //$NON-NLS-1$ // System.out.println(); // for (int i = 0; i < options.length; i++) { // String[] opt = options[i]; // for (int j = 0; j < opt.length; j++) { // String string = opt[j]; // System.out.print(string + " "); //$NON-NLS-1$ // } // System.out.println(); // } // System.out.println(); // System.out // .println("************************* END Options // ***************************"); //$NON-NLS-1$ // System.out.println(); // } }