1 /* 2 * Copyright (c) 1997, 2018, 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 jdk.javadoc.internal.doclets.formats.html.markup.Table; 29 import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; 30 31 import java.util.*; 32 33 import javax.lang.model.element.Element; 34 import javax.lang.model.element.ExecutableElement; 35 import javax.lang.model.element.TypeElement; 36 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.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.*; 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 */ ConstructorWriterImpl(SubWriterHolderWriter writer, TypeElement typeElement)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 */ ConstructorWriterImpl(SubWriterHolderWriter writer)91 public ConstructorWriterImpl(SubWriterHolderWriter writer) { 92 super(writer); 93 } 94 95 /** 96 * {@inheritDoc} 97 */ 98 @Override getMemberSummaryHeader(TypeElement typeElement, Content memberSummaryTree)99 public Content getMemberSummaryHeader(TypeElement typeElement, 100 Content memberSummaryTree) { 101 memberSummaryTree.addContent(HtmlConstants.START_OF_CONSTRUCTOR_SUMMARY); 102 Content memberTree = writer.getMemberTreeHeader(); 103 writer.addSummaryHeader(this, typeElement, memberTree); 104 return memberTree; 105 } 106 107 /** 108 * {@inheritDoc} 109 */ 110 @Override addMemberTree(Content memberSummaryTree, Content memberTree)111 public void addMemberTree(Content memberSummaryTree, Content memberTree) { 112 writer.addMemberTree(memberSummaryTree, memberTree); 113 } 114 115 /** 116 * {@inheritDoc} 117 */ 118 @Override getConstructorDetailsTreeHeader(TypeElement typeElement, Content memberDetailsTree)119 public Content getConstructorDetailsTreeHeader(TypeElement typeElement, 120 Content memberDetailsTree) { 121 memberDetailsTree.addContent(HtmlConstants.START_OF_CONSTRUCTOR_DETAILS); 122 Content constructorDetailsTree = writer.getMemberTreeHeader(); 123 constructorDetailsTree.addContent(links.createAnchor( 124 SectionName.CONSTRUCTOR_DETAIL)); 125 Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, 126 contents.constructorDetailsLabel); 127 constructorDetailsTree.addContent(heading); 128 return constructorDetailsTree; 129 } 130 131 /** 132 * {@inheritDoc} 133 */ 134 @Override getConstructorDocTreeHeader(ExecutableElement constructor, Content constructorDetailsTree)135 public Content getConstructorDocTreeHeader(ExecutableElement constructor, 136 Content constructorDetailsTree) { 137 String erasureAnchor; 138 if ((erasureAnchor = getErasureAnchor(constructor)) != null) { 139 constructorDetailsTree.addContent(links.createAnchor((erasureAnchor))); 140 } 141 constructorDetailsTree.addContent(links.createAnchor(writer.getAnchor(constructor))); 142 Content constructorDocTree = writer.getMemberTreeHeader(); 143 Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING); 144 heading.addContent(name(constructor)); 145 constructorDocTree.addContent(heading); 146 return constructorDocTree; 147 } 148 149 /** 150 * {@inheritDoc} 151 */ 152 @Override getSignature(ExecutableElement constructor)153 public Content getSignature(ExecutableElement constructor) { 154 Content pre = new HtmlTree(HtmlTag.PRE); 155 writer.addAnnotationInfo(constructor, pre); 156 int annotationLength = pre.charCount(); 157 addModifiers(constructor, pre); 158 if (configuration.linksource) { 159 Content constructorName = new StringContent(name(constructor)); 160 writer.addSrcLink(constructor, constructorName, pre); 161 } else { 162 addName(name(constructor), pre); 163 } 164 int indent = pre.charCount() - annotationLength; 165 addParameters(constructor, pre, indent); 166 addExceptions(constructor, pre, indent); 167 return pre; 168 } 169 170 /** 171 * {@inheritDoc} 172 */ 173 @Override addDeprecated(ExecutableElement constructor, Content constructorDocTree)174 public void addDeprecated(ExecutableElement constructor, Content constructorDocTree) { 175 addDeprecatedInfo(constructor, constructorDocTree); 176 } 177 178 /** 179 * {@inheritDoc} 180 */ 181 @Override addComments(ExecutableElement constructor, Content constructorDocTree)182 public void addComments(ExecutableElement constructor, Content constructorDocTree) { 183 addComment(constructor, constructorDocTree); 184 } 185 186 /** 187 * {@inheritDoc} 188 */ 189 @Override addTags(ExecutableElement constructor, Content constructorDocTree)190 public void addTags(ExecutableElement constructor, Content constructorDocTree) { 191 writer.addTagsInfo(constructor, constructorDocTree); 192 } 193 194 /** 195 * {@inheritDoc} 196 */ 197 @Override getConstructorDetails(Content constructorDetailsTree)198 public Content getConstructorDetails(Content constructorDetailsTree) { 199 if (configuration.allowTag(HtmlTag.SECTION)) { 200 HtmlTree htmlTree = HtmlTree.SECTION(getMemberTree(constructorDetailsTree)); 201 return htmlTree; 202 } 203 return getMemberTree(constructorDetailsTree); 204 } 205 206 /** 207 * {@inheritDoc} 208 */ 209 @Override getConstructorDoc(Content constructorDocTree, boolean isLastContent)210 public Content getConstructorDoc(Content constructorDocTree, 211 boolean isLastContent) { 212 return getMemberTree(constructorDocTree, isLastContent); 213 } 214 215 /** 216 * Let the writer know whether a non public constructor was found. 217 * 218 * @param foundNonPubConstructor true if we found a non public constructor. 219 */ 220 @Override setFoundNonPubConstructor(boolean foundNonPubConstructor)221 public void setFoundNonPubConstructor(boolean foundNonPubConstructor) { 222 this.foundNonPubConstructor = foundNonPubConstructor; 223 } 224 225 /** 226 * {@inheritDoc} 227 */ 228 @Override addSummaryLabel(Content memberTree)229 public void addSummaryLabel(Content memberTree) { 230 Content label = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, 231 contents.constructorSummaryLabel); 232 memberTree.addContent(label); 233 } 234 235 /** 236 * {@inheritDoc} 237 */ 238 @Override getSummaryTableHeader(Element member)239 public TableHeader getSummaryTableHeader(Element member) { 240 if (foundNonPubConstructor) { 241 return new TableHeader(contents.modifierLabel, contents.constructorLabel, 242 contents.descriptionLabel); 243 } else { 244 return new TableHeader(contents.constructorLabel, contents.descriptionLabel); 245 } 246 } 247 248 @Override createSummaryTable()249 protected Table createSummaryTable() { 250 List<HtmlStyle> bodyRowStyles; 251 int rowScopeColumn; 252 253 if (foundNonPubConstructor) { 254 bodyRowStyles = Arrays.asList(HtmlStyle.colFirst, HtmlStyle.colConstructorName, 255 HtmlStyle.colLast); 256 rowScopeColumn = 1; 257 } else { 258 bodyRowStyles = Arrays.asList(HtmlStyle.colConstructorName, HtmlStyle.colLast); 259 rowScopeColumn = 0; 260 } 261 262 String summary = resources.getText("doclet.Member_Table_Summary", 263 resources.getText("doclet.Constructor_Summary"), 264 resources.getText("doclet.constructors")); 265 266 return new Table(configuration.htmlVersion, HtmlStyle.memberSummary) 267 .setSummary(summary) 268 .setCaption(contents.constructors) 269 .setHeader(getSummaryTableHeader(typeElement)) 270 .setRowScopeColumn(rowScopeColumn) 271 .setColumnStyles(bodyRowStyles) 272 .setUseTBody(false); // temporary? compatibility mode for TBody 273 } 274 275 /** 276 * {@inheritDoc} 277 */ 278 @Override addSummaryAnchor(TypeElement typeElement, Content memberTree)279 public void addSummaryAnchor(TypeElement typeElement, Content memberTree) { 280 memberTree.addContent(links.createAnchor(SectionName.CONSTRUCTOR_SUMMARY)); 281 } 282 283 /** 284 * {@inheritDoc} 285 */ 286 @Override addInheritedSummaryAnchor(TypeElement typeElement, Content inheritedTree)287 public void addInheritedSummaryAnchor(TypeElement typeElement, Content inheritedTree) { 288 } 289 290 /** 291 * {@inheritDoc} 292 */ 293 @Override addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree)294 public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { 295 } 296 297 /** 298 * {@inheritDoc} 299 */ 300 @Override addSummaryType(Element member, Content tdSummaryType)301 protected void addSummaryType(Element member, Content tdSummaryType) { 302 if (foundNonPubConstructor) { 303 Content code = new HtmlTree(HtmlTag.CODE); 304 if (utils.isProtected(member)) { 305 code.addContent("protected "); 306 } else if (utils.isPrivate(member)) { 307 code.addContent("private "); 308 } else if (utils.isPublic(member)) { 309 code.addContent(Contents.SPACE); 310 } else { 311 code.addContent( 312 configuration.getText("doclet.Package_private")); 313 } 314 tdSummaryType.addContent(code); 315 } 316 } 317 } 318