1 /* 2 * Copyright (c) 2003, 2019, 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 jdk.javadoc.internal.doclets.toolkit.builders; 27 28 import javax.lang.model.element.PackageElement; 29 import javax.lang.model.element.TypeElement; 30 31 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; 32 import jdk.javadoc.internal.doclets.toolkit.ClassWriter; 33 import jdk.javadoc.internal.doclets.toolkit.Content; 34 import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler; 35 import jdk.javadoc.internal.doclets.toolkit.DocletException; 36 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; 37 import jdk.javadoc.internal.doclets.toolkit.util.Utils; 38 39 /** 40 * Builds the summary for a given class. 41 * 42 * <p><b>This is NOT part of any supported API. 43 * If you write code that depends on this, you do so at your own risk. 44 * This code and its internal interfaces are subject to change or 45 * deletion without notice.</b> 46 * 47 * @author Jamie Ho 48 * @author Bhavesh Patel (Modified) 49 */ 50 public class ClassBuilder extends AbstractBuilder { 51 52 /** 53 * The class being documented. 54 */ 55 private final TypeElement typeElement; 56 57 /** 58 * The doclet specific writer. 59 */ 60 private final ClassWriter writer; 61 62 /** 63 * Keep track of whether or not this typeElement is an interface. 64 */ 65 private final boolean isInterface; 66 67 /** 68 * Keep track of whether or not this typeElement is an enum. 69 */ 70 private final boolean isEnum; 71 72 /** 73 * The content tree for the class documentation. 74 */ 75 private Content contentTree; 76 77 private final Utils utils; 78 79 /** 80 * Construct a new ClassBuilder. 81 * 82 * @param context the build context 83 * @param typeElement the class being documented. 84 * @param writer the doclet specific writer. 85 */ 86 private ClassBuilder(Context context, TypeElement typeElement, ClassWriter writer) { 87 super(context); 88 this.typeElement = typeElement; 89 this.writer = writer; 90 this.utils = configuration.utils; 91 if (utils.isInterface(typeElement)) { 92 isInterface = true; 93 isEnum = false; 94 } else if (utils.isEnum(typeElement)) { 95 isInterface = false; 96 isEnum = true; 97 utils.setEnumDocumentation(typeElement); 98 } else { 99 isInterface = false; 100 isEnum = false; 101 } 102 } 103 104 /** 105 * Constructs a new ClassBuilder. 106 * 107 * @param context the build context 108 * @param typeElement the class being documented. 109 * @param writer the doclet specific writer. 110 * @return the new ClassBuilder 111 */ 112 public static ClassBuilder getInstance(Context context, TypeElement typeElement, ClassWriter writer) { 113 return new ClassBuilder(context, typeElement, writer); 114 } 115 116 /** 117 * {@inheritDoc} 118 */ 119 @Override 120 public void build() throws DocletException { 121 buildClassDoc(contentTree); 122 } 123 124 /** 125 * Handles the {@literal <TypeElement>} tag. 126 * 127 * @param contentTree the content tree to which the documentation will be added 128 * @throws DocletException if there is a problem while building the documentation 129 */ 130 protected void buildClassDoc(Content contentTree) throws DocletException { 131 String key; 132 if (isInterface) { 133 key = "doclet.Interface"; 134 } else if (isEnum) { 135 key = "doclet.Enum"; 136 } else { 137 key = "doclet.Class"; 138 } 139 contentTree = writer.getHeader(resources.getText(key) + " " 140 + utils.getSimpleName(typeElement)); 141 Content classContentTree = writer.getClassContentHeader(); 142 143 buildClassTree(classContentTree); 144 buildClassInfo(classContentTree); 145 buildMemberSummary(classContentTree); 146 buildMemberDetails(classContentTree); 147 148 writer.addClassContentTree(contentTree, classContentTree); 149 writer.addFooter(contentTree); 150 writer.printDocument(contentTree); 151 copyDocFiles(); 152 } 153 154 /** 155 * Build the class tree documentation. 156 * 157 * @param classContentTree the content tree to which the documentation will be added 158 */ 159 protected void buildClassTree(Content classContentTree) { 160 writer.addClassTree(classContentTree); 161 } 162 163 /** 164 * Build the class information tree documentation. 165 * 166 * @param classContentTree the content tree to which the documentation will be added 167 * @throws DocletException if there is a problem while building the documentation 168 */ 169 protected void buildClassInfo(Content classContentTree) throws DocletException { 170 Content classInfoTree = new ContentBuilder(); 171 buildTypeParamInfo(classInfoTree); 172 buildSuperInterfacesInfo(classInfoTree); 173 buildImplementedInterfacesInfo(classInfoTree); 174 buildSubClassInfo(classInfoTree); 175 buildSubInterfacesInfo(classInfoTree); 176 buildInterfaceUsageInfo(classInfoTree); 177 buildNestedClassInfo(classInfoTree); 178 buildFunctionalInterfaceInfo(classInfoTree); 179 buildClassSignature(classInfoTree); 180 buildDeprecationInfo(classInfoTree); 181 buildClassDescription(classInfoTree); 182 buildClassTagInfo(classInfoTree); 183 184 classContentTree.add(writer.getClassInfo(classInfoTree)); 185 } 186 187 /** 188 * Build the type parameters of this class. 189 * 190 * @param classInfoTree the content tree to which the documentation will be added 191 */ 192 protected void buildTypeParamInfo(Content classInfoTree) { 193 writer.addTypeParamInfo(classInfoTree); 194 } 195 196 /** 197 * If this is an interface, list all super interfaces. 198 * 199 * @param classInfoTree the content tree to which the documentation will be added 200 */ 201 protected void buildSuperInterfacesInfo(Content classInfoTree) { 202 writer.addSuperInterfacesInfo(classInfoTree); 203 } 204 205 /** 206 * If this is a class, list all interfaces implemented by this class. 207 * 208 * @param classInfoTree the content tree to which the documentation will be added 209 */ 210 protected void buildImplementedInterfacesInfo(Content classInfoTree) { 211 writer.addImplementedInterfacesInfo(classInfoTree); 212 } 213 214 /** 215 * List all the classes extend this one. 216 * 217 * @param classInfoTree the content tree to which the documentation will be added 218 */ 219 protected void buildSubClassInfo(Content classInfoTree) { 220 writer.addSubClassInfo(classInfoTree); 221 } 222 223 /** 224 * List all the interfaces that extend this one. 225 * 226 * @param classInfoTree the content tree to which the documentation will be added 227 */ 228 protected void buildSubInterfacesInfo(Content classInfoTree) { 229 writer.addSubInterfacesInfo(classInfoTree); 230 } 231 232 /** 233 * If this is an interface, list all classes that implement this interface. 234 * 235 * @param classInfoTree the content tree to which the documentation will be added 236 */ 237 protected void buildInterfaceUsageInfo(Content classInfoTree) { 238 writer.addInterfaceUsageInfo(classInfoTree); 239 } 240 241 /** 242 * If this is an functional interface, display appropriate message. 243 * 244 * @param classInfoTree the content tree to which the documentation will be added 245 */ 246 protected void buildFunctionalInterfaceInfo(Content classInfoTree) { 247 writer.addFunctionalInterfaceInfo(classInfoTree); 248 } 249 250 /** 251 * If this class is deprecated, build the appropriate information. 252 * 253 * @param classInfoTree the content tree to which the documentation will be added 254 */ 255 protected void buildDeprecationInfo(Content classInfoTree) { 256 writer.addClassDeprecationInfo(classInfoTree); 257 } 258 259 /** 260 * If this is an inner class or interface, list the enclosing class or interface. 261 * 262 * @param classInfoTree the content tree to which the documentation will be added 263 */ 264 protected void buildNestedClassInfo(Content classInfoTree) { 265 writer.addNestedClassInfo(classInfoTree); 266 } 267 268 /** 269 * Copy the doc files. 270 * 271 * @throws DocFileIOException if there is a problem while copying the files 272 */ 273 private void copyDocFiles() throws DocletException { 274 PackageElement containingPackage = utils.containingPackage(typeElement); 275 if ((configuration.packages == null || 276 !configuration.packages.contains(containingPackage)) && 277 !containingPackagesSeen.contains(containingPackage)) { 278 //Only copy doc files dir if the containing package is not 279 //documented AND if we have not documented a class from the same 280 //package already. Otherwise, we are making duplicate copies. 281 DocFilesHandler docFilesHandler = configuration 282 .getWriterFactory() 283 .getDocFilesHandler(containingPackage); 284 docFilesHandler.copyDocFiles(); 285 containingPackagesSeen.add(containingPackage); 286 } 287 } 288 289 /** 290 * Build the signature of the current class. 291 * 292 * @param classInfoTree the content tree to which the documentation will be added 293 */ 294 protected void buildClassSignature(Content classInfoTree) { 295 writer.addClassSignature(utils.modifiersToString(typeElement, true), classInfoTree); 296 } 297 298 /** 299 * Build the class description. 300 * 301 * @param classInfoTree the content tree to which the documentation will be added 302 */ 303 protected void buildClassDescription(Content classInfoTree) { 304 writer.addClassDescription(classInfoTree); 305 } 306 307 /** 308 * Build the tag information for the current class. 309 * 310 * @param classInfoTree the content tree to which the documentation will be added 311 */ 312 protected void buildClassTagInfo(Content classInfoTree) { 313 writer.addClassTagInfo(classInfoTree); 314 } 315 316 /** 317 * Build the member summary contents of the page. 318 * 319 * @param classContentTree the content tree to which the documentation will be added 320 * @throws DocletException if there is a problem while building the documentation 321 */ 322 protected void buildMemberSummary(Content classContentTree) throws DocletException { 323 Content memberSummaryTree = writer.getMemberTreeHeader(); 324 builderFactory.getMemberSummaryBuilder(writer).build(memberSummaryTree); 325 classContentTree.add(writer.getMemberSummaryTree(memberSummaryTree)); 326 } 327 328 /** 329 * Build the member details contents of the page. 330 * 331 * @param classContentTree the content tree to which the documentation will be added 332 * @throws DocletException if there is a problem while building the documentation 333 */ 334 protected void buildMemberDetails(Content classContentTree) throws DocletException { 335 Content memberDetailsTree = writer.getMemberTreeHeader(); 336 337 buildEnumConstantsDetails(memberDetailsTree); 338 buildPropertyDetails(memberDetailsTree); 339 buildFieldDetails(memberDetailsTree); 340 buildConstructorDetails(memberDetailsTree); 341 buildMethodDetails(memberDetailsTree); 342 343 classContentTree.add(writer.getMemberDetailsTree(memberDetailsTree)); 344 } 345 346 /** 347 * Build the enum constants documentation. 348 * 349 * @param memberDetailsTree the content tree to which the documentation will be added 350 * @throws DocletException if there is a problem while building the documentation 351 */ 352 protected void buildEnumConstantsDetails(Content memberDetailsTree) throws DocletException { 353 builderFactory.getEnumConstantsBuilder(writer).build(memberDetailsTree); 354 } 355 356 /** 357 * Build the field documentation. 358 * 359 * @param memberDetailsTree the content tree to which the documentation will be added 360 * @throws DocletException if there is a problem while building the documentation 361 */ 362 protected void buildFieldDetails(Content memberDetailsTree) throws DocletException { 363 builderFactory.getFieldBuilder(writer).build(memberDetailsTree); 364 } 365 366 /** 367 * Build the property documentation. 368 * 369 * @param memberDetailsTree the content tree to which the documentation will be added 370 * @throws DocletException if there is a problem while building the documentation 371 */ 372 public void buildPropertyDetails( Content memberDetailsTree) throws DocletException { 373 builderFactory.getPropertyBuilder(writer).build(memberDetailsTree); 374 } 375 376 /** 377 * Build the constructor documentation. 378 * 379 * @param memberDetailsTree the content tree to which the documentation will be added 380 * @throws DocletException if there is a problem while building the documentation 381 */ 382 protected void buildConstructorDetails(Content memberDetailsTree) throws DocletException { 383 builderFactory.getConstructorBuilder(writer).build(memberDetailsTree); 384 } 385 386 /** 387 * Build the method documentation. 388 * 389 * @param memberDetailsTree the content tree to which the documentation will be added 390 * @throws DocletException if there is a problem while building the documentation 391 */ 392 protected void buildMethodDetails(Content memberDetailsTree) throws DocletException { 393 builderFactory.getMethodBuilder(writer).build(memberDetailsTree); 394 } 395 }