001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.doxia.util;
020
021import java.io.BufferedWriter;
022import java.io.IOException;
023import java.io.Writer;
024
025/**
026 * Allows to specify the line-length of an output writer.
027 *
028 * @deprecated no longer used by Doxia and scheduled for removal in 2.3.0. It also swallows every
029 * write failure, so a failing writer would produce a silently truncated file.
030 */
031@Deprecated
032public class LineBreaker {
033    /** The default maximal line length. */
034    public static final int DEFAULT_MAX_LINE_LENGTH = 78;
035
036    /** The system dependent EOL. */
037    private static final String EOL = System.getProperty("line.separator");
038
039    /** The destination writer. */
040    private Writer destination;
041
042    /** The writer to use. */
043    private BufferedWriter writer;
044
045    /** The maximal line length. */
046    private int maxLineLength;
047
048    /** The current line length. */
049    private int lineLength = 0;
050
051    /** The string buffer to store the current text. */
052    private StringBuilder word = new StringBuilder(1024);
053
054    /**
055     * Constructs a new LineBreaker with DEFAULT_MAX_LINE_LENGTH.
056     *
057     * @param out The writer to use.
058     */
059    public LineBreaker(Writer out) {
060        this(out, DEFAULT_MAX_LINE_LENGTH);
061    }
062
063    /**
064     * Constructs a new LineBreaker with the given max line length.
065     *
066     * @param out The writer to use.
067     * @param max The maximal line length.
068     */
069    public LineBreaker(Writer out, int max) {
070        if (max <= 0) {
071            throw new IllegalArgumentException("max must be a positive integer");
072        }
073
074        destination = out;
075        this.maxLineLength = max;
076        writer = new BufferedWriter(out);
077    }
078
079    /**
080     * Returns the current destination writer.
081     *
082     * @return The destination.
083     */
084    public Writer getDestination() {
085        return destination;
086    }
087
088    /**
089     * Writes the given text to the writer. White space is not preserved.
090     *
091     * @param text The text to write.
092     * @throws java.io.IOException if there's a problem writing the text.
093     */
094    public void write(String text) throws IOException {
095        write(text, /*preserveSpace*/ false);
096    }
097
098    /**
099     * Writes the given text to the writer.
100     *
101     * @param text The text to write.
102     * @param preserveSpace True to preserve white space.
103     */
104    public void write(String text, boolean preserveSpace) {
105        int length = text.length();
106
107        try {
108            for (int i = 0; i < length; ++i) {
109                char c = text.charAt(i);
110
111                switch (c) {
112                    case ' ':
113                        if (preserveSpace) {
114                            word.append(c);
115                        } else {
116                            writeWord();
117                        }
118                        break;
119
120                    case '\r':
121                        // if \r\n (windows) then just pass along \n
122                        if (i + 1 < length && text.charAt(i + 1) == '\n') {
123                            break;
124                        }
125
126                    case '\n':
127                        writeWord();
128                        writer.write(EOL);
129                        lineLength = 0;
130                        break;
131
132                    default:
133                        word.append(c);
134                }
135            }
136        } catch (Exception e) {
137            // TODO: log
138        }
139    }
140
141    /**
142     * Write out the current StringBuilder and flush the writer.
143     * Any IOException will be swallowed.
144     */
145    public void flush() {
146        try {
147            writeWord();
148            writer.flush();
149        } catch (IOException e) {
150            // TODO: log
151        }
152    }
153
154    /**
155     * Writes the current StringBuilder to the writer.
156     *
157     * @throws IOException if an exception occurs during writing.
158     */
159    private void writeWord() throws IOException {
160        int length = word.length();
161        if (length > 0) {
162            if (lineLength > 0) {
163                if (lineLength + 1 + length > maxLineLength) {
164                    writer.write(EOL);
165                    lineLength = 0;
166                } else {
167                    writer.write(' ');
168                    ++lineLength;
169                }
170            }
171
172            writer.write(word.toString());
173            word.setLength(0);
174
175            lineLength += length;
176        }
177    }
178
179    /**
180     * Close the writer.
181     */
182    public void close() {
183        if (writer == null) {
184            return;
185        }
186
187        try {
188            writer.close();
189        } catch (IOException ex) {
190            // ignore
191        }
192    }
193}