1/*
2 * Copyright (c) 1997, 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 */
25
26package com.sun.codemodel.internal;
27
28import java.util.HashMap;
29import java.util.Map;
30
31/**
32 * JavaDoc comment.
33 *
34 * <p>
35 * A javadoc comment consists of multiple parts. There's the main part (that comes the first in
36 * in the comment section), then the parameter parts (@param), the return part (@return),
37 * and the throws parts (@throws).
38 *
39 * TODO: it would be nice if we have JComment class and we can derive this class from there.
40 */
41public class JDocComment extends JCommentPart implements JGenerable {
42
43        private static final long serialVersionUID = 1L;
44
45        /** list of @param tags */
46    private final Map<String,JCommentPart> atParams = new HashMap<String,JCommentPart>();
47
48    /** list of xdoclets */
49    private final Map<String,Map<String,String>> atXdoclets = new HashMap<String,Map<String,String>>();
50
51    /** list of @throws tags */
52    private final Map<JClass,JCommentPart> atThrows = new HashMap<JClass,JCommentPart>();
53
54    /**
55     * The @return tag part.
56     */
57    private JCommentPart atReturn = null;
58
59    /** The @deprecated tag */
60    private JCommentPart atDeprecated = null;
61
62    private final JCodeModel owner;
63
64
65    public JDocComment(JCodeModel owner) {
66        this.owner = owner;
67    }
68
69    public JDocComment append(Object o) {
70        add(o);
71        return this;
72    }
73
74    /**
75     * Append a text to a @param tag to the javadoc
76     */
77    public JCommentPart addParam( String param ) {
78        JCommentPart p = atParams.get(param);
79        if(p==null)
80            atParams.put(param,p=new JCommentPart());
81        return p;
82    }
83
84    /**
85     * Append a text to an @param tag.
86     */
87    public JCommentPart addParam( JVar param ) {
88        return addParam( param.name() );
89    }
90
91
92    /**
93     * add an @throws tag to the javadoc
94     */
95    public JCommentPart addThrows( Class<? extends Throwable> exception ) {
96        return addThrows( owner.ref(exception) );
97    }
98
99    /**
100     * add an @throws tag to the javadoc
101     */
102    public JCommentPart addThrows( JClass exception ) {
103        JCommentPart p = atThrows.get(exception);
104        if(p==null)
105            atThrows.put(exception,p=new JCommentPart());
106        return p;
107    }
108
109    /**
110     * Appends a text to @return tag.
111     */
112    public JCommentPart addReturn() {
113        if(atReturn==null)
114            atReturn = new JCommentPart();
115        return atReturn;
116    }
117
118    /**
119     * add an @deprecated tag to the javadoc, with the associated message.
120     */
121    public JCommentPart addDeprecated() {
122        if(atDeprecated==null)
123            atDeprecated = new JCommentPart();
124        return atDeprecated;
125    }
126
127    /**
128     * add an xdoclet.
129     */
130    public Map<String,String> addXdoclet(String name) {
131        Map<String,String> p = atXdoclets.get(name);
132        if(p==null)
133            atXdoclets.put(name,p=new HashMap<String,String>());
134        return p;
135    }
136
137    /**
138     * add an xdoclet.
139     */
140    public Map<String,String> addXdoclet(String name, Map<String,String> attributes) {
141        Map<String,String> p = atXdoclets.get(name);
142        if(p==null)
143            atXdoclets.put(name,p=new HashMap<String,String>());
144        p.putAll(attributes);
145        return p;
146    }
147
148    /**
149     * add an xdoclet.
150     */
151    public Map<String,String> addXdoclet(String name, String attribute, String value) {
152        Map<String,String> p = atXdoclets.get(name);
153        if(p==null)
154            atXdoclets.put(name,p=new HashMap<String,String>());
155        p.put(attribute, value);
156        return p;
157    }
158
159    public void generate(JFormatter f) {
160        // I realized that we can't use StringTokenizer because
161        // this will recognize multiple \n as one token.
162
163        f.p("/**").nl();
164
165        format(f," * ");
166
167        f.p(" * ").nl();
168        for (Map.Entry<String,JCommentPart> e : atParams.entrySet()) {
169            f.p(" * @param ").p(e.getKey()).nl();
170            e.getValue().format(f,INDENT);
171        }
172        if( atReturn != null ) {
173            f.p(" * @return").nl();
174            atReturn.format(f,INDENT);
175        }
176        for (Map.Entry<JClass,JCommentPart> e : atThrows.entrySet()) {
177            f.p(" * @throws ").t(e.getKey()).nl();
178            e.getValue().format(f,INDENT);
179        }
180        if( atDeprecated != null ) {
181            f.p(" * @deprecated").nl();
182            atDeprecated.format(f,INDENT);
183        }
184        for (Map.Entry<String,Map<String,String>> e : atXdoclets.entrySet()) {
185            f.p(" * @").p(e.getKey());
186            if (e.getValue() != null) {
187                for (Map.Entry<String,String> a : e.getValue().entrySet()) {
188                    f.p(" ").p(a.getKey()).p("= \"").p(a.getValue()).p("\"");
189                }
190            }
191            f.nl();
192        }
193        f.p(" */").nl();
194    }
195
196    private static final String INDENT = " *     ";
197}
198