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
26package jdk.javadoc.internal.doclets.formats.html;
27
28import javax.lang.model.element.ExecutableElement;
29import javax.lang.model.element.TypeElement;
30import javax.lang.model.type.TypeMirror;
31
32import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
33import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
34import jdk.javadoc.internal.doclets.toolkit.Content;
35import jdk.javadoc.internal.doclets.toolkit.util.Utils;
36import 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 */
45public 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         * The header for method documentation copied from parent.
172         */
173        EXECUTABLE_ELEMENT_COPY,
174
175        /**
176         * Method "specified by" link.
177         */
178        METHOD_SPECIFIED_BY,
179
180        /**
181         * Method "overrides" link.
182         */
183        METHOD_OVERRIDES,
184
185        /**
186         * Annotation link.
187         */
188        ANNOTATION,
189
190        /**
191         * The header for field documentation copied from parent.
192         */
193        VARIABLE_ELEMENT_COPY,
194
195        /**
196         * The parent nodes in the class tree.
197         */
198        CLASS_TREE_PARENT,
199
200        /**
201         * The type parameters of a method or constructor.
202         */
203        MEMBER_TYPE_PARAMS,
204
205        /**
206         * Indicate that the link appears in class use documentation.
207         */
208        CLASS_USE_HEADER,
209
210        /**
211         * The header for property documentation copied from parent.
212         */
213        PROPERTY_COPY,
214
215        /**
216         * A receiver type
217         */
218        RECEIVER_TYPE
219    }
220
221    public final HtmlConfiguration configuration;
222
223    /**
224     * The location of the link.
225     */
226    public Kind context = Kind.DEFAULT;
227
228    /**
229     * The value of the marker #.
230     */
231    public String where = "";
232
233    /**
234     * String style of text defined in style sheet.
235     */
236    public String styleName = "";
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 style to be used for the link.
320     * @param styleName  String style of text defined in style sheet.
321     */
322    public LinkInfoImpl styleName(String styleName) {
323        this.styleName = styleName;
324        return this;
325    }
326
327    /**
328     * Set the target to be used for the link.
329     * @param styleName  String style of text defined in style sheet.
330     */
331    public LinkInfoImpl target(String target) {
332        this.target = target;
333        return this;
334    }
335
336    /**
337     * Set whether or not this is a link to a varargs parameter.
338     */
339    public LinkInfoImpl varargs(boolean varargs) {
340        this.isVarArg = varargs;
341        return this;
342    }
343
344    /**
345     * Set the fragment specifier for the link.
346     */
347    public LinkInfoImpl where(String where) {
348        this.where = where;
349        return this;
350     }
351
352    /**
353     * {@inheritDoc}
354     */
355    public Kind getContext() {
356        return context;
357    }
358
359    /**
360     * {@inheritDoc}
361     *
362     * This method sets the link attributes to the appropriate values
363     * based on the context.
364     *
365     * @param c the context id to set.
366     */
367    public final void setContext(Kind c) {
368        //NOTE:  Put context specific link code here.
369        switch (c) {
370            case ALL_CLASSES_FRAME:
371            case PACKAGE_FRAME:
372            case IMPLEMENTED_CLASSES:
373            case SUBCLASSES:
374            case EXECUTABLE_ELEMENT_COPY:
375            case VARIABLE_ELEMENT_COPY:
376            case PROPERTY_COPY:
377            case CLASS_USE_HEADER:
378                includeTypeInClassLinkLabel = false;
379                break;
380
381            case ANNOTATION:
382                excludeTypeParameterLinks = true;
383                excludeTypeBounds = true;
384                break;
385
386            case IMPLEMENTED_INTERFACES:
387            case SUPER_INTERFACES:
388            case SUBINTERFACES:
389            case CLASS_TREE_PARENT:
390            case TREE:
391            case CLASS_SIGNATURE_PARENT_NAME:
392                excludeTypeParameterLinks = true;
393                excludeTypeBounds = true;
394                includeTypeInClassLinkLabel = false;
395                includeTypeAsSepLink = true;
396                break;
397
398            case PACKAGE:
399            case CLASS_USE:
400            case CLASS_HEADER:
401            case CLASS_SIGNATURE:
402            case RECEIVER_TYPE:
403                excludeTypeParameterLinks = true;
404                includeTypeAsSepLink = true;
405                includeTypeInClassLinkLabel = false;
406                break;
407
408            case MEMBER_TYPE_PARAMS:
409                includeTypeAsSepLink = true;
410                includeTypeInClassLinkLabel = false;
411                break;
412
413            case RETURN_TYPE:
414            case SUMMARY_RETURN_TYPE:
415                excludeTypeBounds = true;
416                break;
417            case EXECUTABLE_MEMBER_PARAM:
418                excludeTypeBounds = true;
419                break;
420        }
421        context = c;
422        if (type != null &&
423            utils.isTypeVariable(type) &&
424            utils.isExecutableElement(utils.asTypeElement(type).getEnclosingElement())) {
425                excludeTypeParameterLinks = true;
426        }
427    }
428
429    /**
430     * Return true if this link is linkable and false if we can't link to the
431     * desired place.
432     *
433     * @return true if this link is linkable and false if we can't link to the
434     * desired place.
435     */
436    @Override
437    public boolean isLinkable() {
438        return configuration.utils.isLinkable(typeElement);
439    }
440
441    @Override
442    public String toString() {
443        return "LinkInfoImpl{" +
444                "context=" + context +
445                ", where=" + where +
446                ", styleName=" + styleName +
447                ", target=" + target +
448                super.toString() + '}';
449    }
450}
451