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