Class EspReader

java.lang.Object
java.io.Reader
java.io.FilterReader
org.apache.sling.scripting.javascript.io.EspReader
All Implemented Interfaces:
Closeable, AutoCloseable, Readable

public class EspReader extends FilterReader
The EspReader is a FilterReader which takes JSP like input and produces plain ECMA script output. The filtering modifications done on the input comprise the following :
  • Template text (HTML) is wrapped by out.write(). At most one line of text is wrapped into a single write() call. Double quote characters in the template text (e.g. for HTML tag attribute values) are escaped.
  • ECMA code is written to the output as is.
  • ECMA slash star (/*) comments are also written as is.
  • ECMA slash slash (//) comments are written as is.
  • JSP style template comments (<%-- -->) are also removed from the stream. Lineendings (LFs and CRLFs) are written, though.
  • HTML comments (<!-- -->) are not treated specially. Rather they are handled as plain template text written to the output wrapped in out.write(). The consequence of this behaviour is, that as in JSP ECMA expressions may be included within the comments.

The nice thing about this reader is, that the line numbers of the resulting stream match the line numbers of the matching contents of the input stream. Due to the insertion of write() calls, column numbers will not necessarily match, though. This is especially true if you mix ECMA code tags (<% %>) with template text on the same line.

For maximum performance it is advisable to not create the EspReader with a plain FileReader or InputStreamReader but rather with a BufferedReader based on one of the simpler Readers. The reasons for this is, that we call the base reader character by character. This in turn is not too performing if the base reader does not buffer its input.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    Javascript statement that sets the "out" variable that's used to output data.

    Fields inherited from class java.io.FilterReader

    in

    Fields inherited from class java.io.Reader

    lock
  • Constructor Summary

    Constructors
    Constructor
    Description
    EspReader(Reader baseReader)
    Create an EspReader on top of the given baseReader.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Close the EspReader.
    void
    mark(int readAheadLimit)
    Mark the present position in the stream.
    boolean
    Tell whether this stream supports the mark() operation, which it does not.
    int
    Return the next filtered character.
    int
    read(char[] cbuf)
    Fill the given buffer with filtered or injected characters.
    int
    read(char[] cbuf, int off, int len)
    Fill the buffer from the offset with the number of characters given.
    boolean
    Check whether we may block at the next read() operation.
    void
    Reset the stream.
    void
    Set the code fragment used to initialize the "out" variable
    long
    skip(long n)
    Skip the number of filtered characters.

    Methods inherited from class java.io.Reader

    nullReader, read, transferTo

    Methods inherited from class java.lang.Object

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

    • DEFAULT_OUT_INIT_STATEMENT

      public static final String DEFAULT_OUT_INIT_STATEMENT
      Javascript statement that sets the "out" variable that's used to output data. Automatically inserted by the reader in code, where needed.
      See Also:
  • Constructor Details

    • EspReader

      public EspReader(Reader baseReader)
      Create an EspReader on top of the given baseReader. The constructor wraps the input reader with a PushbackReader, so that input stream modifications may be handled transparently by our doRead() method.
      Parameters:
      baseReader - the wrapped reader
  • Method Details

    • setOutInitStatement

      public void setOutInitStatement(String statement)
      Set the code fragment used to initialize the "out" variable
      Parameters:
      statement - the statement used for initialization
    • ready

      public boolean ready() throws IOException
      Check whether we may block at the next read() operation. We may be ready if and only if our input reader is ready. But this does not guarantee that we won't block, as due to filtering there may be more than one character needed from the input to return one.
      Overrides:
      ready in class FilterReader
      Returns:
      true if a character is available on the PushbackReader.
      Throws:
      IOException - if the reader is not open
    • read

      public int read() throws IOException
      Return the next filtered character. This need not be the next character of the input stream. It may be a character from the input reader, after having skipped filtered characters or it may be a character injected due to translation of template text to ECMA code.
      Overrides:
      read in class FilterReader
      Returns:
      the next character after filtering or -1 at the end of the input reader
      Throws:
      IOException - if the reader is not open
    • read

      public int read(char[] cbuf) throws IOException
      Fill the given buffer with filtered or injected characters. This need not be the next characters of the input stream. It may be characters from the input reader, after having skipped filtered characters or it may be a characters injected due to translation of template text to ECMA code. This method is exactly the same as read(cbuf, 0, cbuf.length).
      Overrides:
      read in class Reader
      Parameters:
      cbuf - The character buffer to fill with (filtered) characters
      Returns:
      the number of characters filled in the buffer or -1 at the end of the input reader.
      Throws:
      IOException - if the reader is not open
    • read

      public int read(char[] cbuf, int off, int len) throws IOException
      Fill the buffer from the offset with the number of characters given. This need not be the next characters of the input stream. It may be characters from the input reader, after having skipped filtered characters or it may be a characters injected due to translation of template text to ECMA code.
      Overrides:
      read in class FilterReader
      Parameters:
      cbuf - The character buffer to fill with (filtered) characters
      off - Offset from where to start in the buffer
      len - The number of characters to fill into the buffer
      Returns:
      the number of characters filled in the buffer or -1 at the end of the input reader.
      Throws:
      IOException - if the reader is not open
      IndexOutOfBoundsException - if len is negative, off is negative or higher than the buffer length or off+len is negative or beyond the buffer size.
    • skip

      public long skip(long n) throws IOException
      Skip the number of filtered characters. The skip method is the same as calling read() repeatedly for the given number of characters and throwing away the result. If the end of input reader is reached before having skipped the number of characters, the method returns the number characters skipped so far.
      Overrides:
      skip in class FilterReader
      Parameters:
      n - the number of (filtered) characters to skip
      Returns:
      the number of (filtered) characters actually skipped
      Throws:
      IllegalArgumentException - if n is negative
      IOException - if the reading the characters throws
    • close

      public void close() throws IOException
      Close the EspReader.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Overrides:
      close in class FilterReader
      Throws:
      IOException
    • mark

      public void mark(int readAheadLimit) throws IOException
      Mark the present position in the stream. The mark for class EspReader always throws an throwable.
      Overrides:
      mark in class FilterReader
      Parameters:
      readAheadLimit - The number of characters to read ahead
      Throws:
      IOException - Always, since mark is not supported
    • markSupported

      public boolean markSupported()
      Tell whether this stream supports the mark() operation, which it does not.
      Overrides:
      markSupported in class FilterReader
      Returns:
      false Always, since mark is not supported
    • reset

      public void reset() throws IOException
      Reset the stream. The reset method of EspReader always throws an throwable.
      Overrides:
      reset in class FilterReader
      Throws:
      IOException - Always, since reset is not supported