Tue, 23 Oct 2012 13:20:37 -0700
8000741: refactor javadoc to use abstraction to handle relative paths
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.builders;
28 import java.io.*;
29 import java.util.*;
31 import com.sun.javadoc.*;
32 import com.sun.tools.doclets.internal.toolkit.*;
33 import com.sun.tools.doclets.internal.toolkit.util.*;
35 /**
36 * Builds the summary for a given class.
37 *
38 * <p><b>This is NOT part of any supported API.
39 * If you write code that depends on this, you do so at your own risk.
40 * This code and its internal interfaces are subject to change or
41 * deletion without notice.</b>
42 *
43 * @author Jamie Ho
44 * @author Bhavesh Patel (Modified)
45 * @since 1.5
46 */
47 public class ClassBuilder extends AbstractBuilder {
49 /**
50 * The root element of the class XML is {@value}.
51 */
52 public static final String ROOT = "ClassDoc";
54 /**
55 * The class being documented.
56 */
57 private ClassDoc classDoc;
59 /**
60 * The doclet specific writer.
61 */
62 private ClassWriter writer;
64 /**
65 * Keep track of whether or not this classdoc is an interface.
66 */
67 private boolean isInterface = false;
69 /**
70 * Keep track of whether or not this classdoc is an enum.
71 */
72 private boolean isEnum = false;
74 /**
75 * The content tree for the class documentation.
76 */
77 private Content contentTree;
79 /**
80 * Construct a new ClassBuilder.
81 *
82 * @param configuration the current configuration of the
83 * doclet.
84 */
85 private ClassBuilder(Configuration configuration) {
86 super(configuration);
87 }
89 /**
90 * Construct a new ClassBuilder.
91 *
92 * @param configuration the current configuration of the doclet.
93 * @param classDoc the class being documented.
94 * @param writer the doclet specific writer.
95 */
96 public static ClassBuilder getInstance(Configuration configuration,
97 ClassDoc classDoc, ClassWriter writer)
98 throws Exception {
99 ClassBuilder builder = new ClassBuilder(configuration);
100 builder.configuration = configuration;
101 builder.classDoc = classDoc;
102 builder.writer = writer;
103 if (classDoc.isInterface()) {
104 builder.isInterface = true;
105 } else if (classDoc.isEnum()) {
106 builder.isEnum = true;
107 Util.setEnumDocumentation(configuration, classDoc);
108 }
109 if(containingPackagesSeen == null) {
110 containingPackagesSeen = new HashSet<String>();
111 }
112 return builder;
113 }
115 /**
116 * {@inheritDoc}
117 */
118 public void build() throws IOException {
119 build(LayoutParser.getInstance(configuration).parseXML(ROOT), contentTree);
120 }
122 /**
123 * {@inheritDoc}
124 */
125 public String getName() {
126 return ROOT;
127 }
129 /**
130 * Handles the {@literal <ClassDoc>} tag.
131 *
132 * @param node the XML element that specifies which components to document
133 * @param contentTree the content tree to which the documentation will be added
134 */
135 public void buildClassDoc(XMLNode node, Content contentTree) throws Exception {
136 String key;
137 if (isInterface) {
138 key = "doclet.Interface";
139 } else if (isEnum) {
140 key = "doclet.Enum";
141 } else {
142 key = "doclet.Class";
143 }
144 contentTree = writer.getHeader(configuration.getText(key) + " " +
145 classDoc.name());
146 Content classContentTree = writer.getClassContentHeader();
147 buildChildren(node, classContentTree);
148 contentTree.addContent(classContentTree);
149 writer.addFooter(contentTree);
150 writer.printDocument(contentTree);
151 writer.close();
152 copyDocFiles();
153 }
155 /**
156 * Build the class tree documentation.
157 *
158 * @param node the XML element that specifies which components to document
159 * @param classContentTree the content tree to which the documentation will be added
160 */
161 public void buildClassTree(XMLNode node, Content classContentTree) {
162 writer.addClassTree(classContentTree);
163 }
165 /**
166 * Build the class information tree documentation.
167 *
168 * @param node the XML element that specifies which components to document
169 * @param classContentTree the content tree to which the documentation will be added
170 */
171 public void buildClassInfo(XMLNode node, Content classContentTree) {
172 Content classInfoTree = writer.getClassInfoTreeHeader();
173 buildChildren(node, classInfoTree);
174 classContentTree.addContent(writer.getClassInfo(classInfoTree));
175 }
177 /**
178 * Build the typeparameters of this class.
179 *
180 * @param node the XML element that specifies which components to document
181 * @param classInfoTree the content tree to which the documentation will be added
182 */
183 public void buildTypeParamInfo(XMLNode node, Content classInfoTree) {
184 writer.addTypeParamInfo(classInfoTree);
185 }
187 /**
188 * If this is an interface, list all super interfaces.
189 *
190 * @param node the XML element that specifies which components to document
191 * @param classInfoTree the content tree to which the documentation will be added
192 */
193 public void buildSuperInterfacesInfo(XMLNode node, Content classInfoTree) {
194 writer.addSuperInterfacesInfo(classInfoTree);
195 }
197 /**
198 * If this is a class, list all interfaces implemented by this class.
199 *
200 * @param node the XML element that specifies which components to document
201 * @param classInfoTree the content tree to which the documentation will be added
202 */
203 public void buildImplementedInterfacesInfo(XMLNode node, Content classInfoTree) {
204 writer.addImplementedInterfacesInfo(classInfoTree);
205 }
207 /**
208 * List all the classes extend this one.
209 *
210 * @param node the XML element that specifies which components to document
211 * @param classInfoTree the content tree to which the documentation will be added
212 */
213 public void buildSubClassInfo(XMLNode node, Content classInfoTree) {
214 writer.addSubClassInfo(classInfoTree);
215 }
217 /**
218 * List all the interfaces that extend this one.
219 *
220 * @param node the XML element that specifies which components to document
221 * @param classInfoTree the content tree to which the documentation will be added
222 */
223 public void buildSubInterfacesInfo(XMLNode node, Content classInfoTree) {
224 writer.addSubInterfacesInfo(classInfoTree);
225 }
227 /**
228 * If this is an interface, list all classes that implement this interface.
229 *
230 * @param node the XML element that specifies which components to document
231 * @param classInfoTree the content tree to which the documentation will be added
232 */
233 public void buildInterfaceUsageInfo(XMLNode node, Content classInfoTree) {
234 writer.addInterfaceUsageInfo(classInfoTree);
235 }
237 /**
238 * If this class is deprecated, build the appropriate information.
239 *
240 * @param node the XML element that specifies which components to document
241 * @param classInfoTree the content tree to which the documentation will be added
242 */
243 public void buildDeprecationInfo (XMLNode node, Content classInfoTree) {
244 writer.addClassDeprecationInfo(classInfoTree);
245 }
247 /**
248 * If this is an inner class or interface, list the enclosing class or interface.
249 *
250 * @param node the XML element that specifies which components to document
251 * @param classInfoTree the content tree to which the documentation will be added
252 */
253 public void buildNestedClassInfo (XMLNode node, Content classInfoTree) {
254 writer.addNestedClassInfo(classInfoTree);
255 }
257 /**
258 * Copy the doc files for the current ClassDoc if necessary.
259 */
260 private void copyDocFiles() {
261 PackageDoc containingPackage = classDoc.containingPackage();
262 if((configuration.packages == null ||
263 Arrays.binarySearch(configuration.packages,
264 containingPackage) < 0) &&
265 ! containingPackagesSeen.contains(containingPackage.name())){
266 //Only copy doc files dir if the containing package is not
267 //documented AND if we have not documented a class from the same
268 //package already. Otherwise, we are making duplicate copies.
269 Util.copyDocFiles(configuration,
270 new File(Util.getPackageSourcePath(configuration, containingPackage),
271 DocPath.forPackage(classDoc).getPath()),
272 DocPaths.DOC_FILES, true);
273 containingPackagesSeen.add(containingPackage.name());
274 }
275 }
277 /**
278 * Build the signature of the current class.
279 *
280 * @param node the XML element that specifies which components to document
281 * @param classInfoTree the content tree to which the documentation will be added
282 */
283 public void buildClassSignature(XMLNode node, Content classInfoTree) {
284 StringBuilder modifiers = new StringBuilder(classDoc.modifiers() + " ");
285 if (isEnum) {
286 modifiers.append("enum ");
287 int index;
288 if ((index = modifiers.indexOf("abstract")) >= 0) {
289 modifiers.delete(index, index + "abstract".length());
290 modifiers = new StringBuilder(
291 Util.replaceText(modifiers.toString(), " ", " "));
292 }
293 if ((index = modifiers.indexOf("final")) >= 0) {
294 modifiers.delete(index, index + "final".length());
295 modifiers = new StringBuilder(
296 Util.replaceText(modifiers.toString(), " ", " "));
297 }
298 //} else if (classDoc.isAnnotationType()) {
299 //modifiers.append("@interface ");
300 } else if (! isInterface) {
301 modifiers.append("class ");
302 }
303 writer.addClassSignature(modifiers.toString(), classInfoTree);
304 }
306 /**
307 * Build the class description.
308 *
309 * @param node the XML element that specifies which components to document
310 * @param classInfoTree the content tree to which the documentation will be added
311 */
312 public void buildClassDescription(XMLNode node, Content classInfoTree) {
313 writer.addClassDescription(classInfoTree);
314 }
316 /**
317 * Build the tag information for the current class.
318 *
319 * @param node the XML element that specifies which components to document
320 * @param classInfoTree the content tree to which the documentation will be added
321 */
322 public void buildClassTagInfo(XMLNode node, Content classInfoTree) {
323 writer.addClassTagInfo(classInfoTree);
324 }
326 /**
327 * Build the member summary contents of the page.
328 *
329 * @param node the XML element that specifies which components to document
330 * @param classContentTree the content tree to which the documentation will be added
331 */
332 public void buildMemberSummary(XMLNode node, Content classContentTree) throws Exception {
333 Content memberSummaryTree = writer.getMemberTreeHeader();
334 configuration.getBuilderFactory().
335 getMemberSummaryBuilder(writer).buildChildren(node, memberSummaryTree);
336 classContentTree.addContent(writer.getMemberSummaryTree(memberSummaryTree));
337 }
339 /**
340 * Build the member details contents of the page.
341 *
342 * @param node the XML element that specifies which components to document
343 * @param classContentTree the content tree to which the documentation will be added
344 */
345 public void buildMemberDetails(XMLNode node, Content classContentTree) {
346 Content memberDetailsTree = writer.getMemberTreeHeader();
347 buildChildren(node, memberDetailsTree);
348 classContentTree.addContent(writer.getMemberDetailsTree(memberDetailsTree));
349 }
351 /**
352 * Build the enum constants documentation.
353 *
354 * @param node the XML element that specifies which components to document
355 * @param memberDetailsTree the content tree to which the documentation will be added
356 */
357 public void buildEnumConstantsDetails(XMLNode node,
358 Content memberDetailsTree) throws Exception {
359 configuration.getBuilderFactory().
360 getEnumConstantsBuilder(writer).buildChildren(node, memberDetailsTree);
361 }
363 /**
364 * Build the field documentation.
365 *
366 * @param node the XML element that specifies which components to document
367 * @param memberDetailsTree the content tree to which the documentation will be added
368 */
369 public void buildFieldDetails(XMLNode node,
370 Content memberDetailsTree) throws Exception {
371 configuration.getBuilderFactory().
372 getFieldBuilder(writer).buildChildren(node, memberDetailsTree);
373 }
375 /**
376 * Build the constructor documentation.
377 *
378 * @param node the XML element that specifies which components to document
379 * @param memberDetailsTree the content tree to which the documentation will be added
380 */
381 public void buildConstructorDetails(XMLNode node,
382 Content memberDetailsTree) throws Exception {
383 configuration.getBuilderFactory().
384 getConstructorBuilder(writer).buildChildren(node, memberDetailsTree);
385 }
387 /**
388 * Build the method documentation.
389 *
390 * @param node the XML element that specifies which components to document
391 * @param memberDetailsTree the content tree to which the documentation will be added
392 */
393 public void buildMethodDetails(XMLNode node,
394 Content memberDetailsTree) throws Exception {
395 configuration.getBuilderFactory().
396 getMethodBuilder(writer).buildChildren(node, memberDetailsTree);
397 }
398 }