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 
  26 package com.sun.codemodel.internal;
  27 
  28 import java.util.HashMap;
  29 import 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  */
  41 public 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 }