Thu, 15 Nov 2012 19:54:20 -0800
8002079: update DocFile to use a JavaFileManager
Reviewed-by: darcy
1 /*
2 * Copyright (c) 1997, 2012, 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 package com.sun.tools.doclets.formats.html;
27 import java.io.*;
28 import java.util.*;
30 import com.sun.javadoc.*;
31 import com.sun.tools.doclets.internal.toolkit.*;
32 import com.sun.tools.doclets.internal.toolkit.builders.*;
33 import com.sun.tools.doclets.internal.toolkit.util.*;
35 /**
36 * The class with "start" method, calls individual Writers.
37 *
38 * <p><b>This is NOT part of any supported API.
39 * If you write code that depends on this, you do so at your own risk.
40 * This code and its internal interfaces are subject to change or
41 * deletion without notice.</b>
42 *
43 * @author Atul M Dambalkar
44 * @author Robert Field
45 * @author Jamie Ho
46 *
47 */
48 public class HtmlDoclet extends AbstractDoclet {
49 // An instance will be created by validOptions, and used by start.
50 private static HtmlDoclet docletToStart = null;
52 public HtmlDoclet() {
53 configuration = new ConfigurationImpl();
54 }
56 /**
57 * The global configuration information for this run.
58 */
59 public final ConfigurationImpl configuration;
61 /**
62 * The "start" method as required by Javadoc.
63 *
64 * @param root the root of the documentation tree.
65 * @see com.sun.javadoc.RootDoc
66 * @return true if the doclet ran without encountering any errors.
67 */
68 public static boolean start(RootDoc root) {
69 // In typical use, options will have been set up by calling validOptions,
70 // which will create an HtmlDoclet for use here.
71 HtmlDoclet doclet;
72 if (docletToStart != null) {
73 doclet = docletToStart;
74 docletToStart = null;
75 } else {
76 doclet = new HtmlDoclet();
77 }
78 return doclet.start(doclet, root);
79 }
81 /**
82 * Create the configuration instance.
83 * Override this method to use a different
84 * configuration.
85 */
86 public Configuration configuration() {
87 return configuration;
88 }
90 /**
91 * Start the generation of files. Call generate methods in the individual
92 * writers, which will in turn genrate the documentation files. Call the
93 * TreeWriter generation first to ensure the Class Hierarchy is built
94 * first and then can be used in the later generation.
95 *
96 * For new format.
97 *
98 * @see com.sun.javadoc.RootDoc
99 */
100 protected void generateOtherFiles(RootDoc root, ClassTree classtree)
101 throws Exception {
102 super.generateOtherFiles(root, classtree);
103 if (configuration.linksource) {
104 SourceToHTMLConverter.convertRoot(configuration,
105 root, DocPaths.SOURCE_OUTPUT);
106 }
108 if (configuration.topFile.isEmpty()) {
109 configuration.standardmessage.
110 error("doclet.No_Non_Deprecated_Classes_To_Document");
111 return;
112 }
113 boolean nodeprecated = configuration.nodeprecated;
114 performCopy(configuration.helpfile);
115 performCopy(configuration.stylesheetfile);
116 copyResourceFile("background.gif");
117 copyResourceFile("tab.gif");
118 copyResourceFile("titlebar.gif");
119 copyResourceFile("titlebar_end.gif");
120 // do early to reduce memory footprint
121 if (configuration.classuse) {
122 ClassUseWriter.generate(configuration, classtree);
123 }
124 IndexBuilder indexbuilder = new IndexBuilder(configuration, nodeprecated);
126 if (configuration.createtree) {
127 TreeWriter.generate(configuration, classtree);
128 }
129 if (configuration.createindex) {
130 if (configuration.splitindex) {
131 SplitIndexWriter.generate(configuration, indexbuilder);
132 } else {
133 SingleIndexWriter.generate(configuration, indexbuilder);
134 }
135 }
137 if (!(configuration.nodeprecatedlist || nodeprecated)) {
138 DeprecatedListWriter.generate(configuration);
139 }
141 AllClassesFrameWriter.generate(configuration,
142 new IndexBuilder(configuration, nodeprecated, true));
144 FrameOutputWriter.generate(configuration);
146 if (configuration.createoverview) {
147 PackageIndexWriter.generate(configuration);
148 }
149 if (configuration.helpfile.length() == 0 &&
150 !configuration.nohelp) {
151 HelpWriter.generate(configuration);
152 }
153 // If a stylesheet file is not specified, copy the default stylesheet
154 // and replace newline with platform-specific newline.
155 if (configuration.stylesheetfile.length() == 0) {
156 DocFile f = DocFile.createFileForOutput(configuration, DocPaths.STYLESHEET);
157 f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.STYLESHEET), false, true);
158 }
159 }
161 /**
162 * {@inheritDoc}
163 */
164 protected void generateClassFiles(ClassDoc[] arr, ClassTree classtree) {
165 Arrays.sort(arr);
166 for(int i = 0; i < arr.length; i++) {
167 if (!(configuration.isGeneratedDoc(arr[i]) && arr[i].isIncluded())) {
168 continue;
169 }
170 ClassDoc prev = (i == 0)?
171 null:
172 arr[i-1];
173 ClassDoc curr = arr[i];
174 ClassDoc next = (i+1 == arr.length)?
175 null:
176 arr[i+1];
177 try {
178 if (curr.isAnnotationType()) {
179 AbstractBuilder annotationTypeBuilder =
180 configuration.getBuilderFactory()
181 .getAnnotationTypeBuilder((AnnotationTypeDoc) curr,
182 prev, next);
183 annotationTypeBuilder.build();
184 } else {
185 AbstractBuilder classBuilder =
186 configuration.getBuilderFactory()
187 .getClassBuilder(curr, prev, next, classtree);
188 classBuilder.build();
189 }
190 } catch (Exception e) {
191 e.printStackTrace();
192 throw new DocletAbortException();
193 }
194 }
195 }
197 /**
198 * {@inheritDoc}
199 */
200 protected void generatePackageFiles(ClassTree classtree) throws Exception {
201 PackageDoc[] packages = configuration.packages;
202 if (packages.length > 1) {
203 PackageIndexFrameWriter.generate(configuration);
204 }
205 PackageDoc prev = null, next;
206 for (int i = 0; i < packages.length; i++) {
207 // if -nodeprecated option is set and the package is marked as
208 // deprecated, do not generate the package-summary.html, package-frame.html
209 // and package-tree.html pages for that package.
210 if (!(configuration.nodeprecated && Util.isDeprecated(packages[i]))) {
211 PackageFrameWriter.generate(configuration, packages[i]);
212 next = (i + 1 < packages.length &&
213 packages[i + 1].name().length() > 0) ? packages[i + 1] : null;
214 //If the next package is unnamed package, skip 2 ahead if possible
215 next = (i + 2 < packages.length && next == null) ? packages[i + 2] : next;
216 AbstractBuilder packageSummaryBuilder =
217 configuration.getBuilderFactory().getPackageSummaryBuilder(
218 packages[i], prev, next);
219 packageSummaryBuilder.build();
220 if (configuration.createtree) {
221 PackageTreeWriter.generate(configuration,
222 packages[i], prev, next,
223 configuration.nodeprecated);
224 }
225 prev = packages[i];
226 }
227 }
228 }
230 public static final ConfigurationImpl sharedInstanceForOptions =
231 new ConfigurationImpl();
233 /**
234 * Check for doclet added options here.
235 *
236 * @return number of arguments to option. Zero return means
237 * option not known. Negative value means error occurred.
238 */
239 public static int optionLength(String option) {
240 // Construct temporary configuration for check
241 return sharedInstanceForOptions.optionLength(option);
242 }
244 /**
245 * Check that options have the correct arguments here.
246 * <P>
247 * This method is not required and will default gracefully
248 * (to true) if absent.
249 * <P>
250 * Printing option related error messages (using the provided
251 * DocErrorReporter) is the responsibility of this method.
252 *
253 * @return true if the options are valid.
254 */
255 public static boolean validOptions(String options[][],
256 DocErrorReporter reporter) {
257 docletToStart = new HtmlDoclet();
258 return docletToStart.configuration.validOptions(options, reporter);
259 }
261 /**
262 * Copy a file in the resources directory to the destination directory.
263 * @param resource The name of the resource file to copy
264 */
265 private void copyResourceFile(String resource) {
266 DocPath p = DocPaths.RESOURCES.resolve(resource);
267 DocFile f = DocFile.createFileForOutput(configuration, p);
268 f.copyResource(p, false, false);
269 }
271 private void performCopy(String filename) {
272 if (filename.isEmpty())
273 return;
275 try {
276 DocFile fromfile = DocFile.createFileForInput(configuration, filename);
277 DocPath path = DocPath.create(fromfile.getName());
278 DocFile toFile = DocFile.createFileForOutput(configuration, path);
279 if (toFile.isSameFile(fromfile))
280 return;
282 configuration.message.notice((SourcePosition) null,
283 "doclet.Copying_File_0_To_File_1",
284 fromfile.toString(), path.getPath());
285 toFile.copyFile(fromfile);
286 } catch (IOException exc) {
287 configuration.message.error((SourcePosition) null,
288 "doclet.perform_copy_exception_encountered",
289 exc.toString());
290 throw new DocletAbortException();
291 }
292 }
293 }