Wed, 01 Dec 2010 11:02:38 -0800
6851834: Javadoc doclet needs a structured approach to generate the output HTML.
Reviewed-by: jjg
1 /*
2 * Copyright (c) 2003, 2008, 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.*;
30 import com.sun.tools.doclets.internal.toolkit.util.*;
31 import com.sun.tools.doclets.internal.toolkit.*;
32 import com.sun.javadoc.*;
34 /**
35 * Builds the summary for a given class.
36 *
37 * This code is not part of an API.
38 * It is implementation that is subject to change.
39 * Do not use it as an API
40 *
41 * @author Jamie Ho
42 * @author Bhavesh Patel (Modified)
43 * @since 1.5
44 */
45 public class ClassBuilder extends AbstractBuilder {
47 /**
48 * The root element of the class XML is {@value}.
49 */
50 public static final String ROOT = "ClassDoc";
52 /**
53 * The class being documented.
54 */
55 private ClassDoc classDoc;
57 /**
58 * The doclet specific writer.
59 */
60 private ClassWriter writer;
62 /**
63 * Keep track of whether or not this classdoc is an interface.
64 */
65 private boolean isInterface = false;
67 /**
68 * Keep track of whether or not this classdoc is an enum.
69 */
70 private boolean isEnum = false;
72 /**
73 * The content tree for the class documentation.
74 */
75 private Content contentTree;
77 /**
78 * Construct a new ClassBuilder.
79 *
80 * @param configuration the current configuration of the
81 * doclet.
82 */
83 private ClassBuilder(Configuration configuration) {
84 super(configuration);
85 }
87 /**
88 * Construct a new ClassBuilder.
89 *
90 * @param configuration the current configuration of the doclet.
91 * @param classDoc the class being documented.
92 * @param writer the doclet specific writer.
93 */
94 public static ClassBuilder getInstance(Configuration configuration,
95 ClassDoc classDoc, ClassWriter writer)
96 throws Exception {
97 ClassBuilder builder = new ClassBuilder(configuration);
98 builder.configuration = configuration;
99 builder.classDoc = classDoc;
100 builder.writer = writer;
101 if (classDoc.isInterface()) {
102 builder.isInterface = true;
103 } else if (classDoc.isEnum()) {
104 builder.isEnum = true;
105 Util.setEnumDocumentation(configuration, classDoc);
106 }
107 if(containingPackagesSeen == null) {
108 containingPackagesSeen = new HashSet<String>();
109 }
110 return builder;
111 }
113 /**
114 * {@inheritDoc}
115 */
116 public void build() throws IOException {
117 build(LayoutParser.getInstance(configuration).parseXML(ROOT), contentTree);
118 }
120 /**
121 * {@inheritDoc}
122 */
123 public String getName() {
124 return ROOT;
125 }
127 /**
128 * Handles the <ClassDoc> tag.
129 *
130 * @param node the XML element that specifies which components to document
131 * @param contentTree the content tree to which the documentation will be added
132 */
133 public void buildClassDoc(XMLNode node, Content contentTree) throws Exception {
134 String key;
135 if (isInterface) {
136 key = "doclet.Interface";
137 } else if (isEnum) {
138 key = "doclet.Enum";
139 } else {
140 key = "doclet.Class";
141 }
142 contentTree = writer.getHeader(configuration.getText(key) + " " +
143 classDoc.name());
144 Content classContentTree = writer.getClassContentHeader();
145 buildChildren(node, classContentTree);
146 contentTree.addContent(classContentTree);
147 writer.addFooter(contentTree);
148 writer.printDocument(contentTree);
149 writer.close();
150 copyDocFiles();
151 }
153 /**
154 * Build the class tree documentation.
155 *
156 * @param node the XML element that specifies which components to document
157 * @param classContentTree the content tree to which the documentation will be added
158 */
159 public void buildClassTree(XMLNode node, Content classContentTree) {
160 writer.addClassTree(classContentTree);
161 }
163 /**
164 * Build the class information tree documentation.
165 *
166 * @param node the XML element that specifies which components to document
167 * @param classContentTree the content tree to which the documentation will be added
168 */
169 public void buildClassInfo(XMLNode node, Content classContentTree) {
170 Content classInfoTree = writer.getClassInfoTreeHeader();
171 buildChildren(node, classInfoTree);
172 classContentTree.addContent(writer.getClassInfo(classInfoTree));
173 }
175 /**
176 * Build the typeparameters of this class.
177 *
178 * @param node the XML element that specifies which components to document
179 * @param classInfoTree the content tree to which the documentation will be added
180 */
181 public void buildTypeParamInfo(XMLNode node, Content classInfoTree) {
182 writer.addTypeParamInfo(classInfoTree);
183 }
185 /**
186 * If this is an interface, list all super interfaces.
187 *
188 * @param node the XML element that specifies which components to document
189 * @param classInfoTree the content tree to which the documentation will be added
190 */
191 public void buildSuperInterfacesInfo(XMLNode node, Content classInfoTree) {
192 writer.addSuperInterfacesInfo(classInfoTree);
193 }
195 /**
196 * If this is a class, list all interfaces implemented by this class.
197 *
198 * @param node the XML element that specifies which components to document
199 * @param classInfoTree the content tree to which the documentation will be added
200 */
201 public void buildImplementedInterfacesInfo(XMLNode node, Content classInfoTree) {
202 writer.addImplementedInterfacesInfo(classInfoTree);
203 }
205 /**
206 * List all the classes extend this one.
207 *
208 * @param node the XML element that specifies which components to document
209 * @param classInfoTree the content tree to which the documentation will be added
210 */
211 public void buildSubClassInfo(XMLNode node, Content classInfoTree) {
212 writer.addSubClassInfo(classInfoTree);
213 }
215 /**
216 * List all the interfaces that extend this one.
217 *
218 * @param node the XML element that specifies which components to document
219 * @param classInfoTree the content tree to which the documentation will be added
220 */
221 public void buildSubInterfacesInfo(XMLNode node, Content classInfoTree) {
222 writer.addSubInterfacesInfo(classInfoTree);
223 }
225 /**
226 * If this is an interface, list all classes that implement this interface.
227 *
228 * @param node the XML element that specifies which components to document
229 * @param classInfoTree the content tree to which the documentation will be added
230 */
231 public void buildInterfaceUsageInfo(XMLNode node, Content classInfoTree) {
232 writer.addInterfaceUsageInfo(classInfoTree);
233 }
235 /**
236 * If this class is deprecated, build the appropriate information.
237 *
238 * @param node the XML element that specifies which components to document
239 * @param classInfoTree the content tree to which the documentation will be added
240 */
241 public void buildDeprecationInfo (XMLNode node, Content classInfoTree) {
242 writer.addClassDeprecationInfo(classInfoTree);
243 }
245 /**
246 * If this is an inner class or interface, list the enclosing class or interface.
247 *
248 * @param node the XML element that specifies which components to document
249 * @param classInfoTree the content tree to which the documentation will be added
250 */
251 public void buildNestedClassInfo (XMLNode node, Content classInfoTree) {
252 writer.addNestedClassInfo(classInfoTree);
253 }
255 /**
256 * Copy the doc files for the current ClassDoc if necessary.
257 */
258 private void copyDocFiles() {
259 PackageDoc containingPackage = classDoc.containingPackage();
260 if((configuration.packages == null ||
261 Arrays.binarySearch(configuration.packages,
262 containingPackage) < 0) &&
263 ! containingPackagesSeen.contains(containingPackage.name())){
264 //Only copy doc files dir if the containing package is not
265 //documented AND if we have not documented a class from the same
266 //package already. Otherwise, we are making duplicate copies.
267 Util.copyDocFiles(configuration,
268 Util.getPackageSourcePath(configuration,
269 classDoc.containingPackage()) +
270 DirectoryManager.getDirectoryPath(classDoc.containingPackage())
271 + File.separator, DocletConstants.DOC_FILES_DIR_NAME, true);
272 containingPackagesSeen.add(containingPackage.name());
273 }
274 }
276 /**
277 * Build the signature of the current class.
278 *
279 * @param node the XML element that specifies which components to document
280 * @param classInfoTree the content tree to which the documentation will be added
281 */
282 public void buildClassSignature(XMLNode node, Content classInfoTree) {
283 StringBuffer modifiers = new StringBuffer(classDoc.modifiers() + " ");
284 if (isEnum) {
285 modifiers.append("enum ");
286 int index;
287 if ((index = modifiers.indexOf("abstract")) >= 0) {
288 modifiers.delete(index, index + (new String("abstract")).length());
289 modifiers = new StringBuffer(
290 Util.replaceText(modifiers.toString(), " ", " "));
291 }
292 if ((index = modifiers.indexOf("final")) >= 0) {
293 modifiers.delete(index, index + (new String("final")).length());
294 modifiers = new StringBuffer(
295 Util.replaceText(modifiers.toString(), " ", " "));
296 }
297 //} else if (classDoc.isAnnotationType()) {
298 //modifiers.append("@interface ");
299 } else if (! isInterface) {
300 modifiers.append("class ");
301 }
302 writer.addClassSignature(modifiers.toString(), classInfoTree);
303 }
305 /**
306 * Build the class description.
307 *
308 * @param node the XML element that specifies which components to document
309 * @param classInfoTree the content tree to which the documentation will be added
310 */
311 public void buildClassDescription(XMLNode node, Content classInfoTree) {
312 writer.addClassDescription(classInfoTree);
313 }
315 /**
316 * Build the tag information for the current class.
317 *
318 * @param node the XML element that specifies which components to document
319 * @param classInfoTree the content tree to which the documentation will be added
320 */
321 public void buildClassTagInfo(XMLNode node, Content classInfoTree) {
322 writer.addClassTagInfo(classInfoTree);
323 }
325 /**
326 * Build the member summary contents of the page.
327 *
328 * @param node the XML element that specifies which components to document
329 * @param classContentTree the content tree to which the documentation will be added
330 */
331 public void buildMemberSummary(XMLNode node, Content classContentTree) throws Exception {
332 Content memberSummaryTree = writer.getMemberTreeHeader();
333 configuration.getBuilderFactory().
334 getMemberSummaryBuilder(writer).buildChildren(node, memberSummaryTree);
335 classContentTree.addContent(writer.getMemberSummaryTree(memberSummaryTree));
336 }
338 /**
339 * Build the member details contents of the page.
340 *
341 * @param node the XML element that specifies which components to document
342 * @param classContentTree the content tree to which the documentation will be added
343 */
344 public void buildMemberDetails(XMLNode node, Content classContentTree) {
345 Content memberDetailsTree = writer.getMemberTreeHeader();
346 buildChildren(node, memberDetailsTree);
347 classContentTree.addContent(writer.getMemberDetailsTree(memberDetailsTree));
348 }
350 /**
351 * Build the enum constants documentation.
352 *
353 * @param node the XML element that specifies which components to document
354 * @param memberDetailsTree the content tree to which the documentation will be added
355 */
356 public void buildEnumConstantsDetails(XMLNode node,
357 Content memberDetailsTree) throws Exception {
358 configuration.getBuilderFactory().
359 getEnumConstantsBuilder(writer).buildChildren(node, memberDetailsTree);
360 }
362 /**
363 * Build the field documentation.
364 *
365 * @param node the XML element that specifies which components to document
366 * @param memberDetailsTree the content tree to which the documentation will be added
367 */
368 public void buildFieldDetails(XMLNode node,
369 Content memberDetailsTree) throws Exception {
370 configuration.getBuilderFactory().
371 getFieldBuilder(writer).buildChildren(node, memberDetailsTree);
372 }
374 /**
375 * Build the constructor documentation.
376 *
377 * @param node the XML element that specifies which components to document
378 * @param memberDetailsTree the content tree to which the documentation will be added
379 */
380 public void buildConstructorDetails(XMLNode node,
381 Content memberDetailsTree) throws Exception {
382 configuration.getBuilderFactory().
383 getConstructorBuilder(writer).buildChildren(node, memberDetailsTree);
384 }
386 /**
387 * Build the method documentation.
388 *
389 * @param node the XML element that specifies which components to document
390 * @param memberDetailsTree the content tree to which the documentation will be added
391 */
392 public void buildMethodDetails(XMLNode node,
393 Content memberDetailsTree) throws Exception {
394 configuration.getBuilderFactory().
395 getMethodBuilder(writer).buildChildren(node, memberDetailsTree);
396 }
397 }