Class LineAppender

java.lang.Object
org.apache.sis.io.Appender
org.apache.sis.io.LineAppender
All Implemented Interfaces:
Flushable, Appendable
Direct Known Subclasses:
PropertyFormat

public class LineAppender extends Appender implements Flushable
An Appendable which can apply different kinds of reformatting that depend on the End Of Line (EOL) occurrences. Available reformatting include inserting a a margin before each line, wrapping to a maximal line length and replacing tabulations or EOL characters. The actual work to be done can be enabled by invoking one or many of the following methods: In addition this class removes trailing whitespaces before end of lines.

How line lengths are calculated

Line length are measured in unit of Unicode code points. This is usually the same than the number of char primitive values, but not always. Combining characters are not yet recognized by this class, but future versions may improve on that.

For proper line length calculation in presence of tabulation characters ('\t'), this class needs to known the tabulation width. The default value is 8, but this can be changed by a call to setTabulationWidth(int). Note that invoking that method affects only line length calculation; it does not replace tabulations by spaces. For tabulation expansion, see setTabulationExpanded(boolean).

Since:
0.3
Version:
0.4
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private final StringBuilder
    The buffer for the last word being written.
    private int
    The length of the current line, in units of code points (not char).
    private boolean
    true if all occurrences of EOL sequences shall be replaced by the lineSeparator, or false for keeping EOL unchanged.
    private boolean
    true if an escape sequence is in progress.
    private boolean
    true if the next character will be at the beginning of a new line.
    private boolean
    true if this formatter shall expands tabulations into spaces.
    private String
    The line separator, or null if not yet determined.
    private int
    The maximal line length, in units of code points (not char).
    private int
    The number of Java characters (not Unicode code points) in buffer, ignoring trailing whitespaces.
    private boolean
    true if the next character needs to be skipped if equals to '\n'.
    private short
    The tabulation width, in number of code points.

    Fields inherited from class org.apache.sis.io.Appender

    out
  • Constructor Summary

    Constructors
    Constructor
    Description
    Constructs a default formatter.
    LineAppender(Appendable out, int maximalLineLength, boolean isTabulationExpanded)
    Constructs a formatter which will wrap the lines at a given maximal length.
    LineAppender(Appendable out, String lineSeparator, boolean isTabulationExpanded)
    Constructs a formatter which will replaces line separators by the given string.
  • Method Summary

    Modifier and Type
    Method
    Description
    append(char c)
    Writes a single character.
    append(CharSequence sequence, int start, int end)
    Writes a portion of a character sequence.
    void
    Resets the LineAppender internal state as if a new line was beginning.
    private void
    Removes the soft hyphen characters from the given buffer.
    private void
    Writes pending non-white characters, discards trailing whitespaces, and resets column position to zero.
    void
    Sends all pending characters to the underlying appendable, including trailing whitespaces.
    Returns the line separator to be sent to the underlying appendable, or null if EOL sequences are forwarded unchanged.
    int
    Returns the maximal line length, in unit of Unicode characters (code point count).
    int
    Returns the current tabulation width, in unit of Unicode characters (code point count).
    boolean
    Returns true if this formatter expands tabulations into spaces.
    protected void
    onLineBegin(boolean isContinuation)
    Invoked when a new line is beginning.
    void
    setLineSeparator(String lineSeparator)
    Changes the line separator to be sent to the underlying appendable.
    void
    Sets the maximal line length, in units of Unicode characters (code point count).
    void
    setTabulationExpanded(boolean expanded)
    Sets whether this class formatter expands tabulations into spaces.
    void
    setTabulationWidth(int width)
    Sets the tabulation width, in unit of Unicode characters (code point count).
    private void
    transfer(int length)
    Writes the given amount of characters from the buffer, then removes those characters from the buffer.
    private void
    write(int c)
    Writes the specified code point.
    private void
    Writes a line separator to Appender.out.

    Methods inherited from class org.apache.sis.io.Appender

    append, appendCodePoint, appendSurrogate, isHighSurrogate, lineSeparator, toCodePoint, toString

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • lineSeparator

      private String lineSeparator
      The line separator, or null if not yet determined. If null, then the append(CharSequence, int, int) method will try to infer it from the submitted text.

      If isEndOfLineReplaced is false (the default), then this line separator will be used only when this class inserts new line separators as a consequence of line wraps; line separators found in the texts given by the user will be passed "as is". If true, then all line separators are replaced.

    • maximalLineLength

      private int maximalLineLength
      The maximal line length, in units of code points (not char). Can be set to Integer.MAX_VALUE if there is no limit.
      See Also:
    • codePointCount

      private int codePointCount
      The length of the current line, in units of code points (not char). It may be greater than the length of buffer because the latter contains only the last word.
    • tabulationWidth

      private short tabulationWidth
      The tabulation width, in number of code points.
      See Also:
    • isTabulationExpanded

      private boolean isTabulationExpanded
      true if this formatter shall expands tabulations into spaces.
      See Also:
    • isEndOfLineReplaced

      private boolean isEndOfLineReplaced
      true if all occurrences of EOL sequences shall be replaced by the lineSeparator, or false for keeping EOL unchanged.
    • skipLF

      private boolean skipLF
      true if the next character needs to be skipped if equals to '\n'. This field is used in order to avoid writing two EOL in place of "\r\n".
    • isNewLine

      private boolean isNewLine
      true if the next character will be at the beginning of a new line. This flag is set to true only for "real" new lines, as a result of line separator found in the input given to this formatter. The "generated" new lines (resulting from line wrap) will invoke onLineBegin(boolean) directly without the help of this temporary variable.
      See Also:
    • isEscapeSequence

      private boolean isEscapeSequence
      true if an escape sequence is in progress. The escape sequence will stop after the first non-digit character other than X364.BRACKET.
    • buffer

      private final StringBuilder buffer
      The buffer for the last word being written. This buffer will also contain trailing whitespace characters. If whitespaces are followed by at least one non-white character, then the whitespaces are written to the underlying stream before the non-ignorable one. Otherwise if whitespaces are followed by a line separator, then they are discarded.
    • printableLength

      private int printableLength
      The number of Java characters (not Unicode code points) in buffer, ignoring trailing whitespaces.
  • Constructor Details

    • LineAppender

      public LineAppender(Appendable out)
      Constructs a default formatter. Callers should invoke at least one of the following methods after construction in order to perform useful work:
      Parameters:
      out - the underlying stream or buffer to write to.
    • LineAppender

      public LineAppender(Appendable out, String lineSeparator, boolean isTabulationExpanded)
      Constructs a formatter which will replaces line separators by the given string.
      Parameters:
      out - the underlying stream or buffer to write to.
      lineSeparator - the line separator to send to out, or null for forwarding the EOL sequences unchanged.
      isTabulationExpanded - true for expanding tabulations into spaces, or false for sending '\t' characters as-is.
    • LineAppender

      public LineAppender(Appendable out, int maximalLineLength, boolean isTabulationExpanded)
      Constructs a formatter which will wrap the lines at a given maximal length.
      Parameters:
      out - the underlying stream or buffer to write to.
      maximalLineLength - the maximal number of Unicode characters per line, or Integer.MAX_VALUE if there is no limit.
      isTabulationExpanded - true for expanding tabulations into spaces, or false for forwarding '\t' characters as-is.
  • Method Details

    • getMaximalLineLength

      public int getMaximalLineLength()
      Returns the maximal line length, in unit of Unicode characters (code point count). The default value is no limit.
      Returns:
      the current maximal number of Unicode characters per line, or Integer.MAX_VALUE if there is no limit.
    • setMaximalLineLength

      public void setMaximalLineLength(int length)
      Sets the maximal line length, in units of Unicode characters (code point count).
      Parameters:
      length - the new maximal number of Unicode characters per line, or Integer.MAX_VALUE if there is no limit.
    • getTabulationWidth

      public int getTabulationWidth()
      Returns the current tabulation width, in unit of Unicode characters (code point count). The default value is 8.
      Returns:
      the current tabulation width in number of Unicode characters.
    • setTabulationWidth

      public void setTabulationWidth(int width)
      Sets the tabulation width, in unit of Unicode characters (code point count).
      Parameters:
      width - the new tabulation width. Must be greater than 0.
      Throws:
      IllegalArgumentException - if tabWidth is not greater than 0 or is unreasonably high.
    • isTabulationExpanded

      public boolean isTabulationExpanded()
      Returns true if this formatter expands tabulations into spaces. The default value is false, which means that '\t' characters are sent to the underlying appendable as-is.
      Returns:
      true if this formatter expands tabulations into spaces, or false if '\t' characters are forwarded as-is.
    • setTabulationExpanded

      public void setTabulationExpanded(boolean expanded)
      Sets whether this class formatter expands tabulations into spaces.
      Parameters:
      expanded - true if this class shall expands tabulations into spaces, or false for forwarding '\t' characters as-is.
    • getLineSeparator

      public String getLineSeparator()
      Returns the line separator to be sent to the underlying appendable, or null if EOL sequences are forwarded unchanged.
      Returns:
      the current line separator, or null if EOL are forwarded as-is.
    • setLineSeparator

      public void setLineSeparator(String lineSeparator)
      Changes the line separator to be sent to the underlying appendable. This is the string to insert in place of every occurrences of "\r", "\n", "\r\n" or other line separators. If null (the default), then the line separators given to the append methods are forwarded unchanged.
      Parameters:
      lineSeparator - the new line separator, or null for forwarding EOL as-is.
      See Also:
    • writeLineSeparator

      private void writeLineSeparator() throws IOException
      Writes a line separator to Appender.out. This method is invoked for new line separators generated by this class, not for the line separators found in the texts supplied by the user, unless isEndOfLineReplaced is true. The append(CharSequence,int,int) method tries to detect the line separator used in the text, but if no line separator has been found we have to use some fallback.
      Throws:
      IOException
    • endOfLine

      private void endOfLine() throws IOException
      Writes pending non-white characters, discards trailing whitespaces, and resets column position to zero. This method does not write the line separator and does not modify the status of the skipLF flag; those tasks are caller's responsibility.
      Throws:
      IOException
    • deleteSoftHyphen

      private void deleteSoftHyphen(int i)
      Removes the soft hyphen characters from the given buffer. This is invoked when the buffer is about to be written without being split on two lines.
      Parameters:
      i - index after the last character to check. This is either printableLength for checking all characters, or printableLength-1 for preserving the last soft hyphen on the line (while removing all others).
    • transfer

      private void transfer(int length) throws IOException
      Writes the given amount of characters from the buffer, then removes those characters from the buffer. This method does not adjust printableLength; it is caller responsibility to do so.
      Throws:
      IOException
    • write

      private void write(int c) throws IOException
      Writes the specified code point.
      Throws:
      IOException - if an I/O error occurs.
    • append

      public Appendable append(char c) throws IOException
      Writes a single character.
      Specified by:
      append in interface Appendable
      Parameters:
      c - the character to append.
      Returns:
      a reference to this Appendable.
      Throws:
      IOException - if an I/O error occurs.
    • append

      public Appendable append(CharSequence sequence, int start, int end) throws IOException
      Writes a portion of a character sequence.
      Specified by:
      append in interface Appendable
      Parameters:
      sequence - the character sequence to be written.
      start - index from which to start reading characters.
      end - index of the character following the last character to read.
      Returns:
      a reference to this Appendable.
      Throws:
      IOException - if an I/O error occurs.
    • clear

      public void clear() throws IOException
      Resets the LineAppender internal state as if a new line was beginning. Trailing whitespaces not yet sent to the underlying appendable are discarded, and the column position (for tabulation expansion calculation) is reset to 0. This method does not write any line separator.
      Throws:
      IOException - if an error occurred while sending the trailing non-white characters to the underlying stream.
    • flush

      public void flush() throws IOException
      Sends all pending characters to the underlying appendable, including trailing whitespaces. Note that this method should preferably be invoked at the end of a word, sentence or line, since invoking this method may prevent LineAppender to properly wrap the current line if the current position is in the middle of a word.

      Invoking this method also flushes the underlying stream, if flushable. A cheaper way to send pending characters is to make sure that the last character is a line or paragraph terminator, or to invoke clear().

      Specified by:
      flush in interface Flushable
      Throws:
      IOException - if an I/O error occurs.
    • onLineBegin

      protected void onLineBegin(boolean isContinuation) throws IOException
      Invoked when a new line is beginning. The default implementation does nothing, but subclasses can override this method for example in order to insert a margin on the left side before each line.

      If an implementation wishes to write characters, it shall do so by writing directly to Appender.out, not by invoking the append methods of this class.

      Parameters:
      isContinuation - true if the new line is the continuation of the previous line after a "line wrap", or false if a line or paragraph separator has been explicitly sent to this formatter.
      Throws:
      IOException - if an error occurred while writing to Appender.out.