src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFinder.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;
27
28 import java.util.*;
29
30 import com.sun.javadoc.*;
31 import com.sun.tools.doclets.internal.toolkit.taglets.*;
32
33 /**
34 * Search for the requested documentation. Inherit documentation if necessary.
35 *
36 * <p><b>This is NOT part of any supported API.
37 * If you write code that depends on this, you do so at your own risk.
38 * This code and its internal interfaces are subject to change or
39 * deletion without notice.</b>
40 *
41 * @author Jamie Ho
42 * @since 1.5
43 */
44 public class DocFinder {
45
46 /**
47 * The class that encapsulates the input.
48 */
49 public static class Input {
50 /**
51 * The element to search documentation from.
52 */
53 public ProgramElementDoc element;
54 /**
55 * The taglet to search for documentation on behalf of. Null if we want
56 * to search for overall documentation.
57 */
58 public InheritableTaglet taglet = null;
59
60 /**
61 * The id of the tag to retrieve documentation for.
62 */
63 public String tagId = null;
64
65 /**
66 * The tag to retrieve documentation for. This is only used for the
67 * inheritDoc tag.
68 */
69 public Tag tag = null;
70
71 /**
72 * True if we only want to search for the first sentence.
73 */
74 public boolean isFirstSentence = false;
75
76 /**
77 * True if we are looking for documentation to replace the inheritDocTag.
78 */
79 public boolean isInheritDocTag = false;
80
81 /**
82 * Used to distinguish between type variable param tags and regular
83 * param tags.
84 */
85 public boolean isTypeVariableParamTag = false;
86
87 public Input(ProgramElementDoc element, InheritableTaglet taglet, Tag tag,
88 boolean isFirstSentence, boolean isInheritDocTag) {
89 this(element);
90 this.taglet = taglet;
91 this.tag = tag;
92 this.isFirstSentence = isFirstSentence;
93 this.isInheritDocTag = isInheritDocTag;
94 }
95
96 public Input(ProgramElementDoc element, InheritableTaglet taglet, String tagId) {
97 this(element);
98 this.taglet = taglet;
99 this.tagId = tagId;
100 }
101
102 public Input(ProgramElementDoc element, InheritableTaglet taglet, String tagId,
103 boolean isTypeVariableParamTag) {
104 this(element);
105 this.taglet = taglet;
106 this.tagId = tagId;
107 this.isTypeVariableParamTag = isTypeVariableParamTag;
108 }
109
110 public Input(ProgramElementDoc element, InheritableTaglet taglet) {
111 this(element);
112 this.taglet = taglet;
113 }
114
115 public Input(ProgramElementDoc element) {
116 if (element == null)
117 throw new NullPointerException();
118 this.element = element;
119 }
120
121 public Input(ProgramElementDoc element, boolean isFirstSentence) {
122 this(element);
123 this.isFirstSentence = isFirstSentence;
124 }
125
126 public Input copy() {
127 Input clone = new Input(this.element);
128 clone.taglet = this.taglet;
129 clone.tagId = this.tagId;
130 clone.tag = this.tag;
131 clone.isFirstSentence = this.isFirstSentence;
132 clone.isInheritDocTag = this.isInheritDocTag;
133 clone.isTypeVariableParamTag = this.isTypeVariableParamTag;
134 if (clone.element == null)
135 throw new NullPointerException();
136 return clone;
137
138 }
139 }
140
141 /**
142 * The class that encapsulates the output.
143 */
144 public static class Output {
145 /**
146 * The tag that holds the documentation. Null if documentation
147 * is not held by a tag.
148 */
149 public Tag holderTag;
150
151 /**
152 * The Doc object that holds the documentation.
153 */
154 public Doc holder;
155
156 /**
157 * The inherited documentation.
158 */
159 public Tag[] inlineTags = new Tag[] {};
160
161 /**
162 * False if documentation could not be inherited.
163 */
164 public boolean isValidInheritDocTag = true;
165
166 /**
167 * When automatically inheriting throws tags, you sometime must inherit
168 * more than one tag. For example if the element declares that it throws
169 * IOException and the overridden element has throws tags for IOException and
170 * ZipException, both tags would be inherited because ZipException is a
171 * subclass of IOException. This subclass of DocFinder.Output allows
172 * multiple tag inheritence.
173 */
174 public List<Tag> tagList = new ArrayList<Tag>();
175 }
176
177 /**
178 * Search for the requested comments in the given element. If it does not
179 * have comments, return documentation from the overriden element if possible.
180 * If the overriden element does not exist or does not have documentation to
181 * inherit, search for documentation to inherit from implemented methods.
182 *
183 * @param input the input object used to perform the search.
184 *
185 * @return an Output object representing the documentation that was found.
186 */
187 public static Output search(Input input) {
188 Output output = new Output();
189 if (input.isInheritDocTag) {
190 //Do nothing because "element" does not have any documentation.
191 //All it has it {@inheritDoc}.
192 } else if (input.taglet == null) {
193 //We want overall documentation.
194 output.inlineTags = input.isFirstSentence ?
195 input.element.firstSentenceTags() :
196 input.element.inlineTags();
197 output.holder = input.element;
198 } else {
199 input.taglet.inherit(input, output);
200 }
201
202 if (output.inlineTags != null && output.inlineTags.length > 0) {
203 return output;
204 }
205 output.isValidInheritDocTag = false;
206 Input inheritedSearchInput = input.copy();
207 inheritedSearchInput.isInheritDocTag = false;
208 if (input.element instanceof MethodDoc) {
209 MethodDoc overriddenMethod = ((MethodDoc) input.element).overriddenMethod();
210 if (overriddenMethod != null) {
211 inheritedSearchInput.element = overriddenMethod;
212 output = search(inheritedSearchInput);
213 output.isValidInheritDocTag = true;
214 if (output.inlineTags.length > 0) {
215 return output;
216 }
217 }
218 //NOTE: When we fix the bug where ClassDoc.interfaceTypes() does
219 // not pass all implemented interfaces, we will use the
220 // appropriate element here.
221 MethodDoc[] implementedMethods =
222 (new ImplementedMethods((MethodDoc) input.element, null)).build(false);
223 for (int i = 0; i < implementedMethods.length; i++) {
224 inheritedSearchInput.element = implementedMethods[i];
225 output = search(inheritedSearchInput);
226 output.isValidInheritDocTag = true;
227 if (output.inlineTags.length > 0) {
228 return output;
229 }
230 }
231 } else if (input.element instanceof ClassDoc) {
232 ProgramElementDoc superclass = ((ClassDoc) input.element).superclass();
233 if (superclass != null) {
234 inheritedSearchInput.element = superclass;
235 output = search(inheritedSearchInput);
236 output.isValidInheritDocTag = true;
237 if (output.inlineTags.length > 0) {
238 return output;
239 }
240 }
241 }
242 return output;
243 }
244 }

mercurial