JspReader is an input buffer for the JSP parser. It should allow
unlimited lookahead and pushback. It also has a bunch of parsing
utility methods for understanding htmlesque thingies.
| Constructor: |
public JspReader(JspCompilationContext ctxt,
String fname,
String encoding,
JarFile jarFile,
ErrorDispatcher err) throws IOException, JasperException, FileNotFoundException {
this(ctxt, fname, encoding,
JspUtil.getReader(fname, encoding, jarFile, ctxt, err),
err);
}
Parameters:
ctxt - The compilation context
fname - The file name
encoding - The file encoding
jarFile - ?
err - The error dispatcher
Throws:
JasperException - If a Jasper-internal error occurs
FileNotFoundException - If the JSP file is not found (or is unreadable)
IOException - If an IO-level error occurs, e.g. reading the file
|
public JspReader(JspCompilationContext ctxt,
String fname,
String encoding,
InputStreamReader reader,
ErrorDispatcher err) throws JasperException, FileNotFoundException {
this.context = ctxt;
this.err = err;
sourceFiles = new Vector();
currFileId = 0;
size = 0;
singleFile = false;
pushFile(fname, encoding, reader);
}
Constructor: same as above constructor but with initialized reader
to the file given. |
| Method from org.apache.jasper.compiler.JspReader Detail: |
String getFile(int fileid) {
return (String) sourceFiles.get(fileid);
}
Returns the file at the given position in the list. |
JspCompilationContext getJspCompilationContext() {
return context;
}
|
URL getResource(String path) throws MalformedURLException {
return context.getResource(path);
}
Gets the URL for the given path name. |
String getText(Mark start,
Mark stop) throws JasperException {
Mark oldstart = mark();
reset(start);
CharArrayWriter caw = new CharArrayWriter();
while (!stop.equals(mark()))
caw.write(nextChar());
caw.close();
reset(oldstart);
return caw.toString();
}
|
boolean hasMoreInput() throws JasperException {
if (current.cursor >= current.stream.length) {
if (singleFile) return false;
while (popFile()) {
if (current.cursor < current.stream.length) return true;
}
return false;
}
return true;
}
Checks if the current file has more input. |
final boolean isSpace() throws JasperException {
// Note: If this logic changes, also update Node.TemplateText.rtrim()
return peekChar() < = ' ";
}
|
Mark mark() {
return new Mark(current);
}
|
boolean matches(String string) throws JasperException {
Mark mark = mark();
int ch = 0;
int i = 0;
do {
ch = nextChar();
if (((char) ch) != string.charAt(i++)) {
reset(mark);
return false;
}
} while (i < string.length());
return true;
}
search the stream for a match to a string |
boolean matchesETag(String tagName) throws JasperException {
Mark mark = mark();
if (!matches("< /" + tagName))
return false;
skipSpaces();
if (nextChar() == ' >")
return true;
reset(mark);
return false;
}
|
boolean matchesETagWithoutLessThan(String tagName) throws JasperException {
Mark mark = mark();
if (!matches("/" + tagName))
return false;
skipSpaces();
if (nextChar() == ' >")
return true;
reset(mark);
return false;
}
|
boolean matchesIgnoreCase(String string) throws JasperException {
Mark mark = mark();
int ch = 0;
int i = 0;
do {
ch = nextChar();
if (Character.toLowerCase((char) ch) != string.charAt(i++)) {
reset(mark);
return false;
}
} while (i < string.length());
reset(mark);
return true;
}
|
boolean matchesOptionalSpacesFollowedBy(String s) throws JasperException {
Mark mark = mark();
skipSpaces();
boolean result = matches( s );
if( !result ) {
reset( mark );
}
return result;
}
Looks ahead to see if there are optional spaces followed by
the given String. If so, true is returned and those spaces and
characters are skipped. If not, false is returned and the
position is restored to where we were before. |
int nextChar() throws JasperException {
if (!hasMoreInput())
return -1;
int ch = current.stream[current.cursor];
current.cursor++;
if (ch == '\n") {
current.line++;
current.col = 0;
} else {
current.col++;
}
return ch;
}
|
String parseToken(boolean quoted) throws JasperException {
StringBuffer stringBuffer = new StringBuffer();
skipSpaces();
stringBuffer.setLength(0);
if (!hasMoreInput()) {
return "";
}
int ch = peekChar();
if (quoted) {
if (ch == '"" || ch == '\'") {
char endQuote = ch == '"" ? '"" : '\'";
// Consume the open quote:
ch = nextChar();
for (ch = nextChar(); ch != -1 && ch != endQuote;
ch = nextChar()) {
if (ch == '\\")
ch = nextChar();
stringBuffer.append((char) ch);
}
// Check end of quote, skip closing quote:
if (ch == -1) {
err.jspError(mark(), "jsp.error.quotes.unterminated");
}
} else {
err.jspError(mark(), "jsp.error.attr.quoted");
}
} else {
if (!isDelimiter()) {
// Read value until delimiter is found:
do {
ch = nextChar();
// Take care of the quoting here.
if (ch == '\\") {
if (peekChar() == '"" || peekChar() == '\'" ||
peekChar() == ' >" || peekChar() == '%")
ch = nextChar();
}
stringBuffer.append((char) ch);
} while (!isDelimiter());
}
}
return stringBuffer.toString();
}
Parse a space delimited token.
If quoted the token will consume all characters up to a matching quote,
otherwise, it consumes up to the first delimiter character. |
int peekChar() throws JasperException {
if (!hasMoreInput())
return -1;
return current.stream[current.cursor];
}
|
void pushChar() {
current.cursor--;
current.col--;
}
Back up the current cursor by one char, assumes current.cursor > 0,
and that the char to be pushed back is not '\n'. |
void reset(Mark mark) {
current = new Mark(mark);
}
|
void setSingleFile(boolean val) {
singleFile = val;
}
|
int skipSpaces() throws JasperException {
int i = 0;
while (hasMoreInput() && isSpace()) {
i++;
nextChar();
}
return i;
}
|
Mark skipUntil(String limit) throws JasperException {
Mark ret = null;
int limlen = limit.length();
int ch;
skip:
for (ret = mark(), ch = nextChar() ; ch != -1 ;
ret = mark(), ch = nextChar()) {
if (ch == limit.charAt(0)) {
Mark restart = mark();
for (int i = 1 ; i < limlen ; i++) {
if (peekChar() == limit.charAt(i))
nextChar();
else {
reset(restart);
continue skip;
}
}
return ret;
}
}
return null;
}
Skip until the given string is matched in the stream.
When returned, the context is positioned past the end of the match. |
Mark skipUntilETag(String tag) throws JasperException {
Mark ret = skipUntil("< /" + tag);
if (ret != null) {
skipSpaces();
if (nextChar() != ' >")
ret = null;
}
return ret;
}
Skip until the given end tag is matched in the stream.
When returned, the context is positioned past the end of the tag. |
Mark skipUntilIgnoreEsc(String limit) throws JasperException {
Mark ret = null;
int limlen = limit.length();
int ch;
int prev = 'x"; // Doesn't matter
skip:
for (ret = mark(), ch = nextChar() ; ch != -1 ;
ret = mark(), prev = ch, ch = nextChar()) {
if (ch == '\\" && prev == '\\") {
ch = 0; // Double \ is not an escape char anymore
}
else if (ch == limit.charAt(0) && prev != '\\") {
for (int i = 1 ; i < limlen ; i++) {
if (peekChar() == limit.charAt(i))
nextChar();
else
continue skip;
}
return ret;
}
}
return null;
}
Skip until the given string is matched in the stream, but ignoring
chars initially escaped by a '\'.
When returned, the context is positioned past the end of the match. |