8000612: Discrepancy between resources provided in javadoc resource files and resources required by code

Tue, 06 Nov 2012 14:32:49 -0800

author
jjg
date
Tue, 06 Nov 2012 14:32:49 -0800
changeset 1397
8abc56be3131
parent 1396
9b85813d2262
child 1398
55a007aaf63d

8000612: Discrepancy between resources provided in javadoc resource files and resources required by code
Reviewed-by: bpatel

src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties file | annotate | diff | comparison | revisions
test/tools/javac/diags/CheckResourceKeys.java file | annotate | diff | comparison | revisions
test/tools/javadoc/CheckResourceKeys.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties	Tue Nov 06 14:45:27 2012 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties	Tue Nov 06 14:32:49 2012 -0800
     1.3 @@ -41,32 +41,21 @@
     1.4  doclet.Help=Help
     1.5  doclet.Skip_navigation_links=Skip navigation links
     1.6  doclet.New_Page=NewPage
     1.7 -doclet.None=None
     1.8 -doclet.Factory_Method_Detail=Static Factory Method Detail
     1.9  doclet.navDeprecated=Deprecated
    1.10 -doclet.Deprecated_List=Deprecated List
    1.11  doclet.Window_Deprecated_List=Deprecated List
    1.12 -doclet.Note_0_is_deprecated=Note: {0} is deprecated.
    1.13  doclet.Overrides=Overrides:
    1.14  doclet.in_class=in class
    1.15 -doclet.0_Fields_and_Methods="{0}" Fields and Methods
    1.16 -doclet.Index_of_Fields_and_Methods=Index of Fields and Methods
    1.17  doclet.Static_variable_in=Static variable in {0}
    1.18  doclet.Variable_in=Variable in {0}
    1.19  doclet.Constructor_for=Constructor for {0}
    1.20  doclet.Static_method_in=Static method in {0}
    1.21  doclet.Method_in=Method in {0}
    1.22 -doclet.throws=throws
    1.23  doclet.package=package
    1.24  doclet.MalformedURL=Malformed URL: {0}
    1.25  doclet.File_error=Error reading file: {0}
    1.26  doclet.URL_error=Error fetching URL: {0}
    1.27 -doclet.No_Package_Comment_File=For Package {0} Package.Comment file not found
    1.28 -doclet.No_Source_For_Class=Source information for class {0} not available.
    1.29  doclet.see.class_or_package_not_found=Tag {0}: reference not found: {1}
    1.30  doclet.see.class_or_package_not_accessible=Tag {0}: reference not accessible: {1}
    1.31 -doclet.see.malformed_tag=Tag {0}: Malformed: {1}
    1.32 -doclet.Inherited_API_Summary=Inherited API Summary
    1.33  doclet.Deprecated_API=Deprecated API
    1.34  doclet.Deprecated_Packages=Deprecated Packages
    1.35  doclet.Deprecated_Classes=Deprecated Classes
    1.36 @@ -92,10 +81,7 @@
    1.37  doclet.deprecated_methods=deprecated methods
    1.38  doclet.deprecated_enum_constants=deprecated enum constants
    1.39  doclet.deprecated_annotation_type_members=deprecated annotation type elements
    1.40 -doclet.Frame_Output=Frame Output
    1.41 -doclet.Docs_generated_by_Javadoc=Documentation generated by Javadoc.
    1.42  doclet.Generated_Docs_Untitled=Generated Documentation (Untitled)
    1.43 -doclet.Blank=Blank
    1.44  doclet.Other_Packages=Other Packages
    1.45  doclet.Package_Description=Package {0} Description
    1.46  doclet.Description=Description
    1.47 @@ -105,32 +91,24 @@
    1.48  doclet.Subinterfaces=All Known Subinterfaces:
    1.49  doclet.Implementing_Classes=All Known Implementing Classes:
    1.50  doclet.also=also
    1.51 -doclet.Option=Option
    1.52 -doclet.Or=Or
    1.53 +doclet.FRAMES=FRAMES
    1.54  doclet.Frames=Frames
    1.55 +doclet.NO_FRAMES=NO FRAMES
    1.56  doclet.No_Frames=No Frames
    1.57  doclet.Package_Hierarchies=Package Hierarchies:
    1.58  doclet.Hierarchy_For_Package=Hierarchy For Package {0}
    1.59 -doclet.Source_Code=Source Code:
    1.60  doclet.Hierarchy_For_All_Packages=Hierarchy For All Packages
    1.61 -doclet.Cannot_handle_no_packages=Cannot handle no packages.
    1.62  doclet.Frame_Alert=Frame Alert
    1.63 -doclet.Overview-Member-Frame=Overview Member Frame
    1.64  doclet.Frame_Warning_Message=This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to {0}.
    1.65  doclet.No_Script_Message=JavaScript is disabled on your browser.
    1.66  doclet.Non_Frame_Version=Non-frame version
    1.67 -doclet.Frame_Version=Frame version
    1.68 -doclet.Following_From_Class=Following copied from class: {0}
    1.69 -doclet.Following_From_Interface=Following copied from interface: {0}
    1.70  doclet.Description_From_Interface=Description copied from interface:
    1.71  doclet.Description_From_Class=Description copied from class:
    1.72 -doclet.Standard_doclet_invoked=Standard doclet invoked...
    1.73  doclet.No_Non_Deprecated_Classes_To_Document=No non-deprecated classes found to document.
    1.74  doclet.Interfaces_Italic=Interfaces (italic)
    1.75  doclet.Enclosing_Class=Enclosing class:
    1.76  doclet.Enclosing_Interface=Enclosing interface:
    1.77  doclet.Window_Source_title=Source code
    1.78 -doclet.Help_title=API Help
    1.79  doclet.Window_Help_title=API Help
    1.80  doclet.Help_line_1=How This API Document Is Organized
    1.81  doclet.Help_line_2=This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
    1.82 @@ -168,19 +146,6 @@
    1.83  doclet.Help_annotation_type_line_1=Each annotation type has its own separate page with the following sections:
    1.84  doclet.Help_annotation_type_line_2=Annotation Type declaration
    1.85  doclet.Help_annotation_type_line_3=Annotation Type description
    1.86 -doclet.Style_line_1=Javadoc style sheet
    1.87 -doclet.Style_line_2=Define colors, fonts and other style attributes here to override the defaults
    1.88 -doclet.Style_line_3=Page background color
    1.89 -doclet.Style_Headings=Headings
    1.90 -doclet.Style_line_4=Table colors
    1.91 -doclet.Style_line_5=Dark mauve
    1.92 -doclet.Style_line_6=Light mauve
    1.93 -doclet.Style_line_7=White
    1.94 -doclet.Style_line_8=Font used in left-hand frame lists
    1.95 -doclet.Style_line_9=Example of smaller, sans-serif font in frames
    1.96 -doclet.Style_line_10=Navigation bar fonts and colors
    1.97 -doclet.Style_line_11=Dark Blue
    1.98 -doclet.Style_line_12=Table caption style
    1.99  doclet.ClassUse_Packages.that.use.0=Packages that use {0}
   1.100  doclet.ClassUse_Uses.of.0.in.1=Uses of {0} in {1}
   1.101  doclet.ClassUse_Classes.in.0.used.by.1=Classes in {0} used by {1}
   1.102 @@ -210,12 +175,9 @@
   1.103  doclet.Window_ClassUse_Header=Uses of {0} {1}
   1.104  doclet.ClassUse_Title=Uses of {0}<br>{1}
   1.105  doclet.navClassUse=Use
   1.106 -doclet.link_option_twice=Extern URL link option (link or linkoffline) used twice.
   1.107  doclet.Error_in_packagelist=Error in using -group option: {0} {1}
   1.108  doclet.Groupname_already_used=In -group option, groupname already used: {0}
   1.109  doclet.Same_package_name_used=Package name format used twice: {0}
   1.110 -doclet.Serialization.Excluded_Class=Non-transient field {1} uses excluded class {0}.
   1.111 -doclet.Serialization.Nonexcluded_Class=Non-transient field {1} uses hidden, non-included class {0}.
   1.112  doclet.exception_encountered=Exception encountered while processing {1}\n{0}
   1.113  doclet.usage=Provided by Standard doclet:\n\
   1.114    -d <directory>                    Destination directory for output files\n\
     2.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties	Tue Nov 06 14:45:27 2012 +0000
     2.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties	Tue Nov 06 14:32:49 2012 -0800
     2.3 @@ -21,10 +21,8 @@
     2.4  doclet.Copying_File_0_To_File_1=Copying file {0} to file {1}...
     2.5  doclet.No_Public_Classes_To_Document=No public or protected classes found to document.
     2.6  doclet.Unable_to_create_directory_0=Unable to create directory {0}
     2.7 -doclet.destination_directory_not_found_0=Destination directory not found {0}
     2.8  doclet.destination_directory_not_directory_0=Destination directory is not a directory {0}
     2.9  doclet.destination_directory_not_writable_0=Destination directory not writable {0}
    2.10 -doclet.Error_creating_tmp_file=Error creating temporary file, using default platform encoding.
    2.11  doclet.Encoding_not_supported=Encoding not supported: {0}
    2.12  doclet.Building_Tree=Building tree for all the packages and classes...
    2.13  doclet.Building_Index=Building index for all the packages and classes...
    2.14 @@ -74,7 +72,6 @@
    2.15  doclet.Enum_Constant_Summary=Enum Constant Summary
    2.16  doclet.Constructor_Summary=Constructor Summary
    2.17  doclet.Method_Summary=Method Summary
    2.18 -doclet.Factory_Method_Summary=Static Factory Method Summary
    2.19  doclet.Interfaces=Interfaces
    2.20  doclet.Enums=Enums
    2.21  doclet.AnnotationTypes=Annotation Types
    2.22 @@ -88,7 +85,6 @@
    2.23  doclet.All_Implemented_Interfaces=All Implemented Interfaces:
    2.24  doclet.All_classes_and_interfaces=All classes and interfaces (except non-static nested types)
    2.25  doclet.Package_class_and_interface_descriptions=Package, class and interface descriptions
    2.26 -doclet.Members=Members
    2.27  doclet.Interface=Interface
    2.28  doclet.Class=Class
    2.29  doclet.AnnotationType=Annotation Type
    2.30 @@ -107,18 +103,13 @@
    2.31  doclet.Exception=Exception
    2.32  doclet.exception=exception
    2.33  doclet.exceptions=exceptions
    2.34 -doclet.extended_by=extended by
    2.35 -doclet.extends=extends
    2.36  doclet.Package_private=(package private)
    2.37 -doclet.implements=implementsdoclet.Same_package_name_used=Package name format used twice: {0}
    2.38  doclet.Nested_Classes_Interfaces_Inherited_From_Class=Nested classes/interfaces inherited from class
    2.39  doclet.Nested_Classes_Interface_Inherited_From_Interface=Nested classes/interfaces inherited from interface
    2.40  doclet.Methods_Inherited_From_Class=Methods inherited from class
    2.41  doclet.Methods_Inherited_From_Interface=Methods inherited from interface
    2.42  doclet.Fields_Inherited_From_Class=Fields inherited from class
    2.43  doclet.Fields_Inherited_From_Interface=Fields inherited from interface
    2.44 -doclet.Serializable=Serializable
    2.45 -doclet.Externalizable=Externalizable
    2.46  doclet.Annotation_Type_Member_Detail=Element Detail
    2.47  doclet.Enum_Constant_Detail=Enum Constant Detail
    2.48  doclet.Constants_Summary=Constant Field Values
    2.49 @@ -126,7 +117,6 @@
    2.50  doclet.Method_Detail=Method Detail
    2.51  doclet.Constructor_Detail=Constructor Detail
    2.52  doclet.Deprecated=Deprecated.
    2.53 -doclet.Deprecated_class=This class is deprecated.
    2.54  doclet.Groupname_already_used=In -group option, groupname already used: {0}
    2.55  doclet.value_tag_invalid_reference={0} (referenced by @value tag) is an unknown reference.
    2.56  doclet.value_tag_invalid_constant=@value tag (which references {0}) can only be used in constants.
     3.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java	Tue Nov 06 14:45:27 2012 +0000
     3.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java	Tue Nov 06 14:32:49 2012 -0800
     3.3 @@ -555,7 +555,7 @@
     3.4       *
     3.5       * @param cd the ClassDoc to check.
     3.6       * @param lowerCaseOnly true if you want the name returned in lower case.
     3.7 -     *                      If false, the first letter of the name is capatilized.
     3.8 +     *                      If false, the first letter of the name is capitalized.
     3.9       * @return
    3.10       */
    3.11      public static String getTypeName(Configuration config,
     4.1 --- a/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java	Tue Nov 06 14:45:27 2012 +0000
     4.2 +++ b/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java	Tue Nov 06 14:32:49 2012 -0800
     4.3 @@ -267,8 +267,6 @@
     4.4              }
     4.5  
     4.6              if (referencedClass == null) { /* may just not be in this run */
     4.7 -//                docenv().warning(holder, "tag.see.class_not_found",
     4.8 -//                                 where, text);
     4.9                  // check if it's a package name
    4.10                  referencedPackage = docenv().lookupPackage(where);
    4.11                  return;
     5.1 --- a/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Tue Nov 06 14:45:27 2012 +0000
     5.2 +++ b/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Tue Nov 06 14:32:49 2012 -0800
     5.3 @@ -1,5 +1,5 @@
     5.4  #
     5.5 -# Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     5.6 +# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     5.7  # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8  #
     5.9  # This code is free software; you can redistribute it and/or modify it
    5.10 @@ -64,7 +64,6 @@
    5.11  main.incompatible.access.flags=More than one of -public, -private, -package, or -protected specified.
    5.12  main.cant.read=cannot read {0}
    5.13  main.Loading_source_files_for_package=Loading source files for package {0}...
    5.14 -main.Loading_source_file_for_class=Loading source file for class {0}...
    5.15  main.Loading_source_file=Loading source file {0}...
    5.16  main.Building_tree=Constructing Javadoc information...
    5.17  main.no_source_files_for_package=No source files for package {0}
    5.18 @@ -96,13 +95,12 @@
    5.19  tag.see.can_not_find_member=Tag {0}: can''t find {1} in {2}
    5.20  tag.see.no_close_bracket_on_url=Tag {0}: missing final ''>'': "{1}"
    5.21  tag.see.no_close_quote=Tag {0}: no final close quote: "{1}"
    5.22 -tag.see.class_not_found=class {0} not found for @see tag: "{1}"
    5.23  tag.see.class_not_specified=Tag {0}: class not specified: "{1}"
    5.24  tag.see.illegal_character=Tag {0}:illegal character: "{1}" in "{2}"
    5.25  tag.see.malformed_see_tag=Tag {0}: malformed: "{1}"
    5.26 -tag.throws.exception_not_found={0} tag, class {1} not found.
    5.27  tag.End_delimiter_missing_for_possible_SeeTag=End Delimiter } missing for possible See Tag in comment string: "{0}"
    5.28  tag.Improper_Use_Of_Link_Tag=Missing closing ''}'' character for inline tag: "{0}"
    5.29 +tag.serialField.illegal_character=illegal character {0} in @serialField tag: {1}.
    5.30  javadoc.File_Read_Error=Error while reading file {0}
    5.31  javadoc.Body_missing_from_html_file=Body tag missing from HTML file
    5.32  javadoc.End_body_missing_from_html_file=Close body tag missing from HTML file
    5.33 @@ -110,4 +108,3 @@
    5.34  javadoc.class_not_found=Class {0} not found.
    5.35  javadoc.error=error
    5.36  javadoc.warning=warning
    5.37 -tag.serialField.illegal_character=illegal character {0} in @serialField tag: {1}.
     6.1 --- a/test/tools/javac/diags/CheckResourceKeys.java	Tue Nov 06 14:45:27 2012 +0000
     6.2 +++ b/test/tools/javac/diags/CheckResourceKeys.java	Tue Nov 06 14:32:49 2012 -0800
     6.3 @@ -310,9 +310,9 @@
     6.4                      pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) {
     6.5                  String name = fo.getName();
     6.6                  // ignore resource files, and files which are not really part of javac
     6.7 -                if (name.contains("resources")
     6.8 -                        || name.contains("Launcher.class")
     6.9 -                        || name.contains("CreateSymbols.class"))
    6.10 +                if (name.matches(".*resources.[A-Za-z_0-9]+\\.class")
    6.11 +                        || name.endsWith("Launcher.class")
    6.12 +                        || name.endsWith("CreateSymbols.class"))
    6.13                      continue;
    6.14                  scan(fo, results);
    6.15              }
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/tools/javadoc/CheckResourceKeys.java	Tue Nov 06 14:32:49 2012 -0800
     7.3 @@ -0,0 +1,240 @@
     7.4 +/*
     7.5 + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.
    7.11 + *
    7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.15 + * version 2 for more details (a copy is included in the LICENSE file that
    7.16 + * accompanied this code).
    7.17 + *
    7.18 + * You should have received a copy of the GNU General Public License version
    7.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.21 + *
    7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.23 + * or visit www.oracle.com if you need additional information or have any
    7.24 + * questions.
    7.25 + */
    7.26 +
    7.27 +/*
    7.28 + * @test
    7.29 + * @bug 8000612
    7.30 + * @summary need test program to validate javadoc resource bundles
    7.31 + */
    7.32 +
    7.33 +import java.io.*;
    7.34 +import java.util.*;
    7.35 +import javax.tools.*;
    7.36 +import com.sun.tools.classfile.*;
    7.37 +
    7.38 +/**
    7.39 + * Compare string constants in javadoc classes against keys in javadoc resource bundles.
    7.40 + */
    7.41 +public class CheckResourceKeys {
    7.42 +    /**
    7.43 +     * Main program.
    7.44 +     * Options:
    7.45 +     * -finddeadkeys
    7.46 +     *      look for keys in resource bundles that are no longer required
    7.47 +     * -findmissingkeys
    7.48 +     *      look for keys in resource bundles that are missing
    7.49 +     *
    7.50 +     * @throws Exception if invoked by jtreg and errors occur
    7.51 +     */
    7.52 +    public static void main(String... args) throws Exception {
    7.53 +        CheckResourceKeys c = new CheckResourceKeys();
    7.54 +        if (c.run(args))
    7.55 +            return;
    7.56 +
    7.57 +        if (is_jtreg())
    7.58 +            throw new Exception(c.errors + " errors occurred");
    7.59 +        else
    7.60 +            System.exit(1);
    7.61 +    }
    7.62 +
    7.63 +    static boolean is_jtreg() {
    7.64 +        return (System.getProperty("test.src") != null);
    7.65 +    }
    7.66 +
    7.67 +    /**
    7.68 +     * Main entry point.
    7.69 +     */
    7.70 +    boolean run(String... args) throws Exception {
    7.71 +        boolean findDeadKeys = false;
    7.72 +        boolean findMissingKeys = false;
    7.73 +
    7.74 +        if (args.length == 0) {
    7.75 +            if (is_jtreg()) {
    7.76 +                findDeadKeys = true;
    7.77 +                findMissingKeys = true;
    7.78 +            } else {
    7.79 +                System.err.println("Usage: java CheckResourceKeys <options>");
    7.80 +                System.err.println("where options include");
    7.81 +                System.err.println("  -finddeadkeys      find keys in resource bundles which are no longer required");
    7.82 +                System.err.println("  -findmissingkeys   find keys in resource bundles that are required but missing");
    7.83 +                return true;
    7.84 +            }
    7.85 +        } else {
    7.86 +            for (String arg: args) {
    7.87 +                if (arg.equalsIgnoreCase("-finddeadkeys"))
    7.88 +                    findDeadKeys = true;
    7.89 +                else if (arg.equalsIgnoreCase("-findmissingkeys"))
    7.90 +                    findMissingKeys = true;
    7.91 +                else
    7.92 +                    error("bad option: " + arg);
    7.93 +            }
    7.94 +        }
    7.95 +
    7.96 +        if (errors > 0)
    7.97 +            return false;
    7.98 +
    7.99 +        Set<String> codeKeys = getCodeKeys();
   7.100 +        Set<String> resourceKeys = getResourceKeys();
   7.101 +
   7.102 +        System.err.println("found " + codeKeys.size() + " keys in code");
   7.103 +        System.err.println("found " + resourceKeys.size() + " keys in resource bundles");
   7.104 +
   7.105 +        if (findDeadKeys)
   7.106 +            findDeadKeys(codeKeys, resourceKeys);
   7.107 +
   7.108 +        if (findMissingKeys)
   7.109 +            findMissingKeys(codeKeys, resourceKeys);
   7.110 +
   7.111 +        return (errors == 0);
   7.112 +    }
   7.113 +
   7.114 +    /**
   7.115 +     * Find keys in resource bundles which are probably no longer required.
   7.116 +     * A key is required if there is a string in the code that is a resource key,
   7.117 +     * or if the key is well-known according to various pragmatic rules.
   7.118 +     */
   7.119 +    void findDeadKeys(Set<String> codeKeys, Set<String> resourceKeys) {
   7.120 +        for (String rk: resourceKeys) {
   7.121 +            if (codeKeys.contains(rk))
   7.122 +                continue;
   7.123 +
   7.124 +            error("Resource key not found in code: " + rk);
   7.125 +        }
   7.126 +    }
   7.127 +
   7.128 +    /**
   7.129 +     * For all strings in the code that look like they might be
   7.130 +     * a resource key, verify that a key exists.
   7.131 +     */
   7.132 +    void findMissingKeys(Set<String> codeKeys, Set<String> resourceKeys) {
   7.133 +        for (String ck: codeKeys) {
   7.134 +            if (resourceKeys.contains(ck))
   7.135 +                continue;
   7.136 +            error("No resource for \"" + ck + "\"");
   7.137 +        }
   7.138 +    }
   7.139 +
   7.140 +    /**
   7.141 +     * Get the set of strings from (most of) the javadoc classfiles.
   7.142 +     */
   7.143 +    Set<String> getCodeKeys() throws IOException {
   7.144 +        Set<String> results = new TreeSet<String>();
   7.145 +        JavaCompiler c = ToolProvider.getSystemJavaCompiler();
   7.146 +        JavaFileManager fm = c.getStandardFileManager(null, null, null);
   7.147 +        JavaFileManager.Location javadocLoc = findJavadocLocation(fm);
   7.148 +        String[] pkgs = {
   7.149 +            "com.sun.tools.doclets",
   7.150 +            "com.sun.tools.javadoc"
   7.151 +        };
   7.152 +        for (String pkg: pkgs) {
   7.153 +            for (JavaFileObject fo: fm.list(javadocLoc,
   7.154 +                    pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) {
   7.155 +                String name = fo.getName();
   7.156 +                // ignore resource files
   7.157 +                if (name.matches(".*resources.[A-Za-z_0-9]+\\.class"))
   7.158 +                    continue;
   7.159 +                scan(fo, results);
   7.160 +            }
   7.161 +        }
   7.162 +
   7.163 +        // special handling for code strings synthesized in
   7.164 +        // com.sun.tools.doclets.internal.toolkit.util.Util.getTypeName
   7.165 +        String[] extras = {
   7.166 +            "AnnotationType", "Class", "Enum", "Error", "Exception", "Interface"
   7.167 +        };
   7.168 +        for (String s: extras) {
   7.169 +            if (results.contains("doclet." + s))
   7.170 +                results.add("doclet." + s.toLowerCase());
   7.171 +        }
   7.172 +
   7.173 +        return results;
   7.174 +    }
   7.175 +
   7.176 +    // depending on how the test is run, javadoc may be on bootclasspath or classpath
   7.177 +    JavaFileManager.Location findJavadocLocation(JavaFileManager fm) {
   7.178 +        JavaFileManager.Location[] locns =
   7.179 +            { StandardLocation.PLATFORM_CLASS_PATH, StandardLocation.CLASS_PATH };
   7.180 +        try {
   7.181 +            for (JavaFileManager.Location l: locns) {
   7.182 +                JavaFileObject fo = fm.getJavaFileForInput(l,
   7.183 +                    "com.sun.tools.javadoc.Main", JavaFileObject.Kind.CLASS);
   7.184 +                if (fo != null) {
   7.185 +                    System.err.println("found javadoc in " + l);
   7.186 +                    return l;
   7.187 +                }
   7.188 +            }
   7.189 +        } catch (IOException e) {
   7.190 +            throw new Error(e);
   7.191 +        }
   7.192 +        throw new IllegalStateException("Cannot find javadoc");
   7.193 +    }
   7.194 +
   7.195 +    /**
   7.196 +     * Get the set of strings from a class file.
   7.197 +     * Only strings that look like they might be a resource key are returned.
   7.198 +     */
   7.199 +    void scan(JavaFileObject fo, Set<String> results) throws IOException {
   7.200 +        //System.err.println("scan " + fo.getName());
   7.201 +        InputStream in = fo.openInputStream();
   7.202 +        try {
   7.203 +            ClassFile cf = ClassFile.read(in);
   7.204 +            for (ConstantPool.CPInfo cpinfo: cf.constant_pool.entries()) {
   7.205 +                if (cpinfo.getTag() == ConstantPool.CONSTANT_Utf8) {
   7.206 +                    String v = ((ConstantPool.CONSTANT_Utf8_info) cpinfo).value;
   7.207 +                    if (v.matches("(doclet|main|javadoc|tag)\\.[A-Za-z0-9-_.]+"))
   7.208 +                        results.add(v);
   7.209 +                }
   7.210 +            }
   7.211 +        } catch (ConstantPoolException ignore) {
   7.212 +        } finally {
   7.213 +            in.close();
   7.214 +        }
   7.215 +    }
   7.216 +
   7.217 +    /**
   7.218 +     * Get the set of keys from the javadoc resource bundles.
   7.219 +     */
   7.220 +    Set<String> getResourceKeys() {
   7.221 +        String[] names = {
   7.222 +                "com.sun.tools.doclets.formats.html.resources.standard",
   7.223 +                "com.sun.tools.doclets.internal.toolkit.resources.doclets",
   7.224 +                "com.sun.tools.javadoc.resources.javadoc",
   7.225 +        };
   7.226 +        Set<String> results = new TreeSet<String>();
   7.227 +        for (String name : names) {
   7.228 +            ResourceBundle b = ResourceBundle.getBundle(name);
   7.229 +            results.addAll(b.keySet());
   7.230 +        }
   7.231 +        return results;
   7.232 +    }
   7.233 +
   7.234 +    /**
   7.235 +     * Report an error.
   7.236 +     */
   7.237 +    void error(String msg) {
   7.238 +        System.err.println("Error: " + msg);
   7.239 +        errors++;
   7.240 +    }
   7.241 +
   7.242 +    int errors;
   7.243 +}

mercurial