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