24 */
25
26 package jdk.javadoc.internal.doclets.formats.html;
27
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import javax.lang.model.element.AnnotationMirror;
32 import javax.lang.model.element.Element;
33 import javax.lang.model.element.TypeElement;
34 import javax.lang.model.type.DeclaredType;
35 import javax.lang.model.type.TypeMirror;
36
37 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
38 import jdk.javadoc.internal.doclets.formats.html.markup.Entity;
39 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
40 import jdk.javadoc.internal.doclets.toolkit.Content;
41 import jdk.javadoc.internal.doclets.toolkit.Resources;
42 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
43 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
44 import jdk.javadoc.internal.doclets.toolkit.util.links.LinkFactory;
45 import jdk.javadoc.internal.doclets.toolkit.util.links.LinkInfo;
46
47 /**
48 * A factory that returns a link given the information about it.
49 *
50 * <p><b>This is NOT part of any supported API.
51 * If you write code that depends on this, you do so at your own risk.
52 * This code and its internal interfaces are subject to change or
53 * deletion without notice.</b>
54 *
55 * @author Jamie Ho
56 */
57 public class LinkFactoryImpl extends LinkFactory {
58
59 private final HtmlDocletWriter m_writer;
60 private final DocPaths docPaths;
61
62 public LinkFactoryImpl(HtmlDocletWriter writer) {
63 super(writer.configuration.utils);
117 if (crossLink != null) {
118 link.add(crossLink);
119 if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
120 link.add(getTypeParameterLinks(linkInfo));
121 }
122 return link;
123 }
124 }
125 // Can't link so just write label.
126 link.add(label);
127 if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
128 link.add(getTypeParameterLinks(linkInfo));
129 }
130 return link;
131 }
132
133 /**
134 * {@inheritDoc}
135 */
136 @Override
137 protected Content getTypeParameterLinks(LinkInfo linkInfo, boolean isClassLabel){
138 Content links = newContent();
139 List<TypeMirror> vars = new ArrayList<>();
140 TypeMirror ctype = linkInfo.type != null
141 ? utils.getComponentType(linkInfo.type)
142 : null;
143 if (linkInfo.executableElement != null) {
144 linkInfo.executableElement.getTypeParameters().stream().forEach((t) -> {
145 vars.add(t.asType());
146 });
147 } else if (linkInfo.type != null && utils.isDeclaredType(linkInfo.type)) {
148 ((DeclaredType)linkInfo.type).getTypeArguments().stream().forEach(vars::add);
149 } else if (ctype != null && utils.isDeclaredType(ctype)) {
150 ((DeclaredType)ctype).getTypeArguments().stream().forEach(vars::add);
151 } else if (linkInfo.typeElement != null) {
152 linkInfo.typeElement.getTypeParameters().stream().forEach((t) -> {
153 vars.add(t.asType());
154 });
155 } else {
156 // Nothing to document.
157 return links;
158 }
159 if (((linkInfo.includeTypeInClassLinkLabel && isClassLabel)
160 || (linkInfo.includeTypeAsSepLink && !isClassLabel)) && !vars.isEmpty()) {
161 links.add("<");
162 boolean many = false;
163 for (TypeMirror t : vars) {
164 if (many) {
165 links.add(",");
166 links.add(Entity.ZERO_WIDTH_SPACE);
167 }
168 links.add(getTypeParameterLink(linkInfo, t));
169 many = true;
170 }
171 links.add(">");
172 }
173 return links;
174 }
175
176 /**
177 * Returns a link to the given type parameter.
178 *
179 * @param linkInfo the information about the link to construct
180 * @param typeParam the type parameter to link to
181 * @return the link
182 */
183 protected Content getTypeParameterLink(LinkInfo linkInfo, TypeMirror typeParam) {
184 LinkInfoImpl typeLinkInfo = new LinkInfoImpl(m_writer.configuration,
185 ((LinkInfoImpl) linkInfo).getContext(), typeParam);
186 typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds;
187 typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks;
188 typeLinkInfo.linkToSelf = linkInfo.linkToSelf;
189 typeLinkInfo.isJava5DeclarationLocation = false;
190 return getLink(typeLinkInfo);
191 }
192
193 @Override
194 public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
195 ContentBuilder links = new ContentBuilder();
196 List<? extends AnnotationMirror> annotations;
197 if (utils.isAnnotated(linkInfo.type)) {
198 annotations = linkInfo.type.getAnnotationMirrors();
199 } else if (utils.isTypeVariable(linkInfo.type)) {
200 // TODO: use the context for now, and special case for Receiver_Types,
201 // which takes the default case.
202 switch (((LinkInfoImpl)linkInfo).context) {
203 case MEMBER_TYPE_PARAMS:
204 case EXECUTABLE_MEMBER_PARAM:
205 case CLASS_SIGNATURE:
206 Element element = utils.typeUtils.asElement(linkInfo.type);
207 annotations = element.getAnnotationMirrors();
208 break;
209 default:
210 annotations = linkInfo.type.getAnnotationMirrors();
211 break;
212 }
213
214 } else {
215 return links;
216 }
217
218 if (annotations.isEmpty())
219 return links;
220
221 List<Content> annos = m_writer.getAnnotations(0, annotations, false, linkInfo.isJava5DeclarationLocation);
222
223 boolean isFirst = true;
224 for (Content anno : annos) {
225 if (!isFirst) {
226 links.add(" ");
227 }
228 links.add(anno);
229 isFirst = false;
230 }
231 if (!annos.isEmpty()) {
232 links.add(" ");
233 }
234
235 return links;
236 }
237
238 /**
239 * Given a class, return the appropriate tool tip.
240 *
241 * @param typeElement the class to get the tool tip for.
|
24 */
25
26 package jdk.javadoc.internal.doclets.formats.html;
27
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import javax.lang.model.element.AnnotationMirror;
32 import javax.lang.model.element.Element;
33 import javax.lang.model.element.TypeElement;
34 import javax.lang.model.type.DeclaredType;
35 import javax.lang.model.type.TypeMirror;
36
37 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
38 import jdk.javadoc.internal.doclets.formats.html.markup.Entity;
39 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
40 import jdk.javadoc.internal.doclets.toolkit.Content;
41 import jdk.javadoc.internal.doclets.toolkit.Resources;
42 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
43 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
44 import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
45 import jdk.javadoc.internal.doclets.toolkit.util.links.LinkFactory;
46 import jdk.javadoc.internal.doclets.toolkit.util.links.LinkInfo;
47
48 /**
49 * A factory that returns a link given the information about it.
50 *
51 * <p><b>This is NOT part of any supported API.
52 * If you write code that depends on this, you do so at your own risk.
53 * This code and its internal interfaces are subject to change or
54 * deletion without notice.</b>
55 *
56 * @author Jamie Ho
57 */
58 public class LinkFactoryImpl extends LinkFactory {
59
60 private final HtmlDocletWriter m_writer;
61 private final DocPaths docPaths;
62
63 public LinkFactoryImpl(HtmlDocletWriter writer) {
64 super(writer.configuration.utils);
118 if (crossLink != null) {
119 link.add(crossLink);
120 if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
121 link.add(getTypeParameterLinks(linkInfo));
122 }
123 return link;
124 }
125 }
126 // Can't link so just write label.
127 link.add(label);
128 if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
129 link.add(getTypeParameterLinks(linkInfo));
130 }
131 return link;
132 }
133
134 /**
135 * {@inheritDoc}
136 */
137 @Override
138 protected Content getTypeParameterLinks(LinkInfo linkInfo, boolean isClassLabel) {
139 Content links = newContent();
140 List<TypeMirror> vars = new ArrayList<>();
141 TypeMirror ctype = linkInfo.type != null
142 ? utils.getComponentType(linkInfo.type)
143 : null;
144 if (linkInfo.executableElement != null) {
145 linkInfo.executableElement.getTypeParameters().stream().forEach((t) -> {
146 vars.add(t.asType());
147 });
148 } else if (linkInfo.type != null && utils.isDeclaredType(linkInfo.type)) {
149 ((DeclaredType)linkInfo.type).getTypeArguments().stream().forEach(vars::add);
150 } else if (ctype != null && utils.isDeclaredType(ctype)) {
151 ((DeclaredType)ctype).getTypeArguments().stream().forEach(vars::add);
152 } else if (linkInfo.typeElement != null) {
153 linkInfo.typeElement.getTypeParameters().stream().forEach((t) -> {
154 vars.add(t.asType());
155 });
156 } else {
157 // Nothing to document.
158 return links;
159 }
160 if (((linkInfo.includeTypeInClassLinkLabel && isClassLabel)
161 || (linkInfo.includeTypeAsSepLink && !isClassLabel)) && !vars.isEmpty()) {
162 links.add("<");
163 boolean many = false;
164 for (TypeMirror t : vars) {
165 if (many) {
166 links.add(",");
167 links.add(Entity.ZERO_WIDTH_SPACE);
168 if (((LinkInfoImpl) linkInfo).getContext() == LinkInfoImpl.Kind.MEMBER_TYPE_PARAMS) {
169 links.add(DocletConstants.NL);
170 }
171 }
172 links.add(getTypeParameterLink(linkInfo, t));
173 many = true;
174 }
175 links.add(">");
176 }
177 return links;
178 }
179
180 /**
181 * Returns a link to the given type parameter.
182 *
183 * @param linkInfo the information about the link to construct
184 * @param typeParam the type parameter to link to
185 * @return the link
186 */
187 protected Content getTypeParameterLink(LinkInfo linkInfo, TypeMirror typeParam) {
188 LinkInfoImpl typeLinkInfo = new LinkInfoImpl(m_writer.configuration,
189 ((LinkInfoImpl) linkInfo).getContext(), typeParam);
190 typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds;
191 typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks;
192 typeLinkInfo.linkToSelf = linkInfo.linkToSelf;
193 return getLink(typeLinkInfo);
194 }
195
196 @Override
197 public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
198 ContentBuilder links = new ContentBuilder();
199 List<? extends AnnotationMirror> annotations;
200 if (utils.isAnnotated(linkInfo.type)) {
201 annotations = linkInfo.type.getAnnotationMirrors();
202 } else if (utils.isTypeVariable(linkInfo.type)) {
203 // TODO: use the context for now, and special case for Receiver_Types,
204 // which takes the default case.
205 switch (((LinkInfoImpl)linkInfo).context) {
206 case MEMBER_TYPE_PARAMS:
207 case EXECUTABLE_MEMBER_PARAM:
208 case CLASS_SIGNATURE:
209 Element element = utils.typeUtils.asElement(linkInfo.type);
210 annotations = element.getAnnotationMirrors();
211 break;
212 default:
213 annotations = linkInfo.type.getAnnotationMirrors();
214 break;
215 }
216
217 } else {
218 return links;
219 }
220
221 if (annotations.isEmpty())
222 return links;
223
224 List<Content> annos = m_writer.getAnnotations(annotations, false);
225
226 boolean isFirst = true;
227 for (Content anno : annos) {
228 if (!isFirst) {
229 links.add(" ");
230 }
231 links.add(anno);
232 isFirst = false;
233 }
234 if (!annos.isEmpty()) {
235 links.add(" ");
236 }
237
238 return links;
239 }
240
241 /**
242 * Given a class, return the appropriate tool tip.
243 *
244 * @param typeElement the class to get the tool tip for.
|