Thu, 15 Nov 2012 19:54:20 -0800
8002079: update DocFile to use a JavaFileManager
Reviewed-by: darcy
1 /*
2 * Copyright (c) 2003, 2012, 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 */
26 package com.sun.tools.doclets.internal.toolkit.util;
28 import java.util.*;
30 import com.sun.javadoc.*;
31 import com.sun.tools.doclets.internal.toolkit.taglets.*;
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 {
46 /**
47 * The class that encapsulates the input.
48 */
49 public static class Input {
50 /**
51 * The method to search documentation from.
52 */
53 public MethodDoc method = null;
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;
60 /**
61 * The id of the tag to retrieve documentation for.
62 */
63 public String tagId = null;
65 /**
66 * The tag to retrieve documentation for. This is only used for the
67 * inheritDoc tag.
68 */
69 public Tag tag = null;
71 /**
72 * True if we only want to search for the first sentence.
73 */
74 public boolean isFirstSentence = false;
76 /**
77 * True if we are looking for documentation to replace the inheritDocTag.
78 */
79 public boolean isInheritDocTag = false;
81 /**
82 * Used to distinguish between type variable param tags and regular
83 * param tags.
84 */
85 public boolean isTypeVariableParamTag = false;
87 public Input() {}
89 public Input(MethodDoc method, InheritableTaglet taglet, Tag tag,
90 boolean isFirstSentence, boolean isInheritDocTag) {
91 this.method = method;
92 this.taglet = taglet;
93 this.tag = tag;
94 this.isFirstSentence = isFirstSentence;
95 this.isInheritDocTag = isInheritDocTag;
96 }
98 public Input(MethodDoc method, InheritableTaglet taglet, String tagId) {
99 this.method = method;
100 this.taglet = taglet;
101 this.tagId = tagId;
102 }
104 public Input(MethodDoc method, InheritableTaglet taglet, String tagId,
105 boolean isTypeVariableParamTag) {
106 this.method = method;
107 this.taglet = taglet;
108 this.tagId = tagId;
109 this.isTypeVariableParamTag = isTypeVariableParamTag;
110 }
112 public Input(MethodDoc method, InheritableTaglet taglet) {
113 this.method = method;
114 this.taglet = taglet;
115 }
117 public Input(MethodDoc method) {
118 this.method = method;
119 }
121 public Input(MethodDoc method, boolean isFirstSentence) {
122 this.method = method;
123 this.isFirstSentence = isFirstSentence;
124 }
126 public Input copy() {
127 Input clone = new Input();
128 clone.method = this.method;
129 clone.taglet = this.taglet;
130 clone.tagId = this.tagId;
131 clone.tag = this.tag;
132 clone.isFirstSentence = this.isFirstSentence;
133 clone.isInheritDocTag = this.isInheritDocTag;
134 clone.isTypeVariableParamTag = this.isTypeVariableParamTag;
135 return clone;
137 }
138 }
140 /**
141 * The class that encapsulates the output.
142 */
143 public static class Output {
144 /**
145 * The tag that holds the documentation. Null if documentation
146 * is not held by a tag.
147 */
148 public Tag holderTag;
150 /**
151 * The Doc object that holds the documentation.
152 */
153 public Doc holder;
155 /**
156 * The inherited documentation.
157 */
158 public Tag[] inlineTags = new Tag[] {};
160 /**
161 * False if documentation could not be inherited.
162 */
163 public boolean isValidInheritDocTag = true;
165 /**
166 * When automatically inheriting throws tags, you sometime must inherit
167 * more than one tag. For example if the method declares that it throws
168 * IOException and the overidden method has throws tags for IOException and
169 * ZipException, both tags would be inherited because ZipException is a
170 * subclass of IOException. This subclass of DocFinder.Output allows
171 * multiple tag inheritence.
172 */
173 public List<Tag> tagList = new ArrayList<Tag>();
174 }
176 /**
177 * Search for the requested comments in the given method. If it does not
178 * have comments, return documentation from the overriden method if possible.
179 * If the overriden method does not exist or does not have documentation to
180 * inherit, search for documentation to inherit from implemented methods.
181 *
182 * @param input the input object used to perform the search.
183 *
184 * @return an Output object representing the documentation that was found.
185 */
186 public static Output search(Input input) {
187 Output output = new Output();
188 if (input.isInheritDocTag) {
189 //Do nothing because "method" does not have any documentation.
190 //All it has it {@inheritDoc}.
191 } else if (input.taglet == null) {
192 //We want overall documentation.
193 output.inlineTags = input.isFirstSentence ?
194 input.method.firstSentenceTags() :
195 input.method.inlineTags();
196 output.holder = input.method;
197 } else {
198 input.taglet.inherit(input, output);
199 }
201 if (output.inlineTags != null && output.inlineTags.length > 0) {
202 return output;
203 }
204 output.isValidInheritDocTag = false;
205 Input inheritedSearchInput = input.copy();
206 inheritedSearchInput.isInheritDocTag = false;
207 if (input.method.overriddenMethod() != null) {
208 inheritedSearchInput.method = input.method.overriddenMethod();
209 output = search(inheritedSearchInput);
210 output.isValidInheritDocTag = true;
211 if (output != null && output.inlineTags.length > 0) {
212 return output;
213 }
214 }
215 //NOTE: When we fix the bug where ClassDoc.interfaceTypes() does
216 // not pass all implemented interfaces, we will use the
217 // appropriate method here.
218 MethodDoc[] implementedMethods =
219 (new ImplementedMethods(input.method, null)).build(false);
220 for (int i = 0; i < implementedMethods.length; i++) {
221 inheritedSearchInput.method = implementedMethods[i];
222 output = search(inheritedSearchInput);
223 output.isValidInheritDocTag = true;
224 if (output != null && output.inlineTags.length > 0) {
225 return output;
226 }
227 }
228 return output;
229 }
230 }