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

changeset 0
959103a6100f
child 2525
2eb010b6cb22
equal deleted inserted replaced
-1:000000000000 0:959103a6100f
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 */
25
26 package com.sun.tools.doclets.internal.toolkit.util.links;
27
28 import com.sun.javadoc.*;
29 import com.sun.tools.doclets.internal.toolkit.Content;
30
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 {
43
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();
50
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 link.addContent(type.typeName());
64 } else if (type.asAnnotatedType() != null && type.dimension().length() == 0) {
65 link.addContent(getTypeAnnotationLinks(linkInfo));
66 linkInfo.type = type.asAnnotatedType().underlyingType();
67 link.addContent(getLink(linkInfo));
68 return link;
69 } else if (type.asWildcardType() != null) {
70 //Wildcard type.
71 linkInfo.isTypeBound = true;
72 link.addContent("?");
73 WildcardType wildcardType = type.asWildcardType();
74 Type[] extendsBounds = wildcardType.extendsBounds();
75 for (int i = 0; i < extendsBounds.length; i++) {
76 link.addContent(i > 0 ? ", " : " extends ");
77 setBoundsLinkInfo(linkInfo, extendsBounds[i]);
78 link.addContent(getLink(linkInfo));
79 }
80 Type[] superBounds = wildcardType.superBounds();
81 for (int i = 0; i < superBounds.length; i++) {
82 link.addContent(i > 0 ? ", " : " super ");
83 setBoundsLinkInfo(linkInfo, superBounds[i]);
84 link.addContent(getLink(linkInfo));
85 }
86 } else if (type.asTypeVariable()!= null) {
87 link.addContent(getTypeAnnotationLinks(linkInfo));
88 linkInfo.isTypeBound = true;
89 //A type variable.
90 Doc owner = type.asTypeVariable().owner();
91 if ((! linkInfo.excludeTypeParameterLinks) &&
92 owner instanceof ClassDoc) {
93 linkInfo.classDoc = (ClassDoc) owner;
94 Content label = newContent();
95 label.addContent(type.typeName());
96 linkInfo.label = label;
97 link.addContent(getClassLink(linkInfo));
98 } else {
99 //No need to link method type parameters.
100 link.addContent(type.typeName());
101 }
102
103 Type[] bounds = type.asTypeVariable().bounds();
104 if (! linkInfo.excludeTypeBounds) {
105 linkInfo.excludeTypeBounds = true;
106 for (int i = 0; i < bounds.length; i++) {
107 link.addContent(i > 0 ? " & " : " extends ");
108 setBoundsLinkInfo(linkInfo, bounds[i]);
109 link.addContent(getLink(linkInfo));
110 }
111 }
112 } else if (type.asClassDoc() != null) {
113 //A class type.
114 if (linkInfo.isTypeBound &&
115 linkInfo.excludeTypeBoundsLinks) {
116 //Since we are excluding type parameter links, we should not
117 //be linking to the type bound.
118 link.addContent(type.typeName());
119 link.addContent(getTypeParameterLinks(linkInfo));
120 return link;
121 } else {
122 linkInfo.classDoc = type.asClassDoc();
123 link = newContent();
124 link.addContent(getClassLink(linkInfo));
125 if (linkInfo.includeTypeAsSepLink) {
126 link.addContent(getTypeParameterLinks(linkInfo, false));
127 }
128 }
129 }
130
131 if (linkInfo.isVarArg) {
132 if (type.dimension().length() > 2) {
133 //Javadoc returns var args as array.
134 //Strip out the first [] from the var arg.
135 link.addContent(type.dimension().substring(2));
136 }
137 link.addContent("...");
138 } else {
139 while (type != null && type.dimension().length() > 0) {
140 if (type.asAnnotatedType() != null) {
141 linkInfo.type = type;
142 link.addContent(" ");
143 link.addContent(getTypeAnnotationLinks(linkInfo));
144 link.addContent("[]");
145 type = type.asAnnotatedType().underlyingType().getElementType();
146 } else {
147 link.addContent("[]");
148 type = type.getElementType();
149 }
150 }
151 linkInfo.type = type;
152 Content newLink = newContent();
153 newLink.addContent(getTypeAnnotationLinks(linkInfo));
154 newLink.addContent(link);
155 link = newLink;
156 }
157 return link;
158 } else if (linkInfo.classDoc != null) {
159 //Just a class link
160 Content link = newContent();
161 link.addContent(getClassLink(linkInfo));
162 if (linkInfo.includeTypeAsSepLink) {
163 link.addContent(getTypeParameterLinks(linkInfo, false));
164 }
165 return link;
166 } else {
167 return null;
168 }
169 }
170
171 private void setBoundsLinkInfo(LinkInfo linkInfo, Type bound) {
172 linkInfo.classDoc = null;
173 linkInfo.label = null;
174 linkInfo.type = bound;
175 }
176
177 /**
178 * Return the link to the given class.
179 *
180 * @param linkInfo the information about the link to construct.
181 *
182 * @return the link for the given class.
183 */
184 protected abstract Content getClassLink(LinkInfo linkInfo);
185
186 /**
187 * Return the link to the given type parameter.
188 *
189 * @param linkInfo the information about the link to construct.
190 * @param typeParam the type parameter to link to.
191 */
192 protected abstract Content getTypeParameterLink(LinkInfo linkInfo,
193 Type typeParam);
194
195 protected abstract Content getTypeAnnotationLink(LinkInfo linkInfo,
196 AnnotationDesc annotation);
197
198 /**
199 * Return the links to the type parameters.
200 *
201 * @param linkInfo the information about the link to construct.
202 * @return the links to the type parameters.
203 */
204 public Content getTypeParameterLinks(LinkInfo linkInfo) {
205 return getTypeParameterLinks(linkInfo, true);
206 }
207
208 /**
209 * Return the links to the type parameters.
210 *
211 * @param linkInfo the information about the link to construct.
212 * @param isClassLabel true if this is a class label. False if it is
213 * the type parameters portion of the link.
214 * @return the links to the type parameters.
215 */
216 public Content getTypeParameterLinks(LinkInfo linkInfo, boolean isClassLabel) {
217 Content links = newContent();
218 Type[] vars;
219 if (linkInfo.executableMemberDoc != null) {
220 vars = linkInfo.executableMemberDoc.typeParameters();
221 } else if (linkInfo.type != null &&
222 linkInfo.type.asParameterizedType() != null){
223 vars = linkInfo.type.asParameterizedType().typeArguments();
224 } else if (linkInfo.classDoc != null){
225 vars = linkInfo.classDoc.typeParameters();
226 } else {
227 //Nothing to document.
228 return links;
229 }
230 if (((linkInfo.includeTypeInClassLinkLabel && isClassLabel) ||
231 (linkInfo.includeTypeAsSepLink && ! isClassLabel)
232 )
233 && vars.length > 0) {
234 links.addContent("<");
235 for (int i = 0; i < vars.length; i++) {
236 if (i > 0) {
237 links.addContent(",");
238 }
239 links.addContent(getTypeParameterLink(linkInfo, vars[i]));
240 }
241 links.addContent(">");
242 }
243 return links;
244 }
245
246 public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
247 Content links = newContent();
248 if (linkInfo.type.asAnnotatedType() == null)
249 return links;
250 AnnotationDesc[] annotations = linkInfo.type.asAnnotatedType().annotations();
251 for (int i = 0; i < annotations.length; i++) {
252 if (i > 0) {
253 links.addContent(" ");
254 }
255 links.addContent(getTypeAnnotationLink(linkInfo, annotations[i]));
256 }
257
258 links.addContent(" ");
259 return links;
260 }
261 }

mercurial