1/* 2 * Copyright (c) 1997, 2017, 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 26package jdk.javadoc.internal.doclets.formats.html; 27 28import java.util.*; 29 30import javax.lang.model.element.ModuleElement; 31import javax.lang.model.element.PackageElement; 32import javax.lang.model.element.TypeElement; 33 34import jdk.javadoc.doclet.DocletEnvironment; 35import jdk.javadoc.doclet.Reporter; 36import jdk.javadoc.internal.doclets.toolkit.AbstractDoclet; 37import jdk.javadoc.internal.doclets.toolkit.DocletException; 38import jdk.javadoc.internal.doclets.toolkit.Messages; 39import jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder; 40import jdk.javadoc.internal.doclets.toolkit.util.ClassTree; 41import jdk.javadoc.internal.doclets.toolkit.util.DocFile; 42import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; 43import jdk.javadoc.internal.doclets.toolkit.util.DocPath; 44import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; 45import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder; 46 47/** 48 * The class with "start" method, calls individual Writers. 49 * 50 * <p><b>This is NOT part of any supported API. 51 * If you write code that depends on this, you do so at your own risk. 52 * This code and its internal interfaces are subject to change or 53 * deletion without notice.</b> 54 * 55 * @author Atul M Dambalkar 56 * @author Robert Field 57 * @author Jamie Ho 58 * 59 */ 60public class HtmlDoclet extends AbstractDoclet { 61 62 public HtmlDoclet() { 63 configuration = new HtmlConfiguration(this); 64 } 65 66 @Override // defined by Doclet 67 public String getName() { 68 return "Html"; 69 } 70 71 /** 72 * The global configuration information for this run. 73 */ 74 private final HtmlConfiguration configuration; 75 76 private Messages messages; 77 78 79 private static final DocPath DOCLET_RESOURCES = DocPath 80 .create("/jdk/javadoc/internal/doclets/formats/html/resources"); 81 82 @Override // defined by Doclet 83 public void init(Locale locale, Reporter reporter) { 84 configuration.reporter = reporter; 85 configuration.locale = locale; 86 messages = configuration.getMessages(); 87 } 88 89 /** 90 * Create the configuration instance. 91 * Override this method to use a different 92 * configuration. 93 * 94 * @return the configuration 95 */ 96 @Override // defined by AbstractDoclet 97 public HtmlConfiguration getConfiguration() { 98 return configuration; 99 } 100 101 /** 102 * Start the generation of files. Call generate methods in the individual 103 * writers, which will in turn generate the documentation files. Call the 104 * TreeWriter generation first to ensure the Class Hierarchy is built 105 * first and then can be used in the later generation. 106 * 107 * For new format. 108 * 109 * @throws DocletException if there is a problem while writing the other files 110 * @see jdk.doclet.DocletEnvironment 111 */ 112 @Override // defined by AbstractDoclet 113 protected void generateOtherFiles(DocletEnvironment docEnv, ClassTree classtree) 114 throws DocletException { 115 super.generateOtherFiles(docEnv, classtree); 116 if (configuration.linksource) { 117 SourceToHTMLConverter.convertRoot(configuration, 118 docEnv, DocPaths.SOURCE_OUTPUT); 119 } 120 121 if (configuration.topFile.isEmpty()) { 122 messages.error("doclet.No_Non_Deprecated_Classes_To_Document"); 123 return; 124 } 125 boolean nodeprecated = configuration.nodeprecated; 126 performCopy(configuration.helpfile); 127 performCopy(configuration.stylesheetfile); 128 // do early to reduce memory footprint 129 if (configuration.classuse) { 130 ClassUseWriter.generate(configuration, classtree); 131 } 132 IndexBuilder indexbuilder = new IndexBuilder(configuration, nodeprecated); 133 134 if (configuration.createtree) { 135 TreeWriter.generate(configuration, classtree); 136 } 137 if (configuration.createindex) { 138 configuration.buildSearchTagIndex(); 139 if (configuration.splitindex) { 140 SplitIndexWriter.generate(configuration, indexbuilder); 141 } else { 142 SingleIndexWriter.generate(configuration, indexbuilder); 143 } 144 } 145 146 if (!(configuration.nodeprecatedlist || nodeprecated)) { 147 DeprecatedListWriter.generate(configuration); 148 } 149 150 AllClassesFrameWriter.generate(configuration, 151 new IndexBuilder(configuration, nodeprecated, true)); 152 153 if (configuration.frames) { 154 FrameOutputWriter.generate(configuration); 155 } 156 157 if (configuration.createoverview) { 158 if (configuration.showModules) { 159 ModuleIndexWriter.generate(configuration); 160 } else { 161 PackageIndexWriter.generate(configuration); 162 } 163 } 164 165 if (!configuration.frames && !configuration.createoverview) { 166 IndexRedirectWriter.generate(configuration); 167 } 168 169 if (configuration.helpfile.isEmpty() && !configuration.nohelp) { 170 HelpWriter.generate(configuration); 171 } 172 // If a stylesheet file is not specified, copy the default stylesheet 173 // and replace newline with platform-specific newline. 174 DocFile f; 175 if (configuration.stylesheetfile.length() == 0) { 176 f = DocFile.createFileForOutput(configuration, DocPaths.STYLESHEET); 177 f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.STYLESHEET), false, true); 178 } 179 f = DocFile.createFileForOutput(configuration, DocPaths.JAVASCRIPT); 180 f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.JAVASCRIPT), true, true); 181 if (configuration.createindex) { 182 f = DocFile.createFileForOutput(configuration, DocPaths.SEARCH_JS); 183 f.copyResource(DOCLET_RESOURCES.resolve(DocPaths.SEARCH_JS), true, true); 184 185 f = DocFile.createFileForOutput(configuration, DocPaths.RESOURCES.resolve(DocPaths.GLASS_IMG)); 186 f.copyResource(DOCLET_RESOURCES.resolve(DocPaths.GLASS_IMG), true, false); 187 188 f = DocFile.createFileForOutput(configuration, DocPaths.RESOURCES.resolve(DocPaths.X_IMG)); 189 f.copyResource(DOCLET_RESOURCES.resolve(DocPaths.X_IMG), true, false); 190 copyJqueryFiles(); 191 } 192 } 193 194 protected void copyJqueryFiles() throws DocletException { 195 List<String> files = Arrays.asList( 196 "jquery-1.10.2.js", 197 "jquery-ui.js", 198 "jquery-ui.css", 199 "jquery-ui.min.js", 200 "jquery-ui.min.css", 201 "jquery-ui.structure.min.css", 202 "jquery-ui.structure.css", 203 "external/jquery/jquery.js", 204 "jszip/dist/jszip.js", 205 "jszip/dist/jszip.min.js", 206 "jszip-utils/dist/jszip-utils.js", 207 "jszip-utils/dist/jszip-utils.min.js", 208 "jszip-utils/dist/jszip-utils-ie.js", 209 "jszip-utils/dist/jszip-utils-ie.min.js", 210 "images/ui-bg_flat_0_aaaaaa_40x100.png", 211 "images/ui-icons_454545_256x240.png", 212 "images/ui-bg_glass_95_fef1ec_1x400.png", 213 "images/ui-bg_glass_75_dadada_1x400.png", 214 "images/ui-bg_highlight-soft_75_cccccc_1x100.png", 215 "images/ui-icons_888888_256x240.png", 216 "images/ui-icons_2e83ff_256x240.png", 217 "images/ui-bg_glass_65_ffffff_1x400.png", 218 "images/ui-icons_cd0a0a_256x240.png", 219 "images/ui-bg_glass_55_fbf9ee_1x400.png", 220 "images/ui-icons_222222_256x240.png", 221 "images/ui-bg_glass_75_e6e6e6_1x400.png", 222 "images/ui-bg_flat_75_ffffff_40x100.png"); 223 DocFile f; 224 for (String file : files) { 225 DocPath filePath = DocPaths.JQUERY_FILES.resolve(file); 226 f = DocFile.createFileForOutput(configuration, filePath); 227 f.copyResource(DOCLET_RESOURCES.resolve(filePath), true, false); 228 } 229 } 230 231 /** 232 * {@inheritDoc} 233 */ 234 @Override // defined by AbstractDoclet 235 protected void generateClassFiles(SortedSet<TypeElement> arr, ClassTree classtree) 236 throws DocletException { 237 List<TypeElement> list = new ArrayList<>(arr); 238 ListIterator<TypeElement> iterator = list.listIterator(); 239 TypeElement klass = null; 240 while (iterator.hasNext()) { 241 TypeElement prev = iterator.hasPrevious() ? klass : null; 242 klass = iterator.next(); 243 TypeElement next = iterator.nextIndex() == list.size() 244 ? null : list.get(iterator.nextIndex()); 245 246 if (utils.isHidden(klass) || 247 !(configuration.isGeneratedDoc(klass) && utils.isIncluded(klass))) { 248 continue; 249 } 250 251 if (utils.isAnnotationType(klass)) { 252 AbstractBuilder annotationTypeBuilder = 253 configuration.getBuilderFactory() 254 .getAnnotationTypeBuilder(klass, 255 prev == null ? null : prev.asType(), 256 next == null ? null : next.asType()); 257 annotationTypeBuilder.build(); 258 } else { 259 AbstractBuilder classBuilder = 260 configuration.getBuilderFactory().getClassBuilder(klass, 261 prev, next, classtree); 262 classBuilder.build(); 263 } 264 } 265 } 266 267 /** 268 * {@inheritDoc} 269 */ 270 @Override // defined by AbstractDoclet 271 protected void generateModuleFiles() throws DocletException { 272 if (configuration.showModules) { 273 if (configuration.frames && configuration.modules.size() > 1) { 274 ModuleIndexFrameWriter.generate(configuration); 275 } 276 ModuleElement prevModule = null, nextModule; 277 List<ModuleElement> mdles = new ArrayList<>(configuration.modulePackages.keySet()); 278 int i = 0; 279 for (ModuleElement mdle : mdles) { 280 if (configuration.frames && configuration.modules.size() > 1) { 281 ModulePackageIndexFrameWriter.generate(configuration, mdle); 282 ModuleFrameWriter.generate(configuration, mdle); 283 } 284 nextModule = (i + 1 < mdles.size()) ? mdles.get(i + 1) : null; 285 AbstractBuilder moduleSummaryBuilder = 286 configuration.getBuilderFactory().getModuleSummaryBuilder( 287 mdle, prevModule, nextModule); 288 moduleSummaryBuilder.build(); 289 prevModule = mdle; 290 i++; 291 } 292 } 293 } 294 295 PackageElement getNamedPackage(List<PackageElement> list, int idx) { 296 if (idx < list.size()) { 297 PackageElement pkg = list.get(idx); 298 if (pkg != null && !pkg.isUnnamed()) { 299 return pkg; 300 } 301 } 302 return null; 303 } 304 305 /** 306 * {@inheritDoc} 307 */ 308 @Override // defined by AbstractDoclet 309 protected void generatePackageFiles(ClassTree classtree) throws DocletException { 310 Set<PackageElement> packages = configuration.packages; 311 if (packages.size() > 1 && configuration.frames) { 312 PackageIndexFrameWriter.generate(configuration); 313 } 314 List<PackageElement> pList = new ArrayList<>(packages); 315 PackageElement prev = null; 316 for (int i = 0 ; i < pList.size() ; i++) { 317 // if -nodeprecated option is set and the package is marked as 318 // deprecated, do not generate the package-summary.html, package-frame.html 319 // and package-tree.html pages for that package. 320 PackageElement pkg = pList.get(i); 321 if (!(configuration.nodeprecated && utils.isDeprecated(pkg))) { 322 if (configuration.frames) { 323 PackageFrameWriter.generate(configuration, pkg); 324 } 325 int nexti = i + 1; 326 PackageElement next = null; 327 if (nexti < pList.size()) { 328 next = pList.get(nexti); 329 // If the next package is unnamed package, skip 2 ahead if possible 330 if (next.isUnnamed() && ++nexti < pList.size()) { 331 next = pList.get(nexti); 332 } 333 } 334 AbstractBuilder packageSummaryBuilder = 335 configuration.getBuilderFactory().getPackageSummaryBuilder( 336 pkg, prev, next); 337 packageSummaryBuilder.build(); 338 if (configuration.createtree) { 339 PackageTreeWriter.generate(configuration, pkg, prev, next, 340 configuration.nodeprecated); 341 } 342 prev = pkg; 343 } 344 } 345 } 346 347 @Override // defined by Doclet 348 public Set<Option> getSupportedOptions() { 349 return configuration.getSupportedOptions(); 350 } 351 352 private void performCopy(String filename) throws DocFileIOException { 353 if (filename.isEmpty()) 354 return; 355 356 DocFile fromfile = DocFile.createFileForInput(configuration, filename); 357 DocPath path = DocPath.create(fromfile.getName()); 358 DocFile toFile = DocFile.createFileForOutput(configuration, path); 359 if (toFile.isSameFile(fromfile)) 360 return; 361 362 messages.notice("doclet.Copying_File_0_To_File_1", 363 fromfile.toString(), path.getPath()); 364 toFile.copyFile(fromfile); 365 } 366} 367