src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java

Tue, 14 May 2013 10:14:52 -0700

author
jjg
date
Tue, 14 May 2013 10:14:52 -0700
changeset 1737
7a9ef837e57f
parent 1736
74cd21f2c2fe
child 1741
4c43e51433ba
permissions
-rw-r--r--

8011650: reduce use of RawHtml nodes in doclet
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 2003, 2013, 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  */
    26 package com.sun.tools.doclets.internal.toolkit.util.links;
    28 import com.sun.javadoc.*;
    29 import com.sun.tools.doclets.internal.toolkit.Content;
    31 /**
    32  * A factory that constructs links from given link information.
    33  *
    34  *  <p><b>This is NOT part of any supported API.
    35  *  If you write code that depends on this, you do so at your own risk.
    36  *  This code and its internal interfaces are subject to change or
    37  *  deletion without notice.</b>
    38  *
    39  * @author Jamie Ho
    40  * @since 1.5
    41  */
    42 public abstract class LinkFactory {
    44     /**
    45      * Return an empty instance of a content object.
    46      *
    47      * @return an empty instance of a content object.
    48      */
    49     protected abstract Content newContent();
    51     /**
    52      * Constructs a link from the given link information.
    53      *
    54      * @param linkInfo the information about the link.
    55      * @return the output of the link.
    56      */
    57     public Content getLink(LinkInfo linkInfo) {
    58         if (linkInfo.type != null) {
    59             Type type = linkInfo.type;
    60             Content link = newContent();
    61             if (type.isPrimitive()) {
    62                 //Just a primitive.
    63                 linkInfo.displayLength += type.typeName().length();
    64                 link.addContent(type.typeName());
    65             } else if (type.asAnnotatedType() != null && type.dimension().length() == 0) {
    66                 link.addContent(getTypeAnnotationLinks(linkInfo));
    67                 linkInfo.type = type.asAnnotatedType().underlyingType();
    68                 link.addContent(getLink(linkInfo));
    69                 return link;
    70             } else if (type.asWildcardType() != null) {
    71                 //Wildcard type.
    72                 linkInfo.isTypeBound = true;
    73                 linkInfo.displayLength += 1;
    74                 link.addContent("?");
    75                 WildcardType wildcardType = type.asWildcardType();
    76                 Type[] extendsBounds = wildcardType.extendsBounds();
    77                 for (int i = 0; i < extendsBounds.length; i++) {
    78                     linkInfo.displayLength += i > 0 ? 2 : 9;
    79                     link.addContent(i > 0 ? ", " : " extends ");
    80                     setBoundsLinkInfo(linkInfo, extendsBounds[i]);
    81                     link.addContent(getLink(linkInfo));
    82                 }
    83                 Type[] superBounds = wildcardType.superBounds();
    84                 for (int i = 0; i < superBounds.length; i++) {
    85                     linkInfo.displayLength += i > 0 ? 2 : 7;
    86                     link.addContent(i > 0 ? ", " : " super ");
    87                     setBoundsLinkInfo(linkInfo, superBounds[i]);
    88                     link.addContent(getLink(linkInfo));
    89                 }
    90             } else if (type.asTypeVariable()!= null) {
    91                 link.addContent(getTypeAnnotationLinks(linkInfo));
    92                 linkInfo.isTypeBound = true;
    93                 //A type variable.
    94                 Doc owner = type.asTypeVariable().owner();
    95                 if ((! linkInfo.excludeTypeParameterLinks) &&
    96                         owner instanceof ClassDoc) {
    97                     linkInfo.classDoc = (ClassDoc) owner;
    98                     Content label = newContent();
    99                     label.addContent(type.typeName());
   100                     linkInfo.label = label;
   101                     link.addContent(getClassLink(linkInfo));
   102                 } else {
   103                     //No need to link method type parameters.
   104                     linkInfo.displayLength += type.typeName().length();
   105                     link.addContent(type.typeName());
   106                 }
   108                 Type[] bounds = type.asTypeVariable().bounds();
   109                 if (! linkInfo.excludeTypeBounds) {
   110                     linkInfo.excludeTypeBounds = true;
   111                     for (int i = 0; i < bounds.length; i++) {
   112                         linkInfo.displayLength += i > 0 ? 2 : 9;
   113                         link.addContent(i > 0 ? " & " : " extends ");
   114                         setBoundsLinkInfo(linkInfo, bounds[i]);
   115                         link.addContent(getLink(linkInfo));
   116                     }
   117                 }
   118             } else if (type.asClassDoc() != null) {
   119                 //A class type.
   120                 if (linkInfo.isTypeBound &&
   121                         linkInfo.excludeTypeBoundsLinks) {
   122                     //Since we are excluding type parameter links, we should not
   123                     //be linking to the type bound.
   124                     linkInfo.displayLength += type.typeName().length();
   125                     link.addContent(type.typeName());
   126                     link.addContent(getTypeParameterLinks(linkInfo));
   127                     return link;
   128                 } else {
   129                     linkInfo.classDoc = type.asClassDoc();
   130                     link = newContent();
   131                     link.addContent(getClassLink(linkInfo));
   132                     if (linkInfo.includeTypeAsSepLink) {
   133                         link.addContent(getTypeParameterLinks(linkInfo, false));
   134                     }
   135                 }
   136             }
   138             if (linkInfo.isVarArg) {
   139                 if (type.dimension().length() > 2) {
   140                     //Javadoc returns var args as array.
   141                     //Strip out the first [] from the var arg.
   142                     linkInfo.displayLength += type.dimension().length()-2;
   143                     link.addContent(type.dimension().substring(2));
   144                 }
   145                 linkInfo.displayLength += 3;
   146                 link.addContent("...");
   147             } else {
   148                 while (type != null && type.dimension().length() > 0) {
   149                     linkInfo.displayLength += type.dimension().length();
   150                     if (type.asAnnotatedType() != null) {
   151                         linkInfo.type = type;
   152                         link.addContent(" ");
   153                         link.addContent(getTypeAnnotationLinks(linkInfo));
   154                         link.addContent("[]");
   155                         type = type.asAnnotatedType().underlyingType().getElementType();
   156                     } else {
   157                         link.addContent("[]");
   158                         type = type.getElementType();
   159                     }
   160                 }
   161                 linkInfo.type = type;
   162                 Content newLink = newContent();
   163                 newLink.addContent(getTypeAnnotationLinks(linkInfo));
   164                 newLink.addContent(link);
   165                 link = newLink;
   166             }
   167             return link;
   168         } else if (linkInfo.classDoc != null) {
   169             //Just a class link
   170             Content link = newContent();
   171             link.addContent(getClassLink(linkInfo));
   172             if (linkInfo.includeTypeAsSepLink) {
   173                 link.addContent(getTypeParameterLinks(linkInfo, false));
   174             }
   175             return link;
   176         } else {
   177             return null;
   178         }
   179     }
   181     private void setBoundsLinkInfo(LinkInfo linkInfo, Type bound) {
   182         linkInfo.classDoc = null;
   183         linkInfo.label = null;
   184         linkInfo.type = bound;
   185     }
   187     /**
   188      * Return the link to the given class.
   189      *
   190      * @param linkInfo the information about the link to construct.
   191      *
   192      * @return the link for the given class.
   193      */
   194     protected abstract Content getClassLink(LinkInfo linkInfo);
   196     /**
   197      * Return the link to the given type parameter.
   198      *
   199      * @param linkInfo     the information about the link to construct.
   200      * @param typeParam the type parameter to link to.
   201      */
   202     protected abstract Content getTypeParameterLink(LinkInfo linkInfo,
   203         Type typeParam);
   205     protected abstract Content getTypeAnnotationLink(LinkInfo linkInfo,
   206             AnnotationDesc annotation);
   208     /**
   209      * Return the links to the type parameters.
   210      *
   211      * @param linkInfo     the information about the link to construct.
   212      * @return the links to the type parameters.
   213      */
   214     public Content getTypeParameterLinks(LinkInfo linkInfo) {
   215         return getTypeParameterLinks(linkInfo, true);
   216     }
   218     /**
   219      * Return the links to the type parameters.
   220      *
   221      * @param linkInfo     the information about the link to construct.
   222      * @param isClassLabel true if this is a class label.  False if it is
   223      *                     the type parameters portion of the link.
   224      * @return the links to the type parameters.
   225      */
   226     public Content getTypeParameterLinks(LinkInfo linkInfo, boolean isClassLabel) {
   227         Content links = newContent();
   228         Type[] vars;
   229         if (linkInfo.executableMemberDoc != null) {
   230             vars = linkInfo.executableMemberDoc.typeParameters();
   231         } else if (linkInfo.type != null &&
   232                 linkInfo.type.asParameterizedType() != null){
   233             vars =  linkInfo.type.asParameterizedType().typeArguments();
   234         } else if (linkInfo.classDoc != null){
   235             vars = linkInfo.classDoc.typeParameters();
   236         } else {
   237             //Nothing to document.
   238             return links;
   239         }
   240         if (((linkInfo.includeTypeInClassLinkLabel && isClassLabel) ||
   241              (linkInfo.includeTypeAsSepLink && ! isClassLabel)
   242               )
   243             && vars.length > 0) {
   244             linkInfo.displayLength += 1;
   245             links.addContent("<");
   246             for (int i = 0; i < vars.length; i++) {
   247                 if (i > 0) {
   248                     linkInfo.displayLength += 1;
   249                     links.addContent(",");
   250                 }
   251                 links.addContent(getTypeParameterLink(linkInfo, vars[i]));
   252             }
   253             linkInfo.displayLength += 1;
   254             links.addContent(">");
   255         }
   256         return links;
   257     }
   259     public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
   260         Content links = newContent();
   261         if (linkInfo.type.asAnnotatedType() == null)
   262             return links;
   263         AnnotationDesc[] annotations = linkInfo.type.asAnnotatedType().annotations();
   264         for (int i = 0; i < annotations.length; i++) {
   265             if (i > 0) {
   266                 linkInfo.displayLength += 1;
   267                 links.addContent(" ");
   268             }
   269             links.addContent(getTypeAnnotationLink(linkInfo, annotations[i]));
   270         }
   272         linkInfo.displayLength += 1;
   273         links.addContent(" ");
   274         return links;
   275     }
   276 }

mercurial