1 /* 2 * Copyright (c) 2001, 2016, 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.formats.html; 27 28 import java.io.*; 29 import java.util.*; 30 31 import javax.lang.model.element.Modifier; 32 import javax.lang.model.element.PackageElement; 33 import javax.lang.model.element.TypeElement; 34 import javax.lang.model.element.VariableElement; 35 36 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; 37 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; 38 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 40 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 41 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 42 import jdk.javadoc.internal.doclets.toolkit.ConstantsSummaryWriter; 43 import jdk.javadoc.internal.doclets.toolkit.Content; 44 import jdk.javadoc.internal.doclets.toolkit.util.DocLink; 45 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; 46 47 48 /** 49 * Write the Constants Summary Page in HTML format. 50 * 51 * <p><b>This is NOT part of any supported API. 52 * If you write code that depends on this, you do so at your own risk. 53 * This code and its internal interfaces are subject to change or 54 * deletion without notice.</b> 55 * 56 * @author Jamie Ho 57 * @author Bhavesh Patel (Modified) 58 * @since 1.4 59 */ 60 public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements ConstantsSummaryWriter { 61 62 /** 63 * The configuration used in this run of the standard doclet. 64 */ 65 ConfigurationImpl configuration; 66 67 /** 68 * The current class being documented. 69 */ 70 private TypeElement currentTypeElement; 71 72 private final String constantsTableSummary; 73 74 private final List<String> constantsTableHeader; 75 76 /** 77 * The HTML tree for main tag. 78 */ 79 private HtmlTree mainTree = HtmlTree.MAIN(); 80 81 /** 82 * The HTML tree for constant values summary. 83 */ 84 private HtmlTree summaryTree; 85 86 /** 87 * Construct a ConstantsSummaryWriter. 88 * @param configuration the configuration used in this run 89 * of the standard doclet. 90 */ 91 public ConstantsSummaryWriterImpl(ConfigurationImpl configuration) 92 throws IOException { 93 super(configuration, DocPaths.CONSTANT_VALUES); 94 this.configuration = configuration; 95 constantsTableSummary = configuration.getText("doclet.Constants_Table_Summary", 96 configuration.getText("doclet.Constants_Summary")); 97 constantsTableHeader = new ArrayList<>(); 98 constantsTableHeader.add(getModifierTypeHeader()); 99 constantsTableHeader.add(configuration.getText("doclet.ConstantField")); 100 constantsTableHeader.add(configuration.getText("doclet.Value")); 101 } 102 103 /** 104 * {@inheritDoc} 105 */ 106 public Content getHeader() { 107 String label = configuration.getText("doclet.Constants_Summary"); 108 HtmlTree bodyTree = getBody(true, getWindowTitle(label)); 109 HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER)) 110 ? HtmlTree.HEADER() 111 : bodyTree; 112 addTop(htmlTree); 113 addNavLinks(true, htmlTree); 114 if (configuration.allowTag(HtmlTag.HEADER)) { 115 bodyTree.addContent(htmlTree); 116 } 117 return bodyTree; 118 } 119 120 /** 121 * {@inheritDoc} 122 */ 123 public Content getContentsHeader() { 124 return new HtmlTree(HtmlTag.UL); 125 } 126 127 /** 128 * {@inheritDoc} 129 */ 130 public void addLinkToPackageContent(PackageElement pkg, 131 Set<PackageElement> printedPackageHeaders, Content contentListTree) { 132 //add link to summary 133 Content link; 134 if (pkg.isUnnamed()) { 135 link = getHyperLink(getDocLink( 136 SectionName.UNNAMED_PACKAGE_ANCHOR), 137 defaultPackageLabel, "", ""); 138 } else { 139 String parsedPackageName = utils.parsePackageName(pkg); 140 Content packageNameContent = getPackageLabel(parsedPackageName); 141 packageNameContent.addContent(".*"); 142 link = getHyperLink(DocLink.fragment(parsedPackageName), 143 packageNameContent, "", ""); 144 PackageElement abbrevPkg = utils.elementUtils.getPackageElement(parsedPackageName); 145 printedPackageHeaders.add(abbrevPkg); 146 } 147 contentListTree.addContent(HtmlTree.LI(link)); 148 } 149 150 /** 151 * {@inheritDoc} 152 */ 153 public void addContentsList(Content contentTree, Content contentListTree) { 154 Content titleContent = getResource( 155 "doclet.Constants_Summary"); 156 Content pHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true, 157 HtmlStyle.title, titleContent); 158 Content div = HtmlTree.DIV(HtmlStyle.header, pHeading); 159 Content headingContent = getResource( 160 "doclet.Contents"); 161 Content heading = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, true, 162 headingContent); 163 if (configuration.allowTag(HtmlTag.SECTION)) { 164 HtmlTree section = HtmlTree.SECTION(heading); 165 section.addContent(contentListTree); 166 div.addContent(section); 167 mainTree.addContent(div); 168 } else { 169 div.addContent(heading); 170 div.addContent(contentListTree); 171 contentTree.addContent(div); 172 } 173 } 174 175 /** 176 * {@inheritDoc} 177 */ 178 public Content getConstantSummaries() { 179 HtmlTree summariesDiv = new HtmlTree(HtmlTag.DIV); 180 summariesDiv.addStyle(HtmlStyle.constantValuesContainer); 181 return summariesDiv; 182 } 183 184 /** 185 * {@inheritDoc} 186 */ 187 public void addPackageName(PackageElement pkg, Content summariesTree, boolean first) { 188 Content pkgNameContent; 189 if (!first && configuration.allowTag(HtmlTag.SECTION)) { 190 summariesTree.addContent(summaryTree); 191 } 192 if (pkg.isUnnamed()) { 193 summariesTree.addContent(getMarkerAnchor( 194 SectionName.UNNAMED_PACKAGE_ANCHOR)); 195 pkgNameContent = defaultPackageLabel; 196 } else { 197 String parsedPackageName = utils.parsePackageName(pkg); 198 summariesTree.addContent(getMarkerAnchor(parsedPackageName)); 199 pkgNameContent = getPackageLabel(parsedPackageName); 200 } 201 Content headingContent = new StringContent(".*"); 202 Content heading = HtmlTree.HEADING(HtmlConstants.PACKAGE_HEADING, true, 203 pkgNameContent); 204 heading.addContent(headingContent); 205 if (configuration.allowTag(HtmlTag.SECTION)) { 206 summaryTree = HtmlTree.SECTION(heading); 207 } else { 208 summariesTree.addContent(heading); 209 } 210 } 211 212 /** 213 * {@inheritDoc} 214 */ 215 public Content getClassConstantHeader() { 216 HtmlTree ul = new HtmlTree(HtmlTag.UL); 217 ul.addStyle(HtmlStyle.blockList); 218 return ul; 219 } 220 221 /** 222 * {@inheritDoc} 223 */ 224 public void addClassConstant(Content summariesTree, Content classConstantTree) { 225 if (configuration.allowTag(HtmlTag.SECTION)) { 226 summaryTree.addContent(classConstantTree); 227 } else { 228 summariesTree.addContent(classConstantTree); 229 } 230 } 231 232 /** 233 * Get the table caption and header for the constant summary table 234 * 235 * @param typeElement the TypeElement to be documented 236 * @return constant members header content 237 */ 238 public Content getConstantMembersHeader(TypeElement typeElement) { 239 //generate links backward only to public classes. 240 Content classlink = (utils.isPublic(typeElement) || utils.isProtected(typeElement)) ? 241 getLink(new LinkInfoImpl(configuration, 242 LinkInfoImpl.Kind.CONSTANT_SUMMARY, typeElement)) : 243 new StringContent(utils.getFullyQualifiedName(typeElement)); 244 245 PackageElement enclosingPackage = utils.containingPackage(typeElement); 246 if (!enclosingPackage.isUnnamed()) { 247 Content cb = new ContentBuilder(); 248 cb.addContent(enclosingPackage.getQualifiedName().toString()); 249 cb.addContent("."); 250 cb.addContent(classlink); 251 return getClassName(cb); 252 } else { 253 return getClassName(classlink); 254 } 255 } 256 257 /** 258 * Get the class name in the table caption and the table header. 259 * 260 * @param classStr the class name to print. 261 * @return the table caption and header 262 */ 263 protected Content getClassName(Content classStr) { 264 Content caption = getTableCaption(classStr); 265 Content table = (configuration.isOutputHtml5()) 266 ? HtmlTree.TABLE(HtmlStyle.constantsSummary, caption) 267 : HtmlTree.TABLE(HtmlStyle.constantsSummary, constantsTableSummary, caption); 268 table.addContent(getSummaryTableHeader(constantsTableHeader, "col")); 269 return table; 270 } 271 272 /** 273 * {@inheritDoc} 274 */ 275 public void addConstantMembers(TypeElement typeElement, Collection<VariableElement> fields, 276 Content classConstantTree) { 277 currentTypeElement = typeElement; 278 Content tbody = new HtmlTree(HtmlTag.TBODY); 279 boolean altColor = true; 280 for (VariableElement field : fields) { 281 HtmlTree tr = new HtmlTree(HtmlTag.TR); 282 tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor); 283 addConstantMember(field, tr); 284 tbody.addContent(tr); 285 altColor = !altColor; 286 } 287 Content table = getConstantMembersHeader(typeElement); 288 table.addContent(tbody); 289 Content li = HtmlTree.LI(HtmlStyle.blockList, table); 290 classConstantTree.addContent(li); 291 } 292 293 /** 294 * Add the row for the constant summary table. 295 * 296 * @param member the field to be documented. 297 * @param trTree an htmltree object for the table row 298 */ 299 private void addConstantMember(VariableElement member, HtmlTree trTree) { 300 trTree.addContent(getTypeColumn(member)); 301 trTree.addContent(getNameColumn(member)); 302 trTree.addContent(getValue(member)); 303 } 304 305 /** 306 * Get the type column for the constant summary table row. 307 * 308 * @param member the field to be documented. 309 * @return the type column of the constant table row 310 */ 311 private Content getTypeColumn(VariableElement member) { 312 Content anchor = getMarkerAnchor(currentTypeElement.getQualifiedName() + 313 "." + member.getSimpleName()); 314 Content tdType = HtmlTree.TD(HtmlStyle.colFirst, anchor); 315 Content code = new HtmlTree(HtmlTag.CODE); 316 for (Modifier mod : member.getModifiers()) { 317 Content modifier = new StringContent(mod.toString()); 318 code.addContent(modifier); 319 code.addContent(getSpace()); 320 } 321 Content type = getLink(new LinkInfoImpl(configuration, 322 LinkInfoImpl.Kind.CONSTANT_SUMMARY, member.asType())); 323 code.addContent(type); 324 tdType.addContent(code); 325 return tdType; 326 } 327 328 /** 329 * Get the name column for the constant summary table row. 330 * 331 * @param member the field to be documented. 332 * @return the name column of the constant table row 333 */ 334 private Content getNameColumn(VariableElement member) { 335 Content nameContent = getDocLink(LinkInfoImpl.Kind.CONSTANT_SUMMARY, 336 member, member.getSimpleName().toString(), false); 337 Content code = HtmlTree.CODE(nameContent); 338 return HtmlTree.TD(code); 339 } 340 341 /** 342 * Get the value column for the constant summary table row. 343 * 344 * @param member the field to be documented. 345 * @return the value column of the constant table row 346 */ 347 private Content getValue(VariableElement member) { 348 String value = utils.constantValueExpresion(member); 349 Content valueContent = new StringContent(value); 350 Content code = HtmlTree.CODE(valueContent); 351 return HtmlTree.TD(HtmlStyle.colLast, code); 352 } 353 354 /** 355 * {@inheritDoc} 356 */ 357 public void addConstantSummaries(Content contentTree, Content summariesTree) { 358 if (configuration.allowTag(HtmlTag.SECTION) && summaryTree != null) { 359 summariesTree.addContent(summaryTree); 360 } 361 if (configuration.allowTag(HtmlTag.MAIN)) { 362 mainTree.addContent(summariesTree); 363 contentTree.addContent(mainTree); 364 } else { 365 contentTree.addContent(summariesTree); 366 } 367 } 368 369 /** 370 * {@inheritDoc} 371 */ 372 public void addFooter(Content contentTree) { 373 Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER)) 374 ? HtmlTree.FOOTER() 375 : contentTree; 376 addNavLinks(false, htmlTree); 377 addBottom(htmlTree); 378 if (configuration.allowTag(HtmlTag.FOOTER)) { 379 contentTree.addContent(htmlTree); 380 } 381 } 382 383 /** 384 * {@inheritDoc} 385 */ 386 public void printDocument(Content contentTree) throws IOException { 387 printHtmlDocument(null, true, contentTree); 388 } 389 }