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 * @version $Id: LineBreaker.java 1438269 2013-01-24 23:47:50Z olamy $
32 */
33 public class LineBreaker
34 {
35 /** The default maximal line length. */
36 public static final int DEFAULT_MAX_LINE_LENGTH = 78;
37
38 /** The system dependent EOL. */
39 private static final String EOL = System.getProperty( "line.separator" );
40
41 /** The destination writer. */
42 private Writer destination;
43
44 /** The writer to use. */
45 private BufferedWriter writer;
46
47 /** The maximal line length. */
48 private int maxLineLength;
49
50 /** The current line length. */
51 private int lineLength = 0;
52
53 /** The string buffer to store the current text. */
54 private StringBuilder word = new StringBuilder( 1024 );
55
56 /**
57 * Constructs a new LineBreaker with DEFAULT_MAX_LINE_LENGTH.
58 *
59 * @param out The writer to use.
60 */
61 public LineBreaker( Writer out )
62 {
63 this( out, DEFAULT_MAX_LINE_LENGTH );
64 }
65
66 /**
67 * Constructs a new LineBreaker with the given max line length.
68 *
69 * @param out The writer to use.
70 * @param max The maximal line length.
71 */
72 public LineBreaker( Writer out, int max )
73 {
74 if ( max <= 0 )
75 {
76 throw new IllegalArgumentException( "maxLineLength <= 0" );
77 }
78
79 destination = out;
80 this.maxLineLength = max;
81 writer = new BufferedWriter( out );
82 }
83
84 /**
85 * Returns the current destination writer.
86 *
87 * @return The destination.
88 */
89 public Writer getDestination()
90 {
91 return destination;
92 }
93
94 /**
95 * Writes the given text to the writer. White space is not preserved.
96 *
97 * @param text The text to write.
98 * @throws java.io.IOException if there's a problem writing the text.
99 */
100 public void write( String text )
101 throws IOException
102 {
103 write( text, /*preserveSpace*/false );
104 }
105
106 /**
107 * Writes the given text to the writer.
108 *
109 * @param text The text to write.
110 * @param preserveSpace True to preserve white space.
111 */
112 public void write( String text, boolean preserveSpace )
113 {
114 int length = text.length();
115
116 try
117 {
118 for ( int i = 0; i < length; ++i )
119 {
120 char c = text.charAt( i );
121
122 switch ( c )
123 {
124 case ' ':
125 if ( preserveSpace )
126 {
127 word.append( c );
128 }
129 else
130 {
131 writeWord();
132 }
133 break;
134
135 case '\r':
136 // if \r\n (windows) then just pass along \n
137 if ( i + 1 < length && text.charAt( i + 1 ) == '\n' )
138 {
139 break;
140 }
141
142 case '\n':
143 writeWord();
144 writer.write( EOL );
145 lineLength = 0;
146 break;
147
148 default:
149 word.append( c );
150 }
151
152 }
153 }
154 catch ( Exception e )
155 {
156 // TODO: log
157 }
158 }
159
160 /**
161 * Write out the current StringBuilder and flush the writer.
162 * Any IOException will be swallowed.
163 */
164 public void flush()
165 {
166 try
167 {
168 writeWord();
169 writer.flush();
170 }
171 catch ( IOException e )
172 {
173 // TODO: log
174 }
175 }
176
177 /**
178 * Writes the current StringBuilder to the writer.
179 *
180 * @throws IOException if an exception occurs during writing.
181 */
182 private void writeWord()
183 throws IOException
184 {
185 int length = word.length();
186 if ( length > 0 )
187 {
188 if ( lineLength > 0 )
189 {
190 if ( lineLength + 1 + length > maxLineLength )
191 {
192 writer.write( EOL );
193 lineLength = 0;
194 }
195 else
196 {
197 writer.write( ' ' );
198 ++lineLength;
199 }
200 }
201
202 writer.write( word.toString() );
203 word.setLength( 0 );
204
205 lineLength += length;
206 }
207 }
208
209 /**
210 * Close the writer.
211 */
212 public void close()
213 {
214 IOUtil.close( writer );
215 }
216 }