1 /*
   2  * Copyright (c) 2003, 2017, 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 javax.lang.model.element.ExecutableElement;
  29 import javax.lang.model.element.TypeElement;
  30 import javax.lang.model.type.TypeMirror;
  31 
  32 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
  33 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
  34 import jdk.javadoc.internal.doclets.toolkit.Content;
  35 import jdk.javadoc.internal.doclets.toolkit.util.Utils;
  36 import jdk.javadoc.internal.doclets.toolkit.util.links.LinkInfo;
  37 
  38 
  39 /**
  40  *  <p><b>This is NOT part of any supported API.
  41  *  If you write code that depends on this, you do so at your own risk.
  42  *  This code and its internal interfaces are subject to change or
  43  *  deletion without notice.</b>
  44  */
  45 public class LinkInfoImpl extends LinkInfo {
  46 
  47     public enum Kind {
  48         DEFAULT,
  49 
  50         /**
  51          * Indicate that the link appears in a class list.
  52          */
  53         ALL_CLASSES_FRAME,
  54 
  55         /**
  56          * Indicate that the link appears in a class documentation.
  57          */
  58         CLASS,
  59 
  60         /**
  61          * Indicate that the link appears in member documentation.
  62          */
  63         MEMBER,
  64 
  65         /**
  66          * Indicate that the link appears in class use documentation.
  67          */
  68         CLASS_USE,
  69 
  70         /**
  71          * Indicate that the link appears in index documentation.
  72          */
  73         INDEX,
  74 
  75         /**
  76          * Indicate that the link appears in constant value summary.
  77          */
  78         CONSTANT_SUMMARY,
  79 
  80         /**
  81          * Indicate that the link appears in serialized form documentation.
  82          */
  83         SERIALIZED_FORM,
  84 
  85         /**
  86          * Indicate that the link appears in serial member documentation.
  87          */
  88         SERIAL_MEMBER,
  89 
  90         /**
  91          * Indicate that the link appears in package documentation.
  92          */
  93         PACKAGE,
  94 
  95         /**
  96          * Indicate that the link appears in see tag documentation.
  97          */
  98         SEE_TAG,
  99 
 100         /**
 101          * Indicate that the link appears in value tag documentation.
 102          */
 103         VALUE_TAG,
 104 
 105         /**
 106          * Indicate that the link appears in tree documentation.
 107          */
 108         TREE,
 109 
 110         /**
 111          * Indicate that the link appears in a class list.
 112          */
 113         PACKAGE_FRAME,
 114 
 115         /**
 116          * The header in the class documentation.
 117          */
 118         CLASS_HEADER,
 119 
 120         /**
 121          * The signature in the class documentation.
 122          */
 123         CLASS_SIGNATURE,
 124 
 125         /**
 126          * The return type of a method.
 127          */
 128         RETURN_TYPE,
 129 
 130         /**
 131          * The return type of a method in a member summary.
 132          */
 133         SUMMARY_RETURN_TYPE,
 134 
 135         /**
 136          * The type of a method/constructor parameter.
 137          */
 138         EXECUTABLE_MEMBER_PARAM,
 139 
 140         /**
 141          * Super interface links.
 142          */
 143         SUPER_INTERFACES,
 144 
 145         /**
 146          * Implemented interface links.
 147          */
 148         IMPLEMENTED_INTERFACES,
 149 
 150         /**
 151          * Implemented class links.
 152          */
 153         IMPLEMENTED_CLASSES,
 154 
 155         /**
 156          * Subinterface links.
 157          */
 158         SUBINTERFACES,
 159 
 160         /**
 161          * Subclasses links.
 162          */
 163         SUBCLASSES,
 164 
 165         /**
 166          * The signature in the class documentation (implements/extends portion).
 167          */
 168         CLASS_SIGNATURE_PARENT_NAME,
 169 
 170         /**
 171          * Permitted subtypes of a sealed type.
 172          */
 173         PERMITTED_SUBTYPES,
 174 
 175         /**
 176          * The header for method documentation copied from parent.
 177          */
 178         EXECUTABLE_ELEMENT_COPY,
 179 
 180         /**
 181          * Method "specified by" link.
 182          */
 183         METHOD_SPECIFIED_BY,
 184 
 185         /**
 186          * Method "overrides" link.
 187          */
 188         METHOD_OVERRIDES,
 189 
 190         /**
 191          * Annotation link.
 192          */
 193         ANNOTATION,
 194 
 195         /**
 196          * The header for field documentation copied from parent.
 197          */
 198         VARIABLE_ELEMENT_COPY,
 199 
 200         /**
 201          * The parent nodes in the class tree.
 202          */
 203         CLASS_TREE_PARENT,
 204 
 205         /**
 206          * The type parameters of a method or constructor.
 207          */
 208         MEMBER_TYPE_PARAMS,
 209 
 210         /**
 211          * Indicate that the link appears in class use documentation.
 212          */
 213         CLASS_USE_HEADER,
 214 
 215         /**
 216          * The header for property documentation copied from parent.
 217          */
 218         PROPERTY_COPY,
 219 
 220         /**
 221          * A receiver type
 222          */
 223         RECEIVER_TYPE
 224     }
 225 
 226     public final HtmlConfiguration configuration;
 227 
 228     /**
 229      * The location of the link.
 230      */
 231     public Kind context = Kind.DEFAULT;
 232 
 233     /**
 234      * The value of the marker #.
 235      */
 236     public String where = "";
 237 
 238     /**
 239      * The value of the target.
 240      */
 241     public String target = "";
 242     public  final Utils utils;
 243     /**
 244      * Construct a LinkInfo object.
 245      *
 246      * @param configuration the configuration data for the doclet
 247      * @param context    the context of the link.
 248      * @param ee   the member to link to.
 249      */
 250     public LinkInfoImpl(HtmlConfiguration configuration, Kind context, ExecutableElement ee) {
 251         this.configuration = configuration;
 252         this.utils = configuration.utils;
 253         this.executableElement = ee;
 254         setContext(context);
 255     }
 256 
 257     /**
 258      * {@inheritDoc}
 259      */
 260     @Override
 261     protected Content newContent() {
 262         return new ContentBuilder();
 263     }
 264 
 265     /**
 266      * Construct a LinkInfo object.
 267      *
 268      * @param configuration the configuration data for the doclet
 269      * @param context    the context of the link.
 270      * @param typeElement   the class to link to.
 271      */
 272     public LinkInfoImpl(HtmlConfiguration configuration, Kind context, TypeElement typeElement) {
 273         this.configuration = configuration;
 274         this.utils = configuration.utils;
 275         this.typeElement = typeElement;
 276         setContext(context);
 277     }
 278 
 279     /**
 280      * Construct a LinkInfo object.
 281      *
 282      * @param configuration the configuration data for the doclet
 283      * @param context    the context of the link.
 284      * @param type       the class to link to.
 285      */
 286     public LinkInfoImpl(HtmlConfiguration configuration, Kind context, TypeMirror type) {
 287         this.configuration = configuration;
 288         this.utils = configuration.utils;
 289         this.type = type;
 290         setContext(context);
 291     }
 292 
 293     /**
 294      * Set the label for the link.
 295      * @param label plain-text label for the link
 296      */
 297     public LinkInfoImpl label(CharSequence label) {
 298         this.label = new StringContent(label);
 299         return this;
 300     }
 301 
 302     /**
 303      * Set the label for the link.
 304      */
 305     public LinkInfoImpl label(Content label) {
 306         this.label = label;
 307         return this;
 308     }
 309 
 310     /**
 311      * Set whether or not the link should be strong.
 312      */
 313     public LinkInfoImpl strong(boolean strong) {
 314         this.isStrong = strong;
 315         return this;
 316     }
 317 
 318     /**
 319      * Set the target to be used for the link.
 320      * @param target the target name.
 321      */
 322     public LinkInfoImpl target(String target) {
 323         this.target = target;
 324         return this;
 325     }
 326 
 327     /**
 328      * Set whether or not this is a link to a varargs parameter.
 329      */
 330     public LinkInfoImpl varargs(boolean varargs) {
 331         this.isVarArg = varargs;
 332         return this;
 333     }
 334 
 335     /**
 336      * Set the fragment specifier for the link.
 337      */
 338     public LinkInfoImpl where(String where) {
 339         this.where = where;
 340         return this;
 341      }
 342 
 343     /**
 344      * {@inheritDoc}
 345      */
 346     public Kind getContext() {
 347         return context;
 348     }
 349 
 350     /**
 351      * {@inheritDoc}
 352      *
 353      * This method sets the link attributes to the appropriate values
 354      * based on the context.
 355      *
 356      * @param c the context id to set.
 357      */
 358     public final void setContext(Kind c) {
 359         //NOTE:  Put context specific link code here.
 360         switch (c) {
 361             case ALL_CLASSES_FRAME:
 362             case PACKAGE_FRAME:
 363             case IMPLEMENTED_CLASSES:
 364             case SUBCLASSES:
 365             case EXECUTABLE_ELEMENT_COPY:
 366             case VARIABLE_ELEMENT_COPY:
 367             case PROPERTY_COPY:
 368             case CLASS_USE_HEADER:
 369                 includeTypeInClassLinkLabel = false;
 370                 break;
 371 
 372             case ANNOTATION:
 373                 excludeTypeParameterLinks = true;
 374                 excludeTypeBounds = true;
 375                 break;
 376 
 377             case IMPLEMENTED_INTERFACES:
 378             case SUPER_INTERFACES:
 379             case SUBINTERFACES:
 380             case CLASS_TREE_PARENT:
 381             case TREE:
 382             case CLASS_SIGNATURE_PARENT_NAME:
 383             case PERMITTED_SUBTYPES:
 384                 excludeTypeParameterLinks = true;
 385                 excludeTypeBounds = true;
 386                 includeTypeInClassLinkLabel = false;
 387                 includeTypeAsSepLink = true;
 388                 break;
 389 
 390             case PACKAGE:
 391             case CLASS_USE:
 392             case CLASS_HEADER:
 393             case CLASS_SIGNATURE:
 394             case RECEIVER_TYPE:
 395                 excludeTypeParameterLinks = true;
 396                 includeTypeAsSepLink = true;
 397                 includeTypeInClassLinkLabel = false;
 398                 break;
 399 
 400             case MEMBER_TYPE_PARAMS:
 401                 includeTypeAsSepLink = true;
 402                 includeTypeInClassLinkLabel = false;
 403                 break;
 404 
 405             case RETURN_TYPE:
 406             case SUMMARY_RETURN_TYPE:
 407                 excludeTypeBounds = true;
 408                 break;
 409             case EXECUTABLE_MEMBER_PARAM:
 410                 excludeTypeBounds = true;
 411                 break;
 412         }
 413         context = c;
 414         if (type != null &&
 415             utils.isTypeVariable(type) &&
 416             utils.isExecutableElement(utils.asTypeElement(type).getEnclosingElement())) {
 417                 excludeTypeParameterLinks = true;
 418         }
 419     }
 420 
 421     /**
 422      * Return true if this link is linkable and false if we can't link to the
 423      * desired place.
 424      *
 425      * @return true if this link is linkable and false if we can't link to the
 426      * desired place.
 427      */
 428     @Override
 429     public boolean isLinkable() {
 430         return configuration.utils.isLinkable(typeElement);
 431     }
 432 
 433     @Override
 434     public String toString() {
 435         return "LinkInfoImpl{" +
 436                 "context=" + context +
 437                 ", where=" + where +
 438                 ", target=" + target +
 439                 super.toString() + '}';
 440     }
 441 }