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      * @param style the comment style
148      **/
149     public JComment( short style )
150     {
151         this();
152         this.style = style;
153     } //-- JComment
154 
155     /**
156      * Appends the comment String to this JDocComment
157      * @param comment the comment to append
158      **/
159     public void appendComment( String comment )
160     {
161         _comment.append( comment );
162     } //-- appendComment
163 
164 
165     /**
166      * prints this JComment using the given JSourceWriter
167      * @param jsw the JSourceWriter to print to
168      **/
169     public void print( JSourceWriter jsw )
170     {
171 
172 
173         if ( jsw == null ) return; //-- nothing to do
174 
175         LineFormatter formatter = null;
176 
177         //-- calculate comment length
178         short currentIndent = jsw.getIndentSize();
179         int maxLength = MAX_LENGTH - currentIndent;
180 
181         //-- a simple to check to make sure we have some room
182         //-- to print the comment
183         if ( maxLength <= 17 ) maxLength = MAX_LENGTH / 2;
184 
185         short resolvedStyle = style;
186 
187         if ( style == AUTO_STYLE )
188         {
189             //-- estimation of number of lines
190             int nbrLines = _comment.length() / maxLength;
191 
192             if ( nbrLines > 2 )
193                 resolvedStyle = BLOCK_STYLE;
194             else
195                 resolvedStyle = LINE_STYLE;
196         }
197 
198 
199 
200         //-- start comment
201         String prefix = null;
202         String start = null;
203         String end = null;
204 
205         switch ( resolvedStyle )
206         {
207             case BLOCK_STYLE:
208                 start = START_BLOCK;
209                 end = END_BLOCK;
210                 prefix = SPACE_PREFIX;
211                 break;
212             case HEADER_STYLE:
213                 start = START_BLOCK;
214                 end = END_BLOCK;
215                 prefix = ASTERIX_PREFIX;
216                 break;
217             case JAVADOC_STYLE:
218                 start = START_JAVADOC;
219                 end = END_JAVADOC;
220                 prefix = ASTERIX_PREFIX;
221                 break;
222             default: //-- LINE
223                 prefix = LINE_COMMENT_PREFIX;
224                 break;
225         }
226         if ( start != null ) jsw.writeln( start );
227         //-- print main comment
228         formatter = new LineFormatter( _comment.toString(), maxLength, prefix );
229         while ( formatter.hasMoreLines() )
230         {
231             jsw.writeln( formatter.nextLine() );
232         }
233         if ( end != null ) jsw.writeln( end );
234         jsw.flush();
235     } //-- print
236 
237     /**
238      * Sets the comment String of this JDocComment
239      * @param comment the comment String of this JDocComment
240      **/
241     public void setComment( String comment )
242     {
243         _comment.setLength( 0 );
244         _comment.append( comment );
245     } //-- setComment
246 
247     /**
248      * Sets the style for this JComment
249      * @param style the style to use for this JComment
250      **/
251     public void setStyle( short style )
252     {
253         this.style = style;
254     } //-- setStyle
255 
256     /**
257      * Returns the String representation of this Java Doc Comment
258      * @return the String representation of this Java Doc Comment
259      **/
260     public String toString()
261     {
262         return "";
263     } //-- toString
264 
265 } //-- JComment
266 
267 /**
268  * Formats a given String for use within a Java comment
269  * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
270  **/
271 class LineFormatter
272 {
273 
274     String comment = null;
275 
276     int maxLength = 65;
277     int offset = 0;
278     int length = 0;
279 
280     String prefix = null;
281 
282     private StringBuffer sb = null;
283 
284     /**
285      * Creates a LineFormatter for the given comment
286      * @param comment the String to format
287      **/
288     LineFormatter( String comment )
289     {
290         this.comment = comment;
291         if ( comment != null ) this.length = comment.length();
292         sb = new StringBuffer();
293     } //-- LineFormatter
294 
295 
296     /**
297      * Creates a new LineFormatter for the given comment
298      * @param comment the String to format
299      * @param maxLength the maximum number of characters per line
300      **/
301     LineFormatter( String comment, int maxLength )
302     {
303         this( comment, maxLength, null );
304     } //-- LineFormatter
305 
306 
307     /**
308      * Creates a new LineFormatter for the given comment
309      * @param comment the String to format
310      * @param maxLength the maximum number of characters per line
311      * @param prefix a prefix to append to the beginning of each line
312      **/
313     LineFormatter( String comment, int maxLength, String prefix )
314     {
315         this( comment );
316         this.maxLength = maxLength;
317         this.prefix = prefix;
318     } //-- LineFormatter
319 
320     boolean hasMoreLines()
321     {
322         if ( comment == null ) return false;
323         return ( offset < length );
324     } //-- isFinished
325 
326     String nextLine()
327     {
328         if ( comment == null ) return null;
329         if ( offset >= length ) return null;
330 
331         sb.setLength( 0 );
332         if ( prefix != null ) sb.append( prefix );
333 
334         int max = offset + maxLength;
335         if ( max > this.length ) max = this.length;
336 
337 
338         int index = offset;
339         int breakable = offset;
340         for ( ; index < max; index++ )
341         {
342             char ch = comment.charAt( index );
343             if ( isNewLine( ch ) )
344             {
345                 sb.append( comment.substring( offset, index ) );
346                 offset = index + 1;
347                 return sb.toString();
348             }
349             if ( isWhitespace( ch ) ) breakable = index;
350         }
351 
352         if ( index < length - 1 )
353         {
354             //-- if we could not find a breakable character, we must look
355             //-- ahead
356             if ( offset == breakable )
357             {
358                 while ( index < length )
359                 {
360                     if ( isBreakable( comment.charAt( index ) ) ) break;
361                     ++index;
362                 }
363             }
364             else
365                 index = breakable;
366         }
367         sb.append( comment.substring( offset, index ) );
368         offset = index + 1;
369         return sb.toString();
370     } //-- getNextLine
371 
372     /**
373      * Sets the prefix that should be appended to the beginning of
374      * each line
375      * @param prefix the prefix for this LineFormatter
376      **/
377     void setPrefix( String prefix )
378     {
379         this.prefix = prefix;
380     } //-- setPrefix
381 
382     private boolean isBreakable( char ch )
383     {
384         return ( isWhitespace( ch ) || isNewLine( ch ) );
385     }
386 
387     private boolean isWhitespace( char ch )
388     {
389         return ( ( ch == ' ' ) || ( ch == '\t' ) );
390     } //-- isWhitespace
391 
392     private boolean isNewLine( char ch )
393     {
394         return ( ( ch == '\n' ) || ( ch == '\r' ) );
395     } //-- isNewLineChar
396 
397 } //-- LineFormatter
398