1 /*
2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.tools.doclets.internal.toolkit;
27 
28 import com.sun.javadoc.*;
29 import com.sun.tools.doclets.internal.toolkit.builders.*;
30 import com.sun.tools.doclets.internal.toolkit.util.*;
31 
32 /**
33  * An abstract implementation of a Doclet.
34  *
35  *  <p><b>This is NOT part of any supported API.
36  *  If you write code that depends on this, you do so at your own risk.
37  *  This code and its internal interfaces are subject to change or
38  *  deletion without notice.</b>
39  *
40  * @author Jamie Ho
41  */
42 public abstract class AbstractDoclet {
43 
44     /**
45      * The global configuration information for this run.
46      */
47     public Configuration configuration;
48 
49     /**
50      * The only doclet that may use this toolkit is {@value}
51      */
52     private static final String TOOLKIT_DOCLET_NAME =
53         com.sun.tools.doclets.formats.html.HtmlDoclet.class.getName();
54 
55     /**
56      * Verify that the only doclet that is using this toolkit is
57      * {@value #TOOLKIT_DOCLET_NAME}.
58      */
isValidDoclet(AbstractDoclet doclet)59     private boolean isValidDoclet(AbstractDoclet doclet) {
60         if (! doclet.getClass().getName().equals(TOOLKIT_DOCLET_NAME)) {
61             configuration.message.error("doclet.Toolkit_Usage_Violation",
62                 TOOLKIT_DOCLET_NAME);
63             return false;
64         }
65         return true;
66     }
67 
68     /**
69      * The method that starts the execution of the doclet.
70      *
71      * @param doclet the doclet to start the execution for.
72      * @param root   the {@link RootDoc} that points to the source to document.
73      * @return true if the doclet executed without error.  False otherwise.
74      */
start(AbstractDoclet doclet, RootDoc root)75     public boolean start(AbstractDoclet doclet, RootDoc root) {
76         configuration = configuration();
77         configuration.root = root;
78         if (! isValidDoclet(doclet)) {
79             return false;
80         }
81         try {
82             doclet.startGeneration(root);
83         } catch (Configuration.Fault f) {
84             root.printError(f.getMessage());
85             return false;
86         } catch (FatalError fe) {
87             return false;
88         } catch (DocletAbortException e) {
89             Throwable cause = e.getCause();
90             if (cause != null) {
91                 if (cause.getLocalizedMessage() != null) {
92                     root.printError(cause.getLocalizedMessage());
93                 } else {
94                     root.printError(cause.toString());
95                 }
96             }
97             return false;
98         } catch (Exception exc) {
99             exc.printStackTrace();
100             return false;
101         }
102         return true;
103     }
104 
105     /**
106      * Indicate that this doclet supports the 1.5 language features.
107      * @return JAVA_1_5, indicating that the new features are supported.
108      */
languageVersion()109     public static LanguageVersion languageVersion() {
110         return LanguageVersion.JAVA_1_5;
111     }
112 
113 
114     /**
115      * Create the configuration instance and returns it.
116      * @return the configuration of the doclet.
117      */
configuration()118     public abstract Configuration configuration();
119 
120     /**
121      * Start the generation of files. Call generate methods in the individual
122      * writers, which will in turn generate the documentation files. Call the
123      * TreeWriter generation first to ensure the Class Hierarchy is built
124      * first and then can be used in the later generation.
125      *
126      * @see com.sun.javadoc.RootDoc
127      */
startGeneration(RootDoc root)128     private void startGeneration(RootDoc root) throws Configuration.Fault, Exception {
129         if (root.classes().length == 0) {
130             configuration.message.
131                 error("doclet.No_Public_Classes_To_Document");
132             return;
133         }
134         configuration.setOptions();
135         configuration.getDocletSpecificMsg().notice("doclet.build_version",
136             configuration.getDocletSpecificBuildDate());
137         ClassTree classtree = new ClassTree(configuration, configuration.nodeprecated);
138 
139         generateClassFiles(root, classtree);
140         Util.copyDocFiles(configuration, DocPaths.DOC_FILES);
141 
142         PackageListWriter.generate(configuration);
143         generatePackageFiles(classtree);
144         generateProfileFiles();
145 
146         generateOtherFiles(root, classtree);
147         configuration.tagletManager.printReport();
148     }
149 
150     /**
151      * Generate additional documentation that is added to the API documentation.
152      *
153      * @param root      the RootDoc of source to document.
154      * @param classtree the data structure representing the class tree.
155      */
generateOtherFiles(RootDoc root, ClassTree classtree)156     protected void generateOtherFiles(RootDoc root, ClassTree classtree) throws Exception {
157         BuilderFactory builderFactory = configuration.getBuilderFactory();
158         AbstractBuilder constantsSummaryBuilder = builderFactory.getConstantsSummaryBuider();
159         constantsSummaryBuilder.build();
160         AbstractBuilder serializedFormBuilder = builderFactory.getSerializedFormBuilder();
161         serializedFormBuilder.build();
162     }
163 
164     /**
165      * Generate the profile documentation.
166      *
167      */
generateProfileFiles()168     protected abstract void generateProfileFiles() throws Exception;
169 
170     /**
171      * Generate the package documentation.
172      *
173      * @param classtree the data structure representing the class tree.
174      */
generatePackageFiles(ClassTree classtree)175     protected abstract void generatePackageFiles(ClassTree classtree) throws Exception;
176 
177     /**
178      * Generate the class documentation.
179      *
180      * @param classtree the data structure representing the class tree.
181      */
generateClassFiles(ClassDoc[] arr, ClassTree classtree)182     protected abstract void generateClassFiles(ClassDoc[] arr, ClassTree classtree);
183 
184     /**
185      * Iterate through all classes and construct documentation for them.
186      *
187      * @param root      the RootDoc of source to document.
188      * @param classtree the data structure representing the class tree.
189      */
generateClassFiles(RootDoc root, ClassTree classtree)190     protected void generateClassFiles(RootDoc root, ClassTree classtree) {
191         generateClassFiles(classtree);
192         PackageDoc[] packages = root.specifiedPackages();
193         for (int i = 0; i < packages.length; i++) {
194             generateClassFiles(packages[i].allClasses(), classtree);
195         }
196     }
197 
198     /**
199      * Generate the class files for single classes specified on the command line.
200      *
201      * @param classtree the data structure representing the class tree.
202      */
generateClassFiles(ClassTree classtree)203     private void generateClassFiles(ClassTree classtree) {
204         String[] packageNames = configuration.classDocCatalog.packageNames();
205         for (int packageNameIndex = 0; packageNameIndex < packageNames.length;
206                 packageNameIndex++) {
207             generateClassFiles(configuration.classDocCatalog.allClasses(
208                 packageNames[packageNameIndex]), classtree);
209         }
210     }
211 }
212