001    /*
002     * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
003     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004     *
005     * This code is free software; you can redistribute it and/or modify it
006     * under the terms of the GNU General Public License version 2 only, as
007     * published by the Free Software Foundation.  Sun designates this
008     * particular file as subject to the "Classpath" exception as provided
009     * by Sun in the LICENSE file that accompanied this code.
010     *
011     * This code is distributed in the hope that it will be useful, but WITHOUT
012     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014     * version 2 for more details (a copy is included in the LICENSE file that
015     * accompanied this code).
016     *
017     * You should have received a copy of the GNU General Public License version
018     * 2 along with this work; if not, write to the Free Software Foundation,
019     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020     *
021     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022     * CA 95054 USA or visit www.sun.com if you need additional information or
023     * have any questions.
024     */
025    
026    package com.sun.tools.doclets.internal.toolkit.builders;
027    
028    import com.sun.tools.doclets.internal.toolkit.util.*;
029    import com.sun.tools.doclets.internal.toolkit.*;
030    import com.sun.javadoc.*;
031    import java.util.*;
032    import java.lang.reflect.*;
033    
034    /**
035     * Builds documentation for a field.
036     *
037     * This code is not part of an API.
038     * It is implementation that is subject to change.
039     * Do not use it as an API
040     *
041     * @author Jamie Ho
042     * @since 1.5
043     */
044    public class FieldBuilder extends AbstractMemberBuilder {
045    
046            /**
047             * The class whose fields are being documented.
048             */
049            private ClassDoc classDoc;
050    
051            /**
052             * The visible fields for the given class.
053             */
054            private VisibleMemberMap visibleMemberMap;
055    
056            /**
057             * The writer to output the field documentation.
058             */
059            private FieldWriter writer;
060    
061            /**
062             * The list of fields being documented.
063             */
064            private List<ProgramElementDoc> fields;
065    
066            /**
067             * The index of the current field that is being documented at this point
068             * in time.
069             */
070            private int currentFieldIndex;
071    
072            /**
073             * Construct a new FieldBuilder.
074             *
075             * @param configuration the current configuration of the
076             *                      doclet.
077             */
078            private FieldBuilder(Configuration configuration) {
079                    super(configuration);
080            }
081    
082            /**
083             * Construct a new FieldBuilder.
084             *
085             * @param configuration the current configuration of the doclet.
086             * @param classDoc the class whoses members are being documented.
087             * @param writer the doclet specific writer.
088             */
089            public static FieldBuilder getInstance(
090                    Configuration configuration,
091                    ClassDoc classDoc,
092                    FieldWriter writer) {
093                    FieldBuilder builder = new FieldBuilder(configuration);
094                    builder.classDoc = classDoc;
095                    builder.writer = writer;
096                    builder.visibleMemberMap =
097                            new VisibleMemberMap(
098                                    classDoc,
099                                    VisibleMemberMap.FIELDS,
100                                    configuration.nodeprecated);
101                    builder.fields =
102                            new ArrayList<ProgramElementDoc>(builder.visibleMemberMap.getLeafClassMembers(
103                                configuration));
104                    if (configuration.getMemberComparator() != null) {
105                            Collections.sort(
106                                    builder.fields,
107                                    configuration.getMemberComparator());
108                    }
109                    return builder;
110            }
111    
112            /**
113             * {@inheritDoc}
114             */
115            public String getName() {
116                    return "FieldDetails";
117            }
118    
119            /**
120             * {@inheritDoc}
121             */
122            public void invokeMethod(
123                    String methodName,
124                    Class<?>[] paramClasses,
125                    Object[] params)
126                    throws Exception {
127                    if (DEBUG) {
128                            configuration.root.printError(
129                                    "DEBUG: " + this.getClass().getName() + "." + methodName);
130                    }
131                    Method method = this.getClass().getMethod(methodName, paramClasses);
132                    method.invoke(this, params);
133            }
134    
135            /**
136             * Returns a list of fields that will be documented for the given class.
137             * This information can be used for doclet specific documentation
138             * generation.
139             *
140             * @param classDoc the {@link ClassDoc} we want to check.
141             * @return a list of fields that will be documented.
142             */
143            public List<ProgramElementDoc> members(ClassDoc classDoc) {
144                    return visibleMemberMap.getMembersFor(classDoc);
145            }
146    
147            /**
148             * Returns the visible member map for the fields of this class.
149             *
150             * @return the visible member map for the fields of this class.
151             */
152            public VisibleMemberMap getVisibleMemberMap() {
153                    return visibleMemberMap;
154            }
155    
156            /**
157             * summaryOrder.size()
158             */
159            public boolean hasMembersToDocument() {
160                    return fields.size() > 0;
161            }
162    
163            /**
164             * Build the field documentation.
165             *
166             * @param elements the XML elements that specify how to construct this
167             *                documentation.
168             */
169            public void buildFieldDoc(List<?> elements) {
170                    if (writer == null) {
171                            return;
172                    }
173                    for (currentFieldIndex = 0;
174                            currentFieldIndex < fields.size();
175                            currentFieldIndex++) {
176                            build(elements);
177                    }
178            }
179    
180            /**
181             * Build the overall header.
182             */
183            public void buildHeader() {
184                    writer.writeHeader(
185                            classDoc,
186                            configuration.getText("doclet.Field_Detail"));
187            }
188    
189            /**
190             * Build the header for the individual field.
191             */
192            public void buildFieldHeader() {
193                    writer.writeFieldHeader(
194                            (FieldDoc) fields.get(currentFieldIndex),
195                            currentFieldIndex == 0);
196            }
197    
198            /**
199             * Build the signature.
200             */
201            public void buildSignature() {
202                    writer.writeSignature((FieldDoc) fields.get(currentFieldIndex));
203            }
204    
205            /**
206             * Build the deprecation information.
207             */
208            public void buildDeprecationInfo() {
209                    writer.writeDeprecated((FieldDoc) fields.get(currentFieldIndex));
210            }
211    
212            /**
213             * Build the comments for the field.  Do nothing if
214             * {@link Configuration#nocomment} is set to true.
215             */
216            public void buildFieldComments() {
217                    if (!configuration.nocomment) {
218                            writer.writeComments((FieldDoc) fields.get(currentFieldIndex));
219                    }
220            }
221    
222            /**
223             * Build the tag information.
224             */
225            public void buildTagInfo() {
226                    writer.writeTags((FieldDoc) fields.get(currentFieldIndex));
227            }
228    
229            /**
230             * Build the footer for the individual field.
231             */
232            public void buildFieldFooter() {
233                    writer.writeFieldFooter();
234            }
235    
236            /**
237             * Build the overall footer.
238             */
239            public void buildFooter() {
240                    writer.writeFooter(classDoc);
241            }
242    
243            /**
244             * Return the field writer for this builder.
245             *
246             * @return the field writer for this builder.
247             */
248            public FieldWriter getWriter() {
249                    return writer;
250            }
251    }