# HG changeset patch # User jjg # Date 1353049644 28800 # Node ID 2e7bab0639b88b0834651af3dedf02e56c6dc59b # Parent d71d992cb90580165809c544d48d378c06da6373 6493690: javadoc should have a javax.tools.Tool service provider installed in tools.jar Reviewed-by: darcy diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Thu Nov 15 23:07:24 2012 -0800 @@ -517,9 +517,14 @@ */ @Override public JavaFileManager getFileManager() { - if (root instanceof com.sun.tools.javadoc.RootDocImpl) - return ((com.sun.tools.javadoc.RootDocImpl)root).getFileManager(); - else - return new JavacFileManager(new Context(), false, null); + if (fileManager == null) { + if (root instanceof com.sun.tools.javadoc.RootDocImpl) + fileManager = ((com.sun.tools.javadoc.RootDocImpl)root).getFileManager(); + else + fileManager = new JavacFileManager(new Context(), false, null); + } + return fileManager; } + + private JavaFileManager fileManager; } diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Thu Nov 15 23:07:24 2012 -0800 @@ -78,7 +78,7 @@ /** * This is true if option "-serialwarn" is used. Defualt value is false to - * supress excessive warnings about serial tag. + * suppress excessive warnings about serial tag. */ public boolean serialwarn = false; @@ -446,7 +446,7 @@ /** * Initialize the taglet manager. The strings to initialize the simple custom tags should * be in the following format: "[tag name]:[location str]:[heading]". - * @param customTagStrs the set two dimentional arrays of strings. These arrays contain + * @param customTagStrs the set two dimensional arrays of strings. These arrays contain * either -tag or -taglet arguments. */ private void initTagletManager(Set customTagStrs) { @@ -457,11 +457,11 @@ for (Iterator it = customTagStrs.iterator(); it.hasNext(); ) { args = it.next(); if (args[0].equals("-taglet")) { - tagletManager.addCustomTag(args[1], tagletpath); + tagletManager.addCustomTag(args[1], getFileManager(), tagletpath); continue; } String[] tokens = tokenize(args[1], - TagletManager.SIMPLE_TAGLET_OPT_SEPERATOR, 3); + TagletManager.SIMPLE_TAGLET_OPT_SEPARATOR, 3); if (tokens.length == 1) { String tagName = args[1]; if (tagletManager.isKnownCustomTag(tagName)) { diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java Thu Nov 15 23:07:24 2012 -0800 @@ -30,6 +30,9 @@ import java.net.*; import java.util.*; +import javax.tools.DocumentationTool; +import javax.tools.JavaFileManager; + import com.sun.javadoc.*; import com.sun.tools.doclets.internal.toolkit.util.*; @@ -48,16 +51,16 @@ public class TagletManager { /** - * The default seperator for the simple tag option. + * The default separator for the simple tag option. */ - public static final char SIMPLE_TAGLET_OPT_SEPERATOR = ':'; + public static final char SIMPLE_TAGLET_OPT_SEPARATOR = ':'; /** - * The alternate seperator for simple tag options. Use this - * with you want the default seperator to be in the name of the + * The alternate separator for simple tag options. Use this + * when you want the default separator to be in the name of the * custom tag. */ - public static final String ALT_SIMPLE_TAGLET_OPT_SEPERATOR = "-"; + public static final String ALT_SIMPLE_TAGLET_OPT_SEPARATOR = "-"; /** * The map of custom tags. @@ -200,18 +203,24 @@ * @param classname the name of the class representing the custom tag. * @param tagletPath the path to the class representing the custom tag. */ - public void addCustomTag(String classname, String tagletPath) { + public void addCustomTag(String classname, JavaFileManager fileManager, String tagletPath) { try { Class customTagClass = null; // construct class loader String cpString = null; // make sure env.class.path defaults to dot - // do prepends to get correct ordering - cpString = appendPath(System.getProperty("env.class.path"), cpString); - cpString = appendPath(System.getProperty("java.class.path"), cpString); - cpString = appendPath(tagletPath, cpString); - URLClassLoader appClassLoader = new URLClassLoader(pathToURLs(cpString)); - customTagClass = appClassLoader.loadClass(classname); + ClassLoader tagClassLoader; + if (fileManager != null && fileManager.hasLocation(DocumentationTool.Location.TAGLET_PATH)) { + tagClassLoader = fileManager.getClassLoader(DocumentationTool.Location.TAGLET_PATH); + } else { + // do prepends to get correct ordering + cpString = appendPath(System.getProperty("env.class.path"), cpString); + cpString = appendPath(System.getProperty("java.class.path"), cpString); + cpString = appendPath(tagletPath, cpString); + tagClassLoader = new URLClassLoader(pathToURLs(cpString)); + } + + customTagClass = tagClassLoader.loadClass(classname); Method meth = customTagClass.getMethod("register", new Class[] {java.util.Map.class}); Object[] list = customTags.values().toArray(); diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java Thu Nov 15 23:07:24 2012 -0800 @@ -25,10 +25,14 @@ package com.sun.tools.doclets.internal.toolkit.util; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; @@ -36,10 +40,6 @@ import javax.tools.StandardLocation; import com.sun.tools.doclets.internal.toolkit.Configuration; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; /** * Abstraction for handling files, which may be specified directly @@ -115,7 +115,8 @@ /** * Open an output stream for the file. * The file must have been created with a location of - * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path. + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} + * and a corresponding relative path. */ public abstract OutputStream openOutputStream() throws IOException, UnsupportedEncodingException; @@ -123,7 +124,7 @@ * Open an writer for the file, using the encoding (if any) given in the * doclet configuration. * The file must have been created with a location of - * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path. + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path. */ public abstract Writer openWriter() throws IOException, UnsupportedEncodingException; @@ -251,7 +252,8 @@ /** * Resolve a relative file against the given output location. - * @param locn Currently, only SOURCE_OUTPUT is supported. + * @param locn Currently, only + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} is supported. */ - public abstract DocFile resolveAgainst(StandardLocation locn); + public abstract DocFile resolveAgainst(Location locn); } diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java Thu Nov 15 23:07:24 2012 -0800 @@ -69,6 +69,7 @@ throw new IllegalStateException(t); } } + factories.put(configuration, f); } return f; } diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java Thu Nov 15 23:07:24 2012 -0800 @@ -30,7 +30,7 @@ import java.util.HashMap; import java.util.Map; -import javax.tools.StandardLocation; +import javax.tools.DocumentationTool; import com.sun.javadoc.*; import com.sun.tools.doclets.internal.toolkit.*; @@ -253,7 +253,7 @@ throws Fault { DocFile file = pkgListPath.resolve(DocPaths.PACKAGE_LIST); if (! (file.isAbsolute() || linkoffline)){ - file = file.resolveAgainst(StandardLocation.CLASS_OUTPUT); + file = file.resolveAgainst(DocumentationTool.Location.DOCUMENTATION_OUTPUT); } try { if (file.exists() && file.canRead()) { diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java Thu Nov 15 23:07:24 2012 -0800 @@ -42,6 +42,7 @@ import java.util.List; import java.util.Set; +import javax.tools.DocumentationTool; import javax.tools.FileObject; import javax.tools.JavaFileManager.Location; import javax.tools.JavaFileObject; @@ -70,17 +71,17 @@ fileManager = (PathFileManager) configuration.getFileManager(); if (!configuration.destDirName.isEmpty() - || !fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) { + || !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) { try { String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName; Path dir = fileManager.getDefaultFileSystem().getPath(dirName); - fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(dir)); + fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir)); } catch (IOException e) { throw new DocletAbortException(); } } - destDir = fileManager.getLocation(StandardLocation.CLASS_OUTPUT).iterator().next(); + destDir = fileManager.getLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next(); } public DocFile createFileForDirectory(String file) { @@ -92,7 +93,7 @@ } public DocFile createFileForOutput(DocPath path) { - return new StandardDocFile(StandardLocation.CLASS_OUTPUT, path); + return new StandardDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path); } @Override @@ -137,10 +138,10 @@ /** * Open an output stream for the file. * The file must have been created with a location of - * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path. + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path. */ public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException { - if (location != StandardLocation.CLASS_OUTPUT) + if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalStateException(); OutputStream out = getFileObjectForOutput(path).openOutputStream(); @@ -151,10 +152,10 @@ * Open an writer for the file, using the encoding (if any) given in the * doclet configuration. * The file must have been created with a location of - * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path. + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path. */ public Writer openWriter() throws IOException, UnsupportedEncodingException { - if (location != StandardLocation.CLASS_OUTPUT) + if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalStateException(); OutputStream out = getFileObjectForOutput(path).openOutputStream(); @@ -262,10 +263,11 @@ /** * Resolve a relative file against the given output location. - * @param locn Currently, only SOURCE_OUTPUT is supported. + * @param locn Currently, only + * {@link DocumentationTool.Location.DOCUMENTATION_OUTPUT} is supported. */ - public DocFile resolveAgainst(StandardLocation locn) { - if (locn != StandardLocation.CLASS_OUTPUT) + public DocFile resolveAgainst(Location locn) { + if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalArgumentException(); return new StandardDocFile(destDir.resolve(file)); } diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SimpleDocFileFactory.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SimpleDocFileFactory.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SimpleDocFileFactory.java Thu Nov 15 23:07:24 2012 -0800 @@ -43,6 +43,7 @@ import java.util.List; import java.util.Set; +import javax.tools.DocumentationTool; import javax.tools.JavaFileManager.Location; import javax.tools.StandardLocation; @@ -74,7 +75,7 @@ } public DocFile createFileForOutput(DocPath path) { - return new SimpleDocFile(StandardLocation.CLASS_OUTPUT, path); + return new SimpleDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path); } @Override @@ -121,10 +122,10 @@ /** * Open an output stream for the file. * The file must have been created with a location of - * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path. + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path. */ public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException { - if (location != StandardLocation.CLASS_OUTPUT) + if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalStateException(); createDirectoryForFile(file); @@ -135,10 +136,10 @@ * Open an writer for the file, using the encoding (if any) given in the * doclet configuration. * The file must have been created with a location of - * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path. + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path. */ public Writer openWriter() throws IOException, UnsupportedEncodingException { - if (location != StandardLocation.CLASS_OUTPUT) + if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalStateException(); createDirectoryForFile(file); @@ -243,10 +244,11 @@ /** * Resolve a relative file against the given output location. - * @param locn Currently, only SOURCE_OUTPUT is supported. + * @param locn Currently, only + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} is supported. */ - public DocFile resolveAgainst(StandardLocation locn) { - if (locn != StandardLocation.CLASS_OUTPUT) + public DocFile resolveAgainst(Location locn) { + if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalArgumentException(); return new SimpleDocFile( new File(configuration.destDirName, file.getPath())); diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/StandardDocFileFactory.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/StandardDocFileFactory.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/StandardDocFileFactory.java Thu Nov 15 23:07:24 2012 -0800 @@ -41,6 +41,7 @@ import java.util.List; import java.util.Set; +import javax.tools.DocumentationTool; import javax.tools.FileObject; import javax.tools.JavaFileManager.Location; import javax.tools.JavaFileObject; @@ -62,24 +63,29 @@ */ class StandardDocFileFactory extends DocFileFactory { private final StandardJavaFileManager fileManager; - private final File destDir; + private File destDir; public StandardDocFileFactory(Configuration configuration) { super(configuration); fileManager = (StandardJavaFileManager) configuration.getFileManager(); + } - if (!configuration.destDirName.isEmpty() - || !fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) { - try { - String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName; - File dir = new File(dirName); - fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(dir)); - } catch (IOException e) { - throw new DocletAbortException(); + private File getDestDir() { + if (destDir == null) { + if (!configuration.destDirName.isEmpty() + || !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) { + try { + String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName; + File dir = new File(dirName); + fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir)); + } catch (IOException e) { + throw new DocletAbortException(); + } } + + destDir = fileManager.getLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next(); } - - destDir = fileManager.getLocation(StandardLocation.CLASS_OUTPUT).iterator().next(); + return destDir; } public DocFile createFileForDirectory(String file) { @@ -91,7 +97,7 @@ } public DocFile createFileForOutput(DocPath path) { - return new StandardDocFile(StandardLocation.CLASS_OUTPUT, path); + return new StandardDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path); } @Override @@ -100,13 +106,13 @@ throw new IllegalArgumentException(); Set files = new LinkedHashSet(); - if (fileManager.hasLocation(location)) { - for (File f: fileManager.getLocation(location)) { - if (f.isDirectory()) { - f = new File(f, path.getPath()); - if (f.exists()) - files.add(new StandardDocFile(f)); - } + Location l = fileManager.hasLocation(StandardLocation.SOURCE_PATH) + ? StandardLocation.SOURCE_PATH : StandardLocation.CLASS_PATH; + for (File f: fileManager.getLocation(l)) { + if (f.isDirectory()) { + f = new File(f, path.getPath()); + if (f.exists()) + files.add(new StandardDocFile(f)); } } return files; @@ -129,8 +135,8 @@ /** Create a StandardDocFile for a given location and relative path. */ private StandardDocFile(Location location, DocPath path) { super(configuration, location, path); - Assert.check(location == StandardLocation.CLASS_OUTPUT); - this.file = newFile(destDir, path.getPath()); + Assert.check(location == DocumentationTool.Location.DOCUMENTATION_OUTPUT); + this.file = newFile(getDestDir(), path.getPath()); } /** Open an input stream for the file. */ @@ -142,10 +148,10 @@ /** * Open an output stream for the file. * The file must have been created with a location of - * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path. + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path. */ public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException { - if (location != StandardLocation.CLASS_OUTPUT) + if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalStateException(); OutputStream out = getFileObjectForOutput(path).openOutputStream(); @@ -156,10 +162,10 @@ * Open an writer for the file, using the encoding (if any) given in the * doclet configuration. * The file must have been created with a location of - * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path. + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path. */ public Writer openWriter() throws IOException, UnsupportedEncodingException { - if (location != StandardLocation.CLASS_OUTPUT) + if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalStateException(); OutputStream out = getFileObjectForOutput(path).openOutputStream(); @@ -263,12 +269,13 @@ /** * Resolve a relative file against the given output location. - * @param locn Currently, only SOURCE_OUTPUT is supported. + * @param locn Currently, only + * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} is supported. */ - public DocFile resolveAgainst(StandardLocation locn) { - if (locn != StandardLocation.CLASS_OUTPUT) + public DocFile resolveAgainst(Location locn) { + if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT) throw new IllegalArgumentException(); - return new StandardDocFile(newFile(destDir, file.getPath())); + return new StandardDocFile(newFile(getDestDir(), file.getPath())); } /** Return a string to identify the contents of this object, diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java --- a/langtools/src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Thu Nov 15 23:07:24 2012 -0800 @@ -149,7 +149,7 @@ return fo; } - DiagnosticListener wrap(DiagnosticListener dl) { + public DiagnosticListener wrap(DiagnosticListener dl) { if (isTrusted(dl)) return dl; return new WrappedDiagnosticListener(dl); diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Nov 15 23:07:24 2012 -0800 @@ -74,7 +74,7 @@ private List fileObjects; private Map notYetEntered; private ListBuffer> genList; - private AtomicBoolean used = new AtomicBoolean(); + private final AtomicBoolean used = new AtomicBoolean(); private Iterable processors; private Main.Result result = null; @@ -99,11 +99,11 @@ } JavacTaskImpl(Main compilerMain, - Iterable flags, + Iterable args, Context context, Iterable classes, Iterable fileObjects) { - this(compilerMain, toArray(flags), toArray(classes), context, toList(fileObjects)); + this(compilerMain, toArray(args), toArray(classes), context, toList(fileObjects)); } static private String[] toArray(Iterable iter) { diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java --- a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Thu Nov 15 23:07:24 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -253,7 +253,8 @@ for (File f: files) pl.add(f.toPath()); } - pathsForLocation.put(locn, pl); + if (!pl.isEmpty()) + pathsForLocation.put(locn, pl); } private void lazyInitSearchPaths() { @@ -513,7 +514,8 @@ } private static String getRelativePath(String packageName, String relativeName) { - return packageName.replace(".", "/") + relativeName; + return packageName.isEmpty() + ? relativeName : packageName.replace(".", "/") + "/" + relativeName; } private static String getBaseName(String relativePath) { diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Thu Nov 15 23:07:24 2012 -0800 @@ -31,6 +31,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; + import javax.tools.JavaFileObject; import com.sun.tools.javac.api.DiagnosticFormatter; @@ -43,9 +44,8 @@ import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type.CapturedType; +import com.sun.tools.javac.file.BaseFileObject; import com.sun.tools.javac.tree.JCTree.*; - -import com.sun.tools.javac.file.BaseFileObject; import com.sun.tools.javac.tree.Pretty; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*; diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Thu Nov 15 23:07:24 2012 -0800 @@ -32,7 +32,12 @@ import java.net.URL; import java.net.URLClassLoader; +import javax.tools.DocumentationTool; +import javax.tools.JavaFileManager; + import com.sun.javadoc.*; +import com.sun.tools.javac.file.Locations; +import com.sun.tools.javac.util.ClientCodeException; import com.sun.tools.javac.util.List; import static com.sun.javadoc.LanguageVersion.*; @@ -57,6 +62,12 @@ private final Messager messager; + /** + * In API mode, exceptions thrown while calling the doclet are + * propagated using ClientCodeException. + */ + private final boolean apiMode; + private static class DocletInvokeException extends Exception { private static final long serialVersionUID = 0; } @@ -71,24 +82,38 @@ } } - public DocletInvoker(Messager messager, + public DocletInvoker(Messager messager, Class docletClass, boolean apiMode) { + this.messager = messager; + this.docletClass = docletClass; + docletClassName = docletClass.getName(); + appClassLoader = null; + this.apiMode = apiMode; + } + + public DocletInvoker(Messager messager, JavaFileManager fileManager, String docletClassName, String docletPath, - ClassLoader docletParentClassLoader) { + ClassLoader docletParentClassLoader, + boolean apiMode) { this.messager = messager; this.docletClassName = docletClassName; + this.apiMode = apiMode; - // construct class loader - String cpString = null; // make sure env.class.path defaults to dot + if (fileManager != null && fileManager.hasLocation(DocumentationTool.Location.DOCLET_PATH)) { + appClassLoader = fileManager.getClassLoader(DocumentationTool.Location.DOCLET_PATH); + } else { + // construct class loader + String cpString = null; // make sure env.class.path defaults to dot - // do prepends to get correct ordering - cpString = appendPath(System.getProperty("env.class.path"), cpString); - cpString = appendPath(System.getProperty("java.class.path"), cpString); - cpString = appendPath(docletPath, cpString); - URL[] urls = com.sun.tools.javac.file.Locations.pathToURLs(cpString); - if (docletParentClassLoader == null) - appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName)); - else - appClassLoader = new URLClassLoader(urls, docletParentClassLoader); + // do prepends to get correct ordering + cpString = appendPath(System.getProperty("env.class.path"), cpString); + cpString = appendPath(System.getProperty("java.class.path"), cpString); + cpString = appendPath(docletPath, cpString); + URL[] urls = Locations.pathToURLs(cpString); + if (docletParentClassLoader == null) + appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName)); + else + appClassLoader = new URLClassLoader(urls, docletParentClassLoader); + } // attempt to find doclet Class dc = null; @@ -280,7 +305,8 @@ ClassLoader savedCCL = Thread.currentThread().getContextClassLoader(); try { - Thread.currentThread().setContextClassLoader(appClassLoader); + if (appClassLoader != null) // will be null if doclet class provided via API + Thread.currentThread().setContextClassLoader(appClassLoader); return meth.invoke(null , params); } catch (IllegalArgumentException exc) { messager.error(Messager.NOPOS, "main.internal_error_exception_thrown", @@ -296,10 +322,12 @@ throw new DocletInvokeException(); } catch (InvocationTargetException exc) { Throwable err = exc.getTargetException(); + if (apiMode) + throw new ClientCodeException(err); if (err instanceof java.lang.OutOfMemoryError) { messager.error(Messager.NOPOS, "main.out.of.memory"); } else { - messager.error(Messager.NOPOS, "main.exception_thrown", + messager.error(Messager.NOPOS, "main.exception_thrown", docletClassName, methodName, exc.toString()); exc.getTargetException().printStackTrace(); } diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Thu Nov 15 23:07:24 2012 -0800 @@ -119,6 +119,7 @@ ModifierFilter filter, List javaNames, List options, + Iterable fileObjects, boolean breakiterator, List subPackages, List excludedPackages, @@ -140,10 +141,11 @@ ListBuffer packTrees = new ListBuffer(); try { - StandardJavaFileManager fm = (StandardJavaFileManager) docenv.fileManager; + StandardJavaFileManager fm = docenv.fileManager instanceof StandardJavaFileManager + ? (StandardJavaFileManager) docenv.fileManager : null; for (List it = javaNames; it.nonEmpty(); it = it.tail) { String name = it.head; - if (!docClasses && name.endsWith(".java") && new File(name).exists()) { + if (!docClasses && fm != null && name.endsWith(".java") && new File(name).exists()) { JavaFileObject fo = fm.getJavaFileObjects(name).iterator().next(); docenv.notice("main.Loading_source_file", name); JCCompilationUnit tree = parse(fo); @@ -151,11 +153,19 @@ } else if (isValidPackageName(name)) { names = names.append(name); } else if (name.endsWith(".java")) { + if (fm == null) + throw new IllegalArgumentException(); + else docenv.error(null, "main.file_not_found", name); } else { docenv.error(null, "main.illegal_package_name", name); } } + for (JavaFileObject fo: fileObjects) { + docenv.notice("main.Loading_source_file", fo.getName()); + JCCompilationUnit tree = parse(fo); + classTrees.append(tree); + } if (!docClasses) { // Recursively search given subpackages. If any packages diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javadoc/Messager.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java Thu Nov 15 23:07:24 2012 -0800 @@ -33,6 +33,7 @@ import com.sun.javadoc.*; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; import com.sun.tools.javac.util.JavacMessages; import com.sun.tools.javac.util.Log; @@ -174,6 +175,11 @@ * @param msg message to print */ public void printError(SourcePosition pos, String msg) { + if (diagListener != null) { + report(DiagnosticType.ERROR, pos, msg); + return; + } + if (nerrors < MaxErrors) { String prefix = (pos == null) ? programName : pos.toString(); errWriter.println(prefix + ": " + getText("javadoc.error") + " - " + msg); @@ -201,6 +207,11 @@ * @param msg message to print */ public void printWarning(SourcePosition pos, String msg) { + if (diagListener != null) { + report(DiagnosticType.WARNING, pos, msg); + return; + } + if (nwarnings < MaxWarnings) { String prefix = (pos == null) ? programName : pos.toString(); warnWriter.println(prefix + ": " + getText("javadoc.warning") +" - " + msg); @@ -227,6 +238,11 @@ * @param msg message to print */ public void printNotice(SourcePosition pos, String msg) { + if (diagListener != null) { + report(DiagnosticType.NOTE, pos, msg); + return; + } + if (pos == null) noticeWriter.println(msg); else @@ -295,4 +311,22 @@ public void exit() { throw new ExitJavadoc(); } + + private void report(DiagnosticType type, SourcePosition pos, String msg) { + switch (type) { + case ERROR: + case WARNING: + Object prefix = (pos == null) ? programName : pos; + report(javadocDiags.create(type, null, null, "msg", prefix, msg)); + break; + + case NOTE: + String key = (pos == null) ? "msg" : "pos.msg"; + report(javadocDiags.create(type, null, null, key, pos, msg)); + break; + + default: + throw new IllegalArgumentException(type.toString()); + } + } } diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javadoc/Start.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/Start.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/Start.java Thu Nov 15 23:07:24 2012 -0800 @@ -29,9 +29,16 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; import com.sun.javadoc.*; import com.sun.tools.javac.main.CommandLine; +import com.sun.tools.javac.util.ClientCodeException; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; @@ -70,6 +77,12 @@ private DocletInvoker docletInvoker; + /** + * In API mode, exceptions thrown while calling the doclet are + * propagated using ClientCodeException. + */ + private boolean apiMode; + Start(String programName, PrintWriter errWriter, PrintWriter warnWriter, @@ -121,6 +134,7 @@ public Start(Context context) { context.getClass(); // null check this.context = context; + apiMode = true; defaultDocletClassName = standardDocletClassName; docletParentClassLoader = null; @@ -184,15 +198,29 @@ * Main program - external wrapper */ int begin(String... argv) { + boolean ok = begin(null, argv, Collections. emptySet()); + return ok ? 0 : 1; + } + + public boolean begin(Class docletClass, Iterable options, Iterable fileObjects) { + Collection opts = new ArrayList(); + for (String opt: options) opts.add(opt); + return begin(docletClass, opts.toArray(new String[opts.size()]), fileObjects); + } + + private boolean begin(Class docletClass, String[] options, Iterable fileObjects) { boolean failed = false; try { - failed = !parseAndExecute(argv); + failed = !parseAndExecute(docletClass, options, fileObjects); } catch (Messager.ExitJavadoc exc) { // ignore, we just exit this way } catch (OutOfMemoryError ee) { messager.error(Messager.NOPOS, "main.out.of.memory"); failed = true; + } catch (ClientCodeException e) { + // simply rethrow these exceptions, to be caught and handled by JavadocTaskImpl + throw e; } catch (Error ee) { ee.printStackTrace(System.err); messager.error(Messager.NOPOS, "main.fatal.error"); @@ -207,13 +235,16 @@ } failed |= messager.nerrors() > 0; failed |= rejectWarnings && messager.nwarnings() > 0; - return failed ? 1 : 0; + return !failed; } /** * Main program - internal */ - private boolean parseAndExecute(String... argv) throws IOException { + private boolean parseAndExecute( + Class docletClass, + String[] argv, + Iterable fileObjects) throws IOException { long tm = System.currentTimeMillis(); ListBuffer javaNames = new ListBuffer(); @@ -229,7 +260,9 @@ exit(); } - setDocletInvoker(argv); + + JavaFileManager fileManager = context.get(JavaFileManager.class); + setDocletInvoker(docletClass, fileManager, argv); compOpts = Options.instance(context); @@ -287,7 +320,7 @@ } compOpts.notifyListeners(); - if (javaNames.isEmpty() && subPackages.isEmpty()) { + if (javaNames.isEmpty() && subPackages.isEmpty() && isEmpty(fileObjects)) { usageError("main.No_packages_or_classes_specified"); } @@ -310,6 +343,7 @@ showAccess, javaNames.toList(), options.toList(), + fileObjects, breakiterator, subPackages.toList(), excludedPackages.toList(), @@ -334,21 +368,43 @@ return ok; } - private void setDocletInvoker(String[] argv) { + private boolean isEmpty(Iterable iter) { + return !iter.iterator().hasNext(); + } + + /** + * Init the doclet invoker. + * The doclet class may be given explicitly, or via the -doclet option in + * argv. + * If the doclet class is not given explicitly, it will be loaded from + * the file manager's DOCLET_PATH location, if available, or via the + * -doclet path option in argv. + * @param docletClass The doclet class. May be null. + * @param fileManager The file manager used to get the class loader to load + * the doclet class if required. May be null. + * @param argv Args containing -doclet and -docletpath, in case they are required. + */ + private void setDocletInvoker(Class docletClass, JavaFileManager fileManager, String[] argv) { + if (docletClass != null) { + docletInvoker = new DocletInvoker(messager, docletClass, apiMode); + // TODO, check no -doclet, -docletpath + return; + } + String docletClassName = null; String docletPath = null; // Parse doclet specifying arguments for (int i = 0 ; i < argv.length ; i++) { String arg = argv[i]; - if (arg.equals("-doclet")) { + if (arg.equals(ToolOption.DOCLET.opt)) { oneArg(argv, i++); if (docletClassName != null) { usageError("main.more_than_one_doclet_specified_0_and_1", docletClassName, argv[i]); } docletClassName = argv[i]; - } else if (arg.equals("-docletpath")) { + } else if (arg.equals(ToolOption.DOCLETPATH.opt)) { oneArg(argv, i++); if (docletPath == null) { docletPath = argv[i]; @@ -363,9 +419,10 @@ } // attempt to find doclet - docletInvoker = new DocletInvoker(messager, - docletClassName, docletPath, - docletParentClassLoader); + docletInvoker = new DocletInvoker(messager, fileManager, + docletClassName, docletPath, + docletParentClassLoader, + apiMode); } /** diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javadoc/api/JavadocTaskImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/api/JavadocTaskImpl.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.tools.javadoc.api; + +import com.sun.tools.javac.util.ClientCodeException; +import java.util.Locale; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; + +import com.sun.tools.javac.util.Context; +import com.sun.tools.javadoc.Start; +import java.util.Collections; + +/** + * Provides access to functionality specific to the JDK documentation tool, + * javadoc. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice.

+ */ +public class JavadocTaskImpl implements DocumentationTask { + private final AtomicBoolean used = new AtomicBoolean(); + + private final Context context; + private Class docletClass; + private Iterable options; + private Iterable fileObjects; + private Locale locale; + + public JavadocTaskImpl(Context context, Class docletClass, + Iterable options, Iterable fileObjects) { + this.context = context; + this.docletClass = docletClass; + + this.options = (options == null) ? Collections.emptySet() + : nullCheck(options); + this.fileObjects = (fileObjects == null) ? Collections.emptySet() + : nullCheck(fileObjects); + setLocale(Locale.getDefault()); + } + + public void setLocale(Locale locale) { + if (used.get()) + throw new IllegalStateException(); + this.locale = locale; + } + + public Boolean call() { + if (!used.getAndSet(true)) { + initContext(); + Start jdoc = new Start(context); + try { + return jdoc.begin(docletClass, options, fileObjects); + } catch (ClientCodeException e) { + throw new RuntimeException(e.getCause()); + } + } else { + throw new IllegalStateException("multiple calls to method 'call'"); + } + } + + private void initContext() { + //initialize compiler's default locale + context.put(Locale.class, locale); + } + + private static Iterable nullCheck(Iterable items) { + for (T item: items) { + if (item == null) + throw new NullPointerException(); + } + return items; + } +} diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javadoc/api/JavadocTool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/api/JavadocTool.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javadoc.api; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Locale; +import java.util.Set; + +import javax.lang.model.SourceVersion; +import javax.tools.DiagnosticListener; +import javax.tools.DocumentationTool; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; + +import com.sun.tools.javac.api.ClientCodeWrapper; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.util.ClientCodeException; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javadoc.ToolOption; + +/** + * Provides access to functionality specific to the JDK documentation tool, + * javadoc. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice.

+ */ +public class JavadocTool implements DocumentationTool { + @Override + public DocumentationTask getTask( + Writer out, + JavaFileManager fileManager, + DiagnosticListener diagnosticListener, + Class docletClass, + Iterable options, + Iterable compilationUnits) { + Context context = new Context(); + return getTask(out, fileManager, diagnosticListener, + docletClass, options, compilationUnits, context); + } + + public DocumentationTask getTask( + Writer out, + JavaFileManager fileManager, + DiagnosticListener diagnosticListener, + Class docletClass, + Iterable options, + Iterable compilationUnits, + Context context) { + try { + ClientCodeWrapper ccw = ClientCodeWrapper.instance(context); + + if (options != null) { + for (String option : options) + option.getClass(); // null check + } + + if (compilationUnits != null) { + compilationUnits = ccw.wrapJavaFileObjects(compilationUnits); // implicit null check + for (JavaFileObject cu : compilationUnits) { + if (cu.getKind() != JavaFileObject.Kind.SOURCE) { + final String kindMsg = "All compilation units must be of SOURCE kind"; + throw new IllegalArgumentException(kindMsg); + } + } + } + + if (diagnosticListener != null) + context.put(DiagnosticListener.class, ccw.wrap(diagnosticListener)); + + if (out == null) + context.put(Log.outKey, new PrintWriter(System.err, true)); + else if (out instanceof PrintWriter) + context.put(Log.outKey, ((PrintWriter) out)); + else + context.put(Log.outKey, new PrintWriter(out, true)); + + if (fileManager == null) + fileManager = getStandardFileManager(diagnosticListener, null, null); + fileManager = ccw.wrap(fileManager); + context.put(JavaFileManager.class, fileManager); + + return new JavadocTaskImpl(context, docletClass, options, compilationUnits); + } catch (ClientCodeException ex) { + throw new RuntimeException(ex.getCause()); + } + } + + // TODO: used shared static method in JavacFileManager + @Override + public StandardJavaFileManager getStandardFileManager( + DiagnosticListener diagnosticListener, + Locale locale, + Charset charset) { + Context context = new Context(); + context.put(Locale.class, locale); + if (diagnosticListener != null) + context.put(DiagnosticListener.class, diagnosticListener); + PrintWriter pw = (charset == null) + ? new PrintWriter(System.err, true) + : new PrintWriter(new OutputStreamWriter(System.err, charset), true); + context.put(Log.outKey, pw); + return new JavacFileManager(context, true, charset); + } + + @Override + public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) { + PrintWriter err_pw = new PrintWriter(err, true); + PrintWriter out_pw = new PrintWriter(out); + try { + String standardDocletName = "com.sun.tools.doclets.standard.Standard"; + return com.sun.tools.javadoc.Main.execute( + "javadoc", err_pw, err_pw, out_pw, standardDocletName, arguments); + } finally { + err_pw.flush(); + out_pw.flush(); + } + } + + @Override + public Set getSourceVersions() { + return Collections.unmodifiableSet( + EnumSet.range(SourceVersion.RELEASE_3, SourceVersion.latest())); + } + + @Override + public int isSupportedOption(String option) { + if (option == null) + throw new NullPointerException(); + for (ToolOption o: ToolOption.values()) { + if (o.opt.equals(option)) + return o.hasArg ? 1 : 0; + } + return -1; + } + +} diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties --- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Thu Nov 15 23:07:24 2012 -0800 @@ -108,3 +108,8 @@ javadoc.class_not_found=Class {0} not found. javadoc.error=error javadoc.warning=warning + +javadoc.error.msg={0}: error - {1} +javadoc.warning.msg={0}: warning - {1} +javadoc.note.msg = {1} +javadoc.note.pos.msg= {0}: {1} diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/javax/tools/DocumentationTool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/javax/tools/DocumentationTool.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javax.tools; + +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.Locale; +import java.util.concurrent.Callable; + +/** + * Interface to invoke Java™ programming language documentation tools from + * programs. + */ +public interface DocumentationTool extends Tool, OptionChecker { + /** + * Creates a future for a documentation task with the given + * components and arguments. The task might not have + * completed as described in the DocumentationTask interface. + * + *

If a file manager is provided, it must be able to handle all + * locations defined in {@link DocumentationTool.Location}, + * as well as + * {@link StandardLocation#SOURCE_PATH}, + * {@link StandardLocation#CLASS_PATH}, and + * {@link StandardLocation#PLATFORM_CLASS_PATH}. + * + * @param out a Writer for additional output from the tool; + * use {@code System.err} if {@code null} + * + * @param fileManager a file manager; if {@code null} use the + * tool's standard filemanager + * + * @param diagnosticListener a diagnostic listener; if {@code null} + * use the tool's default method for reporting diagnostics + * + * @param docletClass a class providing the necessary methods required + * of a doclet + * + * @param options documentation tool options and doclet options, + * {@code null} means no options + * + * @param compilationUnits the compilation units to compile, {@code + * null} means no compilation units + * + * @return an object representing the compilation + * + * @throws RuntimeException if an unrecoverable error + * occurred in a user supplied component. The + * {@linkplain Throwable#getCause() cause} will be the error in + * user code. + * + * @throws IllegalArgumentException if any of the given + * compilation units are of other kind than + * {@linkplain JavaFileObject.Kind#SOURCE source} + */ + DocumentationTask getTask(Writer out, + JavaFileManager fileManager, + DiagnosticListener diagnosticListener, + Class docletClass, + Iterable options, + Iterable compilationUnits); + + /** + * Gets a new instance of the standard file manager implementation + * for this tool. The file manager will use the given diagnostic + * listener for producing any non-fatal diagnostics. Fatal errors + * will be signaled with the appropriate exceptions. + * + *

The standard file manager will be automatically reopened if + * it is accessed after calls to {@code flush} or {@code close}. + * The standard file manager must be usable with other tools. + * + * @param diagnosticListener a diagnostic listener for non-fatal + * diagnostics; if {@code null} use the compiler's default method + * for reporting diagnostics + * + * @param locale the locale to apply when formatting diagnostics; + * {@code null} means the {@linkplain Locale#getDefault() default locale}. + * + * @param charset the character set used for decoding bytes; if + * {@code null} use the platform default + * + * @return the standard file manager + */ + StandardJavaFileManager getStandardFileManager( + DiagnosticListener diagnosticListener, + Locale locale, + Charset charset); + + /** + * Interface representing a future for a documentation task. The + * task has not yet started. To start the task, call + * the {@linkplain #call call} method. + * + *

Before calling the call method, additional aspects of the + * task can be configured, for example, by calling the + * {@linkplain #setLocale setLocale} method. + */ + interface DocumentationTask extends Callable { + /** + * Set the locale to be applied when formatting diagnostics and + * other localized data. + * + * @param locale the locale to apply; {@code null} means apply no + * locale + * @throws IllegalStateException if the task has started + */ + void setLocale(Locale locale); + + /** + * Performs this documentation task. The task may only + * be performed once. Subsequent calls to this method throw + * IllegalStateException. + * + * @return true if and only all the files were processed without errors; + * false otherwise + * + * @throws RuntimeException if an unrecoverable error occurred + * in a user-supplied component. The + * {@linkplain Throwable#getCause() cause} will be the error + * in user code. + * + * @throws IllegalStateException if called more than once + */ + Boolean call(); + } + + /** + * Locations specific to {@link DocumentationTool}. + * + * @see StandardLocation + */ + enum Location implements JavaFileManager.Location { + /** + * Location of new documentation files. + */ + DOCUMENTATION_OUTPUT, + + /** + * Location to search for doclets. + */ + DOCLET_PATH, + + /** + * Location to search for taglets. + */ + TAGLET_PATH; + + public String getName() { return name(); } + + public boolean isOutputLocation() { + switch (this) { + case DOCUMENTATION_OUTPUT: + return true; + default: + return false; + } + } + } + +} diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/javax/tools/JavaCompiler.java --- a/langtools/src/share/classes/javax/tools/JavaCompiler.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/javax/tools/JavaCompiler.java Thu Nov 15 23:07:24 2012 -0800 @@ -266,7 +266,7 @@ * Gets a new instance of the standard file manager implementation * for this tool. The file manager will use the given diagnostic * listener for producing any non-fatal diagnostics. Fatal errors - * will be signalled with the appropriate exceptions. + * will be signaled with the appropriate exceptions. * *

The standard file manager will be automatically reopened if * it is accessed after calls to {@code flush} or {@code close}. diff -r d71d992cb905 -r 2e7bab0639b8 langtools/src/share/classes/javax/tools/ToolProvider.java --- a/langtools/src/share/classes/javax/tools/ToolProvider.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/src/share/classes/javax/tools/ToolProvider.java Thu Nov 15 23:07:24 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,6 +102,19 @@ return instance().getSystemTool(JavaCompiler.class, defaultJavaCompilerName); } + private static final String defaultDocumentationToolName + = "com.sun.tools.javadoc.api.JavadocTool"; + + /** + * Gets the Java™ programming language documentation tool provided + * with this platform. + * @return the documentation tool provided with this platform or + * {@code null} if no documentation tool is provided + */ + public static DocumentationTool getSystemDocumentationTool() { + return instance().getSystemTool(DocumentationTool.class, defaultDocumentationToolName); + } + /** * Returns the class loader for tools provided with this platform. * This does not include user-installed tools. Use the diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/CheckResourceKeys.java --- a/langtools/test/tools/javadoc/CheckResourceKeys.java Thu Nov 15 19:54:20 2012 -0800 +++ b/langtools/test/tools/javadoc/CheckResourceKeys.java Thu Nov 15 23:07:24 2012 -0800 @@ -167,6 +167,13 @@ results.add("doclet." + s.toLowerCase()); } + // special handling for code strings synthesized in + // com.sun.tools.javadoc.Messager + results.add("javadoc.error.msg"); + results.add("javadoc.note.msg"); + results.add("javadoc.note.pos.msg"); + results.add("javadoc.warning.msg"); + return results; } diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/APITest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/APITest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; + +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; + + +/* + * Superclass with utility methods for API tests. + */ +class APITest { + protected APITest() { } + + /** Marker annotation for test cases. */ + @Retention(RetentionPolicy.RUNTIME) + @interface Test { } + + /** Invoke all methods annotated with @Test. */ + protected void run() throws Exception { + for (Method m: getClass().getDeclaredMethods()) { + Annotation a = m.getAnnotation(Test.class); + if (a != null) { + testCount++; + testName = m.getName(); + System.err.println("test: " + testName); + try { + m.invoke(this, new Object[] { }); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + throw (cause instanceof Exception) ? ((Exception) cause) : e; + } + System.err.println(); + } + } + + if (testCount == 0) + error("no tests found"); + + StringBuilder summary = new StringBuilder(); + if (testCount != 1) + summary.append(testCount).append(" tests"); + if (errorCount > 0) { + if (summary.length() > 0) summary.append(", "); + summary.append(errorCount).append(" errors"); + } + System.err.println(summary); + if (errorCount > 0) + throw new Exception(errorCount + " errors found"); + } + + /** + * Create a directory in which to store generated doc files. + * Avoid using the default (current) directory, so that we can + * be sure that javadoc is writing in the intended location, + * not a default location. + */ + protected File getOutDir() { + File dir = new File(testName); + dir.mkdirs(); + return dir; + } + + /** + * Create a directory in which to store generated doc files. + * Avoid using the default (current) directory, so that we can + * be sure that javadoc is writing in the intended location, + * not a default location. + */ + protected File getOutDir(String path) { + File dir = new File(testName, path); + dir.mkdirs(); + return dir; + } + + protected JavaFileObject createSimpleJavaFileObject() { + return createSimpleJavaFileObject("pkg/C", "package pkg; public class C { }"); + } + + protected JavaFileObject createSimpleJavaFileObject(final String binaryName, final String content) { + return new SimpleJavaFileObject( + URI.create("myfo:///" + binaryName + ".java"), JavaFileObject.Kind.SOURCE) { + @Override + public CharSequence getCharContent(boolean ignoreEncoding) { + return content; + } + }; + } + + protected void checkFiles(File dir, Set expectFiles) { + Set files = new HashSet(); + listFiles(dir, files); + Set foundFiles = new HashSet(); + URI dirURI = dir.toURI(); + for (File f: files) + foundFiles.add(dirURI.relativize(f.toURI()).getPath()); + checkFiles(foundFiles, expectFiles, dir); + } + + protected void checkFiles(Path dir, Set expectFiles) throws IOException { + Set files = new HashSet(); + listFiles(dir, files); + Set foundFiles = new HashSet(); + for (Path f: files) { + foundFiles.add(dir.relativize(f).toString().replace(f.getFileSystem().getSeparator(), "/")); + } + checkFiles(foundFiles, expectFiles, dir); + } + + private void checkFiles(Set foundFiles, Set expectFiles, Object where) { + if (!foundFiles.equals(expectFiles)) { + Set missing = new TreeSet(expectFiles); + missing.removeAll(foundFiles); + if (!missing.isEmpty()) + error("the following files were not found in " + where + ": " + missing); + Set unexpected = new TreeSet(foundFiles); + unexpected.removeAll(expectFiles); + if (!unexpected.isEmpty()) + error("the following unexpected files were found in " + where + ": " + unexpected); + } + } + + protected void listFiles(File dir, Set files) { + for (File f: dir.listFiles()) { + if (f.isDirectory()) + listFiles(f, files); + else if (f.isFile()) + files.add(f); + } + } + + private void listFiles(Path dir, Set files) throws IOException { + for (Path f: Files.newDirectoryStream(dir)) { + if (Files.isDirectory(f)) + listFiles(f, files); + else if (Files.isRegularFile(f)) + files.add(f); + } + } + + protected void error(String msg) { + System.err.println("Error: " + msg); + errorCount++; + } + + protected int testCount; + protected int errorCount; + + protected String testName; + + /** + * Standard files generated by processing a documented class pkg.C. + */ + protected static Set standardExpectFiles = new HashSet(Arrays.asList( + "allclasses-frame.html", + "allclasses-noframe.html", + "constant-values.html", + "deprecated-list.html", + "help-doc.html", + "index-all.html", + "index.html", + "overview-tree.html", + "package-list", + "pkg/C.html", + "pkg/package-frame.html", + "pkg/package-summary.html", + "pkg/package-tree.html", + "resources/background.gif", + "resources/tab.gif", + "resources/titlebar_end.gif", + "resources/titlebar.gif", + "stylesheet.css" + )); +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/DocletPathTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/DocletPathTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main DocletPathTest + */ + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +/** + * Tests for locating a doclet via the file manager's DOCLET_PATH. + */ +public class DocletPathTest extends APITest { + public static void main(String... args) throws Exception { + new DocletPathTest().run(); + } + + /** + * Verify that an alternate doclet can be specified, and located via + * the file manager's DOCLET_PATH. + */ + @Test + public void testDocletPath() throws Exception { + JavaFileObject docletSrc = + createSimpleJavaFileObject("DocletOnDocletPath", docletSrcText); + File docletDir = getOutDir("classes"); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager cfm = compiler.getStandardFileManager(null, null, null); + cfm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(docletDir)); + Iterable cfiles = Arrays.asList(docletSrc); + if (!compiler.getTask(null, cfm, null, null, null, cfiles).call()) + throw new Exception("cannot compile doclet"); + + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir("api"); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + fm.setLocation(DocumentationTool.Location.DOCLET_PATH, Arrays.asList(docletDir)); + Iterable files = Arrays.asList(srcFile); + Iterable options = Arrays.asList("-doclet", "DocletOnDocletPath"); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + DocumentationTask t = tool.getTask(pw, fm, null, null, options, files); + boolean ok = t.call(); + String out = sw.toString(); + System.err.println(">>" + out + "<<"); + if (ok) { + if (out.contains(TEST_STRING)) { + System.err.println("doclet executed as expected"); + } else { + error("test string not found in doclet output"); + } + } else { + error("task failed"); + } + } + + private static final String TEST_STRING = "DocletOnDocletPath found and running"; + + private static final String docletSrcText = + "import com.sun.javadoc.*;\n" + + "public class DocletOnDocletPath {\n" + + " public static boolean start(RootDoc doc) {\n" + + " doc.printNotice(\"" + TEST_STRING + "\");\n" + + " return true;\n" + + " }\n" + + " public static int optionLength(String option) { return 0; }\n" + + " public static boolean validOptions(String options[][],\n" + + " DocErrorReporter reporter) { return true; }\n" + + " public static LanguageVersion languageVersion() {\n" + + " return LanguageVersion.JAVA_1_1;\n" + + " }\n" + + "}\n"; +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/GetSourceVersionsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/GetSourceVersionsTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main GetSourceVersionsTest + */ + +import java.util.EnumSet; +import java.util.Set; +import javax.lang.model.SourceVersion; +import javax.tools.DocumentationTool; +import javax.tools.ToolProvider; + +/** + * Tests for DocumentationTool.getSourceVersions method. + */ +public class GetSourceVersionsTest extends APITest { + public static void main(String... args) throws Exception { + new GetSourceVersionsTest().run(); + } + + /** + * Verify getSourceVersions. + */ + @Test + public void testRun() throws Exception { + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + Set found = tool.getSourceVersions(); + Set expect = EnumSet.range(SourceVersion.RELEASE_3, SourceVersion.latest()); + if (!expect.equals(found)) { + System.err.println("expect: " + expect); + System.err.println(" found: " + expect); + error("unexpected versions"); + } + } +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/GetTask_DiagListenerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/GetTask_DiagListenerTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main GetTask_DiagListenerTest + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +/** + * Tests for DocumentationTool.getTask diagnosticListener parameter. + */ +public class GetTask_DiagListenerTest extends APITest { + public static void main(String... args) throws Exception { + new GetTask_DiagListenerTest().run(); + } + + /** + * Verify that a diagnostic listener can be specified. + * Note that messages from the tool and doclet are imperfectly modeled + * because the DocErrorReporter API works in terms of localized strings + * and file:line positions. Therefore, messages reported via DocErrorReporter + * and simply wrapped and passed through. + */ + @Test + public void testDiagListener() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject("pkg/C", "package pkg; public error { }"); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DiagnosticCollector dc = new DiagnosticCollector(); + DocumentationTask t = tool.getTask(null, fm, dc, null, null, files); + if (t.call()) { + throw new Exception("task succeeded unexpectedly"); + } else { + List diagCodes = new ArrayList(); + for (Diagnostic d: dc.getDiagnostics()) { + System.err.println(d); + diagCodes.add(d.getCode()); + } + List expect = Arrays.asList( + "javadoc.note.msg", // Loading source file + "compiler.err.expected3", // class, interface, or enum expected + "javadoc.note.msg"); // 1 error + if (!diagCodes.equals(expect)) + throw new Exception("unexpected diagnostics occurred"); + System.err.println("diagnostics received as expected"); + } + } + +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/GetTask_DocletClassTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/GetTask_DocletClassTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main GetTask_DocletClassTest + */ + +import com.sun.javadoc.DocErrorReporter; +import com.sun.javadoc.LanguageVersion; +import com.sun.javadoc.RootDoc; +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.Random; +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +/** + * Tests for DocumentationTool.getTask docletClass parameter. + */ +public class GetTask_DocletClassTest extends APITest { + public static void main(String... args) throws Exception { + new GetTask_DocletClassTest().run(); + } + + /** + * Verify that an alternate doclet can be specified. + * + * There is no standard interface or superclass for a doclet; + * the only requirement is that it provides static methods that + * can be invoked via reflection. So, for now, the doclet is + * specified as a class. + * Because we cannot create and use a unique instance of the class, + * we verify that the doclet has been called by having it record + * (in a static field!) the comment from the last time it was invoked, + * which is randomly generated each time the test is run. + */ + @Test + public void testDoclet() throws Exception { + Random r = new Random(); + int key = r.nextInt(); + JavaFileObject srcFile = createSimpleJavaFileObject( + "pkg/C", + "package pkg; /** " + key + "*/ public class C { }"); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, TestDoclet.class, null, files); + if (t.call()) { + System.err.println("task succeeded"); + if (TestDoclet.lastCaller.equals(String.valueOf(key))) + System.err.println("found expected key: " + key); + else + error("Expected key not found"); + checkFiles(outDir, Collections.emptySet()); + } else { + throw new Exception("task failed"); + } + } + + public static class TestDoclet { + static String lastCaller; + public static boolean start(RootDoc root) { + lastCaller = root.classNamed("pkg.C").commentText().trim(); + return true; + } + + public static int optionLength(String option) { + return 0; // default is option unknown + } + + public static boolean validOptions(String options[][], + DocErrorReporter reporter) { + return true; // default is options are valid + } + + public static LanguageVersion languageVersion() { + return LanguageVersion.JAVA_1_1; + } + } + + /** + * Verify that exceptions from a doclet are thrown as expected. + */ + @Test + public void testBadDoclet() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, BadDoclet.class, null, files); + try { + t.call(); + error("call completed without exception"); + } catch (RuntimeException e) { + Throwable c = e.getCause(); + if (c.getClass() == UnexpectedError.class) + System.err.println("exception caught as expected: " + c); + else + throw e; + } + } + + public static class UnexpectedError extends Error { } + + public static class BadDoclet { + public static boolean start(RootDoc root) { + throw new UnexpectedError(); + } + + public static int optionLength(String option) { + return 0; // default is option unknown + } + + public static boolean validOptions(String options[][], + DocErrorReporter reporter) { + return true; // default is options are valid + } + + public static LanguageVersion languageVersion() { + return LanguageVersion.JAVA_1_1; + } + } + +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main GetTask_FileManagerTest + */ + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Set; + +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.ToolProvider; + +import com.sun.tools.javac.nio.JavacPathFileManager; +import com.sun.tools.javac.nio.PathFileManager; +import com.sun.tools.javac.util.Context; + +/** + * Tests for DocumentationTool.getTask fileManager parameter. + */ +public class GetTask_FileManagerTest extends APITest { + public static void main(String... args) throws Exception { + new GetTask_FileManagerTest().run(); + } + + /** + * Verify that an alternate file manager can be specified: + * in this case, a PathFileManager. + */ + @Test + public void testFileManager() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + PathFileManager fm = new JavacPathFileManager(new Context(), false, null); + Path outDir = getOutDir().toPath(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + checkFiles(outDir, standardExpectFiles); + } else { + throw new Exception("task failed"); + } + } + + /** + * Verify that exceptions from a bad file manager are thrown as expected. + */ + @Test + public void testBadFileManager() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + PathFileManager fm = new JavacPathFileManager(new Context(), false, null) { + @Override + public Iterable list(Location location, + String packageName, + Set kinds, + boolean recurse) + throws IOException { + throw new UnexpectedError(); + } + }; + Path outDir = getOutDir().toPath(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + try { + t.call(); + error("call completed without exception"); + } catch (RuntimeException e) { + Throwable c = e.getCause(); + if (c.getClass() == UnexpectedError.class) + System.err.println("exception caught as expected: " + c); + else + throw e; + } + } + + public static class UnexpectedError extends Error { } + +} diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/GetTask_FileObjectsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/GetTask_FileObjectsTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main GetTask_FileObjectsTest + */ + +import java.io.File; +import java.util.Arrays; +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +/** + * Tests for DocumentationTool.getTask fileObjects parameter. + */ +public class GetTask_FileObjectsTest extends APITest { + public static void main(String... args) throws Exception { + new GetTask_FileObjectsTest().run(); + } + + /** + * Verify that expected output files are written via the file manager, + * for a source file read from the file system with StandardJavaFileManager. + */ + @Test + public void testStandardFileObject() throws Exception { + File testSrc = new File(System.getProperty("test.src")); + File srcFile = new File(testSrc, "pkg/C.java"); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = fm.getJavaFileObjects(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + checkFiles(outDir, standardExpectFiles); + } else { + throw new Exception("task failed"); + } + } + + /** + * Verify that expected output files are written via the file manager, + * for an in-memory file object. + */ + @Test + public void testMemoryFileObject() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + checkFiles(outDir, standardExpectFiles); + } else { + throw new Exception("task failed"); + } + } + + /** + * Verify bad file object is handled correctly. + */ + @Test + public void testBadFileObject() throws Exception { + File testSrc = new File(System.getProperty("test.src")); + File srcFile = new File(testSrc, "pkg/C.class"); // unacceptable file kind + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = fm.getJavaFileObjects(srcFile); + try { + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + error("getTask succeeded, no exception thrown"); + } catch (IllegalArgumentException e) { + System.err.println("exception caught as expected: " + e); + } + } + + /** + * Verify null is handled correctly. + */ + @Test + public void testNull() throws Exception { + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList((JavaFileObject) null); + try { + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + error("getTask succeeded, no exception thrown"); + } catch (NullPointerException e) { + System.err.println("exception caught as expected: " + e); + } + } + +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/GetTask_OptionsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/GetTask_OptionsTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main GetTask_OptionsTest + */ + +import java.io.File; +import java.util.Arrays; +import java.util.Set; +import java.util.TreeSet; +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +/** + * Tests for DocumentationTool.getTask options parameter. + */ +public class GetTask_OptionsTest extends APITest { + public static void main(String... args) throws Exception { + new GetTask_OptionsTest().run(); + } + + /** + * Verify that expected output files are written for given options. + */ + @Test + public void testNoIndex() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + Iterable options = Arrays.asList("-noindex"); + DocumentationTask t = tool.getTask(null, fm, null, null, options, files); + if (t.call()) { + System.err.println("task succeeded"); + Set expectFiles = new TreeSet(standardExpectFiles); + expectFiles.remove("index-all.html"); + checkFiles(outDir, expectFiles); + } else { + error("task failed"); + } + } + + /** + * Verify null is handled correctly. + */ + @Test + public void testNull() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable options = Arrays.asList((String) null); + Iterable files = Arrays.asList(srcFile); + try { + DocumentationTask t = tool.getTask(null, fm, null, null, options, files); + error("getTask succeeded, no exception thrown"); + } catch (NullPointerException e) { + System.err.println("exception caught as expected: " + e); + } + } + +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/GetTask_WriterTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/GetTask_WriterTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main GetTask_WriterTest + */ + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +/** + * Tests for DocumentationTool.getTask writer parameter. + */ +public class GetTask_WriterTest extends APITest { + public static void main(String... args) throws Exception { + new GetTask_WriterTest().run(); + } + + /** + * Verify that a writer can be provided. + */ + @Test + public void testWriter() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + DocumentationTask t = tool.getTask(pw, fm, null, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + checkFiles(outDir, standardExpectFiles); + String out = sw.toString(); + System.err.println(">>" + out + "<<"); + for (String f: standardExpectFiles) { + if (f.endsWith(".html") && !out.contains(f)) + throw new Exception("expected string not found: " + f); + } + } else { + throw new Exception("task failed"); + } + } +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/IsSupportedOptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/IsSupportedOptionTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main IsSupportedOptionTest + */ + +import javax.tools.DocumentationTool; +import javax.tools.ToolProvider; + +/** + * Tests for DocumentationTool.usSupportedOption method. + */ +public class IsSupportedOptionTest extends APITest { + public static void main(String... args) throws Exception { + new IsSupportedOptionTest().run(); + } + + /** + * Verify that isSupportedOption method can be invoked. + */ + @Test + public void test() throws Exception { + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + check(tool, "-sourcepath", 1); + check(tool, "-verbose", 0); + check(tool, "-ZZZ", -1); + + try { + check(tool, null, -1); + error("null was accepted without exception"); + } catch (NullPointerException e) { + } + } + + private void check(DocumentationTool tool, String option, int numArgs) { + System.err.println("check " + option); + int n = tool.isSupportedOption(option); + if (n != numArgs) + error("unexpected result for option: " + option + ": " + n); + } +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/JavadocTaskImplTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/JavadocTaskImplTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main JavadocTaskImplTest + */ + +import java.io.File; +import java.util.Arrays; +import java.util.concurrent.Callable; + +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javadoc.Messager; +import com.sun.tools.javadoc.api.JavadocTaskImpl; + +/** + * Misc tests for JavacTaskImpl. + */ +public class JavadocTaskImplTest extends APITest { + public static void main(String... args) throws Exception { + new JavadocTaskImplTest().run(); + } + + @Test + public void testRawCall() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + + @SuppressWarnings("rawtypes") + Callable t = tool.getTask(null, fm, null, null, null, files); + + if (t.call() == Boolean.TRUE) { + System.err.println("task succeeded"); + } else { + throw new Exception("task failed"); + } + } + + @Test + public void testDirectAccess1() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + Iterable files = Arrays.asList(srcFile); + Context c = new Context(); + Messager.preRegister(c, "javadoc"); + StandardJavaFileManager fm = new JavacFileManager(c, true, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + DocumentationTask t = new JavadocTaskImpl(c, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + } else { + throw new Exception("task failed"); + } + } + + @Test + public void testDirectAccess2() throws Exception { + JavaFileObject srcFile = null; // error, provokes NPE + Iterable files = Arrays.asList(srcFile); + Context c = new Context(); + Messager.preRegister(c, "javadoc"); + StandardJavaFileManager fm = new JavacFileManager(c, true, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + try { + DocumentationTask t = new JavadocTaskImpl(c, null, null, files);; + error("getTask succeeded, no exception thrown"); + } catch (NullPointerException e) { + System.err.println("exception caught as expected: " + e); + } + } +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/RunTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/RunTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main RunTest + */ + +import java.io.ByteArrayOutputStream; +import java.io.File; +import javax.tools.DocumentationTool; +import javax.tools.ToolProvider; + +/** + * Tests for DocumentationTool.run method. + */ +public class RunTest extends APITest { + public static void main(String... args) throws Exception { + new RunTest().run(); + } + + /** + * Verify that run method can be invoked. + */ + @Test + public void testRun() throws Exception { + File testSrc = new File(System.getProperty("test.src")); + File srcFile = new File(testSrc, "pkg/C.java"); + File outDir = getOutDir(); + String[] args = { "-d", outDir.getPath(), srcFile.getPath() }; + + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + int rc = tool.run(null, stdout, stderr, args); + System.err.println("stdout >>" + stdout.toString() + "<<"); + System.err.println("stderr >>" + stderr.toString() + "<<"); + + if (rc == 0) { + System.err.println("call succeeded"); + checkFiles(outDir, standardExpectFiles); + String out = stdout.toString(); + for (String f: standardExpectFiles) { + if (f.endsWith(".html") && !out.contains(f)) + error("expected string not found: " + f); + } + } else { + error("call failed"); + } + } + + /** + * Verify that run method can be invoked. + */ + @Test + public void testRun2() throws Exception { + File outDir = getOutDir(); + String badfile = "badfile.java"; + String[] args = { "-d", outDir.getPath(), badfile }; + + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + int rc = tool.run(null, stdout, stderr, args); + System.err.println("stdout >>" + stdout.toString() + "<<"); + System.err.println("stderr >>" + stderr.toString() + "<<"); + + if (rc == 0) { + error("call succeeded unexpectedly"); + } else { + String err = stderr.toString(); + if (err.contains(badfile)) + System.err.println("call failed as expected"); + else + error("expected diagnostic not found"); + } + } + +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/TagletPathTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/TagletPathTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main TagletPathTest + */ + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.List; +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +/** + * Tests for locating a doclet via the file manager's DOCLET_PATH. + */ +public class TagletPathTest extends APITest { + public static void main(String... args) throws Exception { + new TagletPathTest().run(); + } + + /** + * Verify that a taglet can be specified, and located via + * the file manager's TAGLET_PATH. + */ + @Test + public void testTagletPath() throws Exception { + File testSrc = new File(System.getProperty("test.src")); + File tagletSrcFile = new File(testSrc, "taglets/UnderlineTaglet.java"); + File tagletDir = getOutDir("classes"); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager cfm = compiler.getStandardFileManager(null, null, null); + cfm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tagletDir)); + Iterable cfiles = cfm.getJavaFileObjects(tagletSrcFile); + if (!compiler.getTask(null, cfm, null, null, null, cfiles).call()) + throw new Exception("cannot compile taglet"); + + JavaFileObject srcFile = createSimpleJavaFileObject("pkg/C", testSrcText); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir("api"); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + fm.setLocation(DocumentationTool.Location.TAGLET_PATH, Arrays.asList(tagletDir)); + Iterable files = Arrays.asList(srcFile); + Iterable options = Arrays.asList("-taglet", "UnderlineTaglet"); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + DocumentationTask t = tool.getTask(pw, fm, null, null, options, files); + boolean ok = t.call(); + String out = sw.toString(); + System.err.println(">>" + out + "<<"); + if (ok) { + File f = new File(outDir, "pkg/C.html"); + List doc = Files.readAllLines(f.toPath(), Charset.defaultCharset()); + for (String line: doc) { + if (line.contains("" + TEST_STRING + "")) { + System.err.println("taglet executed as expected"); + return; + } + } + error("expected text not found in output " + f); + } else { + error("task failed"); + } + } + + static final String TEST_STRING = "xyzzy"; + static final String testSrcText = + "package pkg;\n" + + "/** {@underline " + TEST_STRING + "} */\n" + + "public class C { }"; +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/Task_reuseTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/Task_reuseTest.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6493690 + * @summary javadoc should have a javax.tools.Tool service provider + * @build APITest + * @run main Task_reuseTest + */ + +import java.io.File; +import java.util.Arrays; +import java.util.Locale; +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +/** + * Tests for reusing a documentation task. + */ +public class Task_reuseTest extends APITest { + public static void main(String... args) throws Exception { + new Task_reuseTest().run(); + } + + /** + * Verify that call can only be called once. + */ + @Test + public void testReuse() throws Exception { + DocumentationTask t = getAndRunTask(); + try { + t.call(); + error("task was reused without exception"); + } catch (IllegalStateException e) { + System.err.println("caught exception " + e); + } + } + + /** + * Verify that cannot update task after call + */ + @Test + public void testUpdateSetLocale() throws Exception { + DocumentationTask t = getAndRunTask(); + try { + t.setLocale(Locale.getDefault()); + error("task was reused without exception"); + } catch (IllegalStateException e) { + System.err.println("caught exception " + e); + } + } + + private DocumentationTask getAndRunTask() throws Exception { + JavaFileObject srcFile = createSimpleJavaFileObject(); + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File outDir = getOutDir(); + fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir)); + Iterable files = Arrays.asList(srcFile); + DocumentationTask t = tool.getTask(null, fm, null, null, null, files); + if (t.call()) { + System.err.println("task succeeded"); + return t; + } else { + throw new Exception("task failed"); + } + } +} + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/pkg/C.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/pkg/C.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg; + +public class C { } + diff -r d71d992cb905 -r 2e7bab0639b8 langtools/test/tools/javadoc/api/basic/taglets/UnderlineTaglet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/api/basic/taglets/UnderlineTaglet.java Thu Nov 15 23:07:24 2012 -0800 @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * -Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * -Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Oracle nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY + * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR + * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR + * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE + * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, + * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER + * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF + * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that Software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + */ + +import com.sun.tools.doclets.Taglet; +import com.sun.javadoc.*; +import java.util.Map; + +/** + * A sample Inline Taglet representing {@underline ...}. This tag can + * be used in any kind of {@link com.sun.javadoc.Doc}. + * The text is underlined. For example, + * "@underline UNDERLINE ME" would be shown as: UNDERLINE ME. + * + * @author Jamie Ho + * @since 1.4 + */ + +public class UnderlineTaglet implements Taglet { + + private static final String NAME = "underline"; + + /** + * Return the name of this custom tag. + */ + public String getName() { + return NAME; + } + + /** + * @return true since this tag can be used in a field + * doc comment + */ + public boolean inField() { + return true; + } + + /** + * @return true since this tag can be used in a constructor + * doc comment + */ + public boolean inConstructor() { + return true; + } + + /** + * @return true since this tag can be used in a method + * doc comment + */ + public boolean inMethod() { + return true; + } + + /** + * @return true since this tag can be used in an overview + * doc comment + */ + public boolean inOverview() { + return true; + } + + /** + * @return true since this tag can be used in a package + * doc comment + */ + public boolean inPackage() { + return true; + } + + /** + * @return true since this + */ + public boolean inType() { + return true; + } + + /** + * Will return true since this is an inline tag. + * @return true since this is an inline tag. + */ + + public boolean isInlineTag() { + return true; + } + + /** + * Register this Taglet. + * @param tagletMap the map to register this tag to. + */ + public static void register(Map tagletMap) { + UnderlineTaglet tag = new UnderlineTaglet(); + Taglet t = (Taglet) tagletMap.get(tag.getName()); + if (t != null) { + tagletMap.remove(tag.getName()); + } + tagletMap.put(tag.getName(), tag); + } + + /** + * Given the Tag representation of this custom + * tag, return its string representation. + * @param tag he Tag representation of this custom tag. + */ + public String toString(Tag tag) { + return "" + tag.text() + ""; + } + + /** + * This method should not be called since arrays of inline tags do not + * exist. Method {@link #tostring(Tag)} should be used to convert this + * inline tag to a string. + * @param tags the array of Tags representing of this custom tag. + */ + public String toString(Tag[] tags) { + return null; + } +} +