1/*
2 * Copyright (c) 2003, 2015, 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
26package com.sun.tools.doclets.internal.toolkit.builders;
27
28import java.io.*;
29
30import com.sun.javadoc.*;
31import com.sun.tools.doclets.internal.toolkit.*;
32
33/**
34 * Builds the summary for a given class.
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 * @author Bhavesh Patel (Modified)
43 * @since 1.5
44 */
45@Deprecated
46public class ClassBuilder extends AbstractBuilder {
47
48    /**
49     * The root element of the class XML is {@value}.
50     */
51    public static final String ROOT = "ClassDoc";
52
53    /**
54     * The class being documented.
55     */
56    private final ClassDoc classDoc;
57
58    /**
59     * The doclet specific writer.
60     */
61    private final ClassWriter writer;
62
63    /**
64     * Keep track of whether or not this classdoc is an interface.
65     */
66    private final boolean isInterface;
67
68    /**
69     * Keep track of whether or not this classdoc is an enum.
70     */
71    private final boolean isEnum;
72
73    /**
74     * The content tree for the class documentation.
75     */
76    private Content contentTree;
77
78    /**
79     * Construct a new ClassBuilder.
80     *
81     * @param context  the build context
82     * @param classDoc the class being documented.
83     * @param writer the doclet specific writer.
84     */
85    private ClassBuilder(Context context,
86            ClassDoc classDoc, ClassWriter writer) {
87        super(context);
88        this.classDoc = classDoc;
89        this.writer = writer;
90        if (classDoc.isInterface()) {
91            isInterface = true;
92            isEnum = false;
93        } else if (classDoc.isEnum()) {
94            isInterface = false;
95            isEnum = true;
96            utils.setEnumDocumentation(configuration, classDoc);
97        } else {
98            isInterface = false;
99            isEnum = false;
100        }
101    }
102
103    /**
104     * Construct a new ClassBuilder.
105     *
106     * @param context  the build context
107     * @param classDoc the class being documented.
108     * @param writer the doclet specific writer.
109     */
110    public static ClassBuilder getInstance(Context context,
111            ClassDoc classDoc, ClassWriter writer) {
112        return new ClassBuilder(context, classDoc, writer);
113    }
114
115    /**
116     * {@inheritDoc}
117     */
118    public void build() throws IOException {
119        build(layoutParser.parseXML(ROOT), contentTree);
120    }
121
122    /**
123     * {@inheritDoc}
124     */
125    public String getName() {
126        return ROOT;
127    }
128
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         writer.addClassContentTree(contentTree, classContentTree);
149         writer.addFooter(contentTree);
150         writer.printDocument(contentTree);
151         writer.close();
152         copyDocFiles();
153     }
154
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    }
164
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    }
176
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    }
186
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    }
196
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    }
206
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    }
216
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    }
226
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    }
236
237    /**
238     * If this is an functional interface, display appropriate message.
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 buildFunctionalInterfaceInfo(XMLNode node, Content classInfoTree) {
244        writer.addFunctionalInterfaceInfo(classInfoTree);
245    }
246
247    /**
248     * If this class is deprecated, build the appropriate information.
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 buildDeprecationInfo (XMLNode node, Content classInfoTree) {
254        writer.addClassDeprecationInfo(classInfoTree);
255    }
256
257    /**
258     * If this is an inner class or interface, list the enclosing class or interface.
259     *
260     * @param node the XML element that specifies which components to document
261     * @param classInfoTree the content tree to which the documentation will be added
262     */
263    public void buildNestedClassInfo (XMLNode node, Content classInfoTree) {
264        writer.addNestedClassInfo(classInfoTree);
265    }
266
267    /**
268     * Copy the doc files for the current ClassDoc if necessary.
269     */
270     private void copyDocFiles() {
271        PackageDoc containingPackage = classDoc.containingPackage();
272        if((configuration.packages == null ||
273            !configuration.packages.contains(containingPackage)) &&
274            ! containingPackagesSeen.contains(containingPackage)){
275            //Only copy doc files dir if the containing package is not
276            //documented AND if we have not documented a class from the same
277            //package already. Otherwise, we are making duplicate copies.
278            utils.copyDocFiles(configuration, containingPackage);
279            containingPackagesSeen.add(containingPackage);
280        }
281     }
282
283    /**
284     * Build the signature of the current class.
285     *
286     * @param node the XML element that specifies which components to document
287     * @param classInfoTree the content tree to which the documentation will be added
288     */
289    public void buildClassSignature(XMLNode node, Content classInfoTree) {
290        StringBuilder modifiers = new StringBuilder(classDoc.modifiers());
291        modifiers.append(modifiers.length() == 0 ? "" : " ");
292        if (isEnum) {
293            modifiers.append("enum ");
294            int index;
295            if ((index = modifiers.indexOf("abstract")) >= 0) {
296                modifiers.delete(index, index + "abstract".length());
297                modifiers = new StringBuilder(
298                        utils.replaceText(modifiers.toString(), "  ", " "));
299            }
300            if ((index = modifiers.indexOf("final")) >= 0) {
301                modifiers.delete(index, index + "final".length());
302                modifiers = new StringBuilder(
303                        utils.replaceText(modifiers.toString(), "  ", " "));
304            }
305        //} else if (classDoc.isAnnotationType()) {
306            //modifiers.append("@interface ");
307        } else if (! isInterface) {
308            modifiers.append("class ");
309        }
310        writer.addClassSignature(modifiers.toString(), classInfoTree);
311    }
312
313    /**
314     * Build the class description.
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 buildClassDescription(XMLNode node, Content classInfoTree) {
320       writer.addClassDescription(classInfoTree);
321    }
322
323    /**
324     * Build the tag information for the current class.
325     *
326     * @param node the XML element that specifies which components to document
327     * @param classInfoTree the content tree to which the documentation will be added
328     */
329    public void buildClassTagInfo(XMLNode node, Content classInfoTree) {
330       writer.addClassTagInfo(classInfoTree);
331    }
332
333    /**
334     * Build the member summary contents of the page.
335     *
336     * @param node the XML element that specifies which components to document
337     * @param classContentTree the content tree to which the documentation will be added
338     */
339    public void buildMemberSummary(XMLNode node, Content classContentTree) throws Exception {
340        Content memberSummaryTree = writer.getMemberTreeHeader();
341        configuration.getBuilderFactory().
342                getMemberSummaryBuilder(writer).buildChildren(node, memberSummaryTree);
343        classContentTree.addContent(writer.getMemberSummaryTree(memberSummaryTree));
344    }
345
346    /**
347     * Build the member details contents of the page.
348     *
349     * @param node the XML element that specifies which components to document
350     * @param classContentTree the content tree to which the documentation will be added
351     */
352    public void buildMemberDetails(XMLNode node, Content classContentTree) {
353        Content memberDetailsTree = writer.getMemberTreeHeader();
354        buildChildren(node, memberDetailsTree);
355        classContentTree.addContent(writer.getMemberDetailsTree(memberDetailsTree));
356    }
357
358    /**
359     * Build the enum constants documentation.
360     *
361     * @param node the XML element that specifies which components to document
362     * @param memberDetailsTree the content tree to which the documentation will be added
363     */
364    public void buildEnumConstantsDetails(XMLNode node,
365            Content memberDetailsTree) throws Exception {
366        configuration.getBuilderFactory().
367                getEnumConstantsBuilder(writer).buildChildren(node, memberDetailsTree);
368    }
369
370    /**
371     * Build the field documentation.
372     *
373     * @param node the XML element that specifies which components to document
374     * @param memberDetailsTree the content tree to which the documentation will be added
375     */
376    public void buildFieldDetails(XMLNode node,
377            Content memberDetailsTree) throws Exception {
378        configuration.getBuilderFactory().
379                getFieldBuilder(writer).buildChildren(node, memberDetailsTree);
380    }
381
382    /**
383     * Build the property documentation.
384     *
385     * @param elements the XML elements that specify how a field is documented.
386     */
387    public void buildPropertyDetails(XMLNode node,
388            Content memberDetailsTree) throws Exception {
389        configuration.getBuilderFactory().
390                getPropertyBuilder(writer).buildChildren(node, memberDetailsTree);
391    }
392
393    /**
394     * Build the constructor documentation.
395     *
396     * @param node the XML element that specifies which components to document
397     * @param memberDetailsTree the content tree to which the documentation will be added
398     */
399    public void buildConstructorDetails(XMLNode node,
400            Content memberDetailsTree) throws Exception {
401        configuration.getBuilderFactory().
402                getConstructorBuilder(writer).buildChildren(node, memberDetailsTree);
403    }
404
405    /**
406     * Build the method documentation.
407     *
408     * @param node the XML element that specifies which components to document
409     * @param memberDetailsTree the content tree to which the documentation will be added
410     */
411    public void buildMethodDetails(XMLNode node,
412            Content memberDetailsTree) throws Exception {
413        configuration.getBuilderFactory().
414                getMethodBuilder(writer).buildChildren(node, memberDetailsTree);
415    }
416}
417