View Javadoc
1   package org.apache.maven.doxia.util;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.codehaus.plexus.util.IOUtil;
23  
24  import java.io.BufferedWriter;
25  import java.io.IOException;
26  import java.io.Writer;
27  
28  /**
29   * Allows to specify the line-length of an output writer.
30   */
31  public class LineBreaker
32  {
33      /** The default maximal line length. */
34      public static final int DEFAULT_MAX_LINE_LENGTH = 78;
35  
36      /** The system dependent EOL. */
37      private static final String EOL = System.getProperty( "line.separator" );
38  
39      /** The destination writer. */
40      private Writer destination;
41  
42      /** The writer to use. */
43      private BufferedWriter writer;
44  
45      /** The maximal line length. */
46      private int maxLineLength;
47  
48      /** The current line length. */
49      private int lineLength = 0;
50  
51      /** The string buffer to store the current text. */
52      private StringBuilder word = new StringBuilder( 1024 );
53  
54      /**
55       * Constructs a new LineBreaker with DEFAULT_MAX_LINE_LENGTH.
56       *
57       * @param out The writer to use.
58       */
59      public LineBreaker( Writer out )
60      {
61          this( out, DEFAULT_MAX_LINE_LENGTH );
62      }
63  
64      /**
65       * Constructs a new LineBreaker with the given max line length.
66       *
67       * @param out The writer to use.
68       * @param max The maximal line length.
69       */
70      public LineBreaker( Writer out, int max )
71      {
72          if ( max <= 0 )
73          {
74              throw new IllegalArgumentException( "maxLineLength <= 0" );
75          }
76  
77          destination = out;
78          this.maxLineLength = max;
79          writer = new BufferedWriter( out );
80      }
81  
82      /**
83       * Returns the current destination writer.
84       *
85       * @return The destination.
86       */
87      public Writer getDestination()
88      {
89          return destination;
90      }
91  
92      /**
93       * Writes the given text to the writer. White space is not preserved.
94       *
95       * @param text The text to write.
96       * @throws java.io.IOException if there's a problem writing the text.
97       */
98      public void write( String text )
99          throws IOException
100     {
101         write( text, /*preserveSpace*/false );
102     }
103 
104     /**
105      * Writes the given text to the writer.
106      *
107      * @param text The text to write.
108      * @param preserveSpace True to preserve white space.
109      */
110     public void write( String text, boolean preserveSpace )
111     {
112         int length = text.length();
113 
114         try
115         {
116             for ( int i = 0; i < length; ++i )
117             {
118                 char c = text.charAt( i );
119 
120                 switch ( c )
121                 {
122                     case ' ':
123                         if ( preserveSpace )
124                         {
125                             word.append( c );
126                         }
127                         else
128                         {
129                             writeWord();
130                         }
131                         break;
132 
133                     case '\r':
134                         // if \r\n (windows) then just pass along \n
135                         if ( i + 1 < length && text.charAt( i + 1 ) == '\n' )
136                         {
137                             break;
138                         }
139 
140                     case '\n':
141                         writeWord();
142                         writer.write( EOL );
143                         lineLength = 0;
144                         break;
145 
146                     default:
147                         word.append( c );
148                 }
149 
150             }
151         }
152         catch ( Exception e )
153         {
154             // TODO: log
155         }
156     }
157 
158     /**
159      * Write out the current StringBuilder and flush the writer.
160      * Any IOException will be swallowed.
161      */
162     public void flush()
163     {
164         try
165         {
166             writeWord();
167             writer.flush();
168         }
169         catch ( IOException e )
170         {
171             // TODO: log
172         }
173     }
174 
175     /**
176      * Writes the current StringBuilder to the writer.
177      *
178      * @throws IOException if an exception occurs during writing.
179      */
180     private void writeWord()
181         throws IOException
182     {
183         int length = word.length();
184         if ( length > 0 )
185         {
186             if ( lineLength > 0 )
187             {
188                 if ( lineLength + 1 + length > maxLineLength )
189                 {
190                     writer.write( EOL );
191                     lineLength = 0;
192                 }
193                 else
194                 {
195                     writer.write( ' ' );
196                     ++lineLength;
197                 }
198             }
199 
200             writer.write( word.toString() );
201             word.setLength( 0 );
202 
203             lineLength += length;
204         }
205     }
206 
207     /**
208      * Close the writer.
209      */
210     public void close()
211     {
212         IOUtil.close( writer );
213     }
214 }