001/* 002 * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package org.jdrupes.mdoclet.internal.doclets.formats.html; 027 028import java.util.Collection; 029 030import javax.lang.model.element.Modifier; 031import javax.lang.model.element.PackageElement; 032import javax.lang.model.element.TypeElement; 033import javax.lang.model.element.VariableElement; 034 035import org.jdrupes.mdoclet.internal.doclets.formats.html.Navigation.PageMode; 036import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.BodyContents; 037import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.ContentBuilder; 038import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.Entity; 039import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlId; 040import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlStyle; 041import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlTree; 042import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.TagName; 043import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.Text; 044import org.jdrupes.mdoclet.internal.doclets.toolkit.ConstantsSummaryWriter; 045import org.jdrupes.mdoclet.internal.doclets.toolkit.Content; 046import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocFileIOException; 047import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocLink; 048import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocPaths; 049import org.jdrupes.mdoclet.internal.doclets.toolkit.util.IndexItem; 050 051/** 052 * Write the Constants Summary Page in HTML format. 053 */ 054public class ConstantsSummaryWriterImpl extends HtmlDocletWriter 055 implements ConstantsSummaryWriter { 056 057 /** 058 * The current class being documented. 059 */ 060 private TypeElement currentTypeElement; 061 062 private final TableHeader constantsTableHeader; 063 064 /** 065 * The HTML tree for constant values summary currently being written. 066 */ 067 private HtmlTree summarySection; 068 069 private final BodyContents bodyContents = new BodyContents(); 070 071 private boolean hasConstants = false; 072 073 /** 074 * Construct a ConstantsSummaryWriter. 075 * @param configuration the configuration used in this run 076 * of the standard doclet. 077 */ 078 public ConstantsSummaryWriterImpl(HtmlConfiguration configuration) { 079 super(configuration, DocPaths.CONSTANT_VALUES); 080 constantsTableHeader = new TableHeader( 081 contents.modifierAndTypeLabel, contents.constantFieldLabel, 082 contents.valueLabel); 083 configuration.conditionalPages 084 .add(HtmlConfiguration.ConditionalPage.CONSTANT_VALUES); 085 } 086 087 @Override 088 public Content getHeader() { 089 String label = resources.getText("doclet.Constants_Summary"); 090 HtmlTree body = getBody(getWindowTitle(label)); 091 bodyContents.setHeader(getHeader(PageMode.CONSTANT_VALUES)); 092 return body; 093 } 094 095 @Override 096 public Content getContentsHeader() { 097 return HtmlTree.UL(HtmlStyle.contentsList); 098 } 099 100 @Override 101 public void addLinkToPackageContent(String abbrevPackageName, 102 Content content) { 103 // add link to summary 104 Content link; 105 if (abbrevPackageName.isEmpty()) { 106 link = links.createLink(HtmlIds.UNNAMED_PACKAGE_ANCHOR, 107 contents.defaultPackageLabel, ""); 108 } else { 109 Content packageNameContent = Text.of(abbrevPackageName + ".*"); 110 link = links.createLink(DocLink.fragment(abbrevPackageName), 111 packageNameContent, ""); 112 } 113 content.add(HtmlTree.LI(link)); 114 } 115 116 @Override 117 public void addContentsList(Content content) { 118 Content titleContent = contents.constantsSummaryTitle; 119 var pHeading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, 120 HtmlStyle.title, titleContent); 121 var div = HtmlTree.DIV(HtmlStyle.header, pHeading); 122 bodyContents.addMainContent(div); 123 Content headingContent = contents.contentsHeading; 124 var heading = HtmlTree.HEADING_TITLE(Headings.CONTENT_HEADING, 125 headingContent); 126 var section = HtmlTree.SECTION(HtmlStyle.packages, heading); 127 section.add(content); 128 bodyContents.addMainContent(section); 129 } 130 131 @Override 132 public Content getConstantSummaries() { 133 return new ContentBuilder(); 134 } 135 136 @Override 137 public void addPackageGroup(String abbrevPackageName, Content toContent) { 138 Content headingContent; 139 HtmlId anchorName; 140 if (abbrevPackageName.isEmpty()) { 141 anchorName = HtmlIds.UNNAMED_PACKAGE_ANCHOR; 142 headingContent = contents.defaultPackageLabel; 143 } else { 144 anchorName = htmlIds.forPackageName(abbrevPackageName); 145 headingContent = new ContentBuilder( 146 getPackageLabel(abbrevPackageName), 147 Text.of(".*")); 148 } 149 var heading = HtmlTree.HEADING_TITLE( 150 Headings.ConstantsSummary.PACKAGE_HEADING, 151 headingContent); 152 summarySection = HtmlTree.SECTION(HtmlStyle.constantsSummary, heading) 153 .setId(anchorName); 154 155 toContent.add(summarySection); 156 } 157 158 @Override 159 public Content getClassConstantHeader() { 160 return HtmlTree.UL(HtmlStyle.blockList); 161 } 162 163 @Override 164 public void addClassConstant(Content fromClassConstant) { 165 summarySection.add(fromClassConstant); 166 hasConstants = true; 167 } 168 169 @Override 170 public void addConstantMembers(TypeElement typeElement, 171 Collection<VariableElement> fields, 172 Content target) { 173 currentTypeElement = typeElement; 174 175 // generate links backward only to public classes. 176 Content classLink 177 = (utils.isPublic(typeElement) || utils.isProtected(typeElement)) 178 ? getLink(new HtmlLinkInfo(configuration, 179 HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_IN_LABEL, typeElement)) 180 : Text.of(utils.getFullyQualifiedName(typeElement)); 181 182 PackageElement enclosingPackage = utils.containingPackage(typeElement); 183 Content caption = new ContentBuilder(); 184 if (!enclosingPackage.isUnnamed()) { 185 caption.add(enclosingPackage.getQualifiedName()); 186 caption.add("."); 187 } 188 caption.add(classLink); 189 190 var table = new Table<Void>(HtmlStyle.summaryTable) 191 .setCaption(caption) 192 .setHeader(constantsTableHeader) 193 .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colSecond, 194 HtmlStyle.colLast); 195 196 for (VariableElement field : fields) { 197 table.addRow(getTypeColumn(field), getNameColumn(field), 198 getValue(field)); 199 } 200 target.add(HtmlTree.LI(table)); 201 } 202 203 /** 204 * Get the type column for the constant summary table row. 205 * 206 * @param member the field to be documented. 207 * @return the type column of the constant table row 208 */ 209 private Content getTypeColumn(VariableElement member) { 210 Content typeContent = new ContentBuilder(); 211 var code = new HtmlTree(TagName.CODE) 212 .setId(htmlIds.forMember(currentTypeElement, member)); 213 for (Modifier mod : member.getModifiers()) { 214 code.add(Text.of(mod.toString())) 215 .add(Entity.NO_BREAK_SPACE); 216 } 217 Content type = getLink(new HtmlLinkInfo(configuration, 218 HtmlLinkInfo.Kind.LINK_TYPE_PARAMS_AND_BOUNDS, member.asType())); 219 code.add(type); 220 typeContent.add(code); 221 return typeContent; 222 } 223 224 /** 225 * Get the name column for the constant summary table row. 226 * 227 * @param member the field to be documented. 228 * @return the name column of the constant table row 229 */ 230 private Content getNameColumn(VariableElement member) { 231 Content nameContent = getDocLink(HtmlLinkInfo.Kind.PLAIN, 232 member, member.getSimpleName()); 233 return HtmlTree.CODE(nameContent); 234 } 235 236 /** 237 * Get the value column for the constant summary table row. 238 * 239 * @param member the field to be documented. 240 * @return the value column of the constant table row 241 */ 242 private Content getValue(VariableElement member) { 243 String value = utils.constantValueExpression(member); 244 return HtmlTree.CODE(Text.of(value)); 245 } 246 247 @Override 248 public void addConstantSummaries(Content content) { 249 bodyContents.addMainContent(content); 250 } 251 252 @Override 253 public void addFooter() { 254 bodyContents.setFooter(getFooter()); 255 } 256 257 @Override 258 public void printDocument(Content content) throws DocFileIOException { 259 content.add(bodyContents); 260 printHtmlDocument(null, "summary of constants", content); 261 262 if (hasConstants && configuration.mainIndex != null) { 263 configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS, 264 resources.getText("doclet.Constants_Summary"), path)); 265 } 266 } 267}