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.markup;
  27 
  28 import jdk.javadoc.internal.doclets.formats.html.SectionName;
  29 import jdk.javadoc.internal.doclets.toolkit.Content;
  30 import jdk.javadoc.internal.doclets.toolkit.util.DocLink;
  31 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
  32 
  33 /**
  34  * Factory for HTML A elements, both links (with a {@code href} attribute)
  35  * and anchors (with an {@code id} or {@code name} attribute).
  36  *
  37  * Most methods in this class are static factory methods.
  38  * The exceptions are those methods that directly or indirectly depend on the HTML version
  39  * being used, when determining valid HTML names (ids),
  40  * and those methods that generate anchors.
  41  *
  42  *  <p><b>This is NOT part of any supported API.
  43  *  If you write code that depends on this, you do so at your own risk.
  44  *  This code and its internal interfaces are subject to change or
  45  *  deletion without notice.</b>
  46  */
  47 public class Links {
  48 
  49     private final DocPath file;
  50 
  51     /**
  52      * Creates a {@code Links} object for a specific file, to be written in a specific HTML version.
  53      * The version is used by the {@link #getName(String) getName} method
  54      * to help determine valid HTML names (ids), and to determine whether
  55      * to use an {@code id} or {@code name} attribute when creating anchors.
  56      *
  57      * @param file the file
  58      */
  59     public Links(DocPath file) {
  60         this.file = file;
  61     }
  62 
  63     /**
  64      * Creates a link of the form {@code <a href="#where">label</a>}.
  65      *
  66      * @param where      the position of the link in the file
  67      * @param label      the content for the link
  68      * @return a content tree for the link
  69      */
  70     public Content createLink(String where, Content label) {
  71         DocLink l = DocLink.fragment(getName(where));
  72         return createLink(l, label, "", "");
  73     }
  74 
  75     /**
  76      * Creates a link of the form {@code <a href="#sectionName">label</a>}.
  77      *
  78      * @param sectionName   the section name to which the link will be created
  79      * @param label         the content for the link
  80      * @return a content tree for the link
  81      */
  82     public Content createLink(SectionName sectionName, Content label) {
  83         DocLink l =  DocLink.fragment(sectionName.getName());
  84         return createLink(l, label, "", "");
  85     }
  86 
  87     /**
  88      * Creates a link of the form {@code <a href="#sectionNameWhere">label</a>}.
  89      *
  90      * @param sectionName   the section name combined with where to which the link
  91      *                      will be created
  92      * @param where         the fragment combined with sectionName to which the link
  93      *                      will be created
  94      * @param label         the content for the link
  95      * @return a content tree for the link
  96      */
  97     public Content createLink(SectionName sectionName, String where, Content label) {
  98         DocLink l =  DocLink.fragment(sectionName.getName() + getName(where));
  99         return createLink(l, label, "", "");
 100     }
 101 
 102     /**
 103      * Creates a link of the form {@code <a href="#stylename" title="title" target="target">label</a>}.
 104      *
 105      * @param sectionName   the section name to which the link will be created
 106      * @param label     the content for the link
 107      * @param title     the title for the link
 108      * @param target    the target for the link, or null
 109      * @return a content tree for the link
 110      */
 111     public Content createLink(SectionName sectionName, Content label, String title, String target) {
 112         DocLink l = DocLink.fragment(sectionName.getName());
 113         return createLink(l, label, title, target);
 114     }
 115 
 116     /**
 117      * Creates a link of the form {@code <a href="path">label</a>}.
 118      *
 119      * @param path   the path for the link
 120      * @param label  the content for the link
 121      * @return a content tree for the link
 122      */
 123     public Content createLink(DocPath path, String label) {
 124         return createLink(path, new StringContent(label), false, "", "");
 125     }
 126 
 127     /**
 128      * Creates a link of the form {@code <a href="path">label</a>}.
 129      *
 130      * @param path   the path for the link
 131      * @param label  the content for the link
 132      * @return a content tree for the link
 133      */
 134     public Content createLink(DocPath path, Content label) {
 135         return createLink(path, label, "", "");
 136     }
 137 
 138     /**
 139      * Creates a link of the form {@code <a href="path" title="title" target="target">label</a>}.
 140      * If {@code strong} is set, the label will be wrapped in
 141      *      {@code <span style="typeNameLink">...</span>}.
 142      *
 143      * @param path      the path for the link
 144      * @param label     the content for the link
 145      * @param strong    whether to wrap the {@code label} in a SPAN element
 146      * @param title     the title for the link
 147      * @param target    the target for the link, or null
 148      * @return a content tree for the link
 149      */
 150     public Content createLink(DocPath path, Content label, boolean strong,
 151             String title, String target) {
 152         return createLink(new DocLink(path), label, strong, title, target);
 153     }
 154 
 155     /**
 156      * Creates a link of the form {@code <a href="path" title="title" target="target">label</a>}.
 157      *
 158      * @param path      the path for the link
 159      * @param label     the content for the link
 160      * @param title     the title for the link
 161      * @param target    the target for the link, or null
 162      * @return a content tree for the link
 163      */
 164     public Content createLink(DocPath path, Content label, String title, String target) {
 165         return createLink(new DocLink(path), label, title, target);
 166     }
 167 
 168     /**
 169      * Creates a link of the form {@code <a href="link">label</a>}.
 170      *
 171      * @param link      the details for the link
 172      * @param label     the content for the link
 173      * @return a content tree for the link
 174      */
 175     public Content createLink(DocLink link, Content label) {
 176         return createLink(link, label, "", "");
 177     }
 178 
 179     /**
 180      * Creates a link of the form {@code <a href="path" title="title" target="target">label</a>}.
 181      *
 182      * @param link      the details for the link
 183      * @param label     the content for the link
 184      * @param title     the title for the link
 185      * @param target    the target for the link, or null
 186      * @return a content tree for the link
 187      */
 188     public Content createLink(DocLink link, Content label, String title, String target) {
 189         HtmlTree anchor = HtmlTree.A(link.relativizeAgainst(file).toString(), label);
 190         if (title != null && title.length() != 0) {
 191             anchor.put(HtmlAttr.TITLE, title);
 192         }
 193         if (target != null && target.length() != 0) {
 194             anchor.put(HtmlAttr.TARGET, target);
 195         }
 196         return anchor;
 197     }
 198 
 199     /**
 200      * Creates a link of the form {@code <a href="link" title="title" target="target">label</a>}.
 201      * If {@code strong} is set, the label will be wrapped in
 202      *      {@code <span style="typeNameLink">...</span>}.
 203      *
 204      * @param link      the details for the link
 205      * @param label     the content for the link
 206      * @param strong    whether to wrap the {@code label} in a SPAN element
 207      * @param title     the title for the link
 208      * @param target    the target for the link, or null
 209      * @return a content tree for the link
 210      */
 211     public Content createLink(DocLink link, Content label, boolean strong,
 212             String title, String target) {
 213         return createLink(link, label, strong, title, target, false);
 214     }
 215 
 216     /**
 217      * Creates a link of the form {@code <a href="link" title="title" target="target">label</a>}.
 218      * If {@code strong} is set, the label will be wrapped in
 219      *      {@code <span style="typeNameLink">...</span>}.
 220      *
 221      * @param link       the details for the link
 222      * @param label      the content for the link
 223      * @param strong     whether to wrap the {@code label} in a SPAN element
 224      * @param title      the title for the link
 225      * @param target     the target for the link, or null
 226      * @param isExternal is the link external to the generated documentation
 227      * @return a content tree for the link
 228      */
 229     public Content createLink(DocLink link, Content label, boolean strong,
 230             String title, String target, boolean isExternal) {
 231         Content body = label;
 232         if (strong) {
 233             body = HtmlTree.SPAN(HtmlStyle.typeNameLink, body);
 234         }
 235         HtmlTree l = HtmlTree.A(link.relativizeAgainst(file).toString(), body);
 236         if (title != null && title.length() != 0) {
 237             l.put(HtmlAttr.TITLE, title);
 238         }
 239         if (target != null && target.length() != 0) {
 240             l.put(HtmlAttr.TARGET, target);
 241         }
 242         if (isExternal) {
 243             l.setStyle(HtmlStyle.externalLink);
 244         }
 245         return l;
 246     }
 247 
 248     /**
 249      * Creates a link.
 250      *
 251      * @param link       the details for the link
 252      * @param label      the content for the link
 253      * @param isExternal is the link external to the generated documentation
 254      * @return a content tree for the link
 255      */
 256     public Content createLink(DocLink link, Content label, boolean isExternal) {
 257         HtmlTree anchor = HtmlTree.A(link.relativizeAgainst(file).toString(), label);
 258         anchor.setStyle(HtmlStyle.externalLink);
 259         return anchor;
 260     }
 261 
 262     /**
 263      * Converts a name to a valid HTML name (id).
 264      * This depends on the HTML version specified when the {@code Links} object was created.
 265      *
 266      * @param name the string that needs to be converted to a valid HTML name
 267      * @return a valid HTML name
 268      */
 269     public String getName(String name) {
 270         return name.replaceAll("\\s+", "");
 271     }
 272 
 273 }