View Javadoc

1   /**
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Intalio, Inc.  For written permission,
18   *    please contact info@codehaus.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Intalio, Inc. Exolab is a registered
23   *    trademark of Intalio, Inc.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.codehaus.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
42   *
43   * $Id$
44   */
45  
46  
47  package org.codehaus.modello.plugin.java.javasource;
48  
49  /*
50   * Copyright (c) 2004, Codehaus.org
51   *
52   * Permission is hereby granted, free of charge, to any person obtaining a copy of
53   * this software and associated documentation files (the "Software"), to deal in
54   * the Software without restriction, including without limitation the rights to
55   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
56   * of the Software, and to permit persons to whom the Software is furnished to do
57   * so, subject to the following conditions:
58   *
59   * The above copyright notice and this permission notice shall be included in all
60   * copies or substantial portions of the Software.
61   *
62   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
66   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
68   * SOFTWARE.
69   */
70  
71  /**
72   * A class that represents a Java comment.
73   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
74   * @version $Revision$ $Date$
75   **/
76  public class JComment
77  {
78  
79  
80      /**
81       * The auto style, allows this JComment to automatically
82       * choose a style for this comment
83       **/
84      public static final short AUTO_STYLE = 0;
85  
86      /**
87       * The block comment style: \/* *\/
88       **/
89      public static final short BLOCK_STYLE = 1;
90  
91      /**
92       * The line comment style: \/\/
93       **/
94      public static final short LINE_STYLE = 2;
95  
96      /**
97       * The header style, similiar to block, but with an '*'
98       * at the start of each line.
99       **/
100     public static final short HEADER_STYLE = 3;
101 
102     /**
103      * Similiar to HEADER_STYLE, but starts with: \/**
104      **/
105     public static final short JAVADOC_STYLE = 4;
106 
107 
108     private static final String START_BLOCK = "/*";
109     private static final String END_BLOCK = " */";
110 
111     private static final String START_JAVADOC = "/**";
112     private static final String END_JAVADOC = " */";
113 
114     private static final String ASTERIX_PREFIX = " * ";
115     private static final String LINE_COMMENT_PREFIX = "// ";
116     private static final String SPACE_PREFIX = " ";
117 
118 
119     /**
120      * The style of this comment
121      **/
122     private short style = AUTO_STYLE;
123 
124     /**
125      * The main comment for this JDocComment
126      **/
127     private StringBuffer _comment = null;
128 
129     /**
130      * The maximum number of characters per line
131      **/
132     protected static final int MAX_LENGTH = 65;
133 
134 
135     /**
136      * Creates a new Java Comment
137      **/
138     public JComment()
139     {
140         super();
141         _comment = new StringBuffer();
142     } //-- JComment
143 
144     /**
145      * Creates a new Java comment with the given style
146      **/
147     public JComment( short style )
148     {
149         this();
150         this.style = style;
151     } //-- JComment
152 
153     /**
154      * Appends the comment String to this JDocComment
155      * @param comment the comment to append
156      **/
157     public void appendComment( String comment )
158     {
159         _comment.append( comment );
160     } //-- appendComment
161 
162 
163     /**
164      * prints this JComment using the given JSourceWriter
165      * @param jsw the JSourceWriter to print to
166      **/
167     public void print( JSourceWriter jsw )
168     {
169 
170 
171         if ( jsw == null ) return; //-- nothing to do
172 
173         LineFormatter formatter = null;
174 
175         //-- calculate comment length
176         short currentIndent = jsw.getIndentSize();
177         int maxLength = MAX_LENGTH - currentIndent;
178 
179         //-- a simple to check to make sure we have some room
180         //-- to print the comment
181         if ( maxLength <= 17 ) maxLength = MAX_LENGTH / 2;
182 
183         short resolvedStyle = style;
184 
185         if ( style == AUTO_STYLE )
186         {
187             //-- estimation of number of lines
188             int nbrLines = _comment.length() / maxLength;
189 
190             if ( nbrLines > 2 )
191                 resolvedStyle = BLOCK_STYLE;
192             else
193                 resolvedStyle = LINE_STYLE;
194         }
195 
196 
197 
198         //-- start comment
199         String prefix = null;
200         String start = null;
201         String end = null;
202 
203         switch ( resolvedStyle )
204         {
205             case BLOCK_STYLE:
206                 start = START_BLOCK;
207                 end = END_BLOCK;
208                 prefix = SPACE_PREFIX;
209                 break;
210             case HEADER_STYLE:
211                 start = START_BLOCK;
212                 end = END_BLOCK;
213                 prefix = ASTERIX_PREFIX;
214                 break;
215             case JAVADOC_STYLE:
216                 start = START_JAVADOC;
217                 end = END_JAVADOC;
218                 prefix = ASTERIX_PREFIX;
219                 break;
220             default: //-- LINE
221                 prefix = LINE_COMMENT_PREFIX;
222                 break;
223         }
224         if ( start != null ) jsw.writeln( start );
225         //-- print main comment
226         formatter = new LineFormatter( _comment.toString(), maxLength, prefix );
227         while ( formatter.hasMoreLines() )
228         {
229             jsw.writeln( formatter.nextLine() );
230         }
231         if ( end != null ) jsw.writeln( end );
232         jsw.flush();
233     } //-- print
234 
235     /**
236      * Sets the comment String of this JDocComment
237      * @param comment the comment String of this JDocComment
238      **/
239     public void setComment( String comment )
240     {
241         _comment.setLength( 0 );
242         _comment.append( comment );
243     } //-- setComment
244 
245     /**
246      * Sets the style for this JComment
247      * @param style the style to use for this JComment
248      **/
249     public void setStyle( short style )
250     {
251         this.style = style;
252     } //-- setStyle
253 
254     /**
255      * Returns the String representation of this Java Doc Comment
256      * @return the String representation of this Java Doc Comment
257      **/
258     public String toString()
259     {
260         return "";
261     } //-- toString
262 
263 } //-- JComment
264 
265 /**
266  * Formats a given String for use within a Java comment
267  * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
268  **/
269 class LineFormatter
270 {
271 
272     String comment = null;
273 
274     int maxLength = 65;
275     int offset = 0;
276     int length = 0;
277 
278     String prefix = null;
279 
280     private StringBuffer sb = null;
281 
282     /**
283      * Creates a LineFormatter for the given comment
284      * @param comment the String to format
285      **/
286     LineFormatter( String comment )
287     {
288         this.comment = comment;
289         if ( comment != null ) this.length = comment.length();
290         sb = new StringBuffer();
291     } //-- LineFormatter
292 
293 
294     /**
295      * Creates a new LineFormatter for the given comment
296      * @param comment the String to format
297      * @param maxLength the maximum number of characters per line
298      **/
299     LineFormatter( String comment, int maxLength )
300     {
301         this( comment, maxLength, null );
302     } //-- LineFormatter
303 
304 
305     /**
306      * Creates a new LineFormatter for the given comment
307      * @param comment the String to format
308      * @param maxLength the maximum number of characters per line
309      * @param prefix a prefix to append to the beginning of each line
310      **/
311     LineFormatter( String comment, int maxLength, String prefix )
312     {
313         this( comment );
314         this.maxLength = maxLength;
315         this.prefix = prefix;
316     } //-- LineFormatter
317 
318     boolean hasMoreLines()
319     {
320         if ( comment == null ) return false;
321         return ( offset < length );
322     } //-- isFinished
323 
324     String nextLine()
325     {
326         if ( comment == null ) return null;
327         if ( offset >= length ) return null;
328 
329         sb.setLength( 0 );
330         if ( prefix != null ) sb.append( prefix );
331 
332         int max = offset + maxLength;
333         if ( max > this.length ) max = this.length;
334 
335 
336         int index = offset;
337         int breakable = offset;
338         for ( ; index < max; index++ )
339         {
340             char ch = comment.charAt( index );
341             if ( isNewLine( ch ) )
342             {
343                 sb.append( comment.substring( offset, index ) );
344                 offset = index + 1;
345                 return sb.toString();
346             }
347             if ( isWhitespace( ch ) ) breakable = index;
348         }
349 
350         if ( index < length - 1 )
351         {
352             //-- if we could not find a breakable character, we must look
353             //-- ahead
354             if ( offset == breakable )
355             {
356                 while ( index < length )
357                 {
358                     if ( isBreakable( comment.charAt( index ) ) ) break;
359                     ++index;
360                 }
361             }
362             else
363                 index = breakable;
364         }
365         sb.append( comment.substring( offset, index ) );
366         offset = index + 1;
367         return sb.toString();
368     } //-- getNextLine
369 
370     /**
371      * Sets the prefix that should be appended to the beginning of
372      * each line
373      * @param prefix the prefix for this LineFormatter
374      **/
375     void setPrefix( String prefix )
376     {
377         this.prefix = prefix;
378     } //-- setPrefix
379 
380     private boolean isBreakable( char ch )
381     {
382         return ( isWhitespace( ch ) || isNewLine( ch ) );
383     }
384 
385     private boolean isWhitespace( char ch )
386     {
387         return ( ( ch == ' ' ) || ( ch == '\t' ) );
388     } //-- isWhitespace
389 
390     private boolean isNewLine( char ch )
391     {
392         return ( ( ch == '\n' ) || ( ch == '\r' ) );
393     } //-- isNewLineChar
394 
395 } //-- LineFormatter
396