001package org.unix4j.io;
002
003import java.io.IOException;
004import java.io.Writer;
005
006import org.unix4j.line.Line;
007
008/**
009 * Output device based on a {@link Writer}.
010 */
011public class WriterOutput implements Output {
012
013        private final Writer writer;
014
015        private Line lastTerminatedLine;
016        private Line lastLine;
017
018        public WriterOutput(Writer writer) {
019                this.writer = writer;
020                init();
021        }
022
023        private void init() {
024                lastTerminatedLine = Line.EMPTY_LINE;
025                lastLine = null;
026        }
027
028        /**
029         * Returns the underlying writer that was passed to the constructor.
030         * 
031         * @return the writer that was passed to the constructor.
032         */
033        protected Writer getWriter() {
034                return writer;
035        }
036
037        @Override
038        public boolean processLine(Line line) {
039                try {
040                        if (lastLine != null) {
041                                writer.write(lastTerminatedLine.getLineEnding());
042                        }
043                        writer.write(line.getContent());
044                } catch (IOException e) {
045                        throw new RuntimeException(e);
046                }
047                lastLine = line;
048                if (line.getLineEndingLength() > 0) {
049                        lastTerminatedLine = line;
050                }
051                return true;
052        }
053
054        @Override
055        public void finish() {
056                try {
057                        if (lastLine != null && writeLastLineEnding()) {
058                                writer.write(lastLine.getLineEnding());
059                        }
060                        writer.flush();
061                        init();
062                } catch (IOException e) {
063                        throw new RuntimeException(e);
064                }
065        }
066
067        /**
068         * Returns true if the last line ending should be written.
069         * <p>
070         * This default implementation always returns true, but certain subclasses
071         * such as {@link StringOutput} sometimes return false when the last line
072         * should <i>not</i> be terminated with a line ending.
073         * 
074         * @return true if the last line ending should be written, and false
075         *         otherwise
076         */
077        protected boolean writeLastLineEnding() {
078                return true;
079        }
080
081}