001    /*
002     * Copyright 1997-2004 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.formats.html;
027    
028    import com.sun.tools.doclets.internal.toolkit.*;
029    import com.sun.tools.doclets.internal.toolkit.taglets.*;
030    import com.sun.tools.doclets.internal.toolkit.util.*;
031    import com.sun.javadoc.*;
032    
033    import java.io.*;
034    
035    /**
036     * Writes field documentation in HTML format.
037     *
038     * @author Robert Field
039     * @author Atul M Dambalkar
040     * @author Jamie Ho (rewrite)
041     */
042    public class FieldWriterImpl extends AbstractMemberWriter
043        implements FieldWriter, MemberSummaryWriter {
044    
045        private boolean printedSummaryHeader = false;
046    
047        public FieldWriterImpl(SubWriterHolderWriter writer, ClassDoc classdoc) {
048            super(writer, classdoc);
049        }
050    
051        public FieldWriterImpl(SubWriterHolderWriter writer) {
052            super(writer);
053        }
054    
055        /**
056         * Write the fields summary header for the given class.
057         *
058         * @param classDoc the class the summary belongs to.
059         */
060        public void writeMemberSummaryHeader(ClassDoc classDoc) {
061            printedSummaryHeader = true;
062            writer.println("<!-- =========== FIELD SUMMARY =========== -->");
063            writer.println();
064            writer.printSummaryHeader(this, classDoc);
065        }
066    
067        /**
068         * Write the fields summary footer for the given class.
069         *
070         * @param classDoc the class the summary belongs to.
071         */
072        public void writeMemberSummaryFooter(ClassDoc classDoc) {
073            writer.tableEnd();
074            writer.space();
075        }
076    
077        /**
078         * Write the inherited fields summary header for the given class.
079         *
080         * @param classDoc the class the summary belongs to.
081         */
082        public void writeInheritedMemberSummaryHeader(ClassDoc classDoc) {
083            if(! printedSummaryHeader){
084                //We don't want inherited summary to not be under heading.
085                writeMemberSummaryHeader(classDoc);
086                writeMemberSummaryFooter(classDoc);
087                printedSummaryHeader = true;
088            }
089            writer.printInheritedSummaryHeader(this, classDoc);
090        }
091    
092        /**
093         * {@inheritDoc}
094         */
095        public void writeInheritedMemberSummary(ClassDoc classDoc,
096            ProgramElementDoc field, boolean isFirst, boolean isLast) {
097            writer.printInheritedSummaryMember(this, classDoc, field, isFirst);
098        }
099    
100        /**
101         * Write the inherited fields summary footer for the given class.
102         *
103         * @param classDoc the class the summary belongs to.
104         */
105        public void writeInheritedMemberSummaryFooter(ClassDoc classDoc) {
106            writer.printInheritedSummaryFooter(this, classDoc);
107        }
108    
109        /**
110         * Write the header for the field documentation.
111         *
112         * @param classDoc the class that the fields belong to.
113         */
114        public void writeHeader(ClassDoc classDoc, String header) {
115            writer.println();
116            writer.println("<!-- ============ FIELD DETAIL =========== -->");
117            writer.println();
118            writer.anchor("field_detail");
119            writer.printTableHeadingBackground(header);
120            writer.println();
121        }
122    
123        /**
124         * Write the field header for the given field.
125         *
126         * @param field the field being documented.
127         * @param isFirst the flag to indicate whether or not the field is the
128         *        first to be documented.
129         */
130        public void writeFieldHeader(FieldDoc field, boolean isFirst) {
131            if (! isFirst) {
132                writer.printMemberHeader();
133                writer.println("");
134            }
135            writer.anchor(field.name());
136            writer.h3();
137            writer.print(field.name());
138            writer.h3End();
139        }
140    
141        /**
142         * Write the signature for the given field.
143         *
144         * @param field the field being documented.
145         */
146        public void writeSignature(FieldDoc field) {
147            writer.pre();
148            writer.writeAnnotationInfo(field);
149            printModifiers(field);
150            writer.printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_MEMBER,
151                field.type()));
152            print(' ');
153            if (configuration().linksource) {
154                writer.printSrcLink(field, field.name());
155            } else {
156                strong(field.name());
157            }
158            writer.preEnd();
159            writer.dl();
160        }
161    
162        /**
163         * Write the deprecated output for the given field.
164         *
165         * @param field the field being documented.
166         */
167        public void writeDeprecated(FieldDoc field) {
168            print(((TagletOutputImpl)
169                (new DeprecatedTaglet()).getTagletOutput(field,
170                writer.getTagletWriterInstance(false))).toString());
171        }
172    
173        /**
174         * Write the comments for the given field.
175         *
176         * @param field the field being documented.
177         */
178        public void writeComments(FieldDoc field) {
179            ClassDoc holder = field.containingClass();
180            if (field.inlineTags().length > 0) {
181                if (holder.equals(classdoc) ||
182                    (! (holder.isPublic() || Util.isLinkable(holder, configuration())))) {
183                    writer.dd();
184                    writer.printInlineComment(field);
185                } else {
186                    String classlink = writer.codeText(
187                        writer.getDocLink(LinkInfoImpl.CONTEXT_FIELD_DOC_COPY,
188                            holder, field,
189                            holder.isIncluded() ?
190                                holder.typeName() : holder.qualifiedTypeName(),
191                            false));
192                    writer.dd();
193                    writer.strong(configuration().getText(holder.isClass()?
194                       "doclet.Description_From_Class" :
195                        "doclet.Description_From_Interface", classlink));
196                    writer.ddEnd();
197                    writer.dd();
198                    writer.printInlineComment(field);
199                }
200            }
201        }
202    
203        /**
204         * Write the tag output for the given field.
205         *
206         * @param field the field being documented.
207         */
208        public void writeTags(FieldDoc field) {
209            writer.printTags(field);
210        }
211    
212        /**
213         * Write the field footer.
214         */
215        public void writeFieldFooter() {
216            writer.dlEnd();
217        }
218    
219        /**
220         * Write the footer for the field documentation.
221         *
222         * @param classDoc the class that the fields belong to.
223         */
224        public void writeFooter(ClassDoc classDoc) {
225            //No footer to write for field documentation
226        }
227    
228        /**
229         * Close the writer.
230         */
231        public void close() throws IOException {
232            writer.close();
233        }
234    
235        public int getMemberKind() {
236            return VisibleMemberMap.FIELDS;
237        }
238    
239        public void printSummaryLabel(ClassDoc cd) {
240            writer.strongText("doclet.Field_Summary");
241        }
242    
243        public void printSummaryAnchor(ClassDoc cd) {
244            writer.anchor("field_summary");
245        }
246    
247        public void printInheritedSummaryAnchor(ClassDoc cd) {
248            writer.anchor("fields_inherited_from_class_" + configuration().getClassName(cd));
249        }
250    
251        public void printInheritedSummaryLabel(ClassDoc cd) {
252            String classlink = writer.getPreQualifiedClassLink(
253                LinkInfoImpl.CONTEXT_MEMBER, cd, false);
254            writer.strong();
255            String key = cd.isClass()?
256                "doclet.Fields_Inherited_From_Class" :
257                "doclet.Fields_Inherited_From_Interface";
258            writer.printText(key, classlink);
259            writer.strongEnd();
260        }
261    
262        protected void writeSummaryLink(int context, ClassDoc cd, ProgramElementDoc member) {
263            writer.strong();
264            writer.printDocLink(context, cd , (MemberDoc) member, member.name(), false);
265            writer.strongEnd();
266        }
267    
268        protected void writeInheritedSummaryLink(ClassDoc cd,
269                ProgramElementDoc member) {
270            writer.printDocLink(LinkInfoImpl.CONTEXT_MEMBER, cd, (MemberDoc)member,
271                member.name(), false);
272        }
273    
274        protected void printSummaryType(ProgramElementDoc member) {
275            FieldDoc field = (FieldDoc)member;
276            printModifierAndType(field, field.type());
277        }
278    
279        protected void writeDeprecatedLink(ProgramElementDoc member) {
280            writer.printDocLink(LinkInfoImpl.CONTEXT_MEMBER,
281                (MemberDoc) member, ((FieldDoc)member).qualifiedName(), false);
282        }
283    
284        protected void printNavSummaryLink(ClassDoc cd, boolean link) {
285            if (link) {
286                writer.printHyperLink("", (cd == null)?
287                            "field_summary":
288                            "fields_inherited_from_class_" +
289                            configuration().getClassName(cd),
290                        configuration().getText("doclet.navField"));
291            } else {
292                writer.printText("doclet.navField");
293            }
294        }
295    
296        protected void printNavDetailLink(boolean link) {
297            if (link) {
298                writer.printHyperLink("", "field_detail",
299                    configuration().getText("doclet.navField"));
300            } else {
301                writer.printText("doclet.navField");
302            }
303        }
304    }