1 /* 2 * Copyright (c) 1997, 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.formats.html; 27 28 import java.util.Arrays; 29 import java.util.List; 30 31 import javax.lang.model.element.Element; 32 import javax.lang.model.element.ExecutableElement; 33 import javax.lang.model.element.TypeElement; 34 35 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; 36 import jdk.javadoc.internal.doclets.formats.html.markup.Entity; 37 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 38 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 40 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 41 import jdk.javadoc.internal.doclets.formats.html.markup.Table; 42 import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; 43 import jdk.javadoc.internal.doclets.toolkit.ConstructorWriter; 44 import jdk.javadoc.internal.doclets.toolkit.Content; 45 import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter; 46 import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable; 47 48 import static jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable.Kind.CONSTRUCTORS; 49 50 51 /** 52 * Writes constructor documentation. 53 * 54 * <p><b>This is NOT part of any supported API. 55 * If you write code that depends on this, you do so at your own risk. 56 * This code and its internal interfaces are subject to change or 57 * deletion without notice.</b> 58 */ 59 public class ConstructorWriterImpl extends AbstractExecutableMemberWriter 60 implements ConstructorWriter, MemberSummaryWriter { 61 62 private boolean foundNonPubConstructor = false; 63 64 /** 65 * Construct a new ConstructorWriterImpl. 66 * 67 * @param writer The writer for the class that the constructors belong to. 68 * @param typeElement the class being documented. 69 */ 70 public ConstructorWriterImpl(SubWriterHolderWriter writer, TypeElement typeElement) { 71 super(writer, typeElement); 72 73 VisibleMemberTable vmt = configuration.getVisibleMemberTable(typeElement); 74 List<? extends Element> constructors = vmt.getVisibleMembers(CONSTRUCTORS); 75 76 for (Element constructor : constructors) { 77 if (utils.isProtected(constructor) || utils.isPrivate(constructor)) { 78 setFoundNonPubConstructor(true); 79 } 80 } 81 } 82 83 /** 84 * Construct a new ConstructorWriterImpl. 85 * 86 * @param writer The writer for the class that the constructors belong to. 87 */ 88 public ConstructorWriterImpl(SubWriterHolderWriter writer) { 89 super(writer); 90 } 91 92 /** 93 * {@inheritDoc} 94 */ 95 @Override 96 public Content getMemberSummaryHeader(TypeElement typeElement, 97 Content memberSummaryTree) { 98 memberSummaryTree.add(MarkerComments.START_OF_CONSTRUCTOR_SUMMARY); 99 Content memberTree = new ContentBuilder(); 100 writer.addSummaryHeader(this, memberTree); 101 return memberTree; 102 } 103 104 /** 105 * {@inheritDoc} 106 */ 107 @Override 108 public void addMemberTree(Content memberSummaryTree, Content memberTree) { 109 writer.addMemberTree(HtmlStyle.constructorSummary, 110 SectionName.CONSTRUCTOR_SUMMARY, memberSummaryTree, memberTree); 111 } 112 113 /** 114 * {@inheritDoc} 115 */ 116 @Override 117 public Content getConstructorDetailsTreeHeader(Content memberDetailsTree) { 118 memberDetailsTree.add(MarkerComments.START_OF_CONSTRUCTOR_DETAILS); 119 Content constructorDetailsTree = new ContentBuilder(); 120 Content heading = HtmlTree.HEADING(Headings.TypeDeclaration.DETAILS_HEADING, 121 contents.constructorDetailsLabel); 122 constructorDetailsTree.add(heading); 123 return constructorDetailsTree; 124 } 125 126 /** 127 * {@inheritDoc} 128 */ 129 @Override 130 public Content getConstructorDocTreeHeader(ExecutableElement constructor) { 131 String erasureAnchor; 132 Content constructorDocTree = new ContentBuilder(); 133 HtmlTree heading = new HtmlTree(Headings.TypeDeclaration.MEMBER_HEADING, 134 new StringContent(name(constructor))); 135 if ((erasureAnchor = getErasureAnchor(constructor)) != null) { 136 heading.setId(erasureAnchor); 137 } 138 constructorDocTree.add(heading); 139 return HtmlTree.SECTION(HtmlStyle.detail, constructorDocTree) 140 .setId(links.getName(writer.getAnchor(constructor))); 141 } 142 143 /** 144 * {@inheritDoc} 145 */ 146 @Override 147 public Content getSignature(ExecutableElement constructor) { 148 return new MemberSignature(constructor) 149 .addParameters(getParameters(constructor, true)) 150 .addExceptions(getExceptions(constructor)) 151 .toContent(); 152 } 153 154 /** 155 * {@inheritDoc} 156 */ 157 @Override 158 public void addDeprecated(ExecutableElement constructor, Content constructorDocTree) { 159 addDeprecatedInfo(constructor, constructorDocTree); 160 } 161 162 /** 163 * {@inheritDoc} 164 */ 165 @Override 166 public void addComments(ExecutableElement constructor, Content constructorDocTree) { 167 addComment(constructor, constructorDocTree); 168 } 169 170 /** 171 * {@inheritDoc} 172 */ 173 @Override 174 public void addTags(ExecutableElement constructor, Content constructorDocTree) { 175 writer.addTagsInfo(constructor, constructorDocTree); 176 } 177 178 /** 179 * {@inheritDoc} 180 */ 181 @Override 182 public Content getConstructorDetails(Content constructorDetailsTreeHeader, Content constructorDetailsTree) { 183 Content constructorDetails = new ContentBuilder(constructorDetailsTreeHeader, constructorDetailsTree); 184 return getMemberTree(HtmlTree.SECTION(HtmlStyle.constructorDetails, constructorDetails) 185 .setId(SectionName.CONSTRUCTOR_DETAIL.getName())); 186 } 187 188 /** 189 * {@inheritDoc} 190 */ 191 @Override 192 public Content getConstructorDoc(Content constructorDocTree) { 193 return getMemberTree(constructorDocTree); 194 } 195 196 /** 197 * Let the writer know whether a non public constructor was found. 198 * 199 * @param foundNonPubConstructor true if we found a non public constructor. 200 */ 201 @Override 202 public void setFoundNonPubConstructor(boolean foundNonPubConstructor) { 203 this.foundNonPubConstructor = foundNonPubConstructor; 204 } 205 206 /** 207 * {@inheritDoc} 208 */ 209 @Override 210 public void addSummaryLabel(Content memberTree) { 211 Content label = HtmlTree.HEADING(Headings.TypeDeclaration.SUMMARY_HEADING, 212 contents.constructorSummaryLabel); 213 memberTree.add(label); 214 } 215 216 /** 217 * {@inheritDoc} 218 */ 219 @Override 220 public TableHeader getSummaryTableHeader(Element member) { 221 if (foundNonPubConstructor) { 222 return new TableHeader(contents.modifierLabel, contents.constructorLabel, 223 contents.descriptionLabel); 224 } else { 225 return new TableHeader(contents.constructorLabel, contents.descriptionLabel); 226 } 227 } 228 229 @Override 230 protected Table createSummaryTable() { 231 List<HtmlStyle> bodyRowStyles; 232 int rowScopeColumn; 233 234 if (foundNonPubConstructor) { 235 bodyRowStyles = Arrays.asList(HtmlStyle.colFirst, HtmlStyle.colConstructorName, 236 HtmlStyle.colLast); 237 rowScopeColumn = 1; 238 } else { 239 bodyRowStyles = Arrays.asList(HtmlStyle.colConstructorName, HtmlStyle.colLast); 240 rowScopeColumn = 0; 241 } 242 243 return new Table(HtmlStyle.memberSummary) 244 .setCaption(contents.constructors) 245 .setHeader(getSummaryTableHeader(typeElement)) 246 .setRowScopeColumn(rowScopeColumn) 247 .setColumnStyles(bodyRowStyles); 248 } 249 250 /** 251 * {@inheritDoc} 252 */ 253 @Override 254 public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { 255 } 256 257 /** 258 * {@inheritDoc} 259 */ 260 @Override 261 protected void addSummaryType(Element member, Content tdSummaryType) { 262 if (foundNonPubConstructor) { 263 Content code = new HtmlTree(HtmlTag.CODE); 264 if (utils.isProtected(member)) { 265 code.add("protected "); 266 } else if (utils.isPrivate(member)) { 267 code.add("private "); 268 } else if (utils.isPublic(member)) { 269 code.add(Entity.NO_BREAK_SPACE); 270 } else { 271 code.add( 272 resources.getText("doclet.Package_private")); 273 } 274 tdSummaryType.add(code); 275 } 276 } 277 278 @Override 279 public Content getMemberTreeHeader(){ 280 return writer.getMemberTreeHeader(); 281 } 282 }