Wed, 31 Oct 2012 13:48:15 -0700
8001664: refactor javadoc to use abstraction to handle files
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, containingPackage);
270 containingPackagesSeen.add(containingPackage.name());
271 }
272 }
274 /**
275 * Build the signature of the current class.
276 *
277 * @param node the XML element that specifies which components to document
278 * @param classInfoTree the content tree to which the documentation will be added
279 */
280 public void buildClassSignature(XMLNode node, Content classInfoTree) {
281 StringBuilder modifiers = new StringBuilder(classDoc.modifiers() + " ");
282 if (isEnum) {
283 modifiers.append("enum ");
284 int index;
285 if ((index = modifiers.indexOf("abstract")) >= 0) {
286 modifiers.delete(index, index + "abstract".length());
287 modifiers = new StringBuilder(
288 Util.replaceText(modifiers.toString(), " ", " "));
289 }
290 if ((index = modifiers.indexOf("final")) >= 0) {
291 modifiers.delete(index, index + "final".length());
292 modifiers = new StringBuilder(
293 Util.replaceText(modifiers.toString(), " ", " "));
294 }
295 //} else if (classDoc.isAnnotationType()) {
296 //modifiers.append("@interface ");
297 } else if (! isInterface) {
298 modifiers.append("class ");
299 }
300 writer.addClassSignature(modifiers.toString(), classInfoTree);
301 }
303 /**
304 * Build the class description.
305 *
306 * @param node the XML element that specifies which components to document
307 * @param classInfoTree the content tree to which the documentation will be added
308 */
309 public void buildClassDescription(XMLNode node, Content classInfoTree) {
310 writer.addClassDescription(classInfoTree);
311 }
313 /**
314 * Build the tag information for the current class.
315 *
316 * @param node the XML element that specifies which components to document
317 * @param classInfoTree the content tree to which the documentation will be added
318 */
319 public void buildClassTagInfo(XMLNode node, Content classInfoTree) {
320 writer.addClassTagInfo(classInfoTree);
321 }
323 /**
324 * Build the member summary contents of the page.
325 *
326 * @param node the XML element that specifies which components to document
327 * @param classContentTree the content tree to which the documentation will be added
328 */
329 public void buildMemberSummary(XMLNode node, Content classContentTree) throws Exception {
330 Content memberSummaryTree = writer.getMemberTreeHeader();
331 configuration.getBuilderFactory().
332 getMemberSummaryBuilder(writer).buildChildren(node, memberSummaryTree);
333 classContentTree.addContent(writer.getMemberSummaryTree(memberSummaryTree));
334 }
336 /**
337 * Build the member details contents of the page.
338 *
339 * @param node the XML element that specifies which components to document
340 * @param classContentTree the content tree to which the documentation will be added
341 */
342 public void buildMemberDetails(XMLNode node, Content classContentTree) {
343 Content memberDetailsTree = writer.getMemberTreeHeader();
344 buildChildren(node, memberDetailsTree);
345 classContentTree.addContent(writer.getMemberDetailsTree(memberDetailsTree));
346 }
348 /**
349 * Build the enum constants documentation.
350 *
351 * @param node the XML element that specifies which components to document
352 * @param memberDetailsTree the content tree to which the documentation will be added
353 */
354 public void buildEnumConstantsDetails(XMLNode node,
355 Content memberDetailsTree) throws Exception {
356 configuration.getBuilderFactory().
357 getEnumConstantsBuilder(writer).buildChildren(node, memberDetailsTree);
358 }
360 /**
361 * Build the field documentation.
362 *
363 * @param node the XML element that specifies which components to document
364 * @param memberDetailsTree the content tree to which the documentation will be added
365 */
366 public void buildFieldDetails(XMLNode node,
367 Content memberDetailsTree) throws Exception {
368 configuration.getBuilderFactory().
369 getFieldBuilder(writer).buildChildren(node, memberDetailsTree);
370 }
372 /**
373 * Build the constructor documentation.
374 *
375 * @param node the XML element that specifies which components to document
376 * @param memberDetailsTree the content tree to which the documentation will be added
377 */
378 public void buildConstructorDetails(XMLNode node,
379 Content memberDetailsTree) throws Exception {
380 configuration.getBuilderFactory().
381 getConstructorBuilder(writer).buildChildren(node, memberDetailsTree);
382 }
384 /**
385 * Build the method documentation.
386 *
387 * @param node the XML element that specifies which components to document
388 * @param memberDetailsTree the content tree to which the documentation will be added
389 */
390 public void buildMethodDetails(XMLNode node,
391 Content memberDetailsTree) throws Exception {
392 configuration.getBuilderFactory().
393 getMethodBuilder(writer).buildChildren(node, memberDetailsTree);
394 }
395 }