HtmlDoclet.java revision 3233:b5d08bc0d224
1160814Ssimon/*
2280304Sjkim * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3280304Sjkim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4280304Sjkim *
5160814Ssimon * This code is free software; you can redistribute it and/or modify it
6160814Ssimon * under the terms of the GNU General Public License version 2 only, as
7160814Ssimon * published by the Free Software Foundation.  Oracle designates this
8160814Ssimon * particular file as subject to the "Classpath" exception as provided
9160814Ssimon * by Oracle in the LICENSE file that accompanied this code.
10160814Ssimon *
11160814Ssimon * This code is distributed in the hope that it will be useful, but WITHOUT
12160814Ssimon * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13160814Ssimon * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14280304Sjkim * version 2 for more details (a copy is included in the LICENSE file that
15160814Ssimon * accompanied this code).
16160814Ssimon *
17160814Ssimon * You should have received a copy of the GNU General Public License version
18160814Ssimon * 2 along with this work; if not, write to the Free Software Foundation,
19160814Ssimon * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20160814Ssimon *
21160814Ssimon * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22160814Ssimon * or visit www.oracle.com if you need additional information or have any
23160814Ssimon * questions.
24160814Ssimon */
25160814Ssimon
26160814Ssimonpackage jdk.javadoc.internal.doclets.formats.html;
27160814Ssimon
28160814Ssimonimport java.io.*;
29160814Ssimonimport java.util.*;
30160814Ssimon
31160814Ssimonimport javax.lang.model.element.PackageElement;
32160814Ssimonimport javax.lang.model.element.TypeElement;
33160814Ssimon
34160814Ssimonimport jdk.javadoc.doclet.Doclet.Option;
35160814Ssimonimport jdk.javadoc.doclet.DocletEnvironment;
36160814Ssimonimport jdk.javadoc.doclet.Reporter;
37160814Ssimonimport jdk.javadoc.internal.doclets.toolkit.AbstractDoclet;
38160814Ssimonimport jdk.javadoc.internal.doclets.toolkit.Configuration;
39160814Ssimonimport jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder;
40160814Ssimonimport jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
41160814Ssimonimport jdk.javadoc.internal.doclets.toolkit.util.DocFile;
42160814Ssimonimport jdk.javadoc.internal.doclets.toolkit.util.DocPath;
43160814Ssimonimport jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
44160814Ssimonimport jdk.javadoc.internal.doclets.toolkit.util.DocletAbortException;
45160814Ssimonimport jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder;
46160814Ssimon
47160814Ssimon/**
48160814Ssimon * The class with "start" method, calls individual Writers.
49160814Ssimon *
50160814Ssimon *  <p><b>This is NOT part of any supported API.
51160814Ssimon *  If you write code that depends on this, you do so at your own risk.
52160814Ssimon *  This code and its internal interfaces are subject to change or
53160814Ssimon *  deletion without notice.</b>
54160814Ssimon *
55160814Ssimon * @author Atul M Dambalkar
56160814Ssimon * @author Robert Field
57160814Ssimon * @author Jamie Ho
58160814Ssimon *
59160814Ssimon */
60160814Ssimonpublic class HtmlDoclet extends AbstractDoclet {
61160814Ssimon
62160814Ssimon    public HtmlDoclet() {
63160814Ssimon        configuration = new ConfigurationImpl();
64160814Ssimon    }
65160814Ssimon
66160814Ssimon    /**
67280304Sjkim     * The global configuration information for this run.
68160814Ssimon     */
69160814Ssimon    public final ConfigurationImpl configuration;
70280304Sjkim
71160814Ssimon
72160814Ssimon    private static final DocPath DOCLET_RESOURCES = DocPath
73280304Sjkim            .create("/jdk/javadoc/internal/doclets/formats/html/resources");
74160814Ssimon
75160814Ssimon    public void init(Locale locale, Reporter reporter) {
76160814Ssimon        configuration.reporter = reporter;
77160814Ssimon        configuration.locale = locale;
78280304Sjkim    }
79160814Ssimon
80280304Sjkim    /**
81280304Sjkim     * The "start" method as required by Javadoc.
82280304Sjkim     *
83280304Sjkim     * @param root the root of the documentation tree.
84280304Sjkim     * @see jdk.doclet.DocletEnvironment
85160814Ssimon     * @return true if the doclet ran without encountering any errors.
86280304Sjkim     */
87280304Sjkim    public boolean run(DocletEnvironment root) {
88160814Ssimon        return startDoclet(root);
89280304Sjkim    }
90160814Ssimon
91160814Ssimon    /**
92160814Ssimon     * Create the configuration instance.
93160814Ssimon     * Override this method to use a different
94280304Sjkim     * configuration.
95160814Ssimon     */
96280304Sjkim    public Configuration configuration() {
97280304Sjkim        return configuration;
98160814Ssimon    }
99280304Sjkim
100280304Sjkim    /**
101280304Sjkim     * Start the generation of files. Call generate methods in the individual
102280304Sjkim     * writers, which will in turn genrate the documentation files. Call the
103280304Sjkim     * TreeWriter generation first to ensure the Class Hierarchy is built
104160814Ssimon     * first and then can be used in the later generation.
105280304Sjkim     *
106280304Sjkim     * For new format.
107280304Sjkim     *
108280304Sjkim     * @see jdk.doclet.RootDoc
109280304Sjkim     */
110160814Ssimon    protected void generateOtherFiles(DocletEnvironment root, ClassTree classtree)
111280304Sjkim            throws Exception {
112280304Sjkim        super.generateOtherFiles(root, classtree);
113160814Ssimon        if (configuration.linksource) {
114280304Sjkim            SourceToHTMLConverter.convertRoot(configuration,
115280304Sjkim                root, DocPaths.SOURCE_OUTPUT);
116280304Sjkim        }
117280304Sjkim
118280304Sjkim        if (configuration.topFile.isEmpty()) {
119160814Ssimon            configuration.standardmessage.
120280304Sjkim                error("doclet.No_Non_Deprecated_Classes_To_Document");
121280304Sjkim            return;
122280304Sjkim        }
123160814Ssimon        boolean nodeprecated = configuration.nodeprecated;
124280304Sjkim        performCopy(configuration.helpfile);
125280304Sjkim        performCopy(configuration.stylesheetfile);
126280304Sjkim        // do early to reduce memory footprint
127280304Sjkim        if (configuration.classuse) {
128160814Ssimon            ClassUseWriter.generate(configuration, classtree);
129280304Sjkim        }
130160814Ssimon        IndexBuilder indexbuilder = new IndexBuilder(configuration, nodeprecated);
131280304Sjkim
132160814Ssimon        if (configuration.createtree) {
133160814Ssimon            TreeWriter.generate(configuration, classtree);
134280304Sjkim        }
135160814Ssimon        if (configuration.createindex) {
136280304Sjkim            configuration.buildSearchTagIndex();
137160814Ssimon            if (configuration.splitindex) {
138280304Sjkim                SplitIndexWriter.generate(configuration, indexbuilder);
139280304Sjkim            } else {
140280304Sjkim                SingleIndexWriter.generate(configuration, indexbuilder);
141280304Sjkim            }
142280304Sjkim        }
143280304Sjkim
144160814Ssimon        if (!(configuration.nodeprecatedlist || nodeprecated)) {
145280304Sjkim            DeprecatedListWriter.generate(configuration);
146160814Ssimon        }
147280304Sjkim
148280304Sjkim        AllClassesFrameWriter.generate(configuration,
149280304Sjkim            new IndexBuilder(configuration, nodeprecated, true));
150280304Sjkim
151280304Sjkim        FrameOutputWriter.generate(configuration);
152280304Sjkim
153280304Sjkim        if (configuration.createoverview) {
154280304Sjkim            PackageIndexWriter.generate(configuration);
155280304Sjkim        }
156280304Sjkim        if (configuration.helpfile.length() == 0 &&
157280304Sjkim            !configuration.nohelp) {
158280304Sjkim            HelpWriter.generate(configuration);
159280304Sjkim        }
160280304Sjkim        // If a stylesheet file is not specified, copy the default stylesheet
161280304Sjkim        // and replace newline with platform-specific newline.
162280304Sjkim        DocFile f;
163280304Sjkim        if (configuration.stylesheetfile.length() == 0) {
164160814Ssimon            f = DocFile.createFileForOutput(configuration, DocPaths.STYLESHEET);
165280304Sjkim            f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.STYLESHEET), false, true);
166160814Ssimon        }
167280304Sjkim        f = DocFile.createFileForOutput(configuration, DocPaths.JAVASCRIPT);
168280304Sjkim        f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.JAVASCRIPT), true, true);
169280304Sjkim        if (configuration.createindex) {
170280304Sjkim            f = DocFile.createFileForOutput(configuration, DocPaths.SEARCH_JS);
171280304Sjkim            f.copyResource(DOCLET_RESOURCES.resolve(DocPaths.SEARCH_JS), true, true);
172280304Sjkim
173280304Sjkim            f = DocFile.createFileForOutput(configuration, DocPaths.RESOURCES.resolve(DocPaths.GLASS_IMG));
174280304Sjkim            f.copyResource(DOCLET_RESOURCES.resolve(DocPaths.GLASS_IMG), true, false);
175280304Sjkim
176280304Sjkim            f = DocFile.createFileForOutput(configuration, DocPaths.RESOURCES.resolve(DocPaths.X_IMG));
177280304Sjkim            f.copyResource(DOCLET_RESOURCES.resolve(DocPaths.X_IMG), true, false);
178280304Sjkim            copyJqueryFiles();
179280304Sjkim        }
180280304Sjkim    }
181280304Sjkim
182160814Ssimon    protected void copyJqueryFiles() {
183280304Sjkim        List<String> files = Arrays.asList(
184160814Ssimon                "jquery-1.10.2.js",
185280304Sjkim                "jquery-ui.js",
186280304Sjkim                "jquery-ui.css",
187280304Sjkim                "jquery-ui.min.js",
188280304Sjkim                "jquery-ui.min.css",
189280304Sjkim                "jquery-ui.structure.min.css",
190280304Sjkim                "jquery-ui.structure.css",
191280304Sjkim                "external/jquery/jquery.js",
192280304Sjkim                "jszip/dist/jszip.js",
193280304Sjkim                "jszip/dist/jszip.min.js",
194280304Sjkim                "jszip-utils/dist/jszip-utils.js",
195280304Sjkim                "jszip-utils/dist/jszip-utils.min.js",
196280304Sjkim                "jszip-utils/dist/jszip-utils-ie.js",
197160814Ssimon                "jszip-utils/dist/jszip-utils-ie.min.js",
198160814Ssimon                "images/ui-bg_flat_0_aaaaaa_40x100.png",
199160814Ssimon                "images/ui-icons_454545_256x240.png",
200160814Ssimon                "images/ui-bg_glass_95_fef1ec_1x400.png",
201160814Ssimon                "images/ui-bg_glass_75_dadada_1x400.png",
202280304Sjkim                "images/ui-bg_highlight-soft_75_cccccc_1x100.png",
203280304Sjkim                "images/ui-icons_888888_256x240.png",
204280304Sjkim                "images/ui-icons_2e83ff_256x240.png",
205280304Sjkim                "images/ui-bg_glass_65_ffffff_1x400.png",
206160814Ssimon                "images/ui-icons_cd0a0a_256x240.png",
207280304Sjkim                "images/ui-bg_glass_55_fbf9ee_1x400.png",
208280304Sjkim                "images/ui-icons_222222_256x240.png",
209280304Sjkim                "images/ui-bg_glass_75_e6e6e6_1x400.png",
210280304Sjkim                "images/ui-bg_flat_75_ffffff_40x100.png");
211280304Sjkim        DocFile f;
212280304Sjkim        for (String file : files) {
213280304Sjkim            DocPath filePath = DocPaths.JQUERY_FILES.resolve(file);
214280304Sjkim            f = DocFile.createFileForOutput(configuration, filePath);
215280304Sjkim            f.copyResource(DOCLET_RESOURCES.resolve(filePath), true, false);
216280304Sjkim        }
217280304Sjkim    }
218280304Sjkim
219280304Sjkim    /**
220280304Sjkim     * {@inheritDoc}
221280304Sjkim     */
222280304Sjkim    protected void generateClassFiles(SortedSet<TypeElement> arr, ClassTree classtree) {
223280304Sjkim        List<TypeElement> list = new ArrayList<>(arr);
224280304Sjkim        ListIterator<TypeElement> iterator = list.listIterator();
225280304Sjkim        TypeElement klass = null;
226280304Sjkim        while (iterator.hasNext()) {
227280304Sjkim            TypeElement prev = iterator.hasPrevious() ? klass : null;
228280304Sjkim            klass = iterator.next();
229280304Sjkim            TypeElement next = iterator.nextIndex() == list.size()
230280304Sjkim                    ? null : list.get(iterator.nextIndex());
231280304Sjkim            if (!(configuration.isGeneratedDoc(klass) && utils.isIncluded(klass))) {
232280304Sjkim                continue;
233160814Ssimon            }
234280304Sjkim            try {
235280304Sjkim                if (utils.isAnnotationType(klass)) {
236280304Sjkim                    AbstractBuilder annotationTypeBuilder =
237280304Sjkim                        configuration.getBuilderFactory()
238280304Sjkim                            .getAnnotationTypeBuilder(klass,
239280304Sjkim                                prev == null ? null : prev.asType(),
240280304Sjkim                                next == null ? null : next.asType());
241280304Sjkim                    annotationTypeBuilder.build();
242280304Sjkim                } else {
243280304Sjkim                    AbstractBuilder classBuilder =
244280304Sjkim                        configuration.getBuilderFactory().getClassBuilder(klass,
245280304Sjkim                                prev, next, classtree);
246280304Sjkim                    classBuilder.build();
247280304Sjkim                }
248280304Sjkim            } catch (IOException e) {
249160814Ssimon                throw new DocletAbortException(e);
250280304Sjkim            } catch (DocletAbortException de) {
251280304Sjkim                throw de;
252280304Sjkim            } catch (Exception e) {
253280304Sjkim                e.printStackTrace();
254280304Sjkim                throw new DocletAbortException(e);
255280304Sjkim            }
256280304Sjkim        }
257280304Sjkim    }
258160814Ssimon
259280304Sjkim
260280304Sjkim    /**
261280304Sjkim     * {@inheritDoc}
262280304Sjkim     */
263160814Ssimon    protected void generatePackageFiles(ClassTree classtree) throws Exception {
264280304Sjkim        Set<PackageElement> packages = configuration.packages;
265160814Ssimon        if (packages.size() > 1) {
266280304Sjkim            PackageIndexFrameWriter.generate(configuration);
267280304Sjkim        }
268280304Sjkim        List<PackageElement> pList = new ArrayList<>(packages);
269280304Sjkim        PackageElement prev = null;
270280304Sjkim        for (int i = 0 ; i < pList.size() ; i++) {
271280304Sjkim            // if -nodeprecated option is set and the package is marked as
272280304Sjkim            // deprecated, do not generate the package-summary.html, package-frame.html
273280304Sjkim            // and package-tree.html pages for that package.
274280304Sjkim            PackageElement pkg = pList.get(i);
275280304Sjkim            if (!(configuration.nodeprecated && utils.isDeprecated(pkg))) {
276160814Ssimon                PackageFrameWriter.generate(configuration, pkg);
277160814Ssimon                int nexti = i + 1;
278280304Sjkim                PackageElement next = null;
279280304Sjkim                if (nexti < pList.size()) {
280280304Sjkim                    next = pList.get(nexti);
281280304Sjkim                    // If the next package is unnamed package, skip 2 ahead if possible
282280304Sjkim                    if (next.isUnnamed() && ++nexti < pList.size()) {
283280304Sjkim                       next = pList.get(nexti);
284280304Sjkim                    }
285280304Sjkim                }
286280304Sjkim                AbstractBuilder packageSummaryBuilder =
287280304Sjkim                        configuration.getBuilderFactory().getPackageSummaryBuilder(
288160814Ssimon                        pkg, prev, next);
289280304Sjkim                packageSummaryBuilder.build();
290280304Sjkim                if (configuration.createtree) {
291280304Sjkim                    PackageTreeWriter.generate(configuration, pkg, prev, next,
292280304Sjkim                            configuration.nodeprecated);
293280304Sjkim                }
294280304Sjkim                prev = pkg;
295160814Ssimon            }
296160814Ssimon        }
297160814Ssimon    }
298280304Sjkim
299280304Sjkim    public Set<Option> getSupportedOptions() {
300280304Sjkim        return configuration.getSupportedOptions();
301280304Sjkim    }
302160814Ssimon
303160814Ssimon    private void performCopy(String filename) {
304160814Ssimon        if (filename.isEmpty())
305160814Ssimon            return;
306160814Ssimon
307280304Sjkim        try {
308280304Sjkim            DocFile fromfile = DocFile.createFileForInput(configuration, filename);
309280304Sjkim            DocPath path = DocPath.create(fromfile.getName());
310280304Sjkim            DocFile toFile = DocFile.createFileForOutput(configuration, path);
311280304Sjkim            if (toFile.isSameFile(fromfile))
312280304Sjkim                return;
313280304Sjkim
314160814Ssimon            configuration.message.notice("doclet.Copying_File_0_To_File_1",
315160814Ssimon                    fromfile.toString(), path.getPath());
316280304Sjkim            toFile.copyFile(fromfile);
317280304Sjkim        } catch (IOException exc) {
318160814Ssimon            configuration.message.error("doclet.perform_copy_exception_encountered",
319160814Ssimon                    exc.toString());
320280304Sjkim            throw new DocletAbortException(exc);
321160814Ssimon        }
322160814Ssimon    }
323160814Ssimon}
324160814Ssimon