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