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