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 }