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